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 18 package com.android.systemui.keyguard.ui.view 19 20 import android.graphics.PixelFormat 21 import android.graphics.Point 22 import android.view.Gravity 23 import android.view.LayoutInflater 24 import android.view.View 25 import android.view.ViewGroup.LayoutParams.MATCH_PARENT 26 import android.view.WindowManager 27 import android.widget.ProgressBar 28 import androidx.core.view.isGone 29 import com.android.systemui.dagger.SysUISingleton 30 import com.android.systemui.res.R 31 import javax.inject.Inject 32 33 private const val TAG = "SideFpsProgressBar" 34 35 @SysUISingleton 36 class SideFpsProgressBar 37 @Inject 38 constructor( 39 private val layoutInflater: LayoutInflater, 40 private val windowManager: WindowManager, 41 ) { 42 private var overlayView: View? = null 43 updateViewnull44 fun updateView( 45 visible: Boolean, 46 viewLeftTopLocation: Point, 47 progressBarWidth: Int, 48 progressBarHeight: Int, 49 rotation: Float, 50 ) { 51 if (visible) { 52 createAndShowOverlay(viewLeftTopLocation, rotation, progressBarWidth, progressBarHeight) 53 } else { 54 hide() 55 } 56 } 57 hidenull58 fun hide() { 59 progressBar?.isGone = true 60 } 61 62 private val overlayViewParams = 63 WindowManager.LayoutParams( 64 // overlay is always full screen 65 MATCH_PARENT, 66 MATCH_PARENT, 67 WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL, 68 WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN or 69 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or 70 WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE or 71 WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, 72 PixelFormat.TRANSPARENT 73 ) <lambda>null74 .apply { 75 title = TAG 76 fitInsetsTypes = 0 // overrides default, avoiding status bars during layout 77 gravity = Gravity.TOP or Gravity.LEFT 78 layoutInDisplayCutoutMode = 79 WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS 80 privateFlags = 81 WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY or 82 WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION 83 } 84 createAndShowOverlaynull85 private fun createAndShowOverlay( 86 viewLeftTop: Point, 87 rotation: Float, 88 progressBarLength: Int, 89 progressBarThickness: Int, 90 ) { 91 if (overlayView == null) { 92 overlayView = layoutInflater.inflate(R.layout.sidefps_progress_bar, null, false) 93 windowManager.addView(overlayView, overlayViewParams) 94 progressBar?.pivotX = 0.0f 95 progressBar?.pivotY = 0.0f 96 } 97 progressBar?.layoutParams?.width = progressBarLength 98 progressBar?.layoutParams?.height = progressBarThickness 99 progressBar?.translationX = viewLeftTop.x.toFloat() 100 progressBar?.translationY = viewLeftTop.y.toFloat() 101 progressBar?.rotation = rotation 102 progressBar?.isGone = false 103 overlayView?.requestLayout() 104 } 105 setProgressnull106 fun setProgress(value: Float) { 107 progressBar?.setProgress((value * 100).toInt(), false) 108 } 109 110 private val progressBar: ProgressBar? 111 get() = overlayView?.findViewById(R.id.side_fps_progress_bar) 112 } 113