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.user.domain.interactor.SelectedUserInteractor;
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 BroadcastDispatcher mBroadcastDispatcher;
57     private final DeviceConfigProxy mDeviceConfigProxy;
58     private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
59     private final SelectedUserInteractor mSelectedUserInteractor;
60 
61     private boolean mEnabled;
62 
63     @Inject
LatencyTester( BroadcastDispatcher broadcastDispatcher, DeviceConfigProxy deviceConfigProxy, @Main DelayableExecutor mainExecutor, KeyguardUpdateMonitor keyguardUpdateMonitor, SelectedUserInteractor selectedUserInteractor )64     public LatencyTester(
65             BroadcastDispatcher broadcastDispatcher,
66             DeviceConfigProxy deviceConfigProxy,
67             @Main DelayableExecutor mainExecutor,
68             KeyguardUpdateMonitor keyguardUpdateMonitor,
69             SelectedUserInteractor selectedUserInteractor
70     ) {
71         mBroadcastDispatcher = broadcastDispatcher;
72         mDeviceConfigProxy = deviceConfigProxy;
73         mKeyguardUpdateMonitor = keyguardUpdateMonitor;
74         mSelectedUserInteractor = selectedUserInteractor;
75 
76         updateEnabled();
77         mDeviceConfigProxy.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_LATENCY_TRACKER,
78                 mainExecutor, properties -> updateEnabled());
79     }
80 
81     @Override
start()82     public void start() {
83     }
84 
fakeWakeAndUnlock(BiometricSourceType type)85     private void fakeWakeAndUnlock(BiometricSourceType type) {
86         if (!mEnabled) {
87             return;
88         }
89         if (type == BiometricSourceType.FACE) {
90             mKeyguardUpdateMonitor.onFaceAuthenticated(mSelectedUserInteractor.getSelectedUserId(),
91                     true);
92         } else if (type == BiometricSourceType.FINGERPRINT) {
93             mKeyguardUpdateMonitor.onFingerprintAuthenticated(
94                     mSelectedUserInteractor.getSelectedUserId(), true);
95         }
96     }
97 
registerForBroadcasts(boolean register)98     private void registerForBroadcasts(boolean register) {
99         if (register) {
100             IntentFilter filter = new IntentFilter();
101             filter.addAction(ACTION_FINGERPRINT_WAKE);
102             filter.addAction(ACTION_FACE_WAKE);
103             mBroadcastDispatcher.registerReceiver(mBroadcastReceiver, filter);
104         } else {
105             mBroadcastDispatcher.unregisterReceiver(mBroadcastReceiver);
106         }
107     }
108 
updateEnabled()109     private void updateEnabled() {
110         boolean wasEnabled = mEnabled;
111         mEnabled = Build.IS_DEBUGGABLE
112                 && mDeviceConfigProxy.getBoolean(DeviceConfig.NAMESPACE_LATENCY_TRACKER,
113                 LatencyTracker.SETTINGS_ENABLED_KEY, DEFAULT_ENABLED);
114         if (mEnabled != wasEnabled) {
115             registerForBroadcasts(mEnabled);
116         }
117     }
118 
119     @Override
dump(@onNull PrintWriter pw, @NonNull String[] args)120     public void dump(@NonNull PrintWriter pw, @NonNull String[] args) {
121         pw.println("mEnabled=" + mEnabled);
122     }
123 
124     private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
125         @Override
126         public void onReceive(Context context, Intent intent) {
127             String action = intent.getAction();
128             if (ACTION_FINGERPRINT_WAKE.equals(action)) {
129                 fakeWakeAndUnlock(BiometricSourceType.FINGERPRINT);
130             } else if (ACTION_FACE_WAKE.equals(action)) {
131                 fakeWakeAndUnlock(BiometricSourceType.FACE);
132             }
133         }
134     };
135 }
136