1 /*
2  * Copyright (C) 2023 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.security;
17 
18 import static android.view.contentprotection.flags.Flags.FLAG_MANAGE_DEVICE_POLICY_ENABLED;
19 
20 import static com.android.settings.core.BasePreferenceController.AVAILABLE;
21 import static com.android.settings.security.ContentProtectionTogglePreferenceController.KEY_CONTENT_PROTECTION_PREFERENCE;
22 
23 import static com.google.common.truth.Truth.assertThat;
24 
25 import static org.mockito.ArgumentMatchers.any;
26 import static org.mockito.Mockito.never;
27 import static org.mockito.Mockito.verify;
28 import static org.mockito.Mockito.when;
29 
30 import android.app.admin.DevicePolicyManager;
31 import android.content.Context;
32 import android.os.UserHandle;
33 import android.platform.test.flag.junit.SetFlagsRule;
34 import android.provider.Settings;
35 
36 import androidx.annotation.Nullable;
37 import androidx.preference.PreferenceScreen;
38 import androidx.test.core.app.ApplicationProvider;
39 
40 import com.android.settings.testutils.shadow.ShadowUtils;
41 import com.android.settings.widget.SettingsMainSwitchPreference;
42 import com.android.settingslib.RestrictedLockUtils;
43 
44 import org.junit.After;
45 import org.junit.Before;
46 import org.junit.Rule;
47 import org.junit.Test;
48 import org.junit.runner.RunWith;
49 import org.mockito.Mock;
50 import org.mockito.junit.MockitoJUnit;
51 import org.mockito.junit.MockitoRule;
52 import org.robolectric.RobolectricTestRunner;
53 import org.robolectric.annotation.Config;
54 
55 @RunWith(RobolectricTestRunner.class)
56 @Config(shadows = {ShadowUtils.class})
57 public class ContentProtectionTogglePreferenceControllerTest {
58 
59     @Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule();
60 
61     @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
62 
63     private final Context mContext = ApplicationProvider.getApplicationContext();
64 
65     @Mock private PreferenceScreen mMockPreferenceScreen;
66 
67     @Mock private SettingsMainSwitchPreference mMockSwitchPreference;
68 
69     @Nullable private RestrictedLockUtils.EnforcedAdmin mEnforcedAdmin;
70 
71     @DevicePolicyManager.ContentProtectionPolicy
72     private int mContentProtectionPolicy = DevicePolicyManager.CONTENT_PROTECTION_DISABLED;
73 
74     private TestContentProtectionTogglePreferenceController mController;
75 
76     private int mSettingBackupValue;
77 
78     @Before
setUp()79     public void setUp() {
80         mController = new TestContentProtectionTogglePreferenceController();
81         SettingsMainSwitchPreference switchPreference = new SettingsMainSwitchPreference(mContext);
82         when(mMockPreferenceScreen.findPreference(mController.getPreferenceKey()))
83                 .thenReturn(switchPreference);
84         mSettingBackupValue = getContentProtectionGlobalSetting();
85         Settings.Global.putInt(mContext.getContentResolver(), KEY_CONTENT_PROTECTION_PREFERENCE, 0);
86     }
87 
88     @After
tearDown()89     public void tearDown() {
90         Settings.Global.putInt(
91                 mContext.getContentResolver(),
92                 KEY_CONTENT_PROTECTION_PREFERENCE,
93                 mSettingBackupValue);
94         ShadowUtils.reset();
95     }
96 
97     @Test
constructor_flagDisabled_doesNotFetchData()98     public void constructor_flagDisabled_doesNotFetchData() {
99         mSetFlagsRule.disableFlags(FLAG_MANAGE_DEVICE_POLICY_ENABLED);
100         mController = new TestContentProtectionTogglePreferenceController();
101 
102         assertThat(mController.mCounterGetManagedProfile).isEqualTo(0);
103         assertThat(mController.mCounterGetEnforcedAdmin).isEqualTo(0);
104         assertThat(mController.mCounterGetContentProtectionPolicy).isEqualTo(0);
105     }
106 
107     @Test
constructor_flagEnabled_fetchesData()108     public void constructor_flagEnabled_fetchesData() {
109         mSetFlagsRule.enableFlags(FLAG_MANAGE_DEVICE_POLICY_ENABLED);
110         mController = new TestContentProtectionTogglePreferenceController();
111 
112         assertThat(mController.mCounterGetManagedProfile).isEqualTo(1);
113         assertThat(mController.mCounterGetEnforcedAdmin).isEqualTo(1);
114         assertThat(mController.mCounterGetContentProtectionPolicy).isEqualTo(1);
115     }
116 
117     @Test
getAvailabilityStatus_available()118     public void getAvailabilityStatus_available() {
119         assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
120         assertThat(mController.isAvailable()).isTrue();
121     }
122 
123     @Test
isChecked_noEnforcedAdmin_readsSettingsTrue()124     public void isChecked_noEnforcedAdmin_readsSettingsTrue() {
125         Settings.Global.putInt(mContext.getContentResolver(), KEY_CONTENT_PROTECTION_PREFERENCE, 1);
126 
127         assertThat(mController.isChecked()).isTrue();
128     }
129 
130     @Test
isChecked_noEnforcedAdmin_readsSettingsFalse()131     public void isChecked_noEnforcedAdmin_readsSettingsFalse() {
132         Settings.Global.putInt(
133                 mContext.getContentResolver(), KEY_CONTENT_PROTECTION_PREFERENCE, -1);
134 
135         assertThat(mController.isChecked()).isFalse();
136     }
137 
138     @Test
isChecked_noEnforcedAdmin_readsSettingsDefaultTrue()139     public void isChecked_noEnforcedAdmin_readsSettingsDefaultTrue() {
140         assertThat(mController.isChecked()).isTrue();
141     }
142 
143     @Test
isChecked_enforcedAdmin_flagDisabled_false()144     public void isChecked_enforcedAdmin_flagDisabled_false() {
145         mSetFlagsRule.disableFlags(FLAG_MANAGE_DEVICE_POLICY_ENABLED);
146         mEnforcedAdmin = new RestrictedLockUtils.EnforcedAdmin();
147         Settings.Global.putInt(mContext.getContentResolver(), KEY_CONTENT_PROTECTION_PREFERENCE, 1);
148         setupForUpdateState();
149         mController.updateState(mMockSwitchPreference);
150 
151         assertThat(mController.isChecked()).isFalse();
152     }
153 
154     @Test
isChecked_enforcedAdmin_flagEnabled_policyDisabled_false()155     public void isChecked_enforcedAdmin_flagEnabled_policyDisabled_false() {
156         mSetFlagsRule.enableFlags(FLAG_MANAGE_DEVICE_POLICY_ENABLED);
157         mEnforcedAdmin = new RestrictedLockUtils.EnforcedAdmin();
158         mContentProtectionPolicy = DevicePolicyManager.CONTENT_PROTECTION_DISABLED;
159         Settings.Global.putInt(mContext.getContentResolver(), KEY_CONTENT_PROTECTION_PREFERENCE, 1);
160         mController = new TestContentProtectionTogglePreferenceController();
161 
162         assertThat(mController.isChecked()).isFalse();
163     }
164 
165     @Test
isChecked_enforcedAdmin_flagEnabled_policyEnabled_true()166     public void isChecked_enforcedAdmin_flagEnabled_policyEnabled_true() {
167         mSetFlagsRule.enableFlags(FLAG_MANAGE_DEVICE_POLICY_ENABLED);
168         mEnforcedAdmin = new RestrictedLockUtils.EnforcedAdmin();
169         mContentProtectionPolicy = DevicePolicyManager.CONTENT_PROTECTION_ENABLED;
170         Settings.Global.putInt(
171                 mContext.getContentResolver(), KEY_CONTENT_PROTECTION_PREFERENCE, -1);
172         mController = new TestContentProtectionTogglePreferenceController();
173 
174         assertThat(mController.isChecked()).isTrue();
175     }
176 
177     @Test
isChecked_enforcedAdmin_flagEnabled_policyNotControlled_readsSettingsTrue()178     public void isChecked_enforcedAdmin_flagEnabled_policyNotControlled_readsSettingsTrue() {
179         mSetFlagsRule.enableFlags(FLAG_MANAGE_DEVICE_POLICY_ENABLED);
180         mEnforcedAdmin = new RestrictedLockUtils.EnforcedAdmin();
181         mContentProtectionPolicy = DevicePolicyManager.CONTENT_PROTECTION_NOT_CONTROLLED_BY_POLICY;
182         Settings.Global.putInt(mContext.getContentResolver(), KEY_CONTENT_PROTECTION_PREFERENCE, 1);
183         mController = new TestContentProtectionTogglePreferenceController();
184 
185         assertThat(mController.isChecked()).isTrue();
186     }
187 
188     @Test
isChecked_enforcedAdmin_flagEnabled_policyNotControlled_readsSettingsFalse()189     public void isChecked_enforcedAdmin_flagEnabled_policyNotControlled_readsSettingsFalse() {
190         mSetFlagsRule.enableFlags(FLAG_MANAGE_DEVICE_POLICY_ENABLED);
191         mEnforcedAdmin = new RestrictedLockUtils.EnforcedAdmin();
192         mContentProtectionPolicy = DevicePolicyManager.CONTENT_PROTECTION_NOT_CONTROLLED_BY_POLICY;
193         Settings.Global.putInt(
194                 mContext.getContentResolver(), KEY_CONTENT_PROTECTION_PREFERENCE, -1);
195         mController = new TestContentProtectionTogglePreferenceController();
196 
197         assertThat(mController.isChecked()).isFalse();
198     }
199 
200     @Test
isChecked_enforcedAdmin_flagEnabled_policyNotControlled_readsSettingsDefaultTrue()201     public void isChecked_enforcedAdmin_flagEnabled_policyNotControlled_readsSettingsDefaultTrue() {
202         mSetFlagsRule.enableFlags(FLAG_MANAGE_DEVICE_POLICY_ENABLED);
203         mEnforcedAdmin = new RestrictedLockUtils.EnforcedAdmin();
204         mContentProtectionPolicy = DevicePolicyManager.CONTENT_PROTECTION_NOT_CONTROLLED_BY_POLICY;
205         mController = new TestContentProtectionTogglePreferenceController();
206 
207         assertThat(mController.isChecked()).isTrue();
208     }
209 
210     @Test
displayPreference()211     public void displayPreference() {
212         setupForDisplayPreference();
213 
214         mController.displayPreference(mMockPreferenceScreen);
215 
216         verify(mMockSwitchPreference).addOnSwitchChangeListener(mController);
217     }
218 
219     @Test
updateState_flagDisabled_noEnforcedAdmin()220     public void updateState_flagDisabled_noEnforcedAdmin() {
221         mSetFlagsRule.disableFlags(FLAG_MANAGE_DEVICE_POLICY_ENABLED);
222         setupForUpdateState();
223 
224         mController.updateState(mMockSwitchPreference);
225 
226         assertThat(mController.mCounterGetEnforcedAdmin).isEqualTo(1);
227         verify(mMockSwitchPreference, never()).setDisabledByAdmin(any());
228     }
229 
230     @Test
updateState_flagDisabled_enforcedAdmin()231     public void updateState_flagDisabled_enforcedAdmin() {
232         mSetFlagsRule.disableFlags(FLAG_MANAGE_DEVICE_POLICY_ENABLED);
233         mEnforcedAdmin = new RestrictedLockUtils.EnforcedAdmin();
234         setupForUpdateState();
235 
236         mController.updateState(mMockSwitchPreference);
237 
238         assertThat(mController.mCounterGetEnforcedAdmin).isEqualTo(1);
239         verify(mMockSwitchPreference).setDisabledByAdmin(mEnforcedAdmin);
240     }
241 
242     @Test
updateState_flagEnabled_noEnforcedAdmin_policyDisabled()243     public void updateState_flagEnabled_noEnforcedAdmin_policyDisabled() {
244         mSetFlagsRule.enableFlags(FLAG_MANAGE_DEVICE_POLICY_ENABLED);
245         mContentProtectionPolicy = DevicePolicyManager.CONTENT_PROTECTION_DISABLED;
246         setupForUpdateState();
247 
248         mController.updateState(mMockSwitchPreference);
249 
250         assertThat(mController.mCounterGetEnforcedAdmin).isEqualTo(1);
251         verify(mMockSwitchPreference, never()).setDisabledByAdmin(any());
252     }
253 
254     @Test
updateState_flagEnabled_noEnforcedAdmin_policyEnabled()255     public void updateState_flagEnabled_noEnforcedAdmin_policyEnabled() {
256         mSetFlagsRule.enableFlags(FLAG_MANAGE_DEVICE_POLICY_ENABLED);
257         mContentProtectionPolicy = DevicePolicyManager.CONTENT_PROTECTION_ENABLED;
258         setupForUpdateState();
259 
260         mController.updateState(mMockSwitchPreference);
261 
262         assertThat(mController.mCounterGetEnforcedAdmin).isEqualTo(1);
263         verify(mMockSwitchPreference, never()).setDisabledByAdmin(any());
264     }
265 
266     @Test
updateState_flagEnabled_noEnforcedAdmin_policyNotControlled()267     public void updateState_flagEnabled_noEnforcedAdmin_policyNotControlled() {
268         mSetFlagsRule.enableFlags(FLAG_MANAGE_DEVICE_POLICY_ENABLED);
269         mContentProtectionPolicy = DevicePolicyManager.CONTENT_PROTECTION_NOT_CONTROLLED_BY_POLICY;
270         setupForUpdateState();
271 
272         mController.updateState(mMockSwitchPreference);
273 
274         assertThat(mController.mCounterGetEnforcedAdmin).isEqualTo(1);
275         verify(mMockSwitchPreference, never()).setDisabledByAdmin(any());
276     }
277 
278     @Test
updateState_flagEnabled_enforcedAdmin_policyDisabled()279     public void updateState_flagEnabled_enforcedAdmin_policyDisabled() {
280         mSetFlagsRule.enableFlags(FLAG_MANAGE_DEVICE_POLICY_ENABLED);
281         mEnforcedAdmin = new RestrictedLockUtils.EnforcedAdmin();
282         mContentProtectionPolicy = DevicePolicyManager.CONTENT_PROTECTION_DISABLED;
283         setupForUpdateState();
284 
285         mController.updateState(mMockSwitchPreference);
286 
287         assertThat(mController.mCounterGetEnforcedAdmin).isEqualTo(1);
288         verify(mMockSwitchPreference).setDisabledByAdmin(mEnforcedAdmin);
289     }
290 
291     @Test
updateState_flagEnabled_enforcedAdmin_policyEnabled()292     public void updateState_flagEnabled_enforcedAdmin_policyEnabled() {
293         mSetFlagsRule.enableFlags(FLAG_MANAGE_DEVICE_POLICY_ENABLED);
294         mEnforcedAdmin = new RestrictedLockUtils.EnforcedAdmin();
295         mContentProtectionPolicy = DevicePolicyManager.CONTENT_PROTECTION_ENABLED;
296         setupForUpdateState();
297 
298         mController.updateState(mMockSwitchPreference);
299 
300         assertThat(mController.mCounterGetEnforcedAdmin).isEqualTo(1);
301         verify(mMockSwitchPreference).setDisabledByAdmin(mEnforcedAdmin);
302     }
303 
304     @Test
updateState_flagEnabled_enforcedAdmin_policyNotControlled()305     public void updateState_flagEnabled_enforcedAdmin_policyNotControlled() {
306         mSetFlagsRule.enableFlags(FLAG_MANAGE_DEVICE_POLICY_ENABLED);
307         mEnforcedAdmin = new RestrictedLockUtils.EnforcedAdmin();
308         mContentProtectionPolicy = DevicePolicyManager.CONTENT_PROTECTION_NOT_CONTROLLED_BY_POLICY;
309         setupForUpdateState();
310 
311         mController.updateState(mMockSwitchPreference);
312 
313         assertThat(mController.mCounterGetEnforcedAdmin).isEqualTo(1);
314         verify(mMockSwitchPreference, never()).setDisabledByAdmin(any());
315     }
316 
317     @Test
onSwitchChanged_switchChecked_manuallyEnabled()318     public void onSwitchChanged_switchChecked_manuallyEnabled() {
319         mController.setChecked(false);
320 
321         mController.onCheckedChanged(/* switchView= */ null, /* isChecked= */ true);
322 
323         assertThat(getContentProtectionGlobalSetting()).isEqualTo(1);
324     }
325 
326     @Test
onSwitchChanged_switchUnchecked_manuallyDisabled()327     public void onSwitchChanged_switchUnchecked_manuallyDisabled() {
328         mController.onCheckedChanged(/* switchView= */ null, /* isChecked= */ false);
329 
330         assertThat(getContentProtectionGlobalSetting()).isEqualTo(-1);
331     }
332 
getContentProtectionGlobalSetting()333     private int getContentProtectionGlobalSetting() {
334         return Settings.Global.getInt(
335                 mContext.getContentResolver(), KEY_CONTENT_PROTECTION_PREFERENCE, 0);
336     }
337 
setupForDisplayPreference()338     private void setupForDisplayPreference() {
339         when(mMockPreferenceScreen.findPreference(any())).thenReturn(mMockSwitchPreference);
340         when(mMockSwitchPreference.getKey()).thenReturn(mController.getPreferenceKey());
341         mController = new TestContentProtectionTogglePreferenceController();
342     }
343 
setupForUpdateState()344     private void setupForUpdateState() {
345         setupForDisplayPreference();
346         mController.displayPreference(mMockPreferenceScreen);
347     }
348 
349     private class TestContentProtectionTogglePreferenceController
350             extends ContentProtectionTogglePreferenceController {
351 
352         public int mCounterGetManagedProfile;
353 
354         public int mCounterGetEnforcedAdmin;
355 
356         public int mCounterGetContentProtectionPolicy;
357 
TestContentProtectionTogglePreferenceController()358         TestContentProtectionTogglePreferenceController() {
359             super(ContentProtectionTogglePreferenceControllerTest.this.mContext, "key");
360         }
361 
362         @Override
363         @Nullable
getManagedProfile()364         protected UserHandle getManagedProfile() {
365             mCounterGetManagedProfile++;
366             return null;
367         }
368 
369         @Override
370         @Nullable
getEnforcedAdmin()371         protected RestrictedLockUtils.EnforcedAdmin getEnforcedAdmin() {
372             mCounterGetEnforcedAdmin++;
373             return mEnforcedAdmin;
374         }
375 
376         @Override
377         @DevicePolicyManager.ContentProtectionPolicy
getContentProtectionPolicy(@ullable UserHandle userHandle)378         protected int getContentProtectionPolicy(@Nullable UserHandle userHandle) {
379             mCounterGetContentProtectionPolicy++;
380             return mContentProtectionPolicy;
381         }
382     }
383 }
384