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 android.content.Context; 20 import android.hardware.camera2.CameraAccessException; 21 import android.hardware.camera2.CameraCharacteristics; 22 import android.hardware.camera2.CameraManager; 23 import android.provider.Settings; 24 import android.util.Log; 25 26 import androidx.annotation.ColorInt; 27 import androidx.annotation.IntDef; 28 import androidx.annotation.NonNull; 29 30 import java.lang.annotation.Retention; 31 import java.lang.annotation.RetentionPolicy; 32 33 class FlashNotificationsUtil { 34 static final String LOG_TAG = "FlashNotificationsUtil"; 35 static final String ACTION_FLASH_NOTIFICATION_START_PREVIEW = 36 "com.android.internal.intent.action.FLASH_NOTIFICATION_START_PREVIEW"; 37 static final String ACTION_FLASH_NOTIFICATION_STOP_PREVIEW = 38 "com.android.internal.intent.action.FLASH_NOTIFICATION_STOP_PREVIEW"; 39 static final String EXTRA_FLASH_NOTIFICATION_PREVIEW_COLOR = 40 "com.android.internal.intent.extra.FLASH_NOTIFICATION_PREVIEW_COLOR"; 41 static final String EXTRA_FLASH_NOTIFICATION_PREVIEW_TYPE = 42 "com.android.internal.intent.extra.FLASH_NOTIFICATION_PREVIEW_TYPE"; 43 44 static final int TYPE_SHORT_PREVIEW = 0; 45 static final int TYPE_LONG_PREVIEW = 1; 46 47 static final int DEFAULT_SCREEN_FLASH_COLOR = ScreenFlashNotificationColor.YELLOW.mColorInt; 48 49 @Retention(RetentionPolicy.SOURCE) 50 @IntDef({ 51 FlashNotificationsUtil.State.OFF, 52 FlashNotificationsUtil.State.CAMERA, 53 FlashNotificationsUtil.State.SCREEN, 54 FlashNotificationsUtil.State.CAMERA_SCREEN, 55 }) 56 @interface State { 57 int OFF = 0; 58 int CAMERA = 1; 59 int SCREEN = 2; 60 int CAMERA_SCREEN = 3; 61 } 62 isTorchAvailable(@onNull Context context)63 static boolean isTorchAvailable(@NonNull Context context) { 64 // TODO This is duplicated logic of FlashNotificationsController.getCameraId. 65 final CameraManager cameraManager = context.getSystemService(CameraManager.class); 66 if (cameraManager == null) return false; 67 68 try { 69 final String[] ids = cameraManager.getCameraIdList(); 70 71 for (String id : ids) { 72 final CameraCharacteristics c = cameraManager.getCameraCharacteristics(id); 73 74 final Boolean flashAvailable = c.get(CameraCharacteristics.FLASH_INFO_AVAILABLE); 75 if (flashAvailable == null) continue; 76 77 final Integer lensFacing = c.get(CameraCharacteristics.LENS_FACING); 78 if (lensFacing == null) continue; 79 80 if (flashAvailable && lensFacing == CameraCharacteristics.LENS_FACING_BACK) { 81 return true; 82 } 83 } 84 } catch (CameraAccessException ignored) { 85 Log.w(LOG_TAG, "Failed to get valid camera for camera flash notification."); 86 } 87 return false; 88 } 89 getScreenColor(@olorInt int colorInt)90 static ScreenFlashNotificationColor getScreenColor(@ColorInt int colorInt) 91 throws ScreenColorNotFoundException { 92 93 colorInt |= ScreenFlashNotificationColor.ALPHA_MASK; 94 for (ScreenFlashNotificationColor color : ScreenFlashNotificationColor.values()) { 95 if (colorInt == color.mOpaqueColorInt) { 96 return color; 97 } 98 } 99 100 throw new ScreenColorNotFoundException(); 101 } 102 103 @NonNull getColorDescriptionText(@onNull Context context, @ColorInt int color)104 static String getColorDescriptionText(@NonNull Context context, @ColorInt int color) { 105 try { 106 return context.getString(getScreenColor(color).mStringRes); 107 } catch (ScreenColorNotFoundException e) { 108 return ""; 109 } 110 } 111 112 @State getFlashNotificationsState(Context context)113 static int getFlashNotificationsState(Context context) { 114 if (context == null) { 115 return State.OFF; 116 } 117 118 final boolean isTorchAvailable = FlashNotificationsUtil.isTorchAvailable(context); 119 final boolean isCameraFlashEnabled = Settings.System.getInt(context.getContentResolver(), 120 Settings.System.CAMERA_FLASH_NOTIFICATION, State.OFF) != State.OFF; 121 final boolean isScreenFlashEnabled = Settings.System.getInt(context.getContentResolver(), 122 Settings.System.SCREEN_FLASH_NOTIFICATION, State.OFF) != State.OFF; 123 124 return ((isTorchAvailable && isCameraFlashEnabled) ? State.CAMERA : State.OFF) 125 | (isScreenFlashEnabled ? State.SCREEN : State.OFF); 126 } 127 128 static class ScreenColorNotFoundException extends Exception { 129 } 130 } 131