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 com.android.settings.core.BasePreferenceController.AVAILABLE;
20 import static com.android.settings.core.BasePreferenceController.DISABLED_DEPENDENT_SETTING;
21 import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
22 
23 import static com.google.common.truth.Truth.assertThat;
24 
25 import static org.mockito.ArgumentMatchers.any;
26 import static org.mockito.ArgumentMatchers.anyInt;
27 import static org.mockito.Mockito.doReturn;
28 import static org.mockito.Mockito.when;
29 
30 import android.Manifest;
31 import android.content.ContentResolver;
32 import android.content.Context;
33 import android.content.pm.PackageManager;
34 import android.content.pm.ResolveInfo;
35 import android.content.pm.ServiceInfo;
36 import android.os.UserHandle;
37 import android.provider.Settings;
38 
39 import androidx.preference.Preference;
40 
41 import com.android.settings.testutils.ResolveInfoBuilder;
42 import com.android.settings.testutils.shadow.ShadowDeviceStateRotationLockSettingsManager;
43 import com.android.settings.testutils.shadow.ShadowRotationPolicy;
44 import com.android.settings.testutils.shadow.ShadowSensorPrivacyManager;
45 import com.android.settings.testutils.shadow.ShadowSystemSettings;
46 import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManager;
47 
48 import org.junit.Before;
49 import org.junit.Test;
50 import org.junit.runner.RunWith;
51 import org.mockito.Mock;
52 import org.mockito.Mockito;
53 import org.mockito.MockitoAnnotations;
54 import org.robolectric.RobolectricTestRunner;
55 import org.robolectric.RuntimeEnvironment;
56 import org.robolectric.annotation.Config;
57 import org.robolectric.shadow.api.Shadow;
58 
59 @RunWith(RobolectricTestRunner.class)
60 @Config(shadows = {ShadowSensorPrivacyManager.class, ShadowSystemSettings.class})
61 public class SmartAutoRotateControllerTest {
62 
63     private static final String PACKAGE_NAME = "package_name";
64 
65     private SmartAutoRotateController mController;
66     @Mock
67     private PackageManager mPackageManager;
68     @Mock
69     private Preference mPreference;
70     private ContentResolver mContentResolver;
71     private final DeviceStateRotationLockSettingsManager mDeviceStateAutoRotateSettingsManager =
72             DeviceStateRotationLockSettingsManager.getInstance(RuntimeEnvironment.application);
73 
74     @Before
setUp()75     public void setUp() {
76         MockitoAnnotations.initMocks(this);
77         final Context context = Mockito.spy(RuntimeEnvironment.application);
78         mContentResolver = RuntimeEnvironment.application.getContentResolver();
79         when(context.getPackageManager()).thenReturn(mPackageManager);
80         when(context.getContentResolver()).thenReturn(mContentResolver);
81         doReturn(PACKAGE_NAME).when(mPackageManager).getRotationResolverPackageName();
82         doReturn(PackageManager.PERMISSION_GRANTED).when(mPackageManager).checkPermission(
83                 Manifest.permission.CAMERA, PACKAGE_NAME);
84         mController = Mockito.spy(new SmartAutoRotateController(context, "test_key"));
85         when(mController.isCameraLocked()).thenReturn(false);
86         when(mController.isPowerSaveMode()).thenReturn(false);
87         doReturn(mController.getPreferenceKey()).when(mPreference).getKey();
88 
89         final ResolveInfo resolveInfo = new ResolveInfoBuilder(PACKAGE_NAME).build();
90         resolveInfo.serviceInfo = new ServiceInfo();
91         when(mPackageManager.resolveService(any(), anyInt())).thenReturn(resolveInfo);
92         enableAutoRotation();
93     }
94 
95     @Test
getAvailabilityStatus_returnAvailable()96     public void getAvailabilityStatus_returnAvailable() {
97         assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
98     }
99 
100     @Test
getAvailabilityStatus_resolveInfoIsNull_returnUnsupportedOnDevice()101     public void getAvailabilityStatus_resolveInfoIsNull_returnUnsupportedOnDevice() {
102         when(mPackageManager.resolveService(any(), anyInt())).thenReturn(null);
103         assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
104     }
105 
106     @Test
getAvailabilityStatus_noCameraPermission_returnDisableDependentSetting()107     public void getAvailabilityStatus_noCameraPermission_returnDisableDependentSetting() {
108         doReturn(PackageManager.PERMISSION_DENIED).when(mPackageManager).checkPermission(
109                 Manifest.permission.CAMERA, PACKAGE_NAME);
110 
111         assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_DEPENDENT_SETTING);
112     }
113 
114     @Test
getAvailabilityStatus_rotationLocked_returnDisableDependentSetting()115     public void getAvailabilityStatus_rotationLocked_returnDisableDependentSetting() {
116         disableAutoRotation();
117         assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_DEPENDENT_SETTING);
118     }
119 
120     @Test
getAvailabilityStatus_cameraDisabled_returnDisableDependentSetting()121     public void getAvailabilityStatus_cameraDisabled_returnDisableDependentSetting() {
122         when(mController.isCameraLocked()).thenReturn(true);
123         assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_DEPENDENT_SETTING);
124     }
125 
126     @Test
getAvailabilityStatus_powerSaveEnabled_returnDisableDependentSetting()127     public void getAvailabilityStatus_powerSaveEnabled_returnDisableDependentSetting() {
128         when(mController.isPowerSaveMode()).thenReturn(true);
129         assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_DEPENDENT_SETTING);
130     }
131 
132     @Test
133     @Config(shadows = {
134             ShadowDeviceStateRotationLockSettingsManager.class,
135             ShadowRotationPolicy.class
136     })
getAvailabilityStatus_deviceStateRotationLocked_returnDisableDependentSetting()137     public void getAvailabilityStatus_deviceStateRotationLocked_returnDisableDependentSetting() {
138         enableDeviceStateRotation();
139         lockDeviceStateRotation();
140 
141         int availabilityStatus = mController.getAvailabilityStatus();
142 
143         assertThat(availabilityStatus).isEqualTo(DISABLED_DEPENDENT_SETTING);
144     }
145 
146     @Test
147     @Config(shadows = {
148             ShadowDeviceStateRotationLockSettingsManager.class,
149             ShadowRotationPolicy.class
150     })
getAvailabilityStatus_deviceStateRotationUnlocked_returnAvailable()151     public void getAvailabilityStatus_deviceStateRotationUnlocked_returnAvailable() {
152         enableDeviceStateRotation();
153         unlockDeviceStateRotation();
154 
155         int availabilityStatus = mController.getAvailabilityStatus();
156 
157         assertThat(availabilityStatus).isEqualTo(AVAILABLE);
158     }
159 
enableAutoRotation()160     private void enableAutoRotation() {
161         Settings.System.putIntForUser(mContentResolver,
162                 Settings.System.ACCELEROMETER_ROTATION, 1, UserHandle.USER_CURRENT);
163     }
164 
disableAutoRotation()165     private void disableAutoRotation() {
166         Settings.System.putIntForUser(mContentResolver,
167                 Settings.System.ACCELEROMETER_ROTATION, 0, UserHandle.USER_CURRENT);
168     }
169 
enableDeviceStateRotation()170     private void enableDeviceStateRotation() {
171         ShadowRotationPolicy.setRotationSupported(true);
172         ShadowDeviceStateRotationLockSettingsManager.setDeviceStateRotationLockEnabled(true);
173     }
174 
lockDeviceStateRotation()175     private void lockDeviceStateRotation() {
176         ShadowDeviceStateRotationLockSettingsManager shadowManager =
177                 Shadow.extract(mDeviceStateAutoRotateSettingsManager);
178         shadowManager.setRotationLockedForAllStates(true);
179     }
180 
unlockDeviceStateRotation()181     private void unlockDeviceStateRotation() {
182         ShadowDeviceStateRotationLockSettingsManager shadowManager =
183                 Shadow.extract(mDeviceStateAutoRotateSettingsManager);
184         shadowManager.setRotationLockedForAllStates(false);
185     }
186 }
187