1 /*
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 
17 package com.android.server.biometrics;
18 
19 import android.content.Context;
20 import android.hardware.biometrics.BiometricAuthenticator;
21 import android.hardware.biometrics.BiometricConstants;
22 import android.hardware.biometrics.BiometricsProtoEnums;
23 import android.os.IBinder;
24 import android.os.RemoteException;
25 import android.util.Slog;
26 
27 import java.util.ArrayList;
28 
29 /**
30  * A class to keep track of the remove state for a given client.
31  */
32 public abstract class RemovalClient extends ClientMonitor {
33     private final int mBiometricId;
34     private final BiometricUtils mBiometricUtils;
35 
RemovalClient(Context context, Constants constants, BiometricServiceBase.DaemonWrapper daemon, long halDeviceId, IBinder token, BiometricServiceBase.ServiceListener listener, int biometricId, int groupId, int userId, boolean restricted, String owner, BiometricUtils utils)36     public RemovalClient(Context context, Constants constants,
37             BiometricServiceBase.DaemonWrapper daemon, long halDeviceId, IBinder token,
38             BiometricServiceBase.ServiceListener listener, int biometricId, int groupId, int userId,
39             boolean restricted, String owner, BiometricUtils utils) {
40         super(context, constants, daemon, halDeviceId, token, listener, userId, groupId, restricted,
41                 owner, 0 /* cookie */);
42         mBiometricId = biometricId;
43         mBiometricUtils = utils;
44     }
45 
46     @Override
notifyUserActivity()47     public void notifyUserActivity() {
48     }
49 
50     @Override
statsAction()51     protected int statsAction() {
52         return BiometricsProtoEnums.ACTION_REMOVE;
53     }
54 
55     @Override
start()56     public int start() {
57         // The biometric template ids will be removed when we get confirmation from the HAL
58         try {
59             final int result = getDaemonWrapper().remove(getGroupId(), mBiometricId);
60             if (result != 0) {
61                 Slog.w(getLogTag(), "startRemove with id = " + mBiometricId + " failed, result=" +
62                         result);
63                 mMetricsLogger.histogram(mConstants.tagRemoveStartError(), result);
64                 onError(getHalDeviceId(), BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE,
65                         0 /* vendorCode */);
66                 return result;
67             }
68         } catch (RemoteException e) {
69             Slog.e(getLogTag(), "startRemove failed", e);
70         }
71         return 0;
72     }
73 
74     @Override
stop(boolean initiatedByClient)75     public int stop(boolean initiatedByClient) {
76         if (mAlreadyCancelled) {
77             Slog.w(getLogTag(), "stopRemove: already cancelled!");
78             return 0;
79         }
80 
81         try {
82             final int result = getDaemonWrapper().cancel();
83             if (result != 0) {
84                 Slog.w(getLogTag(), "stopRemoval failed, result=" + result);
85                 return result;
86             }
87             if (DEBUG) Slog.w(getLogTag(), "client " + getOwnerString() + " is no longer removing");
88         } catch (RemoteException e) {
89             Slog.e(getLogTag(), "stopRemoval failed", e);
90             return ERROR_ESRCH;
91         }
92         mAlreadyCancelled = true;
93         return 0; // success
94     }
95 
96     /*
97      * @return true if we're done.
98      */
sendRemoved(BiometricAuthenticator.Identifier identifier, int remaining)99     private boolean sendRemoved(BiometricAuthenticator.Identifier identifier,
100             int remaining) {
101         try {
102             if (getListener() != null) {
103                 getListener().onRemoved(identifier, remaining);
104             }
105         } catch (RemoteException e) {
106             Slog.w(getLogTag(), "Failed to notify Removed:", e);
107         }
108         return remaining == 0;
109     }
110 
111     @Override
onRemoved(BiometricAuthenticator.Identifier identifier, int remaining)112     public boolean onRemoved(BiometricAuthenticator.Identifier identifier, int remaining) {
113         if (identifier.getBiometricId() != 0) {
114             mBiometricUtils.removeBiometricForUser(getContext(), getTargetUserId(),
115                     identifier.getBiometricId());
116         }
117         return sendRemoved(identifier, remaining);
118     }
119 
120     @Override
onEnrollResult(BiometricAuthenticator.Identifier identifier, int rem)121     public boolean onEnrollResult(BiometricAuthenticator.Identifier identifier, int rem) {
122         if (DEBUG) Slog.w(getLogTag(), "onEnrollResult() called for remove!");
123         return true; // Invalid for Remove
124     }
125 
126     @Override
onAuthenticated(BiometricAuthenticator.Identifier identifier, boolean authenticated, ArrayList<Byte> token)127     public boolean onAuthenticated(BiometricAuthenticator.Identifier identifier,
128             boolean authenticated, ArrayList<Byte> token) {
129         if (DEBUG) Slog.w(getLogTag(), "onAuthenticated() called for remove!");
130         return true; // Invalid for Remove.
131     }
132 
133     @Override
onEnumerationResult(BiometricAuthenticator.Identifier identifier, int remaining)134     public boolean onEnumerationResult(BiometricAuthenticator.Identifier identifier,
135             int remaining) {
136         if (DEBUG) Slog.w(getLogTag(), "onEnumerationResult() called for remove!");
137         return true; // Invalid for Remove.
138     }
139 }
140