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.DEVICE_STATE_ROTATION_LOCK_LOCKED; 20 21 import static com.android.settings.display.SmartAutoRotatePreferenceFragment.AUTO_ROTATE_MAIN_SWITCH_PREFERENCE_KEY; 22 import static com.android.settings.display.SmartAutoRotatePreferenceFragment.AUTO_ROTATE_SWITCH_PREFERENCE_KEY; 23 24 import static com.google.common.truth.Truth.assertThat; 25 26 import static org.mockito.ArgumentMatchers.any; 27 import static org.mockito.ArgumentMatchers.anyInt; 28 import static org.mockito.Mockito.doReturn; 29 import static org.mockito.Mockito.never; 30 import static org.mockito.Mockito.spy; 31 import static org.mockito.Mockito.times; 32 import static org.mockito.Mockito.verify; 33 import static org.mockito.Mockito.when; 34 35 import android.Manifest; 36 import android.content.ContentResolver; 37 import android.content.Context; 38 import android.content.pm.PackageManager; 39 import android.content.pm.ResolveInfo; 40 import android.content.pm.ServiceInfo; 41 import android.content.res.Resources; 42 import android.view.View; 43 44 import androidx.preference.Preference; 45 46 import com.android.settings.R; 47 import com.android.settings.SettingsActivity; 48 import com.android.settings.testutils.ResolveInfoBuilder; 49 import com.android.settings.testutils.shadow.ShadowDeviceStateRotationLockSettingsManager; 50 import com.android.settings.testutils.shadow.ShadowRotationPolicy; 51 import com.android.settingslib.core.AbstractPreferenceController; 52 import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManager; 53 54 import org.junit.Before; 55 import org.junit.Test; 56 import org.junit.runner.RunWith; 57 import org.mockito.Mock; 58 import org.mockito.MockitoAnnotations; 59 import org.robolectric.RobolectricTestRunner; 60 import org.robolectric.RuntimeEnvironment; 61 import org.robolectric.annotation.Config; 62 63 import java.util.List; 64 65 @RunWith(RobolectricTestRunner.class) 66 @Config(shadows = { 67 com.android.settings.testutils.shadow.ShadowFragment.class, 68 ShadowDeviceStateRotationLockSettingsManager.class, 69 ShadowRotationPolicy.class 70 }) 71 public class SmartAutoRotatePreferenceFragmentTest { 72 73 private static final int STATE_FOLDED = 0; 74 private static final int STATE_HALF_FOLDED = 1; 75 private static final int STATE_UNFOLDED = 2; 76 private static final int STATE_REAR_DISPLAY = 3; 77 78 private static final String PACKAGE_NAME = "package_name"; 79 80 private SmartAutoRotatePreferenceFragment mFragment; 81 82 @Mock 83 private PackageManager mPackageManager; 84 85 @Mock 86 private View mView; 87 88 @Mock 89 private SettingsActivity mActivity; 90 91 @Mock 92 private Preference mRotateSwitchPreference; 93 private Resources mResources; 94 private Context mContext; 95 96 @Mock 97 private Preference mRotateMainSwitchPreference; 98 99 @Before setUp()100 public void setUp() { 101 MockitoAnnotations.initMocks(this); 102 103 mContext = spy(RuntimeEnvironment.application); 104 ContentResolver mContentResolver = RuntimeEnvironment.application.getContentResolver(); 105 when(mContext.getPackageManager()).thenReturn(mPackageManager); 106 when(mContext.getContentResolver()).thenReturn(mContentResolver); 107 when(mContext.getApplicationContext()).thenReturn(mContext); 108 doReturn(PACKAGE_NAME).when(mPackageManager).getRotationResolverPackageName(); 109 doReturn(PackageManager.PERMISSION_GRANTED).when(mPackageManager).checkPermission( 110 Manifest.permission.CAMERA, PACKAGE_NAME); 111 112 mResources = spy(mContext.getResources()); 113 when(mContext.getResources()).thenReturn(mResources); 114 115 final ResolveInfo resolveInfo = new ResolveInfoBuilder(PACKAGE_NAME).build(); 116 resolveInfo.serviceInfo = new ServiceInfo(); 117 when(mPackageManager.resolveService(any(), anyInt())).thenReturn(resolveInfo); 118 119 mFragment = spy(new SmartAutoRotatePreferenceFragment()); 120 when(mActivity.getPackageManager()).thenReturn(mPackageManager); 121 when(mFragment.getActivity()).thenReturn(mActivity); 122 when(mFragment.getContext()).thenReturn(mContext); 123 when(mActivity.getResources()).thenReturn(mResources); 124 125 doReturn(mView).when(mFragment).getView(); 126 127 when(mFragment.findPreference(AUTO_ROTATE_SWITCH_PREFERENCE_KEY)).thenReturn( 128 mRotateSwitchPreference); 129 130 when(mFragment.findPreference(AUTO_ROTATE_MAIN_SWITCH_PREFERENCE_KEY)) 131 .thenReturn(mRotateMainSwitchPreference); 132 133 when(mResources.getIntArray(com.android.internal.R.array.config_foldedDeviceStates)) 134 .thenReturn(new int[] {STATE_FOLDED}); 135 when(mResources.getIntArray(com.android.internal.R.array.config_halfFoldedDeviceStates)) 136 .thenReturn(new int[] {STATE_HALF_FOLDED}); 137 when(mResources.getIntArray(com.android.internal.R.array.config_openDeviceStates)) 138 .thenReturn(new int[] {STATE_UNFOLDED}); 139 when(mResources.getIntArray(com.android.internal.R.array.config_rearDisplayDeviceStates)) 140 .thenReturn(new int[] {STATE_REAR_DISPLAY}); 141 } 142 143 @Test createHeader_faceDetectionSupported_switchBarIsEnabled()144 public void createHeader_faceDetectionSupported_switchBarIsEnabled() { 145 ShadowDeviceStateRotationLockSettingsManager.setDeviceStateRotationLockEnabled(false); 146 mFragment.createHeader(mActivity); 147 148 verify(mRotateMainSwitchPreference, never()).setVisible(false); 149 verify(mRotateSwitchPreference, times(1)).setVisible(false); 150 } 151 152 @Test createHeader_deviceStateRotationSupported_switchBarIsDisabled()153 public void createHeader_deviceStateRotationSupported_switchBarIsDisabled() { 154 ShadowRotationPolicy.setRotationSupported(true); 155 ShadowDeviceStateRotationLockSettingsManager.setDeviceStateRotationLockEnabled(true); 156 157 mFragment.createHeader(mActivity); 158 159 verify(mRotateMainSwitchPreference, times(1)).setVisible(false); 160 verify(mRotateSwitchPreference, never()).setVisible(false); 161 } 162 163 @Test createHeader_faceDetectionUnSupported_switchBarIsDisabled()164 public void createHeader_faceDetectionUnSupported_switchBarIsDisabled() { 165 doReturn(null).when(mPackageManager).getRotationResolverPackageName(); 166 167 mFragment.createHeader(mActivity); 168 169 verify(mRotateMainSwitchPreference, times(1)).setVisible(false); 170 verify(mRotateSwitchPreference, never()).setVisible(false); 171 } 172 173 @Test createHeader_faceDetectionNotEnabledByConfig_switchBarIsDisabled()174 public void createHeader_faceDetectionNotEnabledByConfig_switchBarIsDisabled() { 175 doReturn(false).when(mResources).getBoolean( 176 R.bool.config_auto_rotate_face_detection_available); 177 178 mFragment.createHeader(mActivity); 179 180 verify(mRotateMainSwitchPreference, times(1)).setVisible(false); 181 verify(mRotateSwitchPreference, never()).setVisible(false); 182 } 183 184 @Test createPreferenceControllers_noSettableDeviceStates_returnsEmptyList()185 public void createPreferenceControllers_noSettableDeviceStates_returnsEmptyList() { 186 enableDeviceStateSettableRotationStates(new String[] {}, new String[] {}); 187 188 List<AbstractPreferenceController> preferenceControllers = 189 mFragment.createPreferenceControllers(mContext); 190 191 assertThat(preferenceControllers).isEmpty(); 192 } 193 194 @Test createPreferenceControllers_settableDeviceStates_returnsDeviceStateControllers()195 public void createPreferenceControllers_settableDeviceStates_returnsDeviceStateControllers() { 196 enableDeviceStateSettableRotationStates( 197 new String[] { 198 STATE_FOLDED + ":" + DEVICE_STATE_ROTATION_LOCK_LOCKED, 199 STATE_UNFOLDED + ":" + DEVICE_STATE_ROTATION_LOCK_LOCKED 200 }, 201 new String[] {"Folded", "Unfolded"}); 202 203 List<AbstractPreferenceController> preferenceControllers = 204 mFragment.createPreferenceControllers(mContext); 205 206 assertThat(preferenceControllers).hasSize(2); 207 assertThat(preferenceControllers.get(0)) 208 .isInstanceOf(DeviceStateAutoRotateSettingController.class); 209 assertThat(preferenceControllers.get(1)) 210 .isInstanceOf(DeviceStateAutoRotateSettingController.class); 211 } 212 213 @Test setupFooter_linkAddedWhenAppropriate()214 public void setupFooter_linkAddedWhenAppropriate() { 215 doReturn("").when(mFragment).getText(anyInt()); 216 doReturn("").when(mFragment).getString(anyInt()); 217 mFragment.setupFooter(); 218 verify(mFragment, never()).addHelpLink(); 219 220 doReturn("testString").when(mFragment).getText(anyInt()); 221 doReturn("testString").when(mFragment).getString(anyInt()); 222 mFragment.setupFooter(); 223 verify(mFragment, times(1)).addHelpLink(); 224 } 225 enableDeviceStateSettableRotationStates( String[] settableStates, String[] settableStatesDescriptions)226 private void enableDeviceStateSettableRotationStates( 227 String[] settableStates, String[] settableStatesDescriptions) { 228 when(mResources.getStringArray( 229 com.android.internal.R.array.config_perDeviceStateRotationLockDefaults)) 230 .thenReturn(settableStates); 231 when(mResources.getStringArray(R.array.config_settableAutoRotationDeviceStatesDescriptions)) 232 .thenReturn(settableStatesDescriptions); 233 when(mResources.getBoolean(R.bool.config_auto_rotate_face_detection_available)) 234 .thenReturn(true); 235 DeviceStateRotationLockSettingsManager.resetInstance(); 236 DeviceStateRotationLockSettingsManager.getInstance(mContext) 237 .resetStateForTesting(mResources); 238 } 239 } 240