blob: 262c71ae0b1e5c263d16e25c69d43748cbcb67c9 [file] [log] [blame]
Kevin Chynaae4a152018-01-18 11:48:09 -08001/*
2 * Copyright (C) 2018 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
17package com.android.systemui.fingerprint;
18
Kevin Chyn42653e82018-01-19 14:15:46 -080019import android.content.Context;
Kevin Chynaae4a152018-01-18 11:48:09 -080020import android.content.pm.PackageManager;
Kevin Chyn42653e82018-01-19 14:15:46 -080021import android.hardware.fingerprint.FingerprintDialog;
Kevin Chynaae4a152018-01-18 11:48:09 -080022import android.hardware.fingerprint.IFingerprintDialogReceiver;
23import android.os.Bundle;
Kevin Chyn42653e82018-01-19 14:15:46 -080024import android.os.Handler;
25import android.os.Message;
26import android.os.RemoteException;
Kevin Chynaae4a152018-01-18 11:48:09 -080027import android.util.Log;
Kevin Chyn42653e82018-01-19 14:15:46 -080028import android.view.WindowManager;
Kevin Chynaae4a152018-01-18 11:48:09 -080029
Kevin Chyn42653e82018-01-19 14:15:46 -080030import com.android.internal.os.SomeArgs;
Kevin Chynaae4a152018-01-18 11:48:09 -080031import com.android.systemui.SystemUI;
32import com.android.systemui.statusbar.CommandQueue;
33
34public class FingerprintDialogImpl extends SystemUI implements CommandQueue.Callbacks {
35 private static final String TAG = "FingerprintDialogImpl";
Kevin Chyn42653e82018-01-19 14:15:46 -080036 private static final boolean DEBUG = true;
37
38 protected static final int MSG_SHOW_DIALOG = 1;
39 protected static final int MSG_FINGERPRINT_AUTHENTICATED = 2;
40 protected static final int MSG_FINGERPRINT_HELP = 3;
41 protected static final int MSG_FINGERPRINT_ERROR = 4;
42 protected static final int MSG_HIDE_DIALOG = 5;
43 protected static final int MSG_BUTTON_NEGATIVE = 6;
44 protected static final int MSG_USER_CANCELED = 7;
45 protected static final int MSG_BUTTON_POSITIVE = 8;
46 protected static final int MSG_CLEAR_MESSAGE = 9;
47
48
49 private FingerprintDialogView mDialogView;
50 private WindowManager mWindowManager;
51 private IFingerprintDialogReceiver mReceiver;
52 private boolean mDialogShowing;
53
54 private Handler mHandler = new Handler() {
55 @Override
56 public void handleMessage(Message msg) {
57 switch(msg.what) {
58 case MSG_SHOW_DIALOG:
59 handleShowDialog((SomeArgs) msg.obj);
60 break;
61 case MSG_FINGERPRINT_AUTHENTICATED:
62 handleFingerprintAuthenticated();
63 break;
64 case MSG_FINGERPRINT_HELP:
65 handleFingerprintHelp((String) msg.obj);
66 break;
67 case MSG_FINGERPRINT_ERROR:
68 handleFingerprintError((String) msg.obj);
69 break;
70 case MSG_HIDE_DIALOG:
71 handleHideDialog((Boolean) msg.obj);
72 break;
73 case MSG_BUTTON_NEGATIVE:
74 handleButtonNegative();
75 break;
76 case MSG_USER_CANCELED:
77 handleUserCanceled();
78 break;
79 case MSG_BUTTON_POSITIVE:
80 handleButtonPositive();
81 break;
82 case MSG_CLEAR_MESSAGE:
83 handleClearMessage();
84 break;
85 }
86 }
87 };
Kevin Chynaae4a152018-01-18 11:48:09 -080088
89 @Override
90 public void start() {
91 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
92 return;
93 }
94 getComponent(CommandQueue.class).addCallbacks(this);
Kevin Chyne8f3e1b2018-01-23 17:33:58 -080095 mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
Kevin Chyn42653e82018-01-19 14:15:46 -080096 mDialogView = new FingerprintDialogView(mContext, mHandler);
Kevin Chynaae4a152018-01-18 11:48:09 -080097 }
98
99 @Override
100 public void showFingerprintDialog(Bundle bundle, IFingerprintDialogReceiver receiver) {
Kevin Chyn42653e82018-01-19 14:15:46 -0800101 if (DEBUG) Log.d(TAG, "showFingerprintDialog");
102 // Remove these messages as they are part of the previous client
103 mHandler.removeMessages(MSG_FINGERPRINT_ERROR);
104 mHandler.removeMessages(MSG_FINGERPRINT_HELP);
105 mHandler.removeMessages(MSG_FINGERPRINT_AUTHENTICATED);
106 SomeArgs args = SomeArgs.obtain();
107 args.arg1 = bundle;
108 args.arg2 = receiver;
109 mHandler.obtainMessage(MSG_SHOW_DIALOG, args).sendToTarget();
Kevin Chynaae4a152018-01-18 11:48:09 -0800110 }
111
112 @Override
113 public void onFingerprintAuthenticated() {
114 if (DEBUG) Log.d(TAG, "onFingerprintAuthenticated");
Kevin Chyn42653e82018-01-19 14:15:46 -0800115 mHandler.obtainMessage(MSG_FINGERPRINT_AUTHENTICATED).sendToTarget();
Kevin Chynaae4a152018-01-18 11:48:09 -0800116 }
117
118 @Override
119 public void onFingerprintHelp(String message) {
120 if (DEBUG) Log.d(TAG, "onFingerprintHelp: " + message);
Kevin Chyn42653e82018-01-19 14:15:46 -0800121 mHandler.obtainMessage(MSG_FINGERPRINT_HELP, message).sendToTarget();
Kevin Chynaae4a152018-01-18 11:48:09 -0800122 }
123
124 @Override
125 public void onFingerprintError(String error) {
126 if (DEBUG) Log.d(TAG, "onFingerprintError: " + error);
Kevin Chyn42653e82018-01-19 14:15:46 -0800127 mHandler.obtainMessage(MSG_FINGERPRINT_ERROR, error).sendToTarget();
Kevin Chynaae4a152018-01-18 11:48:09 -0800128 }
129
130 @Override
131 public void hideFingerprintDialog() {
132 if (DEBUG) Log.d(TAG, "hideFingerprintDialog");
Kevin Chyn42653e82018-01-19 14:15:46 -0800133 mHandler.obtainMessage(MSG_HIDE_DIALOG, false /* userCanceled */).sendToTarget();
134 }
135
136 private void handleShowDialog(SomeArgs args) {
137 if (DEBUG) Log.d(TAG, "handleShowDialog");
138 if (mDialogShowing) {
139 Log.w(TAG, "Dialog already showing");
140 return;
141 }
142 mReceiver = (IFingerprintDialogReceiver) args.arg2;
143 mDialogView.setBundle((Bundle)args.arg1);
144 mWindowManager.addView(mDialogView, mDialogView.getLayoutParams());
145 mDialogShowing = true;
146 }
147
148 private void handleFingerprintAuthenticated() {
149 if (DEBUG) Log.d(TAG, "handleFingerprintAuthenticated");
150 handleHideDialog(false /* userCanceled */);
151 }
152
153 private void handleFingerprintHelp(String message) {
154 if (DEBUG) Log.d(TAG, "handleFingerprintHelp: " + message);
155 mDialogView.showHelpMessage(message);
156 }
157
158 private void handleFingerprintError(String error) {
159 if (DEBUG) Log.d(TAG, "handleFingerprintError: " + error);
160 if (!mDialogShowing) {
161 if (DEBUG) Log.d(TAG, "Dialog already dismissed");
162 return;
163 }
164 mDialogView.showErrorMessage(error);
165 }
166
167 private void handleHideDialog(boolean userCanceled) {
168 if (DEBUG) Log.d(TAG, "handleHideDialog");
169 if (!mDialogShowing) {
170 // This can happen if there's a race and we get called from both
171 // onAuthenticated and onError, etc.
172 Log.w(TAG, "Dialog already dismissed, userCanceled: " + userCanceled);
173 return;
174 }
175 if (userCanceled) {
176 try {
177 mReceiver.onDialogDismissed(FingerprintDialog.DISMISSED_REASON_USER_CANCEL);
178 } catch (RemoteException e) {
179 Log.e(TAG, "RemoteException when hiding dialog", e);
180 }
181 }
182 mReceiver = null;
183 mWindowManager.removeView(mDialogView);
184 mDialogShowing = false;
185 }
186
187 private void handleButtonNegative() {
188 if (mReceiver == null) {
189 Log.e(TAG, "Receiver is null");
190 return;
191 }
192 try {
193 mReceiver.onDialogDismissed(FingerprintDialog.DISMISSED_REASON_NEGATIVE);
194 } catch (RemoteException e) {
195 Log.e(TAG, "Remote exception when handling negative button", e);
196 }
197 handleHideDialog(false /* userCanceled */);
198 }
199
200 private void handleButtonPositive() {
201 if (mReceiver == null) {
202 Log.e(TAG, "Receiver is null");
203 return;
204 }
205 try {
206 mReceiver.onDialogDismissed(FingerprintDialog.DISMISSED_REASON_POSITIVE);
207 } catch (RemoteException e) {
208 Log.e(TAG, "Remote exception when handling positive button", e);
209 }
210 handleHideDialog(false /* userCanceled */);
211 }
212
213 private void handleClearMessage() {
214 mDialogView.clearMessage();
215 }
216
217 private void handleUserCanceled() {
218 handleHideDialog(true /* userCanceled */);
Kevin Chynaae4a152018-01-18 11:48:09 -0800219 }
220}