1 /*
2  * Copyright (C) 2022 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 
17 package com.android.settings.display;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 
21 import static org.mockito.ArgumentMatchers.any;
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.Mockito.atLeastOnce;
26 import static org.mockito.Mockito.spy;
27 import static org.mockito.Mockito.verify;
28 import static org.mockito.Mockito.when;
29 
30 import android.content.ContentResolver;
31 import android.content.Context;
32 import android.content.pm.ActivityInfo;
33 import android.content.pm.ApplicationInfo;
34 import android.content.pm.PackageManager;
35 import android.content.pm.ResolveInfo;
36 import android.database.Cursor;
37 import android.database.MatrixCursor;
38 import android.provider.Settings;
39 
40 import androidx.preference.Preference;
41 import androidx.preference.PreferenceScreen;
42 import androidx.test.core.app.ApplicationProvider;
43 
44 import com.android.settings.R;
45 import com.android.settings.core.BasePreferenceController;
46 
47 import org.junit.Before;
48 import org.junit.Test;
49 import org.junit.runner.RunWith;
50 import org.mockito.Mock;
51 import org.mockito.Mockito;
52 import org.mockito.MockitoAnnotations;
53 import org.mockito.stubbing.Answer;
54 import org.robolectric.RobolectricTestRunner;
55 
56 @RunWith(RobolectricTestRunner.class)
57 public class ControlsTrivialPrivacyPreferenceControllerTest {
58 
59     private static final String TEST_KEY = "test_key";
60     private static final String SETTING_KEY = Settings.Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS;
61     private static final String DEPENDENCY_SETTING_KEY = Settings.Secure.LOCKSCREEN_SHOW_CONTROLS;
62 
63     private Context mContext;
64     private ContentResolver mContentResolver;
65     private ControlsTrivialPrivacyPreferenceController mController;
66 
67     @Mock
68     private Preference mPreference;
69 
70     @Mock
71     private PreferenceScreen mPreferenceScreen;
72 
73     @Mock
74     private PackageManager mPackageManager;
75 
76     @Before
setUp()77     public void setUp() {
78         MockitoAnnotations.initMocks(this);
79         mContext = spy(ApplicationProvider.getApplicationContext());
80         mContentResolver = spy(mContext.getContentResolver());
81         when(mContext.getContentResolver()).thenReturn(mContentResolver);
82         when(mContext.getPackageManager()).thenReturn(mPackageManager);
83 
84         setCustomizableLockScreenQuickAffordancesEnabled(false);
85 
86         mController = new ControlsTrivialPrivacyPreferenceController(mContext, TEST_KEY);
87     }
88 
89     @Test
isCheckedWhenSettingIsTrue()90     public void isCheckedWhenSettingIsTrue() {
91         Settings.Secure.putInt(mContentResolver, SETTING_KEY, 1);
92 
93         assertThat(mController.isChecked()).isTrue();
94     }
95 
96     @Test
isCheckedWhenSettingIsFalse()97     public void isCheckedWhenSettingIsFalse() {
98         Settings.Secure.putInt(mContentResolver, SETTING_KEY, 0);
99 
100         assertThat(mController.isChecked()).isFalse();
101     }
102 
103     @Test
isCheckedWhenSettingIsNull()104     public void isCheckedWhenSettingIsNull() {
105         Settings.Secure.putString(mContentResolver, SETTING_KEY, null);
106 
107         assertThat(mController.isChecked()).isFalse();
108     }
109 
110     @Test
checkedMeansSettingIsTrue()111     public void checkedMeansSettingIsTrue() {
112         mController.setChecked(true);
113 
114         assertThat(Settings.Secure.getInt(mContentResolver, SETTING_KEY, 0)).isNotEqualTo(0);
115     }
116 
117     @Test
uncheckedMeansSettingIsFalse()118     public void uncheckedMeansSettingIsFalse() {
119         mController.setChecked(false);
120 
121         assertThat(Settings.Secure.getInt(mContentResolver, SETTING_KEY, 0)).isEqualTo(0);
122     }
123 
124     @Test
getSummaryRequireDeviceControls()125     public void getSummaryRequireDeviceControls() {
126         Settings.Secure.putInt(mContentResolver, DEPENDENCY_SETTING_KEY, 0);
127 
128         assertThat(mController.getSummary().toString()).isEqualTo(
129                 mContext.getText(R.string.lockscreen_trivial_disabled_controls_summary));
130     }
131 
132     @Test
getSummaryDefault()133     public void getSummaryDefault() {
134         Settings.Secure.putInt(mContentResolver, DEPENDENCY_SETTING_KEY, 1);
135 
136         assertThat(mController.getSummary().toString()).isEqualTo(
137                 mContext.getText(R.string.lockscreen_trivial_controls_summary));
138     }
139 
140     @Test
updateState()141     public void updateState() {
142         Settings.Secure.putInt(mContentResolver, DEPENDENCY_SETTING_KEY, 1);
143 
144         mController.updateState(mPreference);
145 
146         verify(mPreference).setEnabled(anyBoolean());
147         verify(mPreference, atLeastOnce()).setSummary(mController.getSummary());
148     }
149 
150     @Test
updateStateWithCustomizableLockScreenQuickAffordancesEnabled()151     public void updateStateWithCustomizableLockScreenQuickAffordancesEnabled() {
152         setCustomizableLockScreenQuickAffordancesEnabled(true);
153         Settings.Secure.putInt(mContentResolver, DEPENDENCY_SETTING_KEY, 0);
154 
155         mController.updateState(mPreference);
156 
157         verify(mPreference).setEnabled(true);
158         verify(mPreference, atLeastOnce()).setSummary(
159                 mContext.getString(R.string.lockscreen_trivial_controls_summary));
160     }
161 
162     @Test
getAvailabilityStatusWithoutDeviceControls()163     public void getAvailabilityStatusWithoutDeviceControls() {
164         Settings.Secure.putInt(mContentResolver, DEPENDENCY_SETTING_KEY, 0);
165 
166         assertThat(mController.getAvailabilityStatus()).isEqualTo(
167                 BasePreferenceController.DISABLED_DEPENDENT_SETTING);
168     }
169 
170     @Test
getAvailabilityStatusWithCustomizableLockScreenQuickAffordancesEnabled()171     public void getAvailabilityStatusWithCustomizableLockScreenQuickAffordancesEnabled() {
172         setCustomizableLockScreenQuickAffordancesEnabled(true);
173         Settings.Secure.putInt(mContentResolver, DEPENDENCY_SETTING_KEY, 0);
174 
175         assertThat(mController.getAvailabilityStatus()).isEqualTo(
176                 BasePreferenceController.AVAILABLE);
177     }
178 
179     @Test
getAvailabilityStatusWithDeviceControls()180     public void getAvailabilityStatusWithDeviceControls() {
181         Settings.Secure.putInt(mContentResolver, DEPENDENCY_SETTING_KEY, 1);
182 
183 
184         assertThat(mController.getAvailabilityStatus()).isEqualTo(
185                 BasePreferenceController.AVAILABLE);
186     }
187 
188     @Test
setDependency()189     public void setDependency() {
190         Mockito.when(mPreferenceScreen
191                 .findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
192         mController.displayPreference(mPreferenceScreen);
193         verify(mPreference).setDependency(anyString());
194     }
195 
setCustomizableLockScreenQuickAffordancesEnabled(boolean isEnabled)196     private void setCustomizableLockScreenQuickAffordancesEnabled(boolean isEnabled) {
197         when(
198                 mContentResolver.query(
199                         CustomizableLockScreenUtils.FLAGS_URI, null, null, null))
200                 .thenAnswer((Answer<Cursor>) invocation -> {
201                     final MatrixCursor cursor = new MatrixCursor(
202                             new String[] {
203                                     CustomizableLockScreenUtils.NAME,
204                                     CustomizableLockScreenUtils.VALUE
205                             });
206                     cursor.addRow(
207                             new Object[] {
208                                     CustomizableLockScreenUtils.ENABLED_FLAG, isEnabled ? 1 : 0
209                             });
210                     return cursor;
211                 });
212 
213         if (isEnabled) {
214             final ApplicationInfo applicationInfo = new ApplicationInfo();
215             applicationInfo.packageName = "package";
216 
217             final ActivityInfo activityInfo = new ActivityInfo();
218             activityInfo.applicationInfo = applicationInfo;
219             activityInfo.name = "activity";
220 
221             final ResolveInfo resolveInfo = new ResolveInfo();
222             resolveInfo.activityInfo = activityInfo;
223 
224             when(mPackageManager.resolveActivity(any(), anyInt())).thenReturn(resolveInfo);
225         }
226     }
227 }
228