1 /*
2  * Copyright (C) 2016 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.deviceinfo;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 
21 import static org.mockito.ArgumentMatchers.any;
22 import static org.mockito.ArgumentMatchers.eq;
23 import static org.mockito.Mockito.doReturn;
24 import static org.mockito.Mockito.mock;
25 import static org.mockito.Mockito.spy;
26 import static org.mockito.Mockito.verify;
27 import static org.mockito.Mockito.when;
28 
29 import android.app.Activity;
30 import android.content.Context;
31 import android.os.Looper;
32 import android.os.UserManager;
33 import android.provider.Settings;
34 
35 import androidx.lifecycle.LifecycleOwner;
36 import androidx.preference.Preference;
37 import androidx.test.annotation.UiThreadTest;
38 import androidx.test.core.app.ApplicationProvider;
39 import androidx.test.ext.junit.runners.AndroidJUnit4;
40 
41 import com.android.internal.logging.nano.MetricsProto;
42 import com.android.settings.core.InstrumentedPreferenceFragment;
43 import com.android.settings.testutils.FakeFeatureFactory;
44 import com.android.settingslib.core.lifecycle.Lifecycle;
45 import com.android.settingslib.development.DevelopmentSettingsEnabler;
46 
47 import org.junit.Before;
48 import org.junit.Test;
49 import org.junit.runner.RunWith;
50 import org.mockito.Answers;
51 import org.mockito.Mock;
52 import org.mockito.MockitoAnnotations;
53 
54 @RunWith(AndroidJUnit4.class)
55 public class BuildNumberPreferenceControllerTest {
56 
57     private static final String KEY_BUILD_NUMBER = "build_number";
58     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
59     private InstrumentedPreferenceFragment mFragment;
60 
61     private Context mContext;
62     private UserManager mUserManager;
63     private LifecycleOwner mLifecycleOwner;
64     private Lifecycle mLifecycle;
65     private FakeFeatureFactory mFactory;
66     private Preference mPreference;
67     private BuildNumberPreferenceController mController;
68 
69     @Before
70     @UiThreadTest
setUp()71     public void setUp() {
72         if (Looper.myLooper() == null) {
73             Looper.prepare();
74         }
75         MockitoAnnotations.initMocks(this);
76 
77         mContext = spy(ApplicationProvider.getApplicationContext());
78         mUserManager = (UserManager) spy(mContext.getSystemService(Context.USER_SERVICE));
79         doReturn(mUserManager).when(mContext).getSystemService(Context.USER_SERVICE);
80 
81         mFactory = FakeFeatureFactory.setupForTest();
82         mLifecycleOwner = () -> mLifecycle;
83         mLifecycle = new Lifecycle(mLifecycleOwner);
84         mController = spy(new BuildNumberPreferenceController(mContext, KEY_BUILD_NUMBER));
85         mController.setHost(mFragment);
86 
87         mPreference = new Preference(mContext);
88         mPreference.setKey(mController.getPreferenceKey());
89         DevelopmentSettingsEnabler.setDevelopmentSettingsEnabled(mContext, false);
90         Settings.Global.putInt(mContext.getContentResolver(),
91                 Settings.Global.DEVICE_PROVISIONED, 1);
92     }
93 
94     @Test
handlePrefTreeClick_onlyHandleBuildNumberPref()95     public void handlePrefTreeClick_onlyHandleBuildNumberPref() {
96         assertThat(mController.handlePreferenceTreeClick(mock(Preference.class))).isFalse();
97     }
98 
99     @Test
handlePrefTreeClick_notAdminUser_notDemoUser_doNothing()100     public void handlePrefTreeClick_notAdminUser_notDemoUser_doNothing() {
101         when(mUserManager.isAdminUser()).thenReturn(false);
102         when(mUserManager.isDemoUser()).thenReturn(false);
103 
104         assertThat(mController.handlePreferenceTreeClick(mPreference)).isFalse();
105     }
106 
107     @Test
handlePrefTreeClick_isAdminUser_notDemoUser_handleBuildNumberPref()108     public void handlePrefTreeClick_isAdminUser_notDemoUser_handleBuildNumberPref() {
109         when(mUserManager.isAdminUser()).thenReturn(true);
110         when(mUserManager.isDemoUser()).thenReturn(false);
111 
112         assertThat(mController.handlePreferenceTreeClick(mPreference)).isTrue();
113     }
114 
115     @Test
handlePrefTreeClick_notAdminUser_isDemoUser_handleBuildNumberPref()116     public void handlePrefTreeClick_notAdminUser_isDemoUser_handleBuildNumberPref() {
117         when(mUserManager.isAdminUser()).thenReturn(false);
118         when(mUserManager.isDemoUser()).thenReturn(true);
119 
120         assertThat(mController.handlePreferenceTreeClick(mPreference)).isTrue();
121     }
122 
123     @Test
handlePrefTreeClick_deviceNotProvisioned_doNothing()124     public void handlePrefTreeClick_deviceNotProvisioned_doNothing() {
125         when(mUserManager.isAdminUser()).thenReturn(true);
126         when(mUserManager.isDemoUser()).thenReturn(false);
127 
128         Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.DEVICE_PROVISIONED,
129                 0);
130 
131         assertThat(mController.handlePreferenceTreeClick(mPreference)).isFalse();
132         verify(mFactory.metricsFeatureProvider).action(
133                 any(Context.class),
134                 eq(MetricsProto.MetricsEvent.ACTION_SETTINGS_BUILD_NUMBER_PREF));
135     }
136 
137     @Test
handlePrefTreeClick_isMonkeyRun_doNothing()138     public void handlePrefTreeClick_isMonkeyRun_doNothing() {
139         when(mController.isUserAMonkey()).thenReturn(true);
140         assertThat(mController.handlePreferenceTreeClick(mPreference)).isFalse();
141     }
142 
143     @Test
handlePrefTreeClick_userHasRestriction_doNothing()144     public void handlePrefTreeClick_userHasRestriction_doNothing() {
145         when(mUserManager.isAdminUser()).thenReturn(true);
146         when(mUserManager.isDemoUser()).thenReturn(false);
147         when(mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES))
148                 .thenReturn(true);
149 
150         assertThat(mController.handlePreferenceTreeClick(mPreference)).isFalse();
151         verify(mFactory.metricsFeatureProvider).action(
152                 any(Context.class),
153                 eq(MetricsProto.MetricsEvent.ACTION_SETTINGS_BUILD_NUMBER_PREF));
154     }
155 
156     @Test
onActivityResult_notConfirmPasswordRequest_doNothing()157     public void onActivityResult_notConfirmPasswordRequest_doNothing() {
158         final boolean activityResultHandled = mController.onActivityResult(
159                 BuildNumberPreferenceController.REQUEST_CONFIRM_PASSWORD_FOR_DEV_PREF + 1,
160                 Activity.RESULT_OK,
161                 null);
162 
163         assertThat(activityResultHandled).isFalse();
164         assertThat(DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(mContext)).isFalse();
165     }
166 
167     @Test
onActivityResult_confirmPasswordRequestFailed_doNotEnableDevPref()168     public void onActivityResult_confirmPasswordRequestFailed_doNotEnableDevPref() {
169         final boolean activityResultHandled = mController.onActivityResult(
170                 BuildNumberPreferenceController.REQUEST_CONFIRM_PASSWORD_FOR_DEV_PREF,
171                 Activity.RESULT_CANCELED,
172                 null);
173 
174         assertThat(activityResultHandled).isTrue();
175         assertThat(DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(mContext)).isFalse();
176     }
177 
178     @Test
179     @UiThreadTest
onActivityResult_confirmPasswordRequestCompleted_enableDevPref()180     public void onActivityResult_confirmPasswordRequestCompleted_enableDevPref() {
181         when(mUserManager.isAdminUser()).thenReturn(true);
182 
183         final boolean activityResultHandled = mController.onActivityResult(
184                 BuildNumberPreferenceController.REQUEST_CONFIRM_PASSWORD_FOR_DEV_PREF,
185                 Activity.RESULT_OK,
186                 null);
187 
188         assertThat(activityResultHandled).isTrue();
189         assertThat(DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(mContext)).isTrue();
190     }
191 }
192