127fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver/* 227fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver * Copyright (C) 2017 The Android Open Source Project 327fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver * 427fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver * Licensed under the Apache License, Version 2.0 (the "License"); 527fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver * you may not use this file except in compliance with the License. 627fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver * You may obtain a copy of the License at 727fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver * 827fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver * http://www.apache.org/licenses/LICENSE-2.0 927fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver * 1027fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver * Unless required by applicable law or agreed to in writing, software 1127fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver * distributed under the License is distributed on an "AS IS" BASIS, 1227fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1327fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver * See the License for the specific language governing permissions and 1427fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver * limitations under the License. 1527fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver */ 1627fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver 1727fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaverpackage com.android.server.accessibility; 1827fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver 1927fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaverimport android.accessibilityservice.FingerprintGestureController; 2027fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaverimport android.hardware.fingerprint.IFingerprintClientActiveCallback; 2127fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaverimport android.hardware.fingerprint.IFingerprintService; 2227fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaverimport android.os.Binder; 2327fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaverimport android.os.Handler; 2427fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaverimport android.os.Message; 2527fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaverimport android.os.RemoteException; 2627fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaverimport android.util.Slog; 2727fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaverimport android.view.KeyEvent; 2827fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver 2927fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaverimport java.util.ArrayList; 3027fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaverimport java.util.List; 3127fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver 3227fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver/** 3327fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver * Encapsulate fingerprint gesture logic 3427fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver */ 3527fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaverpublic class FingerprintGestureDispatcher extends IFingerprintClientActiveCallback.Stub 3627fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver implements Handler.Callback{ 3727fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver private static final int MSG_REGISTER = 1; 3827fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver private static final int MSG_UNREGISTER = 2; 3927fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver private static final String LOG_TAG = "FingerprintGestureDispatcher"; 4027fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver 4127fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver private final List<FingerprintGestureClient> mCapturingClients = new ArrayList<>(0); 4227fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver private final Object mLock; 4327fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver private final IFingerprintService mFingerprintService; 4427fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver private final Handler mHandler; 4527fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver 4627fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver // This field is ground truth for whether or not we are registered. Only write to it in handler. 4727fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver private boolean mRegisteredReadOnlyExceptInHandler; 4827fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver 4927fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver /** 5027fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver * @param fingerprintService The system's fingerprint service 5127fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver * @param lock A lock to use when managing internal state 5227fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver */ 5327fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver public FingerprintGestureDispatcher(IFingerprintService fingerprintService, Object lock) { 5427fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver mFingerprintService = fingerprintService; 5527fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver mLock = lock; 5627fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver mHandler = new Handler(this); 5727fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver } 5827fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver 5927fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver /** 6027fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver * @param fingerprintService The system's fingerprint service 6127fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver * @param lock A lock to use when managing internal state 6227fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver * @param handler A handler to use internally. Used for testing. 6327fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver */ 6427fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver public FingerprintGestureDispatcher(IFingerprintService fingerprintService, Object lock, 6527fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver Handler handler) { 6627fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver mFingerprintService = fingerprintService; 6727fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver mLock = lock; 6827fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver mHandler = handler; 6927fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver } 7027fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver 7127fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver /** 7227fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver * Update the list of clients that are interested in fingerprint gestures. 7327fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver * 7427fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver * @param clientList The list of potential clients. 7527fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver */ 7627fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver public void updateClientList(List<? extends FingerprintGestureClient> clientList) { 7727fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver synchronized (mLock) { 7827fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver mCapturingClients.clear(); 7927fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver for (int i = 0; i < clientList.size(); i++) { 8027fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver FingerprintGestureClient client = clientList.get(i); 8127fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver if (client.isCapturingFingerprintGestures()) { 8227fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver mCapturingClients.add(client); 8327fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver } 8427fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver } 8527fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver if (mCapturingClients.isEmpty()) { 8627fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver if (mRegisteredReadOnlyExceptInHandler) { 8727fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver mHandler.obtainMessage(MSG_UNREGISTER).sendToTarget(); 8827fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver } 8927fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver } else { 9027fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver if(!mRegisteredReadOnlyExceptInHandler) { 9127fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver mHandler.obtainMessage(MSG_REGISTER).sendToTarget(); 9227fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver } 9327fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver } 9427fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver } 9527fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver } 9627fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver 9727fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver @Override 9827fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver public void onClientActiveChanged(boolean nonGestureFingerprintClientActive) { 9927fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver synchronized (mLock) { 10027fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver for (int i = 0; i < mCapturingClients.size(); i++) { 10127fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver mCapturingClients.get(i).onFingerprintGestureDetectionActiveChanged( 10227fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver !nonGestureFingerprintClientActive); 10327fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver } 10427fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver } 10527fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver } 10627fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver 10727fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver public boolean isFingerprintGestureDetectionAvailable() { 10827fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver long identity = Binder.clearCallingIdentity(); 10927fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver try { 11027fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver return !mFingerprintService.isClientActive(); 11127fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver } catch (RemoteException re) { 11227fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver return false; 11327fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver } finally { 11427fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver Binder.restoreCallingIdentity(identity); 11527fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver } 11627fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver } 11727fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver 11827fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver /** 11927fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver * Called when the fingerprint sensor detects a gesture 12027fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver * 12127fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver * @param fingerprintKeyCode 12227fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver * @return {@code true} if the gesture is consumed. {@code false} otherwise. 12327fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver */ 12427fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver public boolean onFingerprintGesture(int fingerprintKeyCode) { 12527fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver int idForFingerprintGestureManager; 12627fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver 12727fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver final List<FingerprintGestureClient> clientList; 12827fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver synchronized (mLock) { 12927fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver if (mCapturingClients.isEmpty()) { 13027fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver return false; 13127fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver } 13227fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver switch (fingerprintKeyCode) { 13327fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver case KeyEvent.KEYCODE_SYSTEM_NAVIGATION_UP: 13427fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver idForFingerprintGestureManager = 13527fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver FingerprintGestureController.FINGERPRINT_GESTURE_SWIPE_UP; 13627fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver break; 13727fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver case KeyEvent.KEYCODE_SYSTEM_NAVIGATION_DOWN: 13827fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver idForFingerprintGestureManager = 13927fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver FingerprintGestureController.FINGERPRINT_GESTURE_SWIPE_DOWN; 14027fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver break; 14127fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver case KeyEvent.KEYCODE_SYSTEM_NAVIGATION_RIGHT: 14227fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver idForFingerprintGestureManager = 14327fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver FingerprintGestureController.FINGERPRINT_GESTURE_SWIPE_RIGHT; 14427fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver break; 14527fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver case KeyEvent.KEYCODE_SYSTEM_NAVIGATION_LEFT: 14627fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver idForFingerprintGestureManager = 14727fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver FingerprintGestureController.FINGERPRINT_GESTURE_SWIPE_LEFT; 14827fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver break; 14927fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver default: 15027fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver return false; 15127fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver } 15227fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver clientList = new ArrayList<>(mCapturingClients); 15327fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver } 15427fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver for (int i = 0; i < clientList.size(); i++) { 15527fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver clientList.get(i).onFingerprintGesture(idForFingerprintGestureManager); 15627fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver } 15727fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver return true; 15827fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver } 15927fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver 16027fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver @Override 16127fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver public boolean handleMessage(Message message) { 16227fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver if (message.what == MSG_REGISTER) { 16327fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver long identity = Binder.clearCallingIdentity(); 16427fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver try { 16527fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver mFingerprintService.addClientActiveCallback(this); 16627fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver mRegisteredReadOnlyExceptInHandler = true; 16727fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver } catch (RemoteException re) { 16827fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver Slog.e(LOG_TAG, "Failed to register for fingerprint activity callbacks"); 16927fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver } finally { 17027fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver Binder.restoreCallingIdentity(identity); 17127fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver } 17227fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver return false; 17327fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver } else if (message.what == MSG_UNREGISTER) { 17427fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver long identity = Binder.clearCallingIdentity(); 17527fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver try { 17627fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver mFingerprintService.removeClientActiveCallback(this); 17727fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver } catch (RemoteException re) { 17827fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver Slog.e(LOG_TAG, "Failed to unregister for fingerprint activity callbacks"); 17927fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver } finally { 18027fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver Binder.restoreCallingIdentity(identity); 18127fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver } 18227fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver mRegisteredReadOnlyExceptInHandler = false; 18327fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver } else { 18427fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver Slog.e(LOG_TAG, "Unknown message: " + message.what); 18527fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver return false; 18627fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver } 18727fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver return true; 18827fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver } 18927fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver 19027fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver // Interface for potential clients. 19127fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver public interface FingerprintGestureClient { 19227fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver /** 19327fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver * @return {@code true} if the client is capturing fingerprint gestures 19427fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver */ 19527fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver boolean isCapturingFingerprintGestures(); 19627fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver 19727fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver /** 19827fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver * Callback when gesture detection becomes active or inactive. 19927fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver * 20027fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver * @param active {@code true} when detection is active 20127fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver */ 20227fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver void onFingerprintGestureDetectionActiveChanged(boolean active); 20327fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver 20427fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver /** 20527fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver * Callback when gesture is detected 20627fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver * 20727fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver * @param gesture The identifier for the gesture. For example, 20827fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver * {@link FingerprintGestureController#FINGERPRINT_GESTURE_SWIPE_LEFT} 20927fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver */ 21027fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver void onFingerprintGesture(int gesture); 21127fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver } 21227fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver} 213