• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.server.fingerprint;
18 
19 import android.Manifest;
20 import android.content.Context;
21 import android.hardware.fingerprint.FingerprintManager;
22 import android.hardware.fingerprint.IFingerprintDaemon;
23 import android.hardware.fingerprint.IFingerprintServiceReceiver;
24 import android.os.IBinder;
25 import android.os.RemoteException;
26 import android.util.Slog;
27 
28 import java.util.NoSuchElementException;
29 
30 /**
31  * Abstract base class for keeping track and dispatching events from fingerprintd to the
32  * the current client.  Subclasses are responsible for coordinating the interaction with
33  * fingerprintd for the specific action (e.g. authenticate, enroll, enumerate, etc.).
34  */
35 public abstract class ClientMonitor implements IBinder.DeathRecipient {
36     protected static final String TAG = FingerprintService.TAG; // TODO: get specific name
37     protected static final int ERROR_ESRCH = 3; // Likely fingerprintd is dead. See errno.h.
38     protected static final boolean DEBUG = FingerprintService.DEBUG;
39     private IBinder mToken;
40     private IFingerprintServiceReceiver mReceiver;
41     private int mTargetUserId;
42     private int mGroupId;
43     private boolean mIsRestricted; // True if client does not have MANAGE_FINGERPRINT permission
44     private String mOwner;
45     private Context mContext;
46     private long mHalDeviceId;
47 
48     /**
49      * @param context context of FingerprintService
50      * @param halDeviceId the HAL device ID of the associated fingerprint hardware
51      * @param token a unique token for the client
52      * @param receiver recipient of related events (e.g. authentication)
53      * @param userId target user id for operation
54      * @param groupId groupId for the fingerprint set
55      * @param restricted whether or not client has the {@link Manifest#MANAGE_FINGERPRINT}
56      * permission
57      * @param owner name of the client that owns this
58      */
ClientMonitor(Context context, long halDeviceId, IBinder token, IFingerprintServiceReceiver receiver, int userId, int groupId,boolean restricted, String owner)59     public ClientMonitor(Context context, long halDeviceId, IBinder token,
60             IFingerprintServiceReceiver receiver, int userId, int groupId,boolean restricted,
61             String owner) {
62         mContext = context;
63         mHalDeviceId = halDeviceId;
64         mToken = token;
65         mReceiver = receiver;
66         mTargetUserId = userId;
67         mGroupId = groupId;
68         mIsRestricted = restricted;
69         mOwner = owner;
70         try {
71             token.linkToDeath(this, 0);
72         } catch (RemoteException e) {
73             Slog.w(TAG, "caught remote exception in linkToDeath: ", e);
74         }
75     }
76 
77     /**
78      * Contacts fingerprintd to start the client.
79      * @return 0 on succes, errno from driver on failure
80      */
start()81     public abstract int start();
82 
83     /**
84      * Contacts fingerprintd to stop the client.
85      * @param initiatedByClient whether the operation is at the request of a client
86      */
stop(boolean initiatedByClient)87     public abstract int stop(boolean initiatedByClient);
88 
89     /**
90      * Method to explicitly poke powermanager on events
91      */
notifyUserActivity()92     public abstract void notifyUserActivity();
93 
94     /**
95      * Gets the fingerprint daemon from the cached state in the container class.
96      */
getFingerprintDaemon()97     public abstract IFingerprintDaemon getFingerprintDaemon();
98 
99     // Event callbacks from driver. Inappropriate calls is flagged/logged by the
100     // respective client (e.g. enrolling shouldn't get authenticate events).
101     // All of these return 'true' if the operation is completed and it's ok to move
102     // to the next client (e.g. authentication accepts or rejects a fingerprint).
onEnrollResult(int fingerId, int groupId, int rem)103     public abstract boolean onEnrollResult(int fingerId, int groupId, int rem);
onAuthenticated(int fingerId, int groupId)104     public abstract boolean onAuthenticated(int fingerId, int groupId);
onRemoved(int fingerId, int groupId)105     public abstract boolean onRemoved(int fingerId, int groupId);
onEnumerationResult(int fingerId, int groupId)106     public abstract boolean onEnumerationResult(int fingerId, int groupId);
107 
108     /**
109      * Called when we get notification from fingerprintd that an image has been acquired.
110      * Common to authenticate and enroll.
111      * @param acquiredInfo info about the current image acquisition
112      * @return true if client should be removed
113      */
onAcquired(int acquiredInfo)114     public boolean onAcquired(int acquiredInfo) {
115         if (mReceiver == null)
116             return true; // client not connected
117         try {
118             mReceiver.onAcquired(getHalDeviceId(), acquiredInfo);
119             return false; // acquisition continues...
120         } catch (RemoteException e) {
121             Slog.w(TAG, "Failed to invoke sendAcquired:", e);
122             return true; // client failed
123         } finally {
124             // Good scans will keep the device awake
125             if (acquiredInfo == FingerprintManager.FINGERPRINT_ACQUIRED_GOOD) {
126                 notifyUserActivity();
127             }
128         }
129     }
130 
131     /**
132      * Called when we get notification from fingerprintd that an error has occurred with the
133      * current operation. Common to authenticate, enroll, enumerate and remove.
134      * @param error
135      * @return true if client should be removed
136      */
onError(int error)137     public boolean onError(int error) {
138         if (mReceiver != null) {
139             try {
140                 mReceiver.onError(getHalDeviceId(), error);
141             } catch (RemoteException e) {
142                 Slog.w(TAG, "Failed to invoke sendError:", e);
143             }
144         }
145         return true; // errors always remove current client
146     }
147 
destroy()148     public void destroy() {
149         if (mToken != null) {
150             try {
151                 mToken.unlinkToDeath(this, 0);
152             } catch (NoSuchElementException e) {
153                 // TODO: remove when duplicate call bug is found
154                 Slog.e(TAG, "destroy(): " + this + ":", new Exception("here"));
155             }
156             mToken = null;
157         }
158         mReceiver = null;
159     }
160 
161     @Override
binderDied()162     public void binderDied() {
163         mToken = null;
164         mReceiver = null;
165         onError(FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE);
166     }
167 
168     @Override
finalize()169     protected void finalize() throws Throwable {
170         try {
171             if (mToken != null) {
172                 if (DEBUG) Slog.w(TAG, "removing leaked reference: " + mToken);
173                 onError(FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE);
174             }
175         } finally {
176             super.finalize();
177         }
178     }
179 
getContext()180     public final Context getContext() {
181         return mContext;
182     }
183 
getHalDeviceId()184     public final long getHalDeviceId() {
185         return mHalDeviceId;
186     }
187 
getOwnerString()188     public final String getOwnerString() {
189         return mOwner;
190     }
191 
getReceiver()192     public final IFingerprintServiceReceiver getReceiver() {
193         return mReceiver;
194     }
195 
getIsRestricted()196     public final boolean getIsRestricted() {
197         return mIsRestricted;
198     }
199 
getTargetUserId()200     public final int getTargetUserId() {
201         return mTargetUserId;
202     }
203 
getGroupId()204     public final int getGroupId() {
205         return mGroupId;
206     }
207 
getToken()208     public final IBinder getToken() {
209         return mToken;
210     }
211 }
212