1 /*
2  * Copyright (C) 2016 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;
18 
19 import android.content.BroadcastReceiver;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.content.IntentFilter;
23 import android.hardware.biometrics.BiometricSourceType;
24 import android.os.Build;
25 import android.provider.DeviceConfig;
26 
27 import androidx.annotation.NonNull;
28 
29 import com.android.internal.util.LatencyTracker;
30 import com.android.keyguard.KeyguardUpdateMonitor;
31 import com.android.systemui.broadcast.BroadcastDispatcher;
32 import com.android.systemui.dagger.SysUISingleton;
33 import com.android.systemui.dagger.qualifiers.Main;
34 import com.android.systemui.statusbar.phone.BiometricUnlockController;
35 import com.android.systemui.util.DeviceConfigProxy;
36 import com.android.systemui.util.concurrency.DelayableExecutor;
37 
38 import java.io.PrintWriter;
39 
40 import javax.inject.Inject;
41 
42 /**
43  * Class that only runs on debuggable builds with the LatencyTracker setting enabled
44  * that listens to broadcasts that simulate actions in the
45  * system that are used for testing the latency.
46  */
47 @SysUISingleton
48 public class LatencyTester implements CoreStartable {
49     private static final boolean DEFAULT_ENABLED = Build.IS_ENG;
50     private static final String
51             ACTION_FINGERPRINT_WAKE =
52             "com.android.systemui.latency.ACTION_FINGERPRINT_WAKE";
53     private static final String
54             ACTION_FACE_WAKE =
55             "com.android.systemui.latency.ACTION_FACE_WAKE";
56     private final BiometricUnlockController mBiometricUnlockController;
57     private final BroadcastDispatcher mBroadcastDispatcher;
58     private final DeviceConfigProxy mDeviceConfigProxy;
59     private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
60 
61     private boolean mEnabled;
62 
63     @Inject
LatencyTester( BiometricUnlockController biometricUnlockController, BroadcastDispatcher broadcastDispatcher, DeviceConfigProxy deviceConfigProxy, @Main DelayableExecutor mainExecutor, KeyguardUpdateMonitor keyguardUpdateMonitor )64     public LatencyTester(
65             BiometricUnlockController biometricUnlockController,
66             BroadcastDispatcher broadcastDispatcher,
67             DeviceConfigProxy deviceConfigProxy,
68             @Main DelayableExecutor mainExecutor,
69             KeyguardUpdateMonitor keyguardUpdateMonitor
70     ) {
71         mBiometricUnlockController = biometricUnlockController;
72         mBroadcastDispatcher = broadcastDispatcher;
73         mDeviceConfigProxy = deviceConfigProxy;
74         mKeyguardUpdateMonitor = keyguardUpdateMonitor;
75 
76         updateEnabled();
77         mDeviceConfigProxy.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_LATENCY_TRACKER,
78                 mainExecutor, properties -> updateEnabled());
79     }
80 
81     @Override
start()82     public void start() {
83         registerForBroadcasts(mEnabled);
84     }
85 
fakeWakeAndUnlock(BiometricSourceType type)86     private void fakeWakeAndUnlock(BiometricSourceType type) {
87         if (!mEnabled) {
88             return;
89         }
90         if (type == BiometricSourceType.FACE) {
91             mKeyguardUpdateMonitor.onFaceAuthenticated(KeyguardUpdateMonitor.getCurrentUser(),
92                     true);
93         } else if (type == BiometricSourceType.FINGERPRINT) {
94             mKeyguardUpdateMonitor.onFingerprintAuthenticated(
95                     KeyguardUpdateMonitor.getCurrentUser(), true);
96         }
97     }
98 
registerForBroadcasts(boolean register)99     private void registerForBroadcasts(boolean register) {
100         if (register) {
101             IntentFilter filter = new IntentFilter();
102             filter.addAction(ACTION_FINGERPRINT_WAKE);
103             filter.addAction(ACTION_FACE_WAKE);
104             mBroadcastDispatcher.registerReceiver(mBroadcastReceiver, filter);
105         } else {
106             mBroadcastDispatcher.unregisterReceiver(mBroadcastReceiver);
107         }
108     }
109 
updateEnabled()110     private void updateEnabled() {
111         boolean wasEnabled = mEnabled;
112         mEnabled = Build.IS_DEBUGGABLE
113                 && mDeviceConfigProxy.getBoolean(DeviceConfig.NAMESPACE_LATENCY_TRACKER,
114                 LatencyTracker.SETTINGS_ENABLED_KEY, DEFAULT_ENABLED);
115         if (mEnabled != wasEnabled) {
116             registerForBroadcasts(mEnabled);
117         }
118     }
119 
120     @Override
dump(@onNull PrintWriter pw, @NonNull String[] args)121     public void dump(@NonNull PrintWriter pw, @NonNull String[] args) {
122         pw.println("mEnabled=" + mEnabled);
123     }
124 
125     private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
126         @Override
127         public void onReceive(Context context, Intent intent) {
128             String action = intent.getAction();
129             if (ACTION_FINGERPRINT_WAKE.equals(action)) {
130                 fakeWakeAndUnlock(BiometricSourceType.FINGERPRINT);
131             } else if (ACTION_FACE_WAKE.equals(action)) {
132                 fakeWakeAndUnlock(BiometricSourceType.FACE);
133             }
134         }
135     };
136 }
137