1 /* 2 * Copyright (C) 2024 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 package com.android.systemui.settings.brightness.ui 17 18 import android.animation.Animator 19 import android.animation.AnimatorListenerAdapter 20 import android.annotation.StringRes 21 import android.content.Context 22 import android.graphics.PixelFormat 23 import android.view.Gravity 24 import android.view.View 25 import android.view.WindowManager 26 import com.android.systemui.dagger.SysUISingleton 27 import com.android.systemui.toast.ToastFactory 28 import javax.inject.Inject 29 30 @SysUISingleton 31 class BrightnessWarningToast 32 @Inject 33 constructor( 34 private val toastFactory: ToastFactory, 35 private val windowManager: WindowManager, 36 ) { 37 private var toastView: View? = null 38 shownull39 fun show(viewContext: Context, @StringRes resId: Int) { 40 if (isToastActive()) { 41 return 42 } 43 val res = viewContext.resources 44 // Show the brightness warning toast with passing the toast inflation required context, 45 // userId and resId from SystemUI package. 46 val systemUIToast = toastFactory.createToast( 47 viewContext, viewContext, 48 res.getString(resId), viewContext.packageName, viewContext.getUserId(), 49 res.configuration.orientation 50 ) 51 if (systemUIToast == null) { 52 return 53 } 54 55 toastView = systemUIToast.view 56 57 val params = WindowManager.LayoutParams() 58 params.height = WindowManager.LayoutParams.WRAP_CONTENT 59 params.width = WindowManager.LayoutParams.WRAP_CONTENT 60 params.format = PixelFormat.TRANSLUCENT 61 params.title = "Brightness warning toast" 62 params.type = WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL 63 params.flags = (WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON 64 or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 65 or WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) 66 params.y = systemUIToast.yOffset 67 68 val absGravity = Gravity.getAbsoluteGravity( 69 systemUIToast.gravity, 70 res.configuration.layoutDirection 71 ) 72 params.gravity = absGravity 73 if ((absGravity and Gravity.HORIZONTAL_GRAVITY_MASK) == Gravity.FILL_HORIZONTAL) { 74 params.horizontalWeight = TOAST_PARAMS_HORIZONTAL_WEIGHT 75 } 76 if ((absGravity and Gravity.VERTICAL_GRAVITY_MASK) == Gravity.FILL_VERTICAL) { 77 params.verticalWeight = TOAST_PARAMS_VERTICAL_WEIGHT 78 } 79 80 windowManager.addView(toastView, params) 81 82 val inAnimator = systemUIToast.inAnimation 83 inAnimator?.start() 84 85 toastView?.postDelayed({ 86 val outAnimator = systemUIToast.outAnimation 87 if (outAnimator != null) { 88 outAnimator.start() 89 outAnimator.addListener(object : AnimatorListenerAdapter() { 90 override fun onAnimationEnd(animator: Animator) { 91 if (isToastActive()) { 92 windowManager.removeViewImmediate(toastView) 93 } 94 toastView = null 95 } 96 }) 97 } 98 }, TOAST_DURATION_MS) 99 } 100 isToastActivenull101 fun isToastActive(): Boolean { 102 return toastView?.isAttachedToWindow == true 103 } 104 105 companion object { 106 private const val TOAST_PARAMS_HORIZONTAL_WEIGHT = 1.0f 107 private const val TOAST_PARAMS_VERTICAL_WEIGHT = 1.0f 108 private const val TOAST_DURATION_MS: Long = 3000 109 } 110 } 111