1 /* 2 * Copyright (C) 2018 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.notification; 18 19 import android.app.Notification; 20 import android.content.Context; 21 import android.content.pm.PackageManager; 22 import android.util.Slog; 23 24 /** 25 * Sets the criticality of a notification record. This is used to allow a bypass to all other 26 * ranking signals. It is required in the automotive use case to facilitate placing emergency and 27 * warning notifications above all others. It does not process notifications unless the system 28 * has the automotive feature flag set. 29 * <p> 30 * Note: it is up to the notification ranking system to determine the effect of criticality values 31 * on a notification record 32 * 33 */ 34 public class CriticalNotificationExtractor implements NotificationSignalExtractor { 35 36 private static final String TAG = "CriticalNotificationExt"; 37 private static final boolean DBG = false; 38 private boolean mSupportsCriticalNotifications = false; 39 /** 40 * Intended to bypass all other ranking, notification should be placed above all others. 41 * In the automotive case, the notification would be used to tell a driver to pull over 42 * immediately 43 */ 44 static final int CRITICAL = 0; 45 /** 46 * Indicates a notification should be place above all notifications except those marked as 47 * critical. In the automotive case this is a check engine light. 48 */ 49 static final int CRITICAL_LOW = 1; 50 /** Normal notification. */ 51 static final int NORMAL = 2; 52 53 @Override initialize(Context context, NotificationUsageStats usageStats)54 public void initialize(Context context, NotificationUsageStats usageStats) { 55 if (DBG) Slog.d(TAG, "Initializing " + getClass().getSimpleName() + "."); 56 mSupportsCriticalNotifications = supportsCriticalNotifications(context); 57 } 58 supportsCriticalNotifications(Context context)59 private boolean supportsCriticalNotifications(Context context) { 60 return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, 0); 61 } 62 63 @Override process(NotificationRecord record)64 public RankingReconsideration process(NotificationRecord record) { 65 if (!mSupportsCriticalNotifications) { 66 if (DBG) Slog.d(TAG, "skipping since system does not support critical notification"); 67 return null; 68 } 69 if (record == null || record.getNotification() == null) { 70 if (DBG) Slog.d(TAG, "skipping empty notification"); 71 return null; 72 } 73 // Note: The use of both CATEGORY_CAR_EMERGENCY and CATEGORY_CAR_WARNING is restricted to 74 // System apps 75 if (record.isCategory(Notification.CATEGORY_CAR_EMERGENCY)) { 76 record.setCriticality(CRITICAL); 77 } else if (record.isCategory(Notification.CATEGORY_CAR_WARNING)) { 78 record.setCriticality(CRITICAL_LOW); 79 } else { 80 record.setCriticality(NORMAL); 81 } 82 return null; 83 } 84 85 @Override setConfig(RankingConfig config)86 public void setConfig(RankingConfig config) { 87 } 88 89 @Override setZenHelper(ZenModeHelper helper)90 public void setZenHelper(ZenModeHelper helper) { 91 } 92 93 } 94