OSDN Git Service

DO NOT MERGE. Grant MMS Uri permissions as the calling UID.
[android-x86/frameworks-base.git] / services / core / java / com / android / server / fingerprint / AuthenticationClient.java
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 com.android.internal.logging.MetricsLogger;
20 import com.android.internal.logging.MetricsProto.MetricsEvent;
21
22 import android.content.Context;
23 import android.hardware.fingerprint.Fingerprint;
24 import android.hardware.fingerprint.FingerprintManager;
25 import android.hardware.fingerprint.IFingerprintDaemon;
26 import android.hardware.fingerprint.IFingerprintServiceReceiver;
27 import android.os.IBinder;
28 import android.os.RemoteException;
29 import android.system.ErrnoException;
30 import android.util.Slog;
31
32 /**
33  * A class to keep track of the authentication state for a given client.
34  */
35 public abstract class AuthenticationClient extends ClientMonitor {
36     private long mOpId;
37
38     public abstract boolean handleFailedAttempt();
39     public abstract void resetFailedAttempts();
40
41     public AuthenticationClient(Context context, long halDeviceId, IBinder token,
42             IFingerprintServiceReceiver receiver, int callingUserId, int groupId, long opId,
43             boolean restricted, String owner) {
44         super(context, halDeviceId, token, receiver, callingUserId, groupId, restricted, owner);
45         mOpId = opId;
46     }
47
48     @Override
49     public boolean onAuthenticated(int fingerId, int groupId) {
50         boolean result = false;
51         boolean authenticated = fingerId != 0;
52
53         IFingerprintServiceReceiver receiver = getReceiver();
54         if (receiver != null) {
55             try {
56                 MetricsLogger.action(getContext(), MetricsEvent.ACTION_FINGERPRINT_AUTH,
57                         authenticated);
58                 if (!authenticated) {
59                     receiver.onAuthenticationFailed(getHalDeviceId());
60                 } else {
61                     if (DEBUG) {
62                         Slog.v(TAG, "onAuthenticated(owner=" + getOwnerString()
63                                 + ", id=" + fingerId + ", gp=" + groupId + ")");
64                     }
65                     Fingerprint fp = !getIsRestricted()
66                             ? new Fingerprint("" /* TODO */, groupId, fingerId, getHalDeviceId())
67                             : null;
68                     receiver.onAuthenticationSucceeded(getHalDeviceId(), fp);
69                 }
70             } catch (RemoteException e) {
71                 Slog.w(TAG, "Failed to notify Authenticated:", e);
72                 result = true; // client failed
73             }
74         } else {
75             result = true; // client not listening
76         }
77         if (!authenticated) {
78             if (receiver != null) {
79                 FingerprintUtils.vibrateFingerprintError(getContext());
80             }
81             // allow system-defined limit of number of attempts before giving up
82             boolean inLockoutMode =  handleFailedAttempt();
83             // send lockout event in case driver doesn't enforce it.
84             if (inLockoutMode) {
85                 try {
86                     Slog.w(TAG, "Forcing lockout (fp driver code should do this!)");
87                     receiver.onError(getHalDeviceId(),
88                             FingerprintManager.FINGERPRINT_ERROR_LOCKOUT);
89                 } catch (RemoteException e) {
90                     Slog.w(TAG, "Failed to notify lockout:", e);
91                 }
92             }
93             result |= inLockoutMode;
94         } else {
95             if (receiver != null) {
96                 FingerprintUtils.vibrateFingerprintSuccess(getContext());
97             }
98             result |= true; // we have a valid fingerprint, done
99             resetFailedAttempts();
100         }
101         return result;
102     }
103
104     /**
105      * Start authentication
106      */
107     @Override
108     public int start() {
109         IFingerprintDaemon daemon = getFingerprintDaemon();
110         if (daemon == null) {
111             Slog.w(TAG, "start authentication: no fingeprintd!");
112             return ERROR_ESRCH;
113         }
114         try {
115             final int result = daemon.authenticate(mOpId, getGroupId());
116             if (result != 0) {
117                 Slog.w(TAG, "startAuthentication failed, result=" + result);
118                 onError(FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE);
119                 return result;
120             }
121             if (DEBUG) Slog.w(TAG, "client " + getOwnerString() + " is authenticating...");
122         } catch (RemoteException e) {
123             Slog.e(TAG, "startAuthentication failed", e);
124             return ERROR_ESRCH;
125         }
126         return 0; // success
127     }
128
129     @Override
130     public int stop(boolean initiatedByClient) {
131         IFingerprintDaemon daemon = getFingerprintDaemon();
132         if (daemon == null) {
133             Slog.w(TAG, "stopAuthentication: no fingeprintd!");
134             return ERROR_ESRCH;
135         }
136         try {
137             final int result = daemon.cancelAuthentication();
138             if (result != 0) {
139                 Slog.w(TAG, "stopAuthentication failed, result=" + result);
140                 return result;
141             }
142             if (DEBUG) Slog.w(TAG, "client " + getOwnerString() + " is no longer authenticating");
143         } catch (RemoteException e) {
144             Slog.e(TAG, "stopAuthentication failed", e);
145             return ERROR_ESRCH;
146         }
147         return 0; // success
148     }
149
150     @Override
151     public boolean onEnrollResult(int fingerId, int groupId, int rem) {
152         if (DEBUG) Slog.w(TAG, "onEnrollResult() called for authenticate!");
153         return true; // Invalid for Authenticate
154     }
155
156     @Override
157     public boolean onRemoved(int fingerId, int groupId) {
158         if (DEBUG) Slog.w(TAG, "onRemoved() called for authenticate!");
159         return true; // Invalid for Authenticate
160     }
161
162     @Override
163     public boolean onEnumerationResult(int fingerId, int groupId) {
164         if (DEBUG) Slog.w(TAG, "onEnumerationResult() called for authenticate!");
165         return true; // Invalid for Authenticate
166     }
167 }