1 /*
2  * Copyright (C) 2022 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.systemui.biometrics
18 
19 import android.content.Context
20 import android.os.RemoteException
21 import android.os.Trace
22 import com.android.systemui.util.concurrency.Execution
23 
24 private const val TAG = "UdfpsDisplayMode"
25 
26 /**
27  * UdfpsDisplayMode configures the display for optimal UDFPS operation. For example, sets the
28  * display refresh rate that's optimal for UDFPS.
29  */
30 class UdfpsDisplayMode
31 constructor(
32     private val context: Context,
33     private val execution: Execution,
34     private val authController: AuthController,
35     private val logger: UdfpsLogger
36 ) : UdfpsDisplayModeProvider {
37 
38     // The request is reset to null after it's processed.
39     private var currentRequest: Request? = null
40 
enablenull41     override fun enable(onEnabled: Runnable?) {
42         execution.isMainThread()
43         logger.v(TAG, "enable")
44 
45         if (currentRequest != null) {
46             logger.e(TAG, "enable | already requested")
47             return
48         }
49         if (authController.udfpsRefreshRateCallback == null) {
50             logger.e(TAG, "enable | mDisplayManagerCallback is null")
51             return
52         }
53 
54         Trace.beginSection("UdfpsDisplayMode.enable")
55 
56         // Track this request in one object.
57         val request = Request(context.displayId)
58         currentRequest = request
59 
60         try {
61             // This method is a misnomer. It has nothing to do with HBM, its purpose is to set
62             // the appropriate display refresh rate.
63             authController.udfpsRefreshRateCallback!!.onRequestEnabled(request.displayId)
64             logger.v(TAG, "enable | requested optimal refresh rate for UDFPS")
65         } catch (e: RemoteException) {
66             logger.e(TAG, "enable", e)
67         }
68 
69         onEnabled?.run() ?: logger.w(TAG, "enable | onEnabled is null")
70         Trace.endSection()
71     }
72 
disablenull73     override fun disable(onDisabled: Runnable?) {
74         execution.isMainThread()
75         logger.v(TAG, "disable")
76 
77         val request = currentRequest
78         if (request == null) {
79             logger.w(TAG, "disable | already disabled")
80             return
81         }
82 
83         Trace.beginSection("UdfpsDisplayMode.disable")
84 
85         try {
86             // Allow DisplayManager to unset the UDFPS refresh rate.
87             authController.udfpsRefreshRateCallback!!.onRequestDisabled(request.displayId)
88             logger.v(TAG, "disable | removed the UDFPS refresh rate request")
89         } catch (e: RemoteException) {
90             logger.e(TAG, "disable", e)
91         }
92 
93         currentRequest = null
94         onDisabled?.run() ?: logger.w(TAG, "disable | onDisabled is null")
95         Trace.endSection()
96     }
97 }
98 
99 /** Tracks a request to enable the UDFPS mode. */
100 private data class Request(val displayId: Int)
101