• 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 
20 import static com.google.common.truth.Truth.assertThat;
21 
22 import static org.mockito.ArgumentMatchers.anyBoolean;
23 import static org.mockito.ArgumentMatchers.anyInt;
24 import static org.mockito.ArgumentMatchers.anyString;
25 import static org.mockito.ArgumentMatchers.argThat;
26 import static org.mockito.ArgumentMatchers.eq;
27 import static org.mockito.Mockito.doReturn;
28 import static org.mockito.Mockito.mock;
29 import static org.mockito.Mockito.reset;
30 import static org.mockito.Mockito.spy;
31 import static org.mockito.Mockito.verify;
32 import static org.mockito.Mockito.when;
33 
34 import android.app.ActivityManager;
35 import android.content.Context;
36 import android.content.Intent;
37 import android.content.pm.UserInfo;
38 import android.location.LocationManager;
39 import android.os.UserHandle;
40 import android.os.UserManager;
41 import android.provider.Settings;
42 import android.text.TextUtils;
43 
44 import androidx.lifecycle.LifecycleOwner;
45 
46 import com.android.settings.testutils.shadow.ShadowSecureSettings;
47 import com.android.settingslib.core.lifecycle.Lifecycle;
48 
49 import org.junit.Before;
50 import org.junit.Test;
51 import org.junit.runner.RunWith;
52 import org.mockito.ArgumentMatcher;
53 import org.mockito.Mock;
54 import org.mockito.MockitoAnnotations;
55 import org.robolectric.RobolectricTestRunner;
56 import org.robolectric.RuntimeEnvironment;
57 import org.robolectric.annotation.Config;
58 
59 import java.util.ArrayList;
60 import java.util.List;
61 
62 @RunWith(RobolectricTestRunner.class)
63 @Config(shadows = ShadowSecureSettings.class)
64 public class LocationEnablerTest {
65 
66     @Mock
67     private UserManager mUserManager;
68     @Mock
69     private LocationEnabler.LocationModeChangeListener mListener;
70 
71     private Context mContext;
72     private LocationEnabler mEnabler;
73     private LifecycleOwner mLifecycleOwner;
74     private Lifecycle mLifecycle;
75 
76     @Before
setUp()77     public void setUp() {
78         MockitoAnnotations.initMocks(this);
79         mContext = spy(RuntimeEnvironment.application);
80         when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
81         mLifecycleOwner = () -> mLifecycle;
82         mLifecycle = new Lifecycle(mLifecycleOwner);
83         mEnabler = spy(new LocationEnabler(mContext, mListener, mLifecycle));
84     }
85 
86     @Test
onStart_shouldSetActiveAndRegisterListener()87     public void onStart_shouldSetActiveAndRegisterListener() {
88         mEnabler.onStart();
89 
90         verify(mContext).registerReceiver(eq(mEnabler.mReceiver),
91                 eq(LocationEnabler.INTENT_FILTER_LOCATION_MODE_CHANGED));
92     }
93 
94     @Test
onStart_shouldRefreshLocationMode()95     public void onStart_shouldRefreshLocationMode() {
96         mEnabler.onStart();
97 
98         verify(mEnabler).refreshLocationMode();
99     }
100 
101     @Test
onStop_shouldUnregisterListener()102     public void onStop_shouldUnregisterListener() {
103         mEnabler.onStart();
104         mEnabler.onStop();
105 
106         verify(mContext).unregisterReceiver(mEnabler.mReceiver);
107     }
108 
109     @Test
onReceive_shouldRefreshLocationMode()110     public void onReceive_shouldRefreshLocationMode() {
111         mEnabler.onStart();
112         reset(mListener);
113         mEnabler.mReceiver.onReceive(mContext, new Intent());
114 
115         verify(mListener).onLocationModeChanged(anyInt(), anyBoolean());
116     }
117 
118     @Test
isEnabled_locationOff_shouldReturnFalse()119     public void isEnabled_locationOff_shouldReturnFalse() {
120         assertThat(mEnabler.isEnabled(Settings.Secure.LOCATION_MODE_OFF)).isFalse();
121     }
122 
123     @Test
isEnabled_restricted_shouldReturnFalse()124     public void isEnabled_restricted_shouldReturnFalse() {
125         when(mUserManager.hasUserRestriction(anyString())).thenReturn(true);
126 
127         assertThat(mEnabler.isEnabled(Settings.Secure.LOCATION_MODE_OFF)).isFalse();
128     }
129 
130     @Test
isEnabled_locationNotRestricted_shouldReturnTrue()131     public void isEnabled_locationNotRestricted_shouldReturnTrue() {
132         when(mUserManager.hasUserRestriction(anyString())).thenReturn(false);
133 
134         assertThat(mEnabler.isEnabled(Settings.Secure.LOCATION_MODE_BATTERY_SAVING)).isTrue();
135     }
136 
137     @Test
refreshLocationMode_shouldCallOnLocationModeChanged()138     public void refreshLocationMode_shouldCallOnLocationModeChanged() {
139         mEnabler.refreshLocationMode();
140 
141         verify(mListener).onLocationModeChanged(anyInt(), anyBoolean());
142     }
143 
144     @Test
setLocationEnabled_notRestricted_shouldRefreshLocation()145     public void setLocationEnabled_notRestricted_shouldRefreshLocation() {
146         when(mUserManager.hasUserRestriction(anyString())).thenReturn(false);
147         Settings.Secure.putInt(mContext.getContentResolver(),
148             Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF);
149         mEnabler.setLocationEnabled(true);
150 
151         verify(mEnabler).refreshLocationMode();
152     }
153 
154     @Test
setLocationEnabled_notRestricted_shouldBroadcastUpdateAndSetChanger()155     public void setLocationEnabled_notRestricted_shouldBroadcastUpdateAndSetChanger() {
156         when(mUserManager.hasUserRestriction(anyString())).thenReturn(false);
157         Settings.Secure.putInt(mContext.getContentResolver(),
158             Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF);
159         mEnabler.setLocationEnabled(true);
160 
161         verify(mContext).sendBroadcastAsUser(
162             argThat(actionMatches(LocationManager.MODE_CHANGING_ACTION)),
163             eq(UserHandle.of(ActivityManager.getCurrentUser())),
164             eq(WRITE_SECURE_SETTINGS));
165         assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
166                 Settings.Secure.LOCATION_CHANGER, Settings.Secure.LOCATION_CHANGER_UNKNOWN))
167                 .isEqualTo(Settings.Secure.LOCATION_CHANGER_SYSTEM_SETTINGS);
168     }
169 
170     @Test
isManagedProfileRestrictedByBase_notManagedProfile_shouldReturnFalse()171     public void isManagedProfileRestrictedByBase_notManagedProfile_shouldReturnFalse() {
172         assertThat(mEnabler.isManagedProfileRestrictedByBase()).isFalse();
173     }
174 
175     @Test
isManagedProfileRestrictedByBase_notRestricted_shouldReturnFalse()176     public void isManagedProfileRestrictedByBase_notRestricted_shouldReturnFalse() {
177         mockManagedProfile();
178         doReturn(false).when(mEnabler).hasShareLocationRestriction(anyInt());
179 
180         assertThat(mEnabler.isManagedProfileRestrictedByBase()).isFalse();
181     }
182 
183     @Test
isManagedProfileRestrictedByBase_hasManagedProfile_shouldReturnFalse()184     public void isManagedProfileRestrictedByBase_hasManagedProfile_shouldReturnFalse() {
185         mockManagedProfile();
186         doReturn(true).when(mEnabler).hasShareLocationRestriction(anyInt());
187 
188         assertThat(mEnabler.isManagedProfileRestrictedByBase()).isTrue();
189     }
190 
191     @Test
setRestriction_getShareLocationEnforcedAdmin_shouldReturnEnforcedAdmin()192     public void setRestriction_getShareLocationEnforcedAdmin_shouldReturnEnforcedAdmin() {
193         int userId = UserHandle.myUserId();
194         List<UserManager.EnforcingUser> enforcingUsers = new ArrayList<>();
195         // Add two enforcing users so that RestrictedLockUtils.checkIfRestrictionEnforced returns
196         // non-null.
197         enforcingUsers.add(new UserManager.EnforcingUser(userId,
198                 UserManager.RESTRICTION_SOURCE_DEVICE_OWNER));
199         enforcingUsers.add(new UserManager.EnforcingUser(userId,
200                 UserManager.RESTRICTION_SOURCE_PROFILE_OWNER));
201         when(mUserManager.getUserRestrictionSources(
202                 UserManager.DISALLOW_CONFIG_LOCATION, UserHandle.of(userId)))
203                 .thenReturn(enforcingUsers);
204 
205         assertThat(mEnabler.getShareLocationEnforcedAdmin(userId) != null).isTrue();
206     }
207 
mockManagedProfile()208     private void mockManagedProfile() {
209         final List<UserHandle> userProfiles = new ArrayList<>();
210         final UserHandle userHandle = mock(UserHandle.class);
211         when(userHandle.getIdentifier()).thenReturn(5);
212         userProfiles.add(userHandle);
213         when(mUserManager.getUserProfiles()).thenReturn(userProfiles);
214         when(mUserManager.getUserHandle()).thenReturn(1);
215         when(mUserManager.getUserInfo(5))
216                 .thenReturn(new UserInfo(5, "user 5", UserInfo.FLAG_MANAGED_PROFILE));
217     }
218 
actionMatches(String expected)219     private static ArgumentMatcher<Intent> actionMatches(String expected) {
220         return intent -> TextUtils.equals(expected, intent.getAction());
221     }
222 }
223