1 /*
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  */
14 package com.android.settings.location;
15 
16 import android.content.Context;
17 import android.os.UserHandle;
18 import android.os.UserManager;
19 import android.widget.CompoundButton;
20 import android.widget.CompoundButton.OnCheckedChangeListener;
21 
22 import com.android.settings.widget.SettingsMainSwitchBar;
23 import com.android.settingslib.RestrictedLockUtils;
24 import com.android.settingslib.core.lifecycle.Lifecycle;
25 import com.android.settingslib.core.lifecycle.LifecycleObserver;
26 import com.android.settingslib.core.lifecycle.events.OnStart;
27 import com.android.settingslib.core.lifecycle.events.OnStop;
28 
29 /**
30  * The switch controller for the location.
31  */
32 public class LocationSwitchBarController implements OnCheckedChangeListener,
33         LocationEnabler.LocationModeChangeListener, LifecycleObserver, OnStart, OnStop {
34 
35     private final SettingsMainSwitchBar mSwitchBar;
36     private final LocationEnabler mLocationEnabler;
37     private boolean mValidListener;
38 
LocationSwitchBarController(Context context, SettingsMainSwitchBar switchBar, Lifecycle lifecycle)39     public LocationSwitchBarController(Context context, SettingsMainSwitchBar switchBar,
40             Lifecycle lifecycle) {
41         mSwitchBar = switchBar;
42         mLocationEnabler = new LocationEnabler(context, this /* listener */, lifecycle);
43         if (lifecycle != null) {
44             lifecycle.addObserver(this);
45         }
46     }
47 
48     @Override
onStart()49     public void onStart() {
50         if (!mValidListener) {
51             mSwitchBar.addOnSwitchChangeListener(this);
52             mValidListener = true;
53         }
54     }
55 
56     @Override
onStop()57     public void onStop() {
58         if (mValidListener) {
59             mSwitchBar.removeOnSwitchChangeListener(this);
60             mValidListener = false;
61         }
62     }
63 
64     @Override
onLocationModeChanged(int mode, boolean restricted)65     public void onLocationModeChanged(int mode, boolean restricted) {
66         // Restricted user can't change the location mode, so disable the primary switch. But in
67         // some corner cases, the location might still be enabled. In such case the primary switch
68         // should be disabled but checked.
69         final boolean enabled = mLocationEnabler.isEnabled(mode);
70         final int userId = UserHandle.myUserId();
71         final RestrictedLockUtils.EnforcedAdmin admin =
72                 mLocationEnabler.getShareLocationEnforcedAdmin(userId);
73         final boolean hasBaseUserRestriction =
74                 mLocationEnabler.hasShareLocationRestriction(userId);
75         // Disable the whole switch bar instead of the switch itself. If we disabled the switch
76         // only, it would be re-enabled again if the switch bar is not disabled.
77         if (!hasBaseUserRestriction && admin != null) {
78             mSwitchBar.setDisabledByAdmin(admin);
79         } else if (restricted) {
80             RestrictedLockUtils.EnforcedAdmin enforcedAdmin = RestrictedLockUtils.EnforcedAdmin
81                     .createDefaultEnforcedAdminWithRestriction(UserManager.DISALLOW_SHARE_LOCATION);
82             mSwitchBar.setDisabledByAdmin(enforcedAdmin);
83         } else {
84             mSwitchBar.setEnabled(true);
85         }
86 
87         if (enabled != mSwitchBar.isChecked()) {
88             // set listener to null so that that code below doesn't trigger onCheckedChanged()
89             if (mValidListener) {
90                 mSwitchBar.removeOnSwitchChangeListener(this);
91             }
92             mSwitchBar.setChecked(enabled);
93             if (mValidListener) {
94                 mSwitchBar.addOnSwitchChangeListener(this);
95             }
96         }
97     }
98 
99     /**
100      * Listens to the state change of the location primary switch.
101      */
102     @Override
onCheckedChanged(CompoundButton buttonView, boolean isChecked)103     public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
104         mLocationEnabler.setLocationEnabled(isChecked);
105     }
106 }
107