1 /* 2 * Copyright (C) 2023 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.accessibility; 18 19 import static android.hardware.camera2.CameraCharacteristics.FLASH_INFO_AVAILABLE; 20 import static android.hardware.camera2.CameraCharacteristics.LENS_FACING; 21 import static android.hardware.camera2.CameraCharacteristics.LENS_FACING_BACK; 22 import static android.hardware.camera2.CameraMetadata.LENS_FACING_FRONT; 23 24 import static com.android.settings.accessibility.AccessibilityUtil.State.OFF; 25 import static com.android.settings.accessibility.AccessibilityUtil.State.ON; 26 import static com.android.settings.accessibility.FlashNotificationsUtil.getColorDescriptionText; 27 import static com.android.settings.accessibility.FlashNotificationsUtil.getFlashNotificationsState; 28 import static com.android.settings.accessibility.FlashNotificationsUtil.getScreenColor; 29 import static com.android.settings.accessibility.FlashNotificationsUtil.isTorchAvailable; 30 31 import static com.google.common.truth.Truth.assertThat; 32 33 import static org.junit.Assert.assertThrows; 34 import static org.mockito.Mockito.when; 35 import static org.robolectric.shadow.api.Shadow.extract; 36 import static org.robolectric.shadows.ShadowCameraCharacteristics.newCameraCharacteristics; 37 38 import android.content.ContentResolver; 39 import android.content.Context; 40 import android.hardware.camera2.CameraAccessException; 41 import android.hardware.camera2.CameraCharacteristics; 42 import android.hardware.camera2.CameraManager; 43 import android.provider.Settings; 44 45 import androidx.test.core.app.ApplicationProvider; 46 47 import org.junit.Before; 48 import org.junit.Rule; 49 import org.junit.Test; 50 import org.junit.runner.RunWith; 51 import org.mockito.MockitoAnnotations; 52 import org.mockito.Spy; 53 import org.mockito.junit.MockitoJUnit; 54 import org.mockito.junit.MockitoRule; 55 import org.robolectric.RobolectricTestRunner; 56 import org.robolectric.Shadows; 57 import org.robolectric.shadows.ShadowCameraCharacteristics; 58 import org.robolectric.shadows.ShadowCameraManager; 59 60 @RunWith(RobolectricTestRunner.class) 61 public class FlashNotificationsUtilTest { 62 63 @Rule 64 public MockitoRule mMockitoRule = MockitoJUnit.rule(); 65 @Spy 66 private Context mContext = ApplicationProvider.getApplicationContext(); 67 @Spy 68 private CameraManager mCameraManager = mContext.getSystemService(CameraManager.class); 69 70 private ShadowCameraManager mShadowCameraManager; 71 private ContentResolver mContentResolver; 72 73 @Before setUp()74 public void setUp() { 75 MockitoAnnotations.initMocks(this); 76 mShadowCameraManager = Shadows.shadowOf(mCameraManager); 77 mContentResolver = mContext.getContentResolver(); 78 } 79 80 @Test isTorchAvailable_nullCameraManager_assertFalse()81 public void isTorchAvailable_nullCameraManager_assertFalse() { 82 when(mContext.getSystemService(CameraManager.class)).thenReturn(null); 83 assertThat(isTorchAvailable(mContext)).isFalse(); 84 } 85 86 @Test isTorchAvailable_noCamera_assertFalse()87 public void isTorchAvailable_noCamera_assertFalse() { 88 assertThat(isTorchAvailable(mContext)).isFalse(); 89 } 90 91 @Test isTorchAvailable_getCameraIdListThrowException_assertFalse()92 public void isTorchAvailable_getCameraIdListThrowException_assertFalse() 93 throws CameraAccessException { 94 when(mCameraManager.getCameraIdList()).thenThrow(CameraAccessException.class); 95 assertThat(isTorchAvailable(mContext)).isFalse(); 96 } 97 98 @Test isTorchAvailable_getCameraCharacteristicsThrowException_assertFalse()99 public void isTorchAvailable_getCameraCharacteristicsThrowException_assertFalse() 100 throws CameraAccessException { 101 CameraCharacteristics cameraCharacteristics = newCameraCharacteristics(); 102 mShadowCameraManager.addCamera("0", cameraCharacteristics); 103 104 when(mCameraManager.getCameraCharacteristics("0")).thenThrow(CameraAccessException.class); 105 106 assertThat(isTorchAvailable(mContext)).isFalse(); 107 } 108 109 @Test isTorchAvailable_torchNotPresent_assertFalse()110 public void isTorchAvailable_torchNotPresent_assertFalse() { 111 setTorchNotPresent(); 112 113 assertThat(isTorchAvailable(mContext)).isFalse(); 114 } 115 116 @Test isTorchAvailable_torchPresent_assertTrue()117 public void isTorchAvailable_torchPresent_assertTrue() { 118 setTorchPresent(); 119 120 assertThat(isTorchAvailable(mContext)).isTrue(); 121 } 122 123 @Test isTorchAvailable_lensFacingFront_assertFalse()124 public void isTorchAvailable_lensFacingFront_assertFalse() { 125 CameraCharacteristics cameraCharacteristics = newCameraCharacteristics(); 126 ShadowCameraCharacteristics shadowCameraCharacteristics = extract(cameraCharacteristics); 127 shadowCameraCharacteristics.set(FLASH_INFO_AVAILABLE, true); 128 shadowCameraCharacteristics.set(LENS_FACING, LENS_FACING_FRONT); 129 mShadowCameraManager.addCamera("0", cameraCharacteristics); 130 131 assertThat(isTorchAvailable(mContext)).isFalse(); 132 } 133 134 @Test getScreenColor_undefinedColor_throwException()135 public void getScreenColor_undefinedColor_throwException() { 136 assertThrows(FlashNotificationsUtil.ScreenColorNotFoundException.class, () -> 137 getScreenColor(0x4D0000FF)); 138 } 139 140 @Test getScreenColor_azureColor_returnAzure()141 public void getScreenColor_azureColor_returnAzure() throws Exception { 142 assertThat(getScreenColor(0x660080FF)).isEqualTo(ScreenFlashNotificationColor.AZURE); 143 } 144 145 @Test getColorDescriptionText_undefinedColor_returnEmpty()146 public void getColorDescriptionText_undefinedColor_returnEmpty() { 147 assertThat(getColorDescriptionText(mContext, 0x4D0000FF)).isEqualTo(""); 148 } 149 150 @Test getColorDescriptionText_azureColor_returnAzureName()151 public void getColorDescriptionText_azureColor_returnAzureName() { 152 assertThat(getColorDescriptionText(mContext, ScreenFlashNotificationColor.AZURE.mColorInt)) 153 .isEqualTo(mContext.getString(ScreenFlashNotificationColor.AZURE.mStringRes)); 154 } 155 156 @Test getFlashNotificationsState_torchPresent_cameraOff_screenOff_assertOff()157 public void getFlashNotificationsState_torchPresent_cameraOff_screenOff_assertOff() { 158 setTorchPresent(); 159 Settings.System.putInt(mContentResolver, Settings.System.CAMERA_FLASH_NOTIFICATION, OFF); 160 Settings.System.putInt(mContentResolver, Settings.System.SCREEN_FLASH_NOTIFICATION, OFF); 161 162 assertThat(getFlashNotificationsState(mContext)) 163 .isEqualTo(FlashNotificationsUtil.State.OFF); 164 } 165 166 @Test getFlashNotificationsState_torchNotPresent_cameraOn_screenOff_assertOff()167 public void getFlashNotificationsState_torchNotPresent_cameraOn_screenOff_assertOff() { 168 setTorchNotPresent(); 169 Settings.System.putInt(mContentResolver, Settings.System.CAMERA_FLASH_NOTIFICATION, ON); 170 Settings.System.putInt(mContentResolver, Settings.System.SCREEN_FLASH_NOTIFICATION, OFF); 171 172 assertThat(getFlashNotificationsState(mContext)) 173 .isEqualTo(FlashNotificationsUtil.State.OFF); 174 } 175 176 @Test getFlashNotificationsState_torchPresent_cameraOn_screenOff_assertCamera()177 public void getFlashNotificationsState_torchPresent_cameraOn_screenOff_assertCamera() { 178 setTorchPresent(); 179 Settings.System.putInt(mContentResolver, Settings.System.CAMERA_FLASH_NOTIFICATION, ON); 180 Settings.System.putInt(mContentResolver, Settings.System.SCREEN_FLASH_NOTIFICATION, OFF); 181 182 assertThat(getFlashNotificationsState(mContext)) 183 .isEqualTo(FlashNotificationsUtil.State.CAMERA); 184 } 185 186 @Test getFlashNotificationsState_torchPresent_cameraOff_screenOn_assertScreen()187 public void getFlashNotificationsState_torchPresent_cameraOff_screenOn_assertScreen() { 188 setTorchPresent(); 189 Settings.System.putInt(mContentResolver, Settings.System.CAMERA_FLASH_NOTIFICATION, OFF); 190 Settings.System.putInt(mContentResolver, Settings.System.SCREEN_FLASH_NOTIFICATION, ON); 191 192 assertThat(getFlashNotificationsState(mContext)) 193 .isEqualTo(FlashNotificationsUtil.State.SCREEN); 194 } 195 196 @Test testGetFlashNotificationsState_torchPresent_cameraOn_screenOn_assertCameraScreen()197 public void testGetFlashNotificationsState_torchPresent_cameraOn_screenOn_assertCameraScreen() { 198 setTorchPresent(); 199 Settings.System.putInt(mContentResolver, Settings.System.CAMERA_FLASH_NOTIFICATION, ON); 200 Settings.System.putInt(mContentResolver, Settings.System.SCREEN_FLASH_NOTIFICATION, ON); 201 202 assertThat(getFlashNotificationsState(mContext)) 203 .isEqualTo(FlashNotificationsUtil.State.CAMERA_SCREEN); 204 } 205 setTorchPresent()206 private void setTorchPresent() { 207 CameraCharacteristics cameraCharacteristics = newCameraCharacteristics(); 208 ShadowCameraCharacteristics shadowCameraCharacteristics = extract(cameraCharacteristics); 209 shadowCameraCharacteristics.set(FLASH_INFO_AVAILABLE, true); 210 shadowCameraCharacteristics.set(LENS_FACING, LENS_FACING_BACK); 211 mShadowCameraManager.addCamera("0", cameraCharacteristics); 212 } 213 setTorchNotPresent()214 private void setTorchNotPresent() { 215 CameraCharacteristics cameraCharacteristics = newCameraCharacteristics(); 216 ShadowCameraCharacteristics shadowCameraCharacteristics = extract(cameraCharacteristics); 217 shadowCameraCharacteristics.set(FLASH_INFO_AVAILABLE, false); 218 mShadowCameraManager.addCamera("0", cameraCharacteristics); 219 } 220 } 221