• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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.keyguard;
18 
19 import android.content.res.ColorStateList;
20 import android.content.res.Configuration;
21 import android.hardware.biometrics.BiometricSourceType;
22 import android.os.SystemClock;
23 import android.util.Log;
24 import android.util.Pair;
25 import android.view.View;
26 
27 import androidx.annotation.Nullable;
28 
29 import com.android.systemui.statusbar.policy.ConfigurationController;
30 import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
31 import com.android.systemui.util.ViewController;
32 
33 import javax.inject.Inject;
34 
35 /**
36  * Controller for a {@link KeyguardMessageAreaController}.
37  * @param <T> A subclass of KeyguardMessageArea.
38  */
39 public class KeyguardMessageAreaController<T extends KeyguardMessageArea>
40         extends ViewController<T> {
41     /**
42      * Pair representing:
43      *   first - BiometricSource the currently displayed message is associated with.
44      *   second - Timestamp the biometric message came in uptimeMillis.
45      * This Pair can be null if the message is not associated with a biometric.
46      */
47     @Nullable
48     private Pair<BiometricSourceType, Long> mMessageBiometricSource = null;
49     private static final Long SKIP_SHOWING_FACE_MESSAGE_AFTER_FP_MESSAGE_MS = 3500L;
50 
51     private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
52     private final ConfigurationController mConfigurationController;
53 
54     private KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() {
55         public void onFinishedGoingToSleep(int why) {
56             mView.setSelected(false);
57         }
58 
59         public void onStartedWakingUp() {
60             mView.setSelected(true);
61         }
62     };
63 
64     private ConfigurationListener mConfigurationListener = new ConfigurationListener() {
65         @Override
66         public void onConfigChanged(Configuration newConfig) {
67             mView.onConfigChanged();
68         }
69 
70         @Override
71         public void onThemeChanged() {
72             mView.onThemeChanged();
73         }
74 
75         @Override
76         public void onDensityOrFontScaleChanged() {
77             mView.onDensityOrFontScaleChanged();
78         }
79     };
80 
KeyguardMessageAreaController(T view, KeyguardUpdateMonitor keyguardUpdateMonitor, ConfigurationController configurationController)81     protected KeyguardMessageAreaController(T view,
82             KeyguardUpdateMonitor keyguardUpdateMonitor,
83             ConfigurationController configurationController) {
84         super(view);
85 
86         mKeyguardUpdateMonitor = keyguardUpdateMonitor;
87         mConfigurationController = configurationController;
88     }
89 
90     @Override
onViewAttached()91     protected void onViewAttached() {
92         mConfigurationController.addCallback(mConfigurationListener);
93         mKeyguardUpdateMonitor.registerCallback(mInfoCallback);
94         mView.setSelected(mKeyguardUpdateMonitor.isDeviceInteractive());
95         mView.onThemeChanged();
96     }
97 
98     @Override
onViewDetached()99     protected void onViewDetached() {
100         mConfigurationController.removeCallback(mConfigurationListener);
101         mKeyguardUpdateMonitor.removeCallback(mInfoCallback);
102     }
103 
104     /**
105      * Indicate that view is visible and can display messages.
106      */
setIsVisible(boolean isVisible)107     public void setIsVisible(boolean isVisible) {
108         mView.setIsVisible(isVisible);
109     }
110 
111     /**
112      * Mark this view with {@link View#GONE} visibility to remove this from the layout of the view.
113      * Any calls to {@link #setIsVisible(boolean)} after this will be a no-op.
114      */
disable()115     public void disable() {
116         mView.disable();
117     }
118 
setMessage(CharSequence s)119     public void setMessage(CharSequence s) {
120         setMessage(s, true);
121     }
122 
123     /**
124      * Sets a message to the underlying text view.
125      */
setMessage(CharSequence s, boolean animate)126     public void setMessage(CharSequence s, boolean animate) {
127         setMessage(s, animate, null);
128     }
129 
130     /**
131      * Sets a message to the underlying text view.
132      */
setMessage(CharSequence s, BiometricSourceType biometricSourceType)133     public void setMessage(CharSequence s, BiometricSourceType biometricSourceType) {
134         setMessage(s, true, biometricSourceType);
135     }
136 
setMessage( CharSequence s, boolean animate, BiometricSourceType biometricSourceType)137     private void setMessage(
138             CharSequence s,
139             boolean animate,
140             BiometricSourceType biometricSourceType) {
141         final long uptimeMillis = SystemClock.uptimeMillis();
142         if (skipShowingFaceMessage(biometricSourceType, uptimeMillis)) {
143             Log.d("KeyguardMessageAreaController", "Skip showing face message \"" + s + "\"");
144             return;
145         }
146         mMessageBiometricSource =  new Pair<>(biometricSourceType, uptimeMillis);
147         if (mView.isDisabled()) {
148             return;
149         }
150         mView.setMessage(s, animate);
151     }
152 
skipShowingFaceMessage( BiometricSourceType biometricSourceType, Long currentUptimeMillis )153     private boolean skipShowingFaceMessage(
154             BiometricSourceType biometricSourceType, Long currentUptimeMillis
155     ) {
156         return mMessageBiometricSource != null
157                 && biometricSourceType == BiometricSourceType.FACE
158                 && mMessageBiometricSource.first == BiometricSourceType.FINGERPRINT
159                 && (currentUptimeMillis - mMessageBiometricSource.second)
160                     < SKIP_SHOWING_FACE_MESSAGE_AFTER_FP_MESSAGE_MS;
161     }
162 
setMessage(int resId)163     public void setMessage(int resId) {
164         String message = resId != 0 ? mView.getResources().getString(resId) : null;
165         setMessage(message);
166     }
167 
setNextMessageColor(ColorStateList colorState)168     public void setNextMessageColor(ColorStateList colorState) {
169         mView.setNextMessageColor(colorState);
170     }
171 
172     /** Returns the message of the underlying TextView. */
getMessage()173     public CharSequence getMessage() {
174         return mView.getText();
175     }
176 
177     /** Factory for creating {@link com.android.keyguard.KeyguardMessageAreaController}. */
178     public static class Factory {
179         private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
180         private final ConfigurationController mConfigurationController;
181 
182         @Inject
Factory(KeyguardUpdateMonitor keyguardUpdateMonitor, ConfigurationController configurationController)183         public Factory(KeyguardUpdateMonitor keyguardUpdateMonitor,
184                 ConfigurationController configurationController) {
185             mKeyguardUpdateMonitor = keyguardUpdateMonitor;
186             mConfigurationController = configurationController;
187         }
188 
189         /** Build a new {@link KeyguardMessageAreaController}. */
create(KeyguardMessageArea view)190         public KeyguardMessageAreaController create(KeyguardMessageArea view) {
191             return new KeyguardMessageAreaController(
192                     view, mKeyguardUpdateMonitor, mConfigurationController);
193         }
194     }
195 }
196