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:
@@ -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.
|
||||||
|
|||||||
@@ -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
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -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
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user