1 /* 2 * Copyright (C) 2021 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.server.biometrics.sensors; 18 19 import android.annotation.NonNull; 20 import android.app.Notification; 21 import android.app.NotificationChannel; 22 import android.app.NotificationManager; 23 import android.app.PendingIntent; 24 import android.content.Context; 25 import android.content.Intent; 26 import android.os.SystemClock; 27 import android.os.UserHandle; 28 import android.util.Slog; 29 30 import com.android.internal.R; 31 32 /** 33 * Biometric notification helper class. 34 */ 35 public class BiometricNotificationUtils { 36 37 private static final String TAG = "BiometricNotificationUtils"; 38 private static final String RE_ENROLL_NOTIFICATION_TAG = "FaceService"; 39 private static final String BAD_CALIBRATION_NOTIFICATION_TAG = "FingerprintService"; 40 private static final int NOTIFICATION_ID = 1; 41 private static final long NOTIFICATION_INTERVAL_MS = 24 * 60 * 60 * 1000; 42 private static long sLastAlertTime = 0; 43 44 /** 45 * Shows a face re-enrollment notification. 46 */ showReEnrollmentNotification(@onNull Context context)47 public static void showReEnrollmentNotification(@NonNull Context context) { 48 final NotificationManager notificationManager = 49 context.getSystemService(NotificationManager.class); 50 51 final String name = 52 context.getString(R.string.face_recalibrate_notification_name); 53 final String title = 54 context.getString(R.string.face_recalibrate_notification_title); 55 final String content = 56 context.getString(R.string.face_recalibrate_notification_content); 57 58 final Intent intent = new Intent("android.settings.FACE_SETTINGS"); 59 intent.setPackage("com.android.settings"); 60 61 final PendingIntent pendingIntent = PendingIntent.getActivityAsUser(context, 62 0 /* requestCode */, intent, PendingIntent.FLAG_IMMUTABLE /* flags */, 63 null /* options */, UserHandle.CURRENT); 64 65 final String channelName = "FaceEnrollNotificationChannel"; 66 67 showNotificationHelper(context, name, title, content, pendingIntent, channelName, 68 RE_ENROLL_NOTIFICATION_TAG); 69 } 70 71 /** 72 * Shows a fingerprint bad calibration notification. 73 */ showBadCalibrationNotification(@onNull Context context)74 public static void showBadCalibrationNotification(@NonNull Context context) { 75 final long currentTime = SystemClock.elapsedRealtime(); 76 final long timeSinceLastAlert = currentTime - sLastAlertTime; 77 78 // Only show the notification if not previously shown or a day has 79 // passed since the last notification. 80 if (sLastAlertTime != 0 && (timeSinceLastAlert < NOTIFICATION_INTERVAL_MS)) { 81 Slog.v(TAG, "Skipping calibration notification : " + timeSinceLastAlert); 82 return; 83 } 84 85 sLastAlertTime = currentTime; 86 87 final String name = 88 context.getString(R.string.fingerprint_recalibrate_notification_name); 89 final String title = 90 context.getString(R.string.fingerprint_recalibrate_notification_title); 91 final String content = 92 context.getString(R.string.fingerprint_recalibrate_notification_content); 93 94 final Intent intent = new Intent("android.settings.FINGERPRINT_SETTINGS"); 95 intent.setPackage("com.android.settings"); 96 97 final PendingIntent pendingIntent = PendingIntent.getActivityAsUser(context, 98 0 /* requestCode */, intent, PendingIntent.FLAG_IMMUTABLE /* flags */, 99 null /* options */, UserHandle.CURRENT); 100 101 final String channelName = "FingerprintBadCalibrationNotificationChannel"; 102 103 showNotificationHelper(context, name, title, content, pendingIntent, channelName, 104 BAD_CALIBRATION_NOTIFICATION_TAG); 105 } 106 showNotificationHelper(Context context, String name, String title, String content, PendingIntent pendingIntent, String channelName, String notificationTag)107 private static void showNotificationHelper(Context context, String name, String title, 108 String content, PendingIntent pendingIntent, String channelName, 109 String notificationTag) { 110 final NotificationManager notificationManager = 111 context.getSystemService(NotificationManager.class); 112 final NotificationChannel channel = new NotificationChannel(channelName, name, 113 NotificationManager.IMPORTANCE_HIGH); 114 final Notification notification = new Notification.Builder(context, channelName) 115 .setSmallIcon(R.drawable.ic_lock) 116 .setContentTitle(title) 117 .setContentText(content) 118 .setSubText(name) 119 .setOnlyAlertOnce(true) 120 .setLocalOnly(true) 121 .setAutoCancel(true) 122 .setCategory(Notification.CATEGORY_SYSTEM) 123 .setContentIntent(pendingIntent) 124 .setVisibility(Notification.VISIBILITY_SECRET) 125 .build(); 126 127 notificationManager.createNotificationChannel(channel); 128 notificationManager.notifyAsUser(notificationTag, NOTIFICATION_ID, notification, 129 UserHandle.CURRENT); 130 } 131 132 /** 133 * Cancels a face re-enrollment notification 134 */ cancelReEnrollNotification(@onNull Context context)135 public static void cancelReEnrollNotification(@NonNull Context context) { 136 final NotificationManager notificationManager = 137 context.getSystemService(NotificationManager.class); 138 notificationManager.cancelAsUser(RE_ENROLL_NOTIFICATION_TAG, NOTIFICATION_ID, 139 UserHandle.CURRENT); 140 } 141 142 /** 143 * Cancels a fingerprint bad calibration notification 144 */ cancelBadCalibrationNotification(@onNull Context context)145 public static void cancelBadCalibrationNotification(@NonNull Context context) { 146 final NotificationManager notificationManager = 147 context.getSystemService(NotificationManager.class); 148 notificationManager.cancelAsUser(BAD_CALIBRATION_NOTIFICATION_TAG, NOTIFICATION_ID, 149 UserHandle.CURRENT); 150 } 151 152 } 153