Merge "Add re-enrollment notification for face AIDL" into sc-dev am: eef75a4842

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/13670657

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: If755dc418d630a3da83898543427c74d0d13f66d
This commit is contained in:
Kevin Chyn
2021-02-24 03:30:22 +00:00
committed by Automerger Merge Worker
9 changed files with 120 additions and 50 deletions

View File

@@ -144,6 +144,12 @@ public interface BiometricConstants {
*/ */
int BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED = 15; int BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED = 15;
/**
* Authentication cannot proceed because re-enrollment is required.
* @hide
*/
int BIOMETRIC_ERROR_RE_ENROLL = 16;
/** /**
* This constant is only used by SystemUI. It notifies SystemUI that authentication was paused * This constant is only used by SystemUI. It notifies SystemUI that authentication was paused
* because the authentication attempt was unsuccessful. * because the authentication attempt was unsuccessful.

View File

@@ -152,6 +152,12 @@ public interface BiometricFaceConstants {
*/ */
int BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED = 15; int BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED = 15;
/**
* Authentication cannot proceed because re-enrollment is required.
* @hide
*/
int BIOMETRIC_ERROR_RE_ENROLL = 16;
/** /**
* @hide * @hide
*/ */

View File

@@ -165,6 +165,12 @@ public interface BiometricFingerprintConstants {
*/ */
public static final int BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED = 15; public static final int BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED = 15;
/**
* Authentication cannot proceed because re-enrollment is required.
* @hide
*/
int BIOMETRIC_ERROR_RE_ENROLL = 16;
/** /**
* @hide * @hide
*/ */

View File

@@ -831,6 +831,9 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
case BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED: case BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED:
return context.getString( return context.getString(
com.android.internal.R.string.face_error_security_update_required); com.android.internal.R.string.face_error_security_update_required);
case BIOMETRIC_ERROR_RE_ENROLL:
return context.getString(
com.android.internal.R.string.face_recalibrate_notification_content);
case FACE_ERROR_VENDOR: { case FACE_ERROR_VENDOR: {
String[] msgArray = context.getResources().getStringArray( String[] msgArray = context.getResources().getStringArray(
com.android.internal.R.array.face_error_vendor); com.android.internal.R.array.face_error_vendor);

View File

@@ -0,0 +1,82 @@
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server.biometrics.sensors.face;
import android.annotation.NonNull;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.UserHandle;
import com.android.internal.R;
public class ReEnrollNotificationUtils {
private static final String NOTIFICATION_TAG = "FaceService";
private static final int NOTIFICATION_ID = 1;
public static void showReEnrollmentNotification(@NonNull Context context) {
final NotificationManager notificationManager =
context.getSystemService(NotificationManager.class);
final String name =
context.getString(R.string.face_recalibrate_notification_name);
final String title =
context.getString(R.string.face_recalibrate_notification_title);
final String content =
context.getString(R.string.face_recalibrate_notification_content);
final Intent intent = new Intent("android.settings.FACE_SETTINGS");
intent.setPackage("com.android.settings");
final PendingIntent pendingIntent = PendingIntent.getActivityAsUser(context,
0 /* requestCode */, intent, PendingIntent.FLAG_IMMUTABLE /* flags */,
null /* options */, UserHandle.CURRENT);
final String channelName = "FaceEnrollNotificationChannel";
final NotificationChannel channel = new NotificationChannel(channelName, name,
NotificationManager.IMPORTANCE_HIGH);
final Notification notification = new Notification.Builder(context, channelName)
.setSmallIcon(R.drawable.ic_lock)
.setContentTitle(title)
.setContentText(content)
.setSubText(name)
.setOnlyAlertOnce(true)
.setLocalOnly(true)
.setAutoCancel(true)
.setCategory(Notification.CATEGORY_SYSTEM)
.setContentIntent(pendingIntent)
.setVisibility(Notification.VISIBILITY_SECRET)
.build();
notificationManager.createNotificationChannel(channel);
notificationManager.notifyAsUser(NOTIFICATION_TAG,
NOTIFICATION_ID, notification,
UserHandle.CURRENT);
}
public static void cancelNotification(@NonNull Context context) {
final NotificationManager notificationManager =
context.getSystemService(NotificationManager.class);
notificationManager.cancelAsUser(NOTIFICATION_TAG, NOTIFICATION_ID, UserHandle.CURRENT);
}
}

View File

@@ -41,6 +41,7 @@ import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
import com.android.server.biometrics.sensors.LockoutCache; import com.android.server.biometrics.sensors.LockoutCache;
import com.android.server.biometrics.sensors.LockoutConsumer; import com.android.server.biometrics.sensors.LockoutConsumer;
import com.android.server.biometrics.sensors.LockoutTracker; import com.android.server.biometrics.sensors.LockoutTracker;
import com.android.server.biometrics.sensors.face.ReEnrollNotificationUtils;
import com.android.server.biometrics.sensors.face.UsageStats; import com.android.server.biometrics.sensors.face.UsageStats;
import java.util.ArrayList; import java.util.ArrayList;
@@ -163,6 +164,9 @@ class FaceAuthenticationClient extends AuthenticationClient<ISession> implements
vibrateError(); vibrateError();
} }
break; break;
case BiometricConstants.BIOMETRIC_ERROR_RE_ENROLL:
ReEnrollNotificationUtils.showReEnrollmentNotification(getContext());
break;
default: default:
break; break;
} }

