diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 4bd2cc758cbb5..ef834aa01a360 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -1507,6 +1507,13 @@ Allows the app to use face authentication hardware for authentication + + Face Authentication + + Re-enroll your face + + To improve recognition, please re-enroll your face + Couldn\u2019t capture accurate face data. Try again. diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 6f672a8182f41..bebba5435c409 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -2533,6 +2533,9 @@ + + + diff --git a/services/core/java/com/android/server/biometrics/face/FaceService.java b/services/core/java/com/android/server/biometrics/face/FaceService.java index e218c6b399a21..44fd84602ebe1 100644 --- a/services/core/java/com/android/server/biometrics/face/FaceService.java +++ b/services/core/java/com/android/server/biometrics/face/FaceService.java @@ -23,7 +23,12 @@ import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL; import android.app.ActivityManager; import android.app.AppOpsManager; +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.pm.UserInfo; import android.hardware.biometrics.BiometricAuthenticator; import android.hardware.biometrics.BiometricConstants; @@ -48,10 +53,10 @@ import android.os.SELinux; import android.os.SystemProperties; import android.os.UserHandle; import android.os.UserManager; -import android.provider.Settings; import android.util.Slog; import android.util.proto.ProtoOutputStream; +import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import com.android.internal.logging.MetricsLogger; import com.android.internal.util.DumpUtils; @@ -124,6 +129,49 @@ public class FaceService extends BiometricServiceBase { // but let's leave it as-is for now. return result || !authenticated; } + + @Override + public boolean onAcquired(int acquireInfo, int vendorCode) { + + 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, 0 /* flags */, null /* options */, + UserHandle.CURRENT); + + final String id = "FaceService"; + + NotificationManager nm = + getContext().getSystemService(NotificationManager.class); + NotificationChannel channel = new NotificationChannel(id, name, + NotificationManager.IMPORTANCE_HIGH); + Notification notification = new Notification.Builder(getContext(), id) + .setSmallIcon(R.drawable.ic_lock) + .setContentTitle(title) + .setContentText(content) + .setSubText(name) + .setOnlyAlertOnce(true) + .setLocalOnly(true) + .setAutoCancel(true) + .setCategory(Notification.CATEGORY_SYSTEM) + .setContentIntent(pendingIntent) + .build(); + + nm.createNotificationChannel(channel); + nm.notifyAsUser(null /* tag */, 0 /* id */, notification, UserHandle.CURRENT); + } + + return super.onAcquired(acquireInfo, vendorCode); + } } /**