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 
17 package com.android.systemui.deviceentry.data.repository
18 
19 import android.content.res.Resources
20 import android.os.Build
21 import android.os.PowerManager
22 import com.android.systemui.Dumpable
23 import com.android.systemui.dagger.SysUISingleton
24 import com.android.systemui.dagger.qualifiers.Main
25 import com.android.systemui.dump.DumpManager
26 import com.android.systemui.power.shared.model.WakeSleepReason
27 import com.android.systemui.res.R
28 import com.android.systemui.util.settings.GlobalSettings
29 import dagger.Binds
30 import dagger.Module
31 import java.io.PrintWriter
32 import java.util.stream.Collectors
33 import javax.inject.Inject
34 
35 /** Determines which device wake-ups should trigger passive authentication. */
36 interface FaceWakeUpTriggersConfig {
shouldTriggerFaceAuthOnWakeUpFromnull37     fun shouldTriggerFaceAuthOnWakeUpFrom(@PowerManager.WakeReason pmWakeReason: Int): Boolean
38     fun shouldTriggerFaceAuthOnWakeUpFrom(wakeReason: WakeSleepReason): Boolean
39 }
40 
41 @SysUISingleton
42 class FaceWakeUpTriggersConfigImpl
43 @Inject
44 constructor(@Main resources: Resources, globalSettings: GlobalSettings, dumpManager: DumpManager) :
45     Dumpable, FaceWakeUpTriggersConfig {
46     private val defaultTriggerFaceAuthOnWakeUpFrom: Set<Int> =
47         resources.getIntArray(R.array.config_face_auth_wake_up_triggers).toSet()
48     private val triggerFaceAuthOnWakeUpFrom: Set<Int>
49     private val wakeSleepReasonsToTriggerFaceAuth: Set<WakeSleepReason>
50 
51     init {
52         triggerFaceAuthOnWakeUpFrom =
53             if (Build.IS_DEBUGGABLE) {
54                 // Update face wake triggers via adb on debuggable builds:
55                 // ie: adb shell settings put global face_wake_triggers "1\|4" &&
56                 //     adb shell am crash com.android.systemui
57                 processStringArray(
58                     globalSettings.getString("face_wake_triggers"),
59                     defaultTriggerFaceAuthOnWakeUpFrom
60                 )
61             } else {
62                 defaultTriggerFaceAuthOnWakeUpFrom
63             }
64         wakeSleepReasonsToTriggerFaceAuth =
65             triggerFaceAuthOnWakeUpFrom
66                 .map {
67                     val enumVal = WakeSleepReason.fromPowerManagerWakeReason(it)
68                     assert(enumVal != WakeSleepReason.OTHER)
69                     enumVal
70                 }
71                 .toSet()
72         dumpManager.registerDumpable(this)
73     }
74 
75     override fun shouldTriggerFaceAuthOnWakeUpFrom(
76         @PowerManager.WakeReason pmWakeReason: Int
77     ): Boolean {
78         return triggerFaceAuthOnWakeUpFrom.contains(pmWakeReason)
79     }
80 
81     override fun shouldTriggerFaceAuthOnWakeUpFrom(wakeReason: WakeSleepReason): Boolean =
82         wakeSleepReasonsToTriggerFaceAuth.contains(wakeReason)
83 
84     override fun dump(pw: PrintWriter, args: Array<out String>) {
85         pw.println("FaceWakeUpTriggers:")
86         for (pmWakeReason in triggerFaceAuthOnWakeUpFrom) {
87             pw.println("    ${PowerManager.wakeReasonToString(pmWakeReason)}")
88         }
89     }
90 
91     /** Convert a pipe-separated set of integers into a set of ints. */
92     private fun processStringArray(stringSetting: String?, default: Set<Int>): Set<Int> {
93         return stringSetting?.let {
94             stringSetting.split("|").stream().map(Integer::parseInt).collect(Collectors.toSet())
95         }
96             ?: default
97     }
98 }
99 
100 @Module
101 interface FaceWakeUpTriggersConfigModule {
repositorynull102     @Binds fun repository(impl: FaceWakeUpTriggersConfigImpl): FaceWakeUpTriggersConfig
103 }
104