View File

@@ -41,6 +41,7 @@ import com.android.server.biometrics.sensors.BiometricUtils;
import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter; import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
import com.android.server.biometrics.sensors.EnrollClient; import com.android.server.biometrics.sensors.EnrollClient;
import com.android.server.biometrics.sensors.face.FaceUtils; import com.android.server.biometrics.sensors.face.FaceUtils;
import com.android.server.biometrics.sensors.face.ReEnrollNotificationUtils;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
@@ -84,6 +85,13 @@ public class FaceEnrollClient extends EnrollClient<ISession> {
} }
} }
@Override
public void start(@NonNull Callback callback) {
super.start(callback);
ReEnrollNotificationUtils.cancelNotification(getContext());
}
@Override @Override
public void destroy() { public void destroy() {
try { try {

View File

@@ -19,7 +19,6 @@ package com.android.server.biometrics.sensors.face.hidl;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.app.ActivityManager; import android.app.ActivityManager;
import android.app.NotificationManager;
import android.app.SynchronousUserSwitchObserver; import android.app.SynchronousUserSwitchObserver;
import android.app.UserSwitchObserver; import android.app.UserSwitchObserver;
import android.content.Context; import android.content.Context;
@@ -71,6 +70,7 @@ import com.android.server.biometrics.sensors.PerformanceTracker;
import com.android.server.biometrics.sensors.RemovalConsumer; import com.android.server.biometrics.sensors.RemovalConsumer;
import com.android.server.biometrics.sensors.face.FaceUtils; import com.android.server.biometrics.sensors.face.FaceUtils;
import com.android.server.biometrics.sensors.face.LockoutHalImpl; import com.android.server.biometrics.sensors.face.LockoutHalImpl;
import com.android.server.biometrics.sensors.face.ReEnrollNotificationUtils;
import com.android.server.biometrics.sensors.face.ServiceProvider; import com.android.server.biometrics.sensors.face.ServiceProvider;
import com.android.server.biometrics.sensors.face.UsageStats; import com.android.server.biometrics.sensors.face.UsageStats;
@@ -96,8 +96,6 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
private static final String TAG = "Face10"; private static final String TAG = "Face10";
private static final int ENROLL_TIMEOUT_SEC = 75; private static final int ENROLL_TIMEOUT_SEC = 75;
static final String NOTIFICATION_TAG = "FaceService";
static final int NOTIFICATION_ID = 1;
private boolean mTestHalEnabled; private boolean mTestHalEnabled;
@@ -109,7 +107,6 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
@NonNull private final LockoutResetDispatcher mLockoutResetDispatcher; @NonNull private final LockoutResetDispatcher mLockoutResetDispatcher;
@NonNull private final LockoutHalImpl mLockoutTracker; @NonNull private final LockoutHalImpl mLockoutTracker;
@NonNull private final UsageStats mUsageStats; @NonNull private final UsageStats mUsageStats;
@NonNull private final NotificationManager mNotificationManager;
@NonNull private final Map<Integer, Long> mAuthenticatorIds; @NonNull private final Map<Integer, Long> mAuthenticatorIds;
@Nullable private IBiometricsFace mDaemon; @Nullable private IBiometricsFace mDaemon;
@NonNull private final HalResultController mHalResultController; @NonNull private final HalResultController mHalResultController;
@@ -343,7 +340,6 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
mUsageStats = new UsageStats(context); mUsageStats = new UsageStats(context);
mAuthenticatorIds = new HashMap<>(); mAuthenticatorIds = new HashMap<>();
mLazyDaemon = Face10.this::getDaemon; mLazyDaemon = Face10.this::getDaemon;
mNotificationManager = mContext.getSystemService(NotificationManager.class);
mLockoutTracker = new LockoutHalImpl(); mLockoutTracker = new LockoutHalImpl();
mLockoutResetDispatcher = lockoutResetDispatcher; mLockoutResetDispatcher = lockoutResetDispatcher;
mHalResultController = new HalResultController(sensorId, context, mHandler, mScheduler, mHalResultController = new HalResultController(sensorId, context, mHandler, mScheduler,
@@ -607,8 +603,7 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
mHandler.post(() -> { mHandler.post(() -> {
scheduleUpdateActiveUserWithoutHandler(userId); scheduleUpdateActiveUserWithoutHandler(userId);
mNotificationManager.cancelAsUser(NOTIFICATION_TAG, NOTIFICATION_ID, ReEnrollNotificationUtils.cancelNotification(mContext);
UserHandle.CURRENT);
final FaceEnrollClient client = new FaceEnrollClient(mContext, mLazyDaemon, token, final FaceEnrollClient client = new FaceEnrollClient(mContext, mLazyDaemon, token,
new ClientMonitorCallbackConverter(receiver), userId, hardwareAuthToken, new ClientMonitorCallbackConverter(receiver), userId, hardwareAuthToken,

View File

@@ -17,12 +17,7 @@
package com.android.server.biometrics.sensors.face.hidl; package com.android.server.biometrics.sensors.face.hidl;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context; import android.content.Context;
import android.content.Intent;
import android.content.res.Resources; import android.content.res.Resources;
import android.hardware.biometrics.BiometricAuthenticator; import android.hardware.biometrics.BiometricAuthenticator;
import android.hardware.biometrics.BiometricConstants; import android.hardware.biometrics.BiometricConstants;
@@ -32,7 +27,6 @@ import android.hardware.biometrics.face.V1_0.IBiometricsFace;
import android.hardware.face.FaceManager; import android.hardware.face.FaceManager;
import android.os.IBinder; import android.os.IBinder;
import android.os.RemoteException; import android.os.RemoteException;
import android.os.UserHandle;
import android.util.Slog; import android.util.Slog;
import com.android.internal.R; import com.android.internal.R;
@@ -40,6 +34,7 @@ import com.android.server.biometrics.Utils;
import com.android.server.biometrics.sensors.AuthenticationClient; import com.android.server.biometrics.sensors.AuthenticationClient;
import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter; import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
import com.android.server.biometrics.sensors.LockoutTracker; import com.android.server.biometrics.sensors.LockoutTracker;
import com.android.server.biometrics.sensors.face.ReEnrollNotificationUtils;
import com.android.server.biometrics.sensors.face.UsageStats; import com.android.server.biometrics.sensors.face.UsageStats;
import java.util.ArrayList; import java.util.ArrayList;
@@ -52,7 +47,7 @@ class FaceAuthenticationClient extends AuthenticationClient<IBiometricsFace> {
private static final String TAG = "FaceAuthenticationClient"; private static final String TAG = "FaceAuthenticationClient";
private final NotificationManager mNotificationManager;
private final UsageStats mUsageStats; private final UsageStats mUsageStats;
private final int[] mBiometricPromptIgnoreList; private final int[] mBiometricPromptIgnoreList;
@@ -72,7 +67,6 @@ class FaceAuthenticationClient extends AuthenticationClient<IBiometricsFace> {
owner, cookie, requireConfirmation, sensorId, isStrongBiometric, owner, cookie, requireConfirmation, sensorId, isStrongBiometric,
BiometricsProtoEnums.MODALITY_FACE, statsClient, null /* taskStackListener */, BiometricsProtoEnums.MODALITY_FACE, statsClient, null /* taskStackListener */,
lockoutTracker, isKeyguard); lockoutTracker, isKeyguard);
mNotificationManager = context.getSystemService(NotificationManager.class);
mUsageStats = usageStats; mUsageStats = usageStats;
final Resources resources = getContext().getResources(); final Resources resources = getContext().getResources();
@@ -188,41 +182,7 @@ class FaceAuthenticationClient extends AuthenticationClient<IBiometricsFace> {
mLastAcquire = acquireInfo; mLastAcquire = acquireInfo;
if (acquireInfo == FaceManager.FACE_ACQUIRED_RECALIBRATE) { if (acquireInfo == FaceManager.FACE_ACQUIRED_RECALIBRATE) {
final String name = ReEnrollNotificationUtils.showReEnrollmentNotification(getContext());
getContext().getString(R.string.face_recalibrate_notification_name);
final String title =
getContext().getString(R.string.face_recalibrate_notification_title);
final String content =
getContext().getString(R.string.face_recalibrate_notification_content);
final Intent intent = new Intent("android.settings.FACE_SETTINGS");
intent.setPackage("com.android.settings");
final PendingIntent pendingIntent = PendingIntent.getActivityAsUser(getContext(),
0 /* requestCode */, intent, PendingIntent.FLAG_IMMUTABLE /* flags */,
null /* options */, UserHandle.CURRENT);
final String channelName = "FaceEnrollNotificationChannel";
NotificationChannel channel = new NotificationChannel(channelName, name,
NotificationManager.IMPORTANCE_HIGH);
Notification notification = new Notification.Builder(getContext(), channelName)
.setSmallIcon(R.drawable.ic_lock)
.setContentTitle(title)
.setContentText(content)
.setSubText(name)
.setOnlyAlertOnce(true)
.setLocalOnly(true)
.setAutoCancel(true)
.setCategory(Notification.CATEGORY_SYSTEM)
.setContentIntent(pendingIntent)
.setVisibility(Notification.VISIBILITY_SECRET)
.build();
mNotificationManager.createNotificationChannel(channel);
mNotificationManager.notifyAsUser(Face10.NOTIFICATION_TAG,
Face10.NOTIFICATION_ID, notification,
UserHandle.CURRENT);
} }
final boolean shouldSend = shouldSend(acquireInfo, vendorCode); final boolean shouldSend = shouldSend(acquireInfo, vendorCode);