1 /* 2 * Copyright (C) 2021 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 android.provider.Settings.Secure.CAMERA_AUTOROTATE; 20 21 import static com.google.common.truth.Truth.assertThat; 22 23 import static org.mockito.ArgumentMatchers.any; 24 import static org.mockito.ArgumentMatchers.anyInt; 25 import static org.mockito.ArgumentMatchers.anyString; 26 import static org.mockito.Mockito.doReturn; 27 import static org.mockito.Mockito.when; 28 29 import android.Manifest; 30 import android.content.ContentResolver; 31 import android.content.Context; 32 import android.content.pm.PackageManager; 33 import android.content.pm.ResolveInfo; 34 import android.content.pm.ServiceInfo; 35 import android.content.res.Resources; 36 import android.os.UserHandle; 37 import android.provider.Settings; 38 39 import com.android.settings.R; 40 import com.android.settings.core.BasePreferenceController; 41 import com.android.settings.testutils.FakeFeatureFactory; 42 import com.android.settings.testutils.ResolveInfoBuilder; 43 import com.android.settings.testutils.shadow.ShadowDeviceStateRotationLockSettingsManager; 44 import com.android.settings.testutils.shadow.ShadowSensorPrivacyManager; 45 import com.android.settings.testutils.shadow.ShadowSystemSettings; 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.robolectric.RobolectricTestRunner; 54 import org.robolectric.RuntimeEnvironment; 55 import org.robolectric.annotation.Config; 56 57 @RunWith(RobolectricTestRunner.class) 58 @Config(shadows = { 59 ShadowSystemSettings.class, 60 ShadowSensorPrivacyManager.class, 61 ShadowDeviceStateRotationLockSettingsManager.class 62 }) 63 public class SmartAutoRotatePreferenceControllerTest { 64 65 private static final String PACKAGE_NAME = "package_name"; 66 @Mock 67 private PackageManager mPackageManager; 68 @Mock 69 private Resources mResources; 70 private Context mContext; 71 private ContentResolver mContentResolver; 72 private SmartAutoRotatePreferenceController mController; 73 74 @Before setUp()75 public void setUp() { 76 MockitoAnnotations.initMocks(this); 77 mContext = Mockito.spy(RuntimeEnvironment.application); 78 FakeFeatureFactory.setupForTest(); 79 mContentResolver = RuntimeEnvironment.application.getContentResolver(); 80 81 when(mContext.getPackageManager()).thenReturn(mPackageManager); 82 when(mContext.getResources()).thenReturn(mResources); 83 when(mContext.getContentResolver()).thenReturn(mContentResolver); 84 85 when(mResources.getBoolean(R.bool.config_auto_rotate_face_detection_available)).thenReturn( 86 true); 87 88 doReturn(PACKAGE_NAME).when(mPackageManager).getRotationResolverPackageName(); 89 doReturn(PackageManager.PERMISSION_GRANTED).when(mPackageManager).checkPermission( 90 Manifest.permission.CAMERA, PACKAGE_NAME); 91 when(mContext.getString(R.string.auto_rotate_option_off)) 92 .thenReturn("Off"); 93 when(mContext.getString(R.string.auto_rotate_option_on)) 94 .thenReturn("On"); 95 when(mContext.getString(R.string.auto_rotate_option_face_based)) 96 .thenReturn("On - Face-based"); 97 98 disableCameraBasedRotation(); 99 final ResolveInfo resolveInfo = new ResolveInfoBuilder(PACKAGE_NAME).build(); 100 resolveInfo.serviceInfo = new ServiceInfo(); 101 when(mPackageManager.resolveService(any(), anyInt())).thenReturn(resolveInfo); 102 103 mController = Mockito.spy( 104 new SmartAutoRotatePreferenceController(mContext, "smart_auto_rotate")); 105 when(mController.isCameraLocked()).thenReturn(false); 106 when(mController.isPowerSaveMode()).thenReturn(false); 107 ShadowDeviceStateRotationLockSettingsManager.setDeviceStateRotationLockEnabled(false); 108 } 109 110 @Test isAvailableWhenPolicyAllows()111 public void isAvailableWhenPolicyAllows() { 112 assertThat(mController.isAvailable()).isFalse(); 113 114 enableAutoRotationPreference(); 115 116 assertThat(mController.isAvailable()).isTrue(); 117 } 118 119 @Test getSummary_settingsIsOff_returnsOff()120 public void getSummary_settingsIsOff_returnsOff() { 121 disableAutoRotation(); 122 123 assertThat(mController.getSummary()).isEqualTo("Off"); 124 } 125 126 @Test getSummary_settingsIsOn_returnsOn()127 public void getSummary_settingsIsOn_returnsOn() { 128 enableAutoRotation(); 129 130 assertThat(mController.getSummary()).isEqualTo("On"); 131 } 132 133 @Test getSummary_autoRotateOffSmartAutoRotateOn_returnsOff()134 public void getSummary_autoRotateOffSmartAutoRotateOn_returnsOff() { 135 enableCameraBasedRotation(); 136 disableAutoRotation(); 137 138 assertThat(mController.getSummary()).isEqualTo("Off"); 139 } 140 141 @Test updatePreference_smartAutoRotateOn_returnsFaceBased()142 public void updatePreference_smartAutoRotateOn_returnsFaceBased() { 143 enableCameraBasedRotation(); 144 enableAutoRotation(); 145 146 assertThat(mController.getSummary()).isEqualTo("On - Face-based"); 147 } 148 149 @Test getSummary_noSmartAuto_returnsOff()150 public void getSummary_noSmartAuto_returnsOff() { 151 disableAutoRotation(); 152 Settings.Secure.putStringForUser(mContentResolver, 153 CAMERA_AUTOROTATE, null, UserHandle.USER_CURRENT); 154 155 assertThat(mController.getSummary()).isEqualTo("Off"); 156 157 } 158 159 @Test getSummary_noSmartAuto_returnsOn()160 public void getSummary_noSmartAuto_returnsOn() { 161 enableAutoRotation(); 162 Settings.Secure.putStringForUser(mContentResolver, 163 CAMERA_AUTOROTATE, null, UserHandle.USER_CURRENT); 164 165 assertThat(mController.getSummary()).isEqualTo("On"); 166 } 167 168 @Test getSummary_noCameraPermission_returnsOn()169 public void getSummary_noCameraPermission_returnsOn() { 170 enableAutoRotation(); 171 enableCameraBasedRotation(); 172 doReturn(PackageManager.PERMISSION_DENIED).when(mPackageManager).checkPermission( 173 Manifest.permission.CAMERA, PACKAGE_NAME); 174 175 assertThat(mController.getSummary()).isEqualTo("On"); 176 } 177 178 @Test getSummary_cameraDisabled_returnsOn()179 public void getSummary_cameraDisabled_returnsOn() { 180 enableAutoRotation(); 181 enableCameraBasedRotation(); 182 when(mController.isCameraLocked()).thenReturn(true); 183 184 assertThat(mController.getSummary()).isEqualTo("On"); 185 } 186 187 @Test getSummary_powerSaveEnabled_returnsOn()188 public void getSummary_powerSaveEnabled_returnsOn() { 189 enableAutoRotation(); 190 enableCameraBasedRotation(); 191 when(mController.isPowerSaveMode()).thenReturn(true); 192 193 assertThat(mController.getSummary()).isEqualTo("On"); 194 } 195 196 @Test testGetAvailabilityStatus()197 public void testGetAvailabilityStatus() { 198 assertThat(mController.getAvailabilityStatus()).isEqualTo(BasePreferenceController 199 .UNSUPPORTED_ON_DEVICE); 200 201 enableAutoRotationPreference(); 202 203 assertThat(mController.getAvailabilityStatus()).isEqualTo(BasePreferenceController 204 .AVAILABLE); 205 206 disableAutoRotationPreference(); 207 208 assertThat(mController.getAvailabilityStatus()).isEqualTo(BasePreferenceController 209 .UNSUPPORTED_ON_DEVICE); 210 } 211 212 213 @Test getAvailabilityStatus_deviceStateRotationEnabled_returnsUnsupported()214 public void getAvailabilityStatus_deviceStateRotationEnabled_returnsUnsupported() { 215 enableAutoRotationPreference(); 216 ShadowDeviceStateRotationLockSettingsManager.setDeviceStateRotationLockEnabled(true); 217 218 assertThat(mController.getAvailabilityStatus()).isEqualTo( 219 BasePreferenceController.UNSUPPORTED_ON_DEVICE); 220 } 221 222 @Test isSliceableCorrectKey_returnsTrue()223 public void isSliceableCorrectKey_returnsTrue() { 224 final AutoRotatePreferenceController controller = 225 new AutoRotatePreferenceController(mContext, "auto_rotate"); 226 assertThat(controller.isSliceable()).isTrue(); 227 } 228 229 @Test isSliceableIncorrectKey_returnsFalse()230 public void isSliceableIncorrectKey_returnsFalse() { 231 final AutoRotatePreferenceController controller = 232 new AutoRotatePreferenceController(mContext, "bad_key"); 233 assertThat(controller.isSliceable()).isFalse(); 234 } 235 enableAutoRotationPreference()236 private void enableAutoRotationPreference() { 237 when(mPackageManager.hasSystemFeature(anyString())).thenReturn(true); 238 when(mResources.getBoolean(anyInt())).thenReturn(true); 239 Settings.System.putIntForUser(mContentResolver, 240 Settings.System.HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY, 0, 241 UserHandle.USER_CURRENT); 242 } 243 disableAutoRotationPreference()244 private void disableAutoRotationPreference() { 245 when(mPackageManager.hasSystemFeature(anyString())).thenReturn(true); 246 when(mResources.getBoolean(anyInt())).thenReturn(true); 247 Settings.System.putIntForUser(mContentResolver, 248 Settings.System.HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY, 1, 249 UserHandle.USER_CURRENT); 250 } 251 enableAutoRotation()252 private void enableAutoRotation() { 253 Settings.System.putIntForUser(mContentResolver, 254 Settings.System.ACCELEROMETER_ROTATION, 1, UserHandle.USER_CURRENT); 255 } 256 disableAutoRotation()257 private void disableAutoRotation() { 258 Settings.System.putIntForUser(mContentResolver, 259 Settings.System.ACCELEROMETER_ROTATION, 0, UserHandle.USER_CURRENT); 260 } 261 enableCameraBasedRotation()262 private void enableCameraBasedRotation() { 263 Settings.Secure.putIntForUser(mContentResolver, 264 CAMERA_AUTOROTATE, 1, UserHandle.USER_CURRENT); 265 } 266 disableCameraBasedRotation()267 private void disableCameraBasedRotation() { 268 Settings.Secure.putIntForUser(mContentResolver, 269 CAMERA_AUTOROTATE, 0, UserHandle.USER_CURRENT); 270 } 271 } 272