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