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

This commit is contained in:
Kevin Chyn
2021-02-24 03:17:15 +00:00
committed by Android (Google) Code Review
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;
/**
* 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
* because the authentication attempt was unsuccessful.

View File

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

View File

@@ -165,6 +165,12 @@ public interface BiometricFingerprintConstants {
*/
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
*/

View File

@@ -831,6 +831,9 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
case BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED:
return context.getString(
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: {
String[] msgArray = context.getResources().getStringArray(
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.LockoutConsumer;
import com.android.server.biometrics.sensors.LockoutTracker;
import com.android.server.biometrics.sensors.face.ReEnrollNotificationUtils;
import com.android.server.biometrics.sensors.face.UsageStats;
import java.util.ArrayList;
@@ -163,6 +164,9 @@ class FaceAuthenticationClient extends AuthenticationClient<ISession> implements
vibrateError();
}
break;
case BiometricConstants.BIOMETRIC_ERROR_RE_ENROLL:
ReEnrollNotificationUtils.showReEnrollmentNotification(getContext());
break;
default:
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.EnrollClient;
import com.android.server.biometrics.sensors.face.FaceUtils;
import com.android.server.biometrics.sensors.face.ReEnrollNotificationUtils;
import java.io.IOException;
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
public void destroy() {
try {

View File

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

View File

@@ -17,12 +17,7 @@
package com.android.server.biometrics.sensors.face.hidl;
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.content.res.Resources;
import android.hardware.biometrics.BiometricAuthenticator;
import android.hardware.biometrics.BiometricConstants;
@@ -32,7 +27,6 @@ import android.hardware.biometrics.face.V1_0.IBiometricsFace;
import android.hardware.face.FaceManager;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.UserHandle;
import android.util.Slog;
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.ClientMonitorCallbackConverter;
import com.android.server.biometrics.sensors.LockoutTracker;
import com.android.server.biometrics.sensors.face.ReEnrollNotificationUtils;
import com.android.server.biometrics.sensors.face.UsageStats;
import java.util.ArrayList;
@@ -52,7 +47,7 @@ class FaceAuthenticationClient extends AuthenticationClient<IBiometricsFace> {
private static final String TAG = "FaceAuthenticationClient";
private final NotificationManager mNotificationManager;
private final UsageStats mUsageStats;
private final int[] mBiometricPromptIgnoreList;
@@ -72,7 +67,6 @@ class FaceAuthenticationClient extends AuthenticationClient<IBiometricsFace> {
owner, cookie, requireConfirmation, sensorId, isStrongBiometric,
BiometricsProtoEnums.MODALITY_FACE, statsClient, null /* taskStackListener */,
lockoutTracker, isKeyguard);
mNotificationManager = context.getSystemService(NotificationManager.class);
mUsageStats = usageStats;
final Resources resources = getContext().getResources();
@@ -188,41 +182,7 @@ class FaceAuthenticationClient extends AuthenticationClient<IBiometricsFace> {
mLastAcquire = acquireInfo;
if (acquireInfo == FaceManager.FACE_ACQUIRED_RECALIBRATE) {
final String name =
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);
ReEnrollNotificationUtils.showReEnrollmentNotification(getContext());
}
final boolean shouldSend = shouldSend(acquireInfo, vendorCode);