• 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 com.google.common.truth.Truth.assertThat;
19 
20 import static org.mockito.ArgumentMatchers.any;
21 import static org.mockito.ArgumentMatchers.anyInt;
22 import static org.mockito.ArgumentMatchers.eq;
23 import static org.mockito.Mockito.doReturn;
24 import static org.mockito.Mockito.spy;
25 import static org.mockito.Mockito.verify;
26 import static org.mockito.Mockito.when;
27 
28 import android.app.admin.DevicePolicyManager;
29 import android.app.admin.DevicePolicyResourcesManager;
30 import android.content.ComponentName;
31 import android.content.Context;
32 import android.content.pm.UserInfo;
33 import android.os.UserHandle;
34 import android.os.UserManager;
35 import android.platform.test.flag.junit.SetFlagsRule;
36 import android.provider.Settings;
37 import android.util.ArrayMap;
38 import android.util.ArraySet;
39 
40 import androidx.lifecycle.LifecycleOwner;
41 import androidx.preference.Preference;
42 import androidx.preference.PreferenceCategory;
43 import androidx.preference.PreferenceScreen;
44 import androidx.test.core.app.ApplicationProvider;
45 
46 import com.android.settings.testutils.shadow.ShadowDevicePolicyManager;
47 import com.android.settings.testutils.shadow.ShadowUserManager;
48 import com.android.settings.widget.RestrictedAppPreference;
49 import com.android.settingslib.core.lifecycle.Lifecycle;
50 
51 import org.junit.Before;
52 import org.junit.Rule;
53 import org.junit.Test;
54 import org.junit.runner.RunWith;
55 import org.mockito.Answers;
56 import org.mockito.ArgumentCaptor;
57 import org.mockito.Mock;
58 import org.mockito.junit.MockitoJUnit;
59 import org.mockito.junit.MockitoRule;
60 import org.robolectric.RobolectricTestRunner;
61 import org.robolectric.annotation.Config;
62 
63 import java.util.ArrayList;
64 import java.util.List;
65 import java.util.Map;
66 
67 @RunWith(RobolectricTestRunner.class)
68 @Config(shadows = {ShadowUserManager.class, ShadowDevicePolicyManager.class})
69 public class LocationInjectedServicesPreferenceControllerTest {
70     @Rule
71     public final MockitoRule mMockitoRule = MockitoJUnit.rule();
72     @Rule
73     public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
74 
75     private static final String KEY_LOCATION_SERVICES = "location_service";
76 
77     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
78     private LocationSettings mFragment;
79     @Mock
80     private PreferenceCategory mCategoryPrimary;
81     @Mock
82     private PreferenceScreen mScreen;
83     @Mock
84     private AppSettingsInjector mSettingsInjector;
85     @Mock
86     private DevicePolicyManager mDevicePolicyManager;
87     @Mock
88     private DevicePolicyResourcesManager mDevicePolicyResourcesManager;
89 
90     private Context mContext;
91     private LocationInjectedServicesPreferenceController mController;
92     private LifecycleOwner mLifecycleOwner;
93     private Lifecycle mLifecycle;
94 
95     @Before
setUp()96     public void setUp() {
97         mContext = spy(ApplicationProvider.getApplicationContext());
98         mLifecycleOwner = () -> mLifecycle;
99         mLifecycle = new Lifecycle(mLifecycleOwner);
100         mController = spy(
101                 new LocationInjectedServicesPreferenceController(mContext, KEY_LOCATION_SERVICES));
102         when(mFragment.getSettingsLifecycle()).thenReturn(mLifecycle);
103         mController.init(mFragment);
104         mController.mInjector = mSettingsInjector;
105         final String key = mController.getPreferenceKey();
106         when(mScreen.findPreference(key)).thenReturn(mCategoryPrimary);
107         when(mCategoryPrimary.getKey()).thenReturn(key);
108         when(mContext.getSystemService(Context.DEVICE_POLICY_SERVICE))
109                 .thenReturn(mDevicePolicyManager);
110         when(mDevicePolicyManager.getResources()).thenReturn(mDevicePolicyResourcesManager);
111     }
112 
113     @Test
onResume_shouldRegisterListener()114     public void onResume_shouldRegisterListener() {
115         mController.onResume();
116 
117         verify(mContext).registerReceiver(eq(mController.mInjectedSettingsReceiver),
118                 eq(mController.INTENT_FILTER_INJECTED_SETTING_CHANGED),
119                 anyInt());
120     }
121 
122     @Test
onPause_shouldUnregisterListener()123     public void onPause_shouldUnregisterListener() {
124         mController.onResume();
125         mController.onPause();
126 
127         verify(mContext).unregisterReceiver(mController.mInjectedSettingsReceiver);
128     }
129 
130     @Test
workProfileDisallowShareLocationOn_getParentUserLocationServicesOnly()131     public void workProfileDisallowShareLocationOn_getParentUserLocationServicesOnly() {
132         final int fakeWorkProfileId = 123;
133         ShadowUserManager.getShadow().setProfileIdsWithDisabled(
134                 new int[]{UserHandle.myUserId(), fakeWorkProfileId});
135         ShadowUserManager.getShadow().addProfile(new UserInfo(UserHandle.myUserId(), "", 0));
136         ShadowUserManager.getShadow().addProfile(new UserInfo(fakeWorkProfileId, "",
137                 UserInfo.FLAG_MANAGED_PROFILE | UserInfo.FLAG_PROFILE));
138 
139         // Mock RestrictedLockUtils.checkIfRestrictionEnforced and let it return non-null.
140         final List<UserManager.EnforcingUser> enforcingUsers = new ArrayList<>();
141         enforcingUsers.add(new UserManager.EnforcingUser(fakeWorkProfileId,
142                 UserManager.RESTRICTION_SOURCE_DEVICE_OWNER));
143         final ComponentName componentName = new ComponentName("test", "test");
144         // Ensure that RestrictedLockUtils.checkIfRestrictionEnforced doesn't return null.
145         ShadowUserManager.getShadow().setUserRestrictionSources(
146                 UserManager.DISALLOW_SHARE_LOCATION,
147                 UserHandle.of(fakeWorkProfileId),
148                 enforcingUsers);
149         when(mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser()).thenReturn(componentName);
150 
151         mController.displayPreference(mScreen);
152 
153         ArgumentCaptor<ArraySet<UserHandle>> profilesArgumentCaptor =
154                 ArgumentCaptor.forClass(ArraySet.class);
155         verify(mSettingsInjector).getInjectedSettings(
156                 any(Context.class), profilesArgumentCaptor.capture());
157         assertThat(profilesArgumentCaptor.getValue())
158                 .doesNotContain(UserHandle.of(fakeWorkProfileId));
159     }
160 
161     @Test
workProfileDisallowShareLocationOff_getAllUserLocationServices()162     public void workProfileDisallowShareLocationOff_getAllUserLocationServices() {
163         final int fakeWorkProfileId = 123;
164         ShadowUserManager.getShadow().setProfileIdsWithDisabled(
165                 new int[]{UserHandle.myUserId(), fakeWorkProfileId});
166         ShadowUserManager.getShadow().addProfile(new UserInfo(UserHandle.myUserId(), "", 0));
167         ShadowUserManager.getShadow().addProfile(new UserInfo(fakeWorkProfileId, "",
168                 UserInfo.FLAG_MANAGED_PROFILE | UserInfo.FLAG_PROFILE));
169 
170         // Mock RestrictedLockUtils.checkIfRestrictionEnforced and let it return null.
171         // Empty enforcing users.
172         final List<UserManager.EnforcingUser> enforcingUsers = new ArrayList<>();
173         ShadowUserManager.getShadow().setUserRestrictionSources(
174                 UserManager.DISALLOW_SHARE_LOCATION,
175                 UserHandle.of(fakeWorkProfileId),
176                 enforcingUsers);
177 
178         mController.displayPreference(mScreen);
179 
180         ArgumentCaptor<ArraySet<UserHandle>> profilesArgumentCaptor =
181                 ArgumentCaptor.forClass(ArraySet.class);
182         verify(mSettingsInjector).getInjectedSettings(
183                 any(Context.class), profilesArgumentCaptor.capture());
184         assertThat(profilesArgumentCaptor.getValue()).contains(UserHandle.of(fakeWorkProfileId));
185     }
186 
187     @Test
privateProfileDisallowShareLocationOn_getParentUserLocationServicesOnly()188     public void privateProfileDisallowShareLocationOn_getParentUserLocationServicesOnly() {
189         mSetFlagsRule.enableFlags(
190                 android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE,
191                 android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES,
192                 android.multiuser.Flags.FLAG_HANDLE_INTERLEAVED_SETTINGS_FOR_PRIVATE_SPACE);
193         final int fakePrivateProfileId = 123;
194         ShadowUserManager.getShadow().setProfileIdsWithDisabled(
195                 new int[]{UserHandle.myUserId(), fakePrivateProfileId});
196         ShadowUserManager.getShadow().addProfile(new UserInfo(UserHandle.myUserId(), "", 0));
197         ShadowUserManager.getShadow().setPrivateProfile(fakePrivateProfileId, "private", 0);
198         ShadowUserManager.getShadow().addUserProfile(UserHandle.of(fakePrivateProfileId));
199 
200         // Mock RestrictedLockUtils.checkIfRestrictionEnforced and let it return non-null.
201         final List<UserManager.EnforcingUser> enforcingUsers = new ArrayList<>();
202         enforcingUsers.add(new UserManager.EnforcingUser(fakePrivateProfileId,
203                 UserManager.RESTRICTION_SOURCE_DEVICE_OWNER));
204         final ComponentName componentName = new ComponentName("test", "test");
205         // Ensure that RestrictedLockUtils.checkIfRestrictionEnforced doesn't return null.
206         ShadowUserManager.getShadow().setUserRestrictionSources(
207                 UserManager.DISALLOW_SHARE_LOCATION,
208                 UserHandle.of(fakePrivateProfileId),
209                 enforcingUsers);
210         when(mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser()).thenReturn(componentName);
211 
212         mController.displayPreference(mScreen);
213 
214         ArgumentCaptor<ArraySet<UserHandle>> profilesArgumentCaptor =
215                 ArgumentCaptor.forClass(ArraySet.class);
216         verify(mSettingsInjector).getInjectedSettings(
217                 any(Context.class), profilesArgumentCaptor.capture());
218         assertThat(profilesArgumentCaptor.getValue())
219                 .doesNotContain(UserHandle.of(fakePrivateProfileId));
220     }
221 
222     @Test
privateProfileDisallowShareLocationOff_getAllUserLocationServices()223     public void privateProfileDisallowShareLocationOff_getAllUserLocationServices() {
224         mSetFlagsRule.enableFlags(
225                 android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE,
226                 android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES,
227                 android.multiuser.Flags.FLAG_HANDLE_INTERLEAVED_SETTINGS_FOR_PRIVATE_SPACE);
228         final int fakePrivateProfileId = 123;
229         ShadowUserManager.getShadow().setProfileIdsWithDisabled(
230                 new int[]{UserHandle.myUserId(), fakePrivateProfileId});
231         ShadowUserManager.getShadow().addProfile(new UserInfo(UserHandle.myUserId(), "", 0));
232         ShadowUserManager.getShadow().setPrivateProfile(fakePrivateProfileId, "private", 0);
233         ShadowUserManager.getShadow().addUserProfile(UserHandle.of(fakePrivateProfileId));
234 
235         // Mock RestrictedLockUtils.checkIfRestrictionEnforced and let it return null.
236         // Empty enforcing users.
237         final List<UserManager.EnforcingUser> enforcingUsers = new ArrayList<>();
238         ShadowUserManager.getShadow().setUserRestrictionSources(
239                 UserManager.DISALLOW_SHARE_LOCATION,
240                 UserHandle.of(fakePrivateProfileId),
241                 enforcingUsers);
242 
243         mController.displayPreference(mScreen);
244 
245         ArgumentCaptor<ArraySet<UserHandle>> profilesArgumentCaptor =
246                 ArgumentCaptor.forClass(ArraySet.class);
247         verify(mSettingsInjector).getInjectedSettings(
248                 any(Context.class), profilesArgumentCaptor.capture());
249         assertThat(profilesArgumentCaptor.getValue()).contains(UserHandle.of(fakePrivateProfileId));
250     }
251 
252     @Test
onLocationModeChanged_shouldRequestReloadInjectedSettigns()253     public void onLocationModeChanged_shouldRequestReloadInjectedSettigns() {
254         mController.onLocationModeChanged(Settings.Secure.LOCATION_MODE_BATTERY_SAVING, false);
255 
256         verify(mSettingsInjector).reloadStatusMessages();
257     }
258 
259     @Test
withUserRestriction_shouldDisableLocationAccuracy()260     public void withUserRestriction_shouldDisableLocationAccuracy() {
261         final List<Preference> preferences = new ArrayList<>();
262         final RestrictedAppPreference pref = new RestrictedAppPreference(mContext,
263                 UserManager.DISALLOW_CONFIG_LOCATION);
264         pref.setTitle("Location Accuracy");
265         preferences.add(pref);
266         final Map<Integer, List<Preference>> map = new ArrayMap<>();
267         map.put(UserHandle.myUserId(), preferences);
268         doReturn(map).when(mSettingsInjector)
269                 .getInjectedSettings(any(Context.class), any(ArraySet.class));
270         ShadowUserManager.getShadow().setProfileIdsWithDisabled(new int[]{UserHandle.myUserId()});
271 
272         final int userId = UserHandle.myUserId();
273         List<UserManager.EnforcingUser> enforcingUsers = new ArrayList<>();
274         enforcingUsers.add(new UserManager.EnforcingUser(userId,
275                 UserManager.RESTRICTION_SOURCE_DEVICE_OWNER));
276         ComponentName componentName = new ComponentName("test", "test");
277         // Ensure that RestrictedLockUtils.checkIfRestrictionEnforced doesn't return null.
278         ShadowUserManager.getShadow().setUserRestrictionSources(
279                 UserManager.DISALLOW_CONFIG_LOCATION,
280                 UserHandle.of(userId),
281                 enforcingUsers);
282         when(mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser()).thenReturn(componentName);
283         when(mDevicePolicyResourcesManager.getString(any(), any())).thenReturn(any());
284 
285         mController.displayPreference(mScreen);
286 
287         assertThat(pref.isEnabled()).isFalse();
288         assertThat(pref.isDisabledByAdmin()).isTrue();
289     }
290 }
291