• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.settings.location;
17 
18 import static android.Manifest.permission.WRITE_SECURE_SETTINGS;
19 import static com.google.common.truth.Truth.assertThat;
20 import static org.mockito.ArgumentMatchers.anyBoolean;
21 import static org.mockito.ArgumentMatchers.anyInt;
22 import static org.mockito.ArgumentMatchers.anyString;
23 import static org.mockito.ArgumentMatchers.argThat;
24 import static org.mockito.ArgumentMatchers.eq;
25 import static org.mockito.Mockito.doReturn;
26 import static org.mockito.Mockito.mock;
27 import static org.mockito.Mockito.reset;
28 import static org.mockito.Mockito.spy;
29 import static org.mockito.Mockito.verify;
30 import static org.mockito.Mockito.when;
31 
32 import android.app.ActivityManager;
33 import android.arch.lifecycle.LifecycleOwner;
34 import android.content.Context;
35 import android.content.Intent;
36 import android.content.pm.UserInfo;
37 import android.location.LocationManager;
38 import android.os.UserHandle;
39 import android.os.UserManager;
40 import android.provider.Settings;
41 import android.text.TextUtils;
42 
43 import com.android.settings.testutils.SettingsRobolectricTestRunner;
44 import com.android.settings.testutils.shadow.ShadowSecureSettings;
45 import com.android.settingslib.core.lifecycle.Lifecycle;
46 import com.android.settingslib.wrapper.LocationManagerWrapper;
47 
48 import org.junit.Before;
49 import org.junit.Test;
50 import org.junit.runner.RunWith;
51 import org.mockito.ArgumentMatcher;
52 import org.mockito.Mock;
53 import org.mockito.MockitoAnnotations;
54 import org.robolectric.RuntimeEnvironment;
55 import org.robolectric.annotation.Config;
56 import org.robolectric.annotation.Implementation;
57 import org.robolectric.annotation.Implements;
58 
59 import java.util.ArrayList;
60 import java.util.List;
61 
62 @RunWith(SettingsRobolectricTestRunner.class)
63 @Config(shadows = {
64     ShadowSecureSettings.class,
65     LocationEnablerTest.ShadowLocationManagerWrapper.class})
66 public class LocationEnablerTest {
67 
68     @Mock
69     private UserManager mUserManager;
70     @Mock
71     private LocationEnabler.LocationModeChangeListener mListener;
72 
73     private Context mContext;
74     private LocationEnabler mEnabler;
75     private LifecycleOwner mLifecycleOwner;
76     private Lifecycle mLifecycle;
77 
78     @Before
setUp()79     public void setUp() {
80         MockitoAnnotations.initMocks(this);
81         mContext = spy(RuntimeEnvironment.application);
82         when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
83         mLifecycleOwner = () -> mLifecycle;
84         mLifecycle = new Lifecycle(mLifecycleOwner);
85         mEnabler = spy(new LocationEnabler(mContext, mListener, mLifecycle));
86     }
87 
88     @Test
onResume_shouldSetActiveAndRegisterListener()89     public void onResume_shouldSetActiveAndRegisterListener() {
90         mEnabler.onResume();
91 
92         verify(mContext).registerReceiver(eq(mEnabler.mReceiver),
93                 eq(LocationEnabler.INTENT_FILTER_LOCATION_MODE_CHANGED));
94     }
95 
96     @Test
onResume_shouldRefreshLocationMode()97     public void onResume_shouldRefreshLocationMode() {
98         mEnabler.onResume();
99 
100         verify(mEnabler).refreshLocationMode();
101     }
102 
103     @Test
onPause_shouldUnregisterListener()104     public void onPause_shouldUnregisterListener() {
105         mEnabler.onPause();
106 
107         verify(mContext).unregisterReceiver(mEnabler.mReceiver);
108     }
109 
110     @Test
onReceive_shouldRefreshLocationMode()111     public void onReceive_shouldRefreshLocationMode() {
112         mEnabler.onResume();
113         reset(mListener);
114         mEnabler.mReceiver.onReceive(mContext, new Intent());
115 
116         verify(mListener).onLocationModeChanged(anyInt(), anyBoolean());
117     }
118 
119     @Test
isEnabled_locationOff_shouldReturnFalse()120     public void isEnabled_locationOff_shouldReturnFalse() {
121         assertThat(mEnabler.isEnabled(Settings.Secure.LOCATION_MODE_OFF)).isFalse();
122     }
123 
124     @Test
isEnabled_restricted_shouldReturnFalse()125     public void isEnabled_restricted_shouldReturnFalse() {
126         when(mUserManager.hasUserRestriction(anyString())).thenReturn(true);
127 
128         assertThat(mEnabler.isEnabled(Settings.Secure.LOCATION_MODE_OFF)).isFalse();
129     }
130 
131     @Test
isEnabled_locationNotRestricted_shouldReturnTrue()132     public void isEnabled_locationNotRestricted_shouldReturnTrue() {
133         when(mUserManager.hasUserRestriction(anyString())).thenReturn(false);
134 
135         assertThat(mEnabler.isEnabled(Settings.Secure.LOCATION_MODE_BATTERY_SAVING)).isTrue();
136     }
137 
138     @Test
refreshLocationMode_shouldCallOnLocationModeChanged()139     public void refreshLocationMode_shouldCallOnLocationModeChanged() {
140         mEnabler.refreshLocationMode();
141 
142         verify(mListener).onLocationModeChanged(anyInt(), anyBoolean());
143     }
144 
145     @Test
setLocationMode_restricted_shouldSetCurrentMode()146     public void setLocationMode_restricted_shouldSetCurrentMode() {
147         when(mUserManager.hasUserRestriction(anyString())).thenReturn(true);
148         Settings.Secure.putInt(mContext.getContentResolver(),
149                 Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_BATTERY_SAVING);
150 
151         mEnabler.setLocationMode(Settings.Secure.LOCATION_MODE_HIGH_ACCURACY);
152 
153         verify(mListener).onLocationModeChanged(Settings.Secure.LOCATION_MODE_BATTERY_SAVING, true);
154     }
155 
156     @Test
setLocationMode_notRestricted_shouldUpdateSecureSettings()157     public void setLocationMode_notRestricted_shouldUpdateSecureSettings() {
158         when(mUserManager.hasUserRestriction(anyString())).thenReturn(false);
159         Settings.Secure.putInt(mContext.getContentResolver(),
160                 Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_BATTERY_SAVING);
161 
162         mEnabler.setLocationMode(Settings.Secure.LOCATION_MODE_HIGH_ACCURACY);
163 
164         assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
165                 Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_BATTERY_SAVING))
166                 .isEqualTo(Settings.Secure.LOCATION_MODE_HIGH_ACCURACY);
167     }
168 
169     @Test
setLocationMode_notRestricted_shouldRefreshLocation()170     public void setLocationMode_notRestricted_shouldRefreshLocation() {
171         when(mUserManager.hasUserRestriction(anyString())).thenReturn(false);
172         Settings.Secure.putInt(mContext.getContentResolver(),
173                 Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_BATTERY_SAVING);
174 
175         mEnabler.setLocationMode(Settings.Secure.LOCATION_MODE_HIGH_ACCURACY);
176 
177         verify(mEnabler).refreshLocationMode();
178     }
179 
180     @Test
setLocationMode_notRestricted_shouldBroadcastUpdateAndSetChanger()181     public void setLocationMode_notRestricted_shouldBroadcastUpdateAndSetChanger() {
182         when(mUserManager.hasUserRestriction(anyString())).thenReturn(false);
183         Settings.Secure.putInt(mContext.getContentResolver(),
184                 Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_BATTERY_SAVING);
185         mEnabler.setLocationMode(Settings.Secure.LOCATION_MODE_HIGH_ACCURACY);
186 
187         verify(mContext).sendBroadcastAsUser(
188                 argThat(actionMatches(LocationManager.MODE_CHANGING_ACTION)),
189                 eq(UserHandle.of(ActivityManager.getCurrentUser())),
190                 eq(WRITE_SECURE_SETTINGS));
191         assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
192                 Settings.Secure.LOCATION_CHANGER, Settings.Secure.LOCATION_CHANGER_UNKNOWN))
193                 .isEqualTo(Settings.Secure.LOCATION_CHANGER_SYSTEM_SETTINGS);
194     }
195 
196     @Test
setLocationEnabled_notRestricted_shouldRefreshLocation()197     public void setLocationEnabled_notRestricted_shouldRefreshLocation() {
198         when(mUserManager.hasUserRestriction(anyString())).thenReturn(false);
199         Settings.Secure.putInt(mContext.getContentResolver(),
200             Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF);
201         mEnabler.setLocationEnabled(true);
202 
203         verify(mEnabler).refreshLocationMode();
204     }
205 
206     @Test
setLocationEnabled_notRestricted_shouldBroadcastUpdateAndSetChanger()207     public void setLocationEnabled_notRestricted_shouldBroadcastUpdateAndSetChanger() {
208         when(mUserManager.hasUserRestriction(anyString())).thenReturn(false);
209         Settings.Secure.putInt(mContext.getContentResolver(),
210             Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF);
211         mEnabler.setLocationEnabled(true);
212 
213         verify(mContext).sendBroadcastAsUser(
214             argThat(actionMatches(LocationManager.MODE_CHANGING_ACTION)),
215             eq(UserHandle.of(ActivityManager.getCurrentUser())),
216             eq(WRITE_SECURE_SETTINGS));
217         assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
218                 Settings.Secure.LOCATION_CHANGER, Settings.Secure.LOCATION_CHANGER_UNKNOWN))
219                 .isEqualTo(Settings.Secure.LOCATION_CHANGER_SYSTEM_SETTINGS);
220     }
221 
222     @Test
isManagedProfileRestrictedByBase_notManagedProfile_shouldReturnFalse()223     public void isManagedProfileRestrictedByBase_notManagedProfile_shouldReturnFalse() {
224         assertThat(mEnabler.isManagedProfileRestrictedByBase()).isFalse();
225     }
226 
227     @Test
isManagedProfileRestrictedByBase_notRestricted_shouldReturnFalse()228     public void isManagedProfileRestrictedByBase_notRestricted_shouldReturnFalse() {
229         mockManagedProfile();
230         doReturn(false).when(mEnabler).hasShareLocationRestriction(anyInt());
231 
232         assertThat(mEnabler.isManagedProfileRestrictedByBase()).isFalse();
233     }
234 
235     @Test
isManagedProfileRestrictedByBase_hasManagedProfile_shouldReturnFalse()236     public void isManagedProfileRestrictedByBase_hasManagedProfile_shouldReturnFalse() {
237         mockManagedProfile();
238         doReturn(true).when(mEnabler).hasShareLocationRestriction(anyInt());
239 
240         assertThat(mEnabler.isManagedProfileRestrictedByBase()).isTrue();
241     }
242 
243     @Test
setRestriction_getShareLocationEnforcedAdmin_shouldReturnEnforcedAdmin()244     public void setRestriction_getShareLocationEnforcedAdmin_shouldReturnEnforcedAdmin() {
245         int userId = UserHandle.myUserId();
246         List<UserManager.EnforcingUser> enforcingUsers = new ArrayList<>();
247         // Add two enforcing users so that RestrictedLockUtils.checkIfRestrictionEnforced returns
248         // non-null.
249         enforcingUsers.add(new UserManager.EnforcingUser(userId,
250                 UserManager.RESTRICTION_SOURCE_DEVICE_OWNER));
251         enforcingUsers.add(new UserManager.EnforcingUser(userId,
252                 UserManager.RESTRICTION_SOURCE_PROFILE_OWNER));
253         when(mUserManager.getUserRestrictionSources(
254                 UserManager.DISALLOW_CONFIG_LOCATION, UserHandle.of(userId)))
255                 .thenReturn(enforcingUsers);
256 
257         assertThat(mEnabler.getShareLocationEnforcedAdmin(userId) != null).isTrue();
258     }
259 
mockManagedProfile()260     private void mockManagedProfile() {
261         final List<UserHandle> userProfiles = new ArrayList<>();
262         final UserHandle userHandle = mock(UserHandle.class);
263         when(userHandle.getIdentifier()).thenReturn(5);
264         userProfiles.add(userHandle);
265         when(mUserManager.getUserProfiles()).thenReturn(userProfiles);
266         when(mUserManager.getUserHandle()).thenReturn(1);
267         when(mUserManager.getUserInfo(5))
268                 .thenReturn(new UserInfo(5, "user 5", UserInfo.FLAG_MANAGED_PROFILE));
269     }
270 
actionMatches(String expected)271     private static ArgumentMatcher<Intent> actionMatches(String expected) {
272         return intent -> TextUtils.equals(expected, intent.getAction());
273     }
274 
275     @Implements(value = LocationManagerWrapper.class)
276     public static class ShadowLocationManagerWrapper {
277 
278         @Implementation
setLocationEnabledForUser(boolean enabled, UserHandle userHandle)279         public void setLocationEnabledForUser(boolean enabled, UserHandle userHandle) {
280             // Do nothing
281         }
282     }
283 }
284