blob: db5397330e13c78a11c4eb02eb5129aee255bced [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
95 void refreshLocationMode() {
96 final int mode = Settings.Secure.getInt(mContext.getContentResolver(),
97 Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF);
98 if (Log.isLoggable(TAG, Log.INFO)) {
99 Log.i(TAG, "Location mode has been changed");
100 }
101 if (mListener != null) {
102 mListener.onLocationModeChanged(mode, isRestricted());
103 }
104 }
105
Maggie85e2f612018-01-04 15:35:49 -0800106 void setLocationEnabled(boolean enabled) {
107 final int currentMode = Settings.Secure.getInt(mContext.getContentResolver(),
108 Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF);
109
110 if (isRestricted()) {
111 // Location toggling disabled by user restriction. Read the current location mode to
112 // update the location master switch.
113 if (Log.isLoggable(TAG, Log.INFO)) {
114 Log.i(TAG, "Restricted user, not setting location mode");
115 }
116 if (mListener != null) {
117 mListener.onLocationModeChanged(currentMode, true);
118 }
119 return;
120 }
Lifu Tange6032be2018-01-23 21:12:14 -0800121 updateLocationEnabled(mContext, enabled, UserHandle.myUserId(),
122 Settings.Secure.LOCATION_CHANGER_SYSTEM_SETTINGS);
Maggie85e2f612018-01-04 15:35:49 -0800123 refreshLocationMode();
124 }
125
Doris Ling9ed29a22017-11-02 16:42:45 -0700126 boolean isEnabled(int mode) {
127 return mode != Settings.Secure.LOCATION_MODE_OFF && !isRestricted();
128 }
129
130 /**
131 * Checking if device policy has put a location access lock-down on the managed profile.
132 *
133 * @return true if device policy has put a location access lock-down on the managed profile
134 */
135 boolean isManagedProfileRestrictedByBase() {
136 final UserHandle managedProfile = Utils.getManagedProfile(mUserManager);
137 return managedProfile != null
138 && hasShareLocationRestriction(managedProfile.getIdentifier());
139 }
140
141 RestrictedLockUtils.EnforcedAdmin getShareLocationEnforcedAdmin(int userId) {
yuemingw754ca512018-01-03 18:09:31 +0000142 RestrictedLockUtils.EnforcedAdmin admin = checkIfRestrictionEnforced(
Doris Ling9ed29a22017-11-02 16:42:45 -0700143 mContext, UserManager.DISALLOW_SHARE_LOCATION, userId);
yuemingw754ca512018-01-03 18:09:31 +0000144
145 if (admin == null) {
Philip P. Moltmanne3f72112018-08-28 15:01:43 -0700146 admin = RestrictedLockUtilsInternal.checkIfRestrictionEnforced(
yuemingwa1416d22018-02-01 17:52:50 +0000147 mContext, UserManager.DISALLOW_CONFIG_LOCATION, userId);
yuemingw754ca512018-01-03 18:09:31 +0000148 }
149 return admin;
Doris Ling9ed29a22017-11-02 16:42:45 -0700150 }
151
152 boolean hasShareLocationRestriction(int userId) {
Philip P. Moltmanne3f72112018-08-28 15:01:43 -0700153 return RestrictedLockUtilsInternal.hasBaseUserRestriction(
Doris Ling9ed29a22017-11-02 16:42:45 -0700154 mContext, UserManager.DISALLOW_SHARE_LOCATION, userId);
155 }
156
157 private boolean isRestricted() {
158 return mUserManager.hasUserRestriction(UserManager.DISALLOW_SHARE_LOCATION);
159 }
Doris Ling9ed29a22017-11-02 16:42:45 -0700160}