1 /* 2 * Copyright (C) 2022 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.settings.biometrics.face; 18 19 import android.content.Context; 20 import android.content.Intent; 21 import android.hardware.face.Face; 22 import android.hardware.face.FaceEnrollCell; 23 import android.hardware.face.FaceEnrollOptions; 24 import android.hardware.face.FaceManager; 25 import android.os.CancellationSignal; 26 import android.view.Surface; 27 28 import androidx.annotation.Nullable; 29 30 import com.android.settings.Utils; 31 import com.android.settings.biometrics.BiometricUtils; 32 import com.android.settings.safetycenter.BiometricsSafetySource; 33 34 /** 35 * Responsible for making {@link FaceManager#enroll} and {@link FaceManager#remove} calls and thus 36 * updating the face setting. 37 */ 38 public class FaceUpdater { 39 40 private final Context mContext; 41 private final FaceManager mFaceManager; 42 FaceUpdater(Context context)43 public FaceUpdater(Context context) { 44 mContext = context; 45 mFaceManager = Utils.getFaceManagerOrNull(context); 46 } 47 FaceUpdater(Context context, FaceManager faceManager)48 public FaceUpdater(Context context, FaceManager faceManager) { 49 mContext = context; 50 mFaceManager = faceManager; 51 } 52 53 /** Wrapper around the {@link FaceManager#enroll} method. */ enroll(int userId, byte[] hardwareAuthToken, CancellationSignal cancel, FaceManager.EnrollmentCallback callback, int[] disabledFeatures, Intent intent)54 public void enroll(int userId, byte[] hardwareAuthToken, CancellationSignal cancel, 55 FaceManager.EnrollmentCallback callback, int[] disabledFeatures, Intent intent) { 56 this.enroll(userId, hardwareAuthToken, cancel, 57 new NotifyingEnrollmentCallback(mContext, callback), disabledFeatures, 58 null, false, intent); 59 } 60 61 /** Wrapper around the {@link FaceManager#enroll} method. */ enroll(int userId, byte[] hardwareAuthToken, CancellationSignal cancel, FaceManager.EnrollmentCallback callback, int[] disabledFeatures, @Nullable Surface previewSurface, boolean debugConsent, Intent intent)62 public void enroll(int userId, byte[] hardwareAuthToken, CancellationSignal cancel, 63 FaceManager.EnrollmentCallback callback, int[] disabledFeatures, 64 @Nullable Surface previewSurface, boolean debugConsent, Intent intent) { 65 mFaceManager.enroll(userId, hardwareAuthToken, cancel, 66 new NotifyingEnrollmentCallback(mContext, callback), disabledFeatures, 67 previewSurface, debugConsent, toFaceEnrollOptions(intent)); 68 } 69 70 /** Wrapper around the {@link FaceManager#remove} method. */ remove(Face face, int userId, FaceManager.RemovalCallback callback)71 public void remove(Face face, int userId, FaceManager.RemovalCallback callback) { 72 mFaceManager.remove(face, userId, new NotifyingRemovalCallback(mContext, callback)); 73 } 74 75 /** 76 * Decorator of the {@link FaceManager.EnrollmentCallback} class that notifies other 77 * interested parties that a face setting has changed. 78 */ 79 private static class NotifyingEnrollmentCallback 80 extends FaceManager.EnrollmentCallback { 81 82 private final Context mContext; 83 private final FaceManager.EnrollmentCallback mCallback; 84 NotifyingEnrollmentCallback(Context context, FaceManager.EnrollmentCallback callback)85 NotifyingEnrollmentCallback(Context context, 86 FaceManager.EnrollmentCallback callback) { 87 mContext = context; 88 mCallback = callback; 89 } 90 91 @Override onEnrollmentError(int errMsgId, CharSequence errString)92 public void onEnrollmentError(int errMsgId, CharSequence errString) { 93 mCallback.onEnrollmentError(errMsgId, errString); 94 } 95 96 @Override onEnrollmentHelp(int helpMsgId, CharSequence helpString)97 public void onEnrollmentHelp(int helpMsgId, CharSequence helpString) { 98 mCallback.onEnrollmentHelp(helpMsgId, helpString); 99 } 100 101 @Override onEnrollmentFrame(int helpCode, @Nullable CharSequence helpMessage, @Nullable FaceEnrollCell cell, int stage, float pan, float tilt, float distance)102 public void onEnrollmentFrame(int helpCode, @Nullable CharSequence helpMessage, 103 @Nullable FaceEnrollCell cell, int stage, float pan, float tilt, float distance) { 104 mCallback.onEnrollmentFrame(helpCode, helpMessage, cell, stage, pan, tilt, distance); 105 } 106 107 @Override onEnrollmentProgress(int remaining)108 public void onEnrollmentProgress(int remaining) { 109 mCallback.onEnrollmentProgress(remaining); 110 if (remaining == 0) { 111 BiometricsSafetySource.onBiometricsChanged(mContext); // biometrics data changed 112 } 113 } 114 } 115 116 /** 117 * Decorator of the {@link FaceManager.RemovalCallback} class that notifies other 118 * interested parties that a face setting has changed. 119 */ 120 private static class NotifyingRemovalCallback extends FaceManager.RemovalCallback { 121 122 private final Context mContext; 123 private final FaceManager.RemovalCallback mCallback; 124 NotifyingRemovalCallback(Context context, FaceManager.RemovalCallback callback)125 NotifyingRemovalCallback(Context context, FaceManager.RemovalCallback callback) { 126 mContext = context; 127 mCallback = callback; 128 } 129 130 @Override onRemovalError(Face fp, int errMsgId, CharSequence errString)131 public void onRemovalError(Face fp, int errMsgId, CharSequence errString) { 132 mCallback.onRemovalError(fp, errMsgId, errString); 133 } 134 135 @Override onRemovalSucceeded(@ullable Face fp, int remaining)136 public void onRemovalSucceeded(@Nullable Face fp, int remaining) { 137 mCallback.onRemovalSucceeded(fp, remaining); 138 BiometricsSafetySource.onBiometricsChanged(mContext); // biometrics data changed 139 } 140 } 141 toFaceEnrollOptions(Intent intent)142 private FaceEnrollOptions toFaceEnrollOptions(Intent intent) { 143 final int reason = intent.getIntExtra(BiometricUtils.EXTRA_ENROLL_REASON, -1); 144 final FaceEnrollOptions.Builder builder = new FaceEnrollOptions.Builder(); 145 builder.setEnrollReason(FaceEnrollOptions.ENROLL_REASON_UNKNOWN); 146 if (reason != -1) { 147 builder.setEnrollReason(reason); 148 } 149 return builder.build(); 150 } 151 } 152