1010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham/* 2010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham * Copyright (C) 2017 The Android Open Source Project 3010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham * 4010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham * Licensed under the Apache License, Version 2.0 (the "License"); 5010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham * you may not use this file except in compliance with the License. 6010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham * You may obtain a copy of the License at 7010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham * 8010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham * http://www.apache.org/licenses/LICENSE-2.0 9010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham * 10010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham * Unless required by applicable law or agreed to in writing, software 11010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham * distributed under the License is distributed on an "AS IS" BASIS, 12010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham * See the License for the specific language governing permissions and 14010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham * limitations under the License. 15010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham */ 16010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham 179438ed414fdabadb4cd09da184867b1c44b91095Tony Wickhampackage com.android.launcher3.notification; 18010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham 19541e13c2652badee856aebc448e578a75229661eRajeev Kumarimport android.annotation.TargetApi; 20010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickhamimport android.app.Notification; 2174884ce164b228afe93f4cae5f0351ec969ed55cTony Wickhamimport android.app.NotificationChannel; 22541e13c2652badee856aebc448e578a75229661eRajeev Kumarimport android.os.Build; 23010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickhamimport android.os.Handler; 24010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickhamimport android.os.Looper; 25010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickhamimport android.os.Message; 26010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickhamimport android.service.notification.NotificationListenerService; 27010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickhamimport android.service.notification.StatusBarNotification; 28010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickhamimport android.support.annotation.Nullable; 2974884ce164b228afe93f4cae5f0351ec969ed55cTony Wickhamimport android.text.TextUtils; 30541e13c2652badee856aebc448e578a75229661eRajeev Kumarimport android.util.ArraySet; 31f423f0a6d440836e968f112e295d85eae8f146caAdam Cohenimport android.util.Log; 32de57cafbb2f30d2255ffc334323b8eb8083dd748Sunny Goyalimport android.util.Pair; 33d48710c2835d891b216914ef1fdd3740e6cfc101Tony 34010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickhamimport com.android.launcher3.LauncherModel; 35010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickhamimport com.android.launcher3.util.PackageUserKey; 36d48710c2835d891b216914ef1fdd3740e6cfc101Tonyimport com.android.launcher3.util.SettingsObserver; 37d48710c2835d891b216914ef1fdd3740e6cfc101Tony 38010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickhamimport java.util.ArrayList; 39010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickhamimport java.util.Arrays; 40010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickhamimport java.util.Collections; 41010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickhamimport java.util.List; 42010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickhamimport java.util.Set; 43010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham 44d48710c2835d891b216914ef1fdd3740e6cfc101Tonyimport static com.android.launcher3.SettingsActivity.NOTIFICATION_BADGING; 45d48710c2835d891b216914ef1fdd3740e6cfc101Tony 46010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham/** 47010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham * A {@link NotificationListenerService} that sends updates to its 48010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham * {@link NotificationsChangedListener} when notifications are posted or canceled, 49010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham * as well and when this service first connects. An instance of NotificationListener, 50be3c7d0c56fe35e8822c4bb5ee22ad44ed504850Tony * and its methods for getting notifications, can be obtained via {@link #getInstanceIfConnected()}. 51010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham */ 52541e13c2652badee856aebc448e578a75229661eRajeev Kumar@TargetApi(Build.VERSION_CODES.O) 53010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickhampublic class NotificationListener extends NotificationListenerService { 54010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham 55f423f0a6d440836e968f112e295d85eae8f146caAdam Cohen public static final String TAG = "NotificationListener"; 56f423f0a6d440836e968f112e295d85eae8f146caAdam Cohen 57010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham private static final int MSG_NOTIFICATION_POSTED = 1; 58010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham private static final int MSG_NOTIFICATION_REMOVED = 2; 59010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham private static final int MSG_NOTIFICATION_FULL_REFRESH = 3; 60010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham 61010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham private static NotificationListener sNotificationListenerInstance = null; 62010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham private static NotificationsChangedListener sNotificationsChangedListener; 63be3c7d0c56fe35e8822c4bb5ee22ad44ed504850Tony private static boolean sIsConnected; 64d48710c2835d891b216914ef1fdd3740e6cfc101Tony private static boolean sIsCreated; 65010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham 66010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham private final Handler mWorkerHandler; 67010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham private final Handler mUiHandler; 68541e13c2652badee856aebc448e578a75229661eRajeev Kumar private final Ranking mTempRanking = new Ranking(); 69d670b995d28615113687e432f6c098aa4cf7b303Tony Wickham 70d48710c2835d891b216914ef1fdd3740e6cfc101Tony private SettingsObserver mNotificationBadgingObserver; 71d48710c2835d891b216914ef1fdd3740e6cfc101Tony 72541e13c2652badee856aebc448e578a75229661eRajeev Kumar private final Handler.Callback mWorkerCallback = new Handler.Callback() { 73010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham @Override 74010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham public boolean handleMessage(Message message) { 75010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham switch (message.what) { 76010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham case MSG_NOTIFICATION_POSTED: 77010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham mUiHandler.obtainMessage(message.what, message.obj).sendToTarget(); 78010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham break; 79010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham case MSG_NOTIFICATION_REMOVED: 80010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham mUiHandler.obtainMessage(message.what, message.obj).sendToTarget(); 81010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham break; 82010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham case MSG_NOTIFICATION_FULL_REFRESH: 83f423f0a6d440836e968f112e295d85eae8f146caAdam Cohen List<StatusBarNotification> activeNotifications; 84f423f0a6d440836e968f112e295d85eae8f146caAdam Cohen if (sIsConnected) { 85f423f0a6d440836e968f112e295d85eae8f146caAdam Cohen try { 86d48710c2835d891b216914ef1fdd3740e6cfc101Tony activeNotifications = filterNotifications(getActiveNotifications()); 87f423f0a6d440836e968f112e295d85eae8f146caAdam Cohen } catch (SecurityException ex) { 88f423f0a6d440836e968f112e295d85eae8f146caAdam Cohen Log.e(TAG, "SecurityException: failed to fetch notifications"); 89f423f0a6d440836e968f112e295d85eae8f146caAdam Cohen activeNotifications = new ArrayList<StatusBarNotification>(); 90f423f0a6d440836e968f112e295d85eae8f146caAdam Cohen 91f423f0a6d440836e968f112e295d85eae8f146caAdam Cohen } 92f423f0a6d440836e968f112e295d85eae8f146caAdam Cohen } else { 93f423f0a6d440836e968f112e295d85eae8f146caAdam Cohen activeNotifications = new ArrayList<StatusBarNotification>(); 94f423f0a6d440836e968f112e295d85eae8f146caAdam Cohen } 95f423f0a6d440836e968f112e295d85eae8f146caAdam Cohen 96010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham mUiHandler.obtainMessage(message.what, activeNotifications).sendToTarget(); 97010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham break; 98010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham } 99010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham return true; 100010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham } 101010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham }; 102010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham 103541e13c2652badee856aebc448e578a75229661eRajeev Kumar private final Handler.Callback mUiCallback = new Handler.Callback() { 104010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham @Override 105010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham public boolean handleMessage(Message message) { 106010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham switch (message.what) { 107010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham case MSG_NOTIFICATION_POSTED: 108010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham if (sNotificationsChangedListener != null) { 109988f34b7f2bb7e57d99ec19fbe9b7024da1fe52fTony Wickham NotificationPostedMsg msg = (NotificationPostedMsg) message.obj; 110988f34b7f2bb7e57d99ec19fbe9b7024da1fe52fTony Wickham sNotificationsChangedListener.onNotificationPosted(msg.packageUserKey, 111988f34b7f2bb7e57d99ec19fbe9b7024da1fe52fTony Wickham msg.notificationKey, msg.shouldBeFilteredOut); 112010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham } 113010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham break; 114010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham case MSG_NOTIFICATION_REMOVED: 115010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham if (sNotificationsChangedListener != null) { 1162f5bb169154d25bc8c164f057117fb056ad2de96Tony Wickham Pair<PackageUserKey, NotificationKeyData> pair 1172f5bb169154d25bc8c164f057117fb056ad2de96Tony Wickham = (Pair<PackageUserKey, NotificationKeyData>) message.obj; 118010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham sNotificationsChangedListener.onNotificationRemoved(pair.first, pair.second); 119010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham } 120010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham break; 121010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham case MSG_NOTIFICATION_FULL_REFRESH: 122010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham if (sNotificationsChangedListener != null) { 123010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham sNotificationsChangedListener.onNotificationFullRefresh( 124010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham (List<StatusBarNotification>) message.obj); 125010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham } 126010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham break; 127010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham } 128010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham return true; 129010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham } 130010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham }; 131010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham 132010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham public NotificationListener() { 133010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham super(); 134010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham mWorkerHandler = new Handler(LauncherModel.getWorkerLooper(), mWorkerCallback); 135010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham mUiHandler = new Handler(Looper.getMainLooper(), mUiCallback); 136be3c7d0c56fe35e8822c4bb5ee22ad44ed504850Tony sNotificationListenerInstance = this; 137010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham } 138010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham 139d48710c2835d891b216914ef1fdd3740e6cfc101Tony @Override 140d48710c2835d891b216914ef1fdd3740e6cfc101Tony public void onCreate() { 141d48710c2835d891b216914ef1fdd3740e6cfc101Tony super.onCreate(); 142d48710c2835d891b216914ef1fdd3740e6cfc101Tony sIsCreated = true; 143d48710c2835d891b216914ef1fdd3740e6cfc101Tony mNotificationBadgingObserver = new SettingsObserver.Secure(getContentResolver()) { 144d48710c2835d891b216914ef1fdd3740e6cfc101Tony @Override 145d48710c2835d891b216914ef1fdd3740e6cfc101Tony public void onSettingChanged(boolean isNotificationBadgingEnabled) { 146d48710c2835d891b216914ef1fdd3740e6cfc101Tony if (!isNotificationBadgingEnabled) { 147d48710c2835d891b216914ef1fdd3740e6cfc101Tony requestUnbind(); 148d48710c2835d891b216914ef1fdd3740e6cfc101Tony } 149d48710c2835d891b216914ef1fdd3740e6cfc101Tony } 150d48710c2835d891b216914ef1fdd3740e6cfc101Tony }; 151d48710c2835d891b216914ef1fdd3740e6cfc101Tony mNotificationBadgingObserver.register(NOTIFICATION_BADGING); 152d48710c2835d891b216914ef1fdd3740e6cfc101Tony } 153d48710c2835d891b216914ef1fdd3740e6cfc101Tony 154d48710c2835d891b216914ef1fdd3740e6cfc101Tony @Override 155d48710c2835d891b216914ef1fdd3740e6cfc101Tony public void onDestroy() { 156d48710c2835d891b216914ef1fdd3740e6cfc101Tony super.onDestroy(); 157d48710c2835d891b216914ef1fdd3740e6cfc101Tony sIsCreated = false; 158d48710c2835d891b216914ef1fdd3740e6cfc101Tony mNotificationBadgingObserver.unregister(); 159d48710c2835d891b216914ef1fdd3740e6cfc101Tony } 160d48710c2835d891b216914ef1fdd3740e6cfc101Tony 161be3c7d0c56fe35e8822c4bb5ee22ad44ed504850Tony public static @Nullable NotificationListener getInstanceIfConnected() { 162be3c7d0c56fe35e8822c4bb5ee22ad44ed504850Tony return sIsConnected ? sNotificationListenerInstance : null; 163010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham } 164010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham 165010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham public static void setNotificationsChangedListener(NotificationsChangedListener listener) { 166010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham sNotificationsChangedListener = listener; 167010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham 168cba189344d82753ccce0cc5479771c5a78e85c56Tony Wickham NotificationListener notificationListener = getInstanceIfConnected(); 169cba189344d82753ccce0cc5479771c5a78e85c56Tony Wickham if (notificationListener != null) { 170cba189344d82753ccce0cc5479771c5a78e85c56Tony Wickham notificationListener.onNotificationFullRefresh(); 171d48710c2835d891b216914ef1fdd3740e6cfc101Tony } else if (!sIsCreated && sNotificationsChangedListener != null) { 172d48710c2835d891b216914ef1fdd3740e6cfc101Tony // User turned off badging globally, so we unbound this service; 173d48710c2835d891b216914ef1fdd3740e6cfc101Tony // tell the listener that there are no notifications to remove dots. 174d48710c2835d891b216914ef1fdd3740e6cfc101Tony sNotificationsChangedListener.onNotificationFullRefresh( 175d48710c2835d891b216914ef1fdd3740e6cfc101Tony Collections.<StatusBarNotification>emptyList()); 176010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham } 177010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham } 178010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham 179010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham public static void removeNotificationsChangedListener() { 180010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham sNotificationsChangedListener = null; 181010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham } 182010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham 183010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham @Override 184010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham public void onListenerConnected() { 185010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham super.onListenerConnected(); 186be3c7d0c56fe35e8822c4bb5ee22ad44ed504850Tony sIsConnected = true; 187010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham onNotificationFullRefresh(); 188010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham } 189010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham 190010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham private void onNotificationFullRefresh() { 191010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham mWorkerHandler.obtainMessage(MSG_NOTIFICATION_FULL_REFRESH).sendToTarget(); 192010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham } 193010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham 194010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham @Override 195010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham public void onListenerDisconnected() { 196010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham super.onListenerDisconnected(); 197be3c7d0c56fe35e8822c4bb5ee22ad44ed504850Tony sIsConnected = false; 198010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham } 199010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham 200010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham @Override 201010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham public void onNotificationPosted(final StatusBarNotification sbn) { 202010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham super.onNotificationPosted(sbn); 203988f34b7f2bb7e57d99ec19fbe9b7024da1fe52fTony Wickham mWorkerHandler.obtainMessage(MSG_NOTIFICATION_POSTED, new NotificationPostedMsg(sbn)) 204988f34b7f2bb7e57d99ec19fbe9b7024da1fe52fTony Wickham .sendToTarget(); 205988f34b7f2bb7e57d99ec19fbe9b7024da1fe52fTony Wickham } 206988f34b7f2bb7e57d99ec19fbe9b7024da1fe52fTony Wickham 207988f34b7f2bb7e57d99ec19fbe9b7024da1fe52fTony Wickham /** 208988f34b7f2bb7e57d99ec19fbe9b7024da1fe52fTony Wickham * An object containing data to send to MSG_NOTIFICATION_POSTED targets. 209988f34b7f2bb7e57d99ec19fbe9b7024da1fe52fTony Wickham */ 210988f34b7f2bb7e57d99ec19fbe9b7024da1fe52fTony Wickham private class NotificationPostedMsg { 211541e13c2652badee856aebc448e578a75229661eRajeev Kumar final PackageUserKey packageUserKey; 212541e13c2652badee856aebc448e578a75229661eRajeev Kumar final NotificationKeyData notificationKey; 213541e13c2652badee856aebc448e578a75229661eRajeev Kumar final boolean shouldBeFilteredOut; 214988f34b7f2bb7e57d99ec19fbe9b7024da1fe52fTony Wickham 215988f34b7f2bb7e57d99ec19fbe9b7024da1fe52fTony Wickham NotificationPostedMsg(StatusBarNotification sbn) { 216988f34b7f2bb7e57d99ec19fbe9b7024da1fe52fTony Wickham packageUserKey = PackageUserKey.fromNotification(sbn); 2172f5bb169154d25bc8c164f057117fb056ad2de96Tony Wickham notificationKey = NotificationKeyData.fromNotification(sbn); 218d670b995d28615113687e432f6c098aa4cf7b303Tony Wickham shouldBeFilteredOut = shouldBeFilteredOut(sbn); 219010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham } 220010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham } 221010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham 222010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham @Override 223010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham public void onNotificationRemoved(final StatusBarNotification sbn) { 224010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham super.onNotificationRemoved(sbn); 2252f5bb169154d25bc8c164f057117fb056ad2de96Tony Wickham Pair<PackageUserKey, NotificationKeyData> packageUserKeyAndNotificationKey 2262f5bb169154d25bc8c164f057117fb056ad2de96Tony Wickham = new Pair<>(PackageUserKey.fromNotification(sbn), 2272f5bb169154d25bc8c164f057117fb056ad2de96Tony Wickham NotificationKeyData.fromNotification(sbn)); 228988f34b7f2bb7e57d99ec19fbe9b7024da1fe52fTony Wickham mWorkerHandler.obtainMessage(MSG_NOTIFICATION_REMOVED, packageUserKeyAndNotificationKey) 229988f34b7f2bb7e57d99ec19fbe9b7024da1fe52fTony Wickham .sendToTarget(); 230010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham } 231010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham 232010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham /** This makes a potentially expensive binder call and should be run on a background thread. */ 2332f5bb169154d25bc8c164f057117fb056ad2de96Tony Wickham public List<StatusBarNotification> getNotificationsForKeys(List<NotificationKeyData> keys) { 234010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham StatusBarNotification[] notifications = NotificationListener.this 2352f5bb169154d25bc8c164f057117fb056ad2de96Tony Wickham .getActiveNotifications(NotificationKeyData.extractKeysOnly(keys) 2362f5bb169154d25bc8c164f057117fb056ad2de96Tony Wickham .toArray(new String[keys.size()])); 237541e13c2652badee856aebc448e578a75229661eRajeev Kumar return notifications == null 238d48710c2835d891b216914ef1fdd3740e6cfc101Tony ? Collections.<StatusBarNotification>emptyList() : Arrays.asList(notifications); 239010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham } 240010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham 241010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham /** 242010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham * Filter out notifications that don't have an intent 243010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham * or are headers for grouped notifications. 244010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham * 245d670b995d28615113687e432f6c098aa4cf7b303Tony Wickham * @see #shouldBeFilteredOut(StatusBarNotification) 246010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham */ 247010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham private List<StatusBarNotification> filterNotifications( 248010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham StatusBarNotification[] notifications) { 249010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham if (notifications == null) return null; 250541e13c2652badee856aebc448e578a75229661eRajeev Kumar Set<Integer> removedNotifications = new ArraySet<>(); 251010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham for (int i = 0; i < notifications.length; i++) { 252d670b995d28615113687e432f6c098aa4cf7b303Tony Wickham if (shouldBeFilteredOut(notifications[i])) { 253010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham removedNotifications.add(i); 254010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham } 255010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham } 256010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham List<StatusBarNotification> filteredNotifications = new ArrayList<>( 257010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham notifications.length - removedNotifications.size()); 258010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham for (int i = 0; i < notifications.length; i++) { 259010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham if (!removedNotifications.contains(i)) { 260010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham filteredNotifications.add(notifications[i]); 261010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham } 262010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham } 263010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham return filteredNotifications; 264010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham } 265010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham 266d670b995d28615113687e432f6c098aa4cf7b303Tony Wickham private boolean shouldBeFilteredOut(StatusBarNotification sbn) { 2675632e183f335470cbe0f0d1018a2b5b99f9d41c6Tony Wickham getCurrentRanking().getRanking(sbn.getKey(), mTempRanking); 2685632e183f335470cbe0f0d1018a2b5b99f9d41c6Tony Wickham if (!mTempRanking.canShowBadge()) { 2695632e183f335470cbe0f0d1018a2b5b99f9d41c6Tony Wickham return true; 270d670b995d28615113687e432f6c098aa4cf7b303Tony Wickham } 271d670b995d28615113687e432f6c098aa4cf7b303Tony Wickham Notification notification = sbn.getNotification(); 27274884ce164b228afe93f4cae5f0351ec969ed55cTony Wickham if (mTempRanking.getChannel().getId().equals(NotificationChannel.DEFAULT_CHANNEL_ID)) { 27374884ce164b228afe93f4cae5f0351ec969ed55cTony Wickham // Special filtering for the default, legacy "Miscellaneous" channel. 27474884ce164b228afe93f4cae5f0351ec969ed55cTony Wickham if ((notification.flags & Notification.FLAG_ONGOING_EVENT) != 0) { 27574884ce164b228afe93f4cae5f0351ec969ed55cTony Wickham return true; 27674884ce164b228afe93f4cae5f0351ec969ed55cTony Wickham } 27774884ce164b228afe93f4cae5f0351ec969ed55cTony Wickham } 278010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham boolean isGroupHeader = (notification.flags & Notification.FLAG_GROUP_SUMMARY) != 0; 27974884ce164b228afe93f4cae5f0351ec969ed55cTony Wickham CharSequence title = notification.extras.getCharSequence(Notification.EXTRA_TITLE); 28074884ce164b228afe93f4cae5f0351ec969ed55cTony Wickham CharSequence text = notification.extras.getCharSequence(Notification.EXTRA_TEXT); 28144410552339377f55a98b32dbadb4f7cf3aa8d83Tony Wickham boolean missingTitleAndText = TextUtils.isEmpty(title) && TextUtils.isEmpty(text); 28244410552339377f55a98b32dbadb4f7cf3aa8d83Tony Wickham return (isGroupHeader || missingTitleAndText); 283010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham } 284010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham 285010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham public interface NotificationsChangedListener { 2862f5bb169154d25bc8c164f057117fb056ad2de96Tony Wickham void onNotificationPosted(PackageUserKey postedPackageUserKey, 2872f5bb169154d25bc8c164f057117fb056ad2de96Tony Wickham NotificationKeyData notificationKey, boolean shouldBeFilteredOut); 2882f5bb169154d25bc8c164f057117fb056ad2de96Tony Wickham void onNotificationRemoved(PackageUserKey removedPackageUserKey, 2892f5bb169154d25bc8c164f057117fb056ad2de96Tony Wickham NotificationKeyData notificationKey); 290010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham void onNotificationFullRefresh(List<StatusBarNotification> activeNotifications); 291010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham } 292010d2550184179785e4467ff1ffb4f4f4e850ec2Tony Wickham} 293