blob: cbe1c779bc5626cd026d088d88a7167942d71f95 [file] [log] [blame]
Doris Ling9ed29a22017-11-02 16:42:45 -07001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5 * except in compliance with the License. You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software distributed under the
10 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
11 * KIND, either express or implied. See the License for the specific language governing
12 * permissions and limitations under the License.
13 */
14package com.android.settings.location;
15
Philip P. Moltmanne3f72112018-08-28 15:01:43 -070016import static com.android.settingslib.RestrictedLockUtilsInternal.checkIfRestrictionEnforced;
Fan Zhangc7162cd2018-06-18 15:21:41 -070017import static com.android.settingslib.Utils.updateLocationEnabled;
Fan Zhangc7162cd2018-06-18 15:21:41 -070018
Doris Ling9ed29a22017-11-02 16:42:45 -070019import android.content.BroadcastReceiver;
20import android.content.Context;
21import android.content.Intent;
22import android.content.IntentFilter;
23import android.location.LocationManager;
24import android.os.UserHandle;
25import android.os.UserManager;
26import android.provider.Settings;
Doris Ling9ed29a22017-11-02 16:42:45 -070027import android.util.Log;
28
Fan Zhang23f8d592018-08-28 15:11:40 -070029import androidx.annotation.VisibleForTesting;
30
Doris Ling9ed29a22017-11-02 16:42:45 -070031import com.android.settings.Utils;
32import com.android.settingslib.RestrictedLockUtils;
Philip P. Moltmanne3f72112018-08-28 15:01:43 -070033import com.android.settingslib.RestrictedLockUtilsInternal;
Doris Ling9ed29a22017-11-02 16:42:45 -070034import com.android.settingslib.core.lifecycle.Lifecycle;
35import com.android.settingslib.core.lifecycle.LifecycleObserver;
Lifu Tang3da8f8d2018-12-11 13:50:34 -080036import com.android.settingslib.core.lifecycle.events.OnStart;
37import com.android.settingslib.core.lifecycle.events.OnStop;
Doris Ling9ed29a22017-11-02 16:42:45 -070038
Maggie85e2f612018-01-04 15:35:49 -080039
Doris Ling9ed29a22017-11-02 16:42:45 -070040/**
41 * A class that listens to location settings change and modifies location settings
42 * settings.
43 */
Lifu Tang3da8f8d2018-12-11 13:50:34 -080044public class LocationEnabler implements LifecycleObserver, OnStart, OnStop {
Doris Ling9ed29a22017-11-02 16:42:45 -070045
46 private static final String TAG = "LocationEnabler";
47 @VisibleForTesting
Doris Ling9ed29a22017-11-02 16:42:45 -070048 static final IntentFilter INTENT_FILTER_LOCATION_MODE_CHANGED =
49 new IntentFilter(LocationManager.MODE_CHANGED_ACTION);
50
51 private final Context mContext;
52 private final UserManager mUserManager;
53 private final LocationModeChangeListener mListener;
54
55 @VisibleForTesting
56 BroadcastReceiver mReceiver;
57
58 public interface LocationModeChangeListener {
59 /** Called when location mode has changed. */
60 void onLocationModeChanged(int mode, boolean restricted);
61 }
62
63 public LocationEnabler(Context context, LocationModeChangeListener listener,
64 Lifecycle lifecycle) {
65 mContext = context;
66 mListener = listener;
67 mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
68 if (lifecycle != null) {
69 lifecycle.addObserver(this);
70 }
71 }
72
73 @Override
Lifu Tang3da8f8d2018-12-11 13:50:34 -080074 public void onStart() {
Doris Ling9ed29a22017-11-02 16:42:45 -070075 if (mReceiver == null) {
76 mReceiver = new BroadcastReceiver() {
77 @Override
78 public void onReceive(Context context, Intent intent) {
79 if (Log.isLoggable(TAG, Log.DEBUG)) {
80 Log.d(TAG, "Received location mode change intent: " + intent);
81 }
82 refreshLocationMode();
83 }
84 };
85 }
86 mContext.registerReceiver(mReceiver, INTENT_FILTER_LOCATION_MODE_CHANGED);
87 refreshLocationMode();
88 }
89
90 @Override
Lifu Tang3da8f8d2018-12-11 13:50:34 -080091 public void onStop() {
92 mContext.unregisterReceiver(mReceiver);
Doris Ling9ed29a22017-11-02 16:42:45 -070093 }
94
Nate Myren232962c2022-01-13 12:03:39 -080095 /**
96 * Get the current location enable state, and update listeners
97 */
98 public void refreshLocationMode() {
Doris Ling9ed29a22017-11-02 16:42:45 -070099 final int mode = Settings.Secure.getInt(mContext.getContentResolver(),
100 Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF);
101 if (Log.isLoggable(TAG, Log.INFO)) {
102 Log.i(TAG, "Location mode has been changed");
103 }
104 if (mListener != null) {
105 mListener.onLocationModeChanged(mode, isRestricted());
106 }
107 }
108
Nate Myren232962c2022-01-13 12:03:39 -0800109 /**
110 * Set the device's location enable state
111 */
112 public void setLocationEnabled(boolean enabled) {
Maggie85e2f612018-01-04 15:35:49 -0800113 final int currentMode = Settings.Secure.getInt(mContext.getContentResolver(),
114 Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF);
115
116 if (isRestricted()) {
117 // Location toggling disabled by user restriction. Read the current location mode to
Edgar Wang4e02ceb2020-07-29 12:47:42 +0800118 // update the location primary switch.
Maggie85e2f612018-01-04 15:35:49 -0800119 if (Log.isLoggable(TAG, Log.INFO)) {
120 Log.i(TAG, "Restricted user, not setting location mode");
121 }
122 if (mListener != null) {
123 mListener.onLocationModeChanged(currentMode, true);
124 }
125 return;
126 }
Lifu Tange6032be2018-01-23 21:12:14 -0800127 updateLocationEnabled(mContext, enabled, UserHandle.myUserId(),
128 Settings.Secure.LOCATION_CHANGER_SYSTEM_SETTINGS);
Maggie85e2f612018-01-04 15:35:49 -0800129 refreshLocationMode();
130 }
131
Nate Myren232962c2022-01-13 12:03:39 -0800132 /**
133 * Checks if location is enabled, based on mode and restrictions.
134 */
135 public boolean isEnabled(int mode) {
Doris Ling9ed29a22017-11-02 16:42:45 -0700136 return mode != Settings.Secure.LOCATION_MODE_OFF && !isRestricted();
137 }
138
139 /**
140 * Checking if device policy has put a location access lock-down on the managed profile.
141 *
142 * @return true if device policy has put a location access lock-down on the managed profile
143 */
Nate Myren232962c2022-01-13 12:03:39 -0800144 public boolean isManagedProfileRestrictedByBase() {
Doris Ling9ed29a22017-11-02 16:42:45 -0700145 final UserHandle managedProfile = Utils.getManagedProfile(mUserManager);
146 return managedProfile != null
147 && hasShareLocationRestriction(managedProfile.getIdentifier());
148 }
149
Nate Myren232962c2022-01-13 12:03:39 -0800150 /**
151 * Gets the admin enforcement for location for the current user
152 */
153 public RestrictedLockUtils.EnforcedAdmin getShareLocationEnforcedAdmin(int userId) {
yuemingw754ca512018-01-03 18:09:31 +0000154 RestrictedLockUtils.EnforcedAdmin admin = checkIfRestrictionEnforced(
Doris Ling9ed29a22017-11-02 16:42:45 -0700155 mContext, UserManager.DISALLOW_SHARE_LOCATION, userId);
yuemingw754ca512018-01-03 18:09:31 +0000156
157 if (admin == null) {
Philip P. Moltmanne3f72112018-08-28 15:01:43 -0700158 admin = RestrictedLockUtilsInternal.checkIfRestrictionEnforced(
yuemingwa1416d22018-02-01 17:52:50 +0000159 mContext, UserManager.DISALLOW_CONFIG_LOCATION, userId);
yuemingw754ca512018-01-03 18:09:31 +0000160 }
161 return admin;
Doris Ling9ed29a22017-11-02 16:42:45 -0700162 }
163
Nate Myren232962c2022-01-13 12:03:39 -0800164 /**
165 * Check if the current user has a location restriction
166 */
167 public boolean hasShareLocationRestriction(int userId) {
Philip P. Moltmanne3f72112018-08-28 15:01:43 -0700168 return RestrictedLockUtilsInternal.hasBaseUserRestriction(
Doris Ling9ed29a22017-11-02 16:42:45 -0700169 mContext, UserManager.DISALLOW_SHARE_LOCATION, userId);
170 }
171
172 private boolean isRestricted() {
173 return mUserManager.hasUserRestriction(UserManager.DISALLOW_SHARE_LOCATION);
174 }
Doris Ling9ed29a22017-11-02 16:42:45 -0700175}