NotificationListenerService.java revision 0efdb88ccc9d650e7a644b9be8f63792f2c66841
1894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/* 2894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Copyright (C) 2013 The Android Open Source Project 3894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 4894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Licensed under the Apache License, Version 2.0 (the "License"); 5894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * you may not use this file except in compliance with the License. 6894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * You may obtain a copy of the License at 7894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 8894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * http://www.apache.org/licenses/LICENSE-2.0 9894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 10894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Unless required by applicable law or agreed to in writing, software 11894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * distributed under the License is distributed on an "AS IS" BASIS, 12894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * See the License for the specific language governing permissions and 14894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * limitations under the License. 15894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 16894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanpackage android.service.notification; 1819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 1919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanimport android.os.Handler; 20894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanimport android.os.Looper; 21894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanimport android.os.Message; 22894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 23894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanimport android.annotation.IntDef; 24894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanimport android.annotation.SystemApi; 25894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanimport android.annotation.SdkConstant; 26894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanimport android.app.INotificationManager; 27894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanimport android.app.Notification; 28894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanimport android.app.Notification.Builder; 29894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanimport android.app.NotificationManager; 30894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanimport android.app.Service; 31894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanimport android.content.ComponentName; 32894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanimport android.content.Context; 33894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanimport android.content.Intent; 34894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanimport android.content.pm.ParceledListSlice; 35894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanimport android.graphics.drawable.BitmapDrawable; 36894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanimport android.graphics.drawable.Drawable; 37894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanimport android.graphics.drawable.Icon; 38894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanimport android.graphics.Bitmap; 39894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanimport android.os.Build; 40894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanimport android.os.Bundle; 41894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanimport android.os.IBinder; 42894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanimport android.os.Parcel; 43894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanimport android.os.Parcelable; 44894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanimport android.os.RemoteException; 4519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanimport android.os.ServiceManager; 4619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanimport android.util.ArrayMap; 47894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanimport android.util.ArraySet; 48894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanimport android.util.Log; 49894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanimport android.widget.RemoteViews; 50894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanimport com.android.internal.annotations.GuardedBy; 51894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanimport com.android.internal.os.SomeArgs; 52894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanimport java.lang.annotation.Retention; 53894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanimport java.lang.annotation.RetentionPolicy; 54894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanimport java.util.ArrayList; 55894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanimport java.util.Collections; 56894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanimport java.util.List; 57894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 58894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/** 59894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * A service that receives calls from the system when new notifications are 60894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * posted or removed, or their ranking changed. 61894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * <p>To extend this class, you must declare the service in your manifest file with 62894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * the {@link android.Manifest.permission#BIND_NOTIFICATION_LISTENER_SERVICE} permission 63894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * and include an intent filter with the {@link #SERVICE_INTERFACE} action. For example:</p> 64894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * <pre> 65894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * <service android:name=".NotificationListener" 66894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * android:label="@string/service_name" 67894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"> 68894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * <intent-filter> 69894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * <action android:name="android.service.notification.NotificationListenerService" /> 70894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * </intent-filter> 71894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * </service></pre> 72894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * <p> Typically, while enabled in user settings, this service will be bound on boot or when a 73894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * settings change occurs that could affect whether this service should run. However, for some 74894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * system usage modes, the you may instead specify that this service is instead bound and unbound 75894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * in response to mode changes by including a category in the intent filter. Currently 76894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * supported categories are: 77894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * <ul> 78894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * <li>{@link #CATEGORY_VR_NOTIFICATIONS} - this service is bound when an Activity has enabled 79894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * VR mode. {@see android.app.Activity#setVrMode(boolean)}.</li> 80894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * </ul> 81894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * </p> 82894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 83894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic abstract class NotificationListenerService extends Service { 84894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // TAG = "NotificationListenerService[MySubclass]" 85894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman private final String TAG = NotificationListenerService.class.getSimpleName() 86894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman + "[" + getClass().getSimpleName() + "]"; 87894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 88894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** 89894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * {@link #getCurrentInterruptionFilter() Interruption filter} constant - 90894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Normal interruption filter. 91894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 92894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public static final int INTERRUPTION_FILTER_ALL 93894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman = NotificationManager.INTERRUPTION_FILTER_ALL; 94894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 95894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** 96894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * {@link #getCurrentInterruptionFilter() Interruption filter} constant - 97894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Priority interruption filter. 98894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 99894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public static final int INTERRUPTION_FILTER_PRIORITY 100894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman = NotificationManager.INTERRUPTION_FILTER_PRIORITY; 101894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 102894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** 103894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * {@link #getCurrentInterruptionFilter() Interruption filter} constant - 104894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * No interruptions filter. 105894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 106894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public static final int INTERRUPTION_FILTER_NONE 107894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman = NotificationManager.INTERRUPTION_FILTER_NONE; 108894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 109894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** 110894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * {@link #getCurrentInterruptionFilter() Interruption filter} constant - 111894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Alarms only interruption filter. 112894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 113894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public static final int INTERRUPTION_FILTER_ALARMS 114894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman = NotificationManager.INTERRUPTION_FILTER_ALARMS; 115894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 116894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** {@link #getCurrentInterruptionFilter() Interruption filter} constant - returned when 117894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * the value is unavailable for any reason. For example, before the notification listener 118894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * is connected. 119894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 120894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * {@see #onListenerConnected()} 121894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 122894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public static final int INTERRUPTION_FILTER_UNKNOWN 123894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman = NotificationManager.INTERRUPTION_FILTER_UNKNOWN; 124894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 125894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** {@link #getCurrentListenerHints() Listener hints} constant - the primary device UI 12619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman * should disable notification sound, vibrating and other visual or aural effects. 12719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman * This does not change the interruption filter, only the effects. **/ 128894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public static final int HINT_HOST_DISABLE_EFFECTS = 1; 129894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 130894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** 13119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman * Whether notification suppressed by DND should not interruption visually when the screen is 132894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * off. 133894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 134894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public static final int SUPPRESSED_EFFECT_SCREEN_OFF = 13519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_OFF; 13619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman /** 13719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman * Whether notification suppressed by DND should not interruption visually when the screen is 138894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * on. 139894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 140894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public static final int SUPPRESSED_EFFECT_SCREEN_ON = 141894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_ON; 142894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 143894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** 144894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * The full trim of the StatusBarNotification including all its features. 145894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 146894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @hide 147894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 148894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman @SystemApi 149894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public static final int TRIM_FULL = 0; 150894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 151894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** 152894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * A light trim of the StatusBarNotification excluding the following features: 153894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 154894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * <ol> 155894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * <li>{@link Notification#tickerView tickerView}</li> 156894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * <li>{@link Notification#contentView contentView}</li> 157894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * <li>{@link Notification#largeIcon largeIcon}</li> 158894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * <li>{@link Notification#bigContentView bigContentView}</li> 159894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * <li>{@link Notification#headsUpContentView headsUpContentView}</li> 160894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * <li>{@link Notification#EXTRA_LARGE_ICON extras[EXTRA_LARGE_ICON]}</li> 161894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * <li>{@link Notification#EXTRA_LARGE_ICON_BIG extras[EXTRA_LARGE_ICON_BIG]}</li> 162894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * <li>{@link Notification#EXTRA_PICTURE extras[EXTRA_PICTURE]}</li> 163894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * <li>{@link Notification#EXTRA_BIG_TEXT extras[EXTRA_BIG_TEXT]}</li> 164894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * </ol> 165894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 166894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @hide 167894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 168894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman @SystemApi 169894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public static final int TRIM_LIGHT = 1; 170894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 171894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman private final Object mLock = new Object(); 172894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 173894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman private Handler mHandler; 174894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 175894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** @hide */ 176894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman protected NotificationListenerWrapper mWrapper = null; 177894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 178894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman @GuardedBy("mLock") 179894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman private RankingMap mRankingMap; 180894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 181894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman private INotificationManager mNoMan; 182894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 183894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** 184894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Only valid after a successful call to (@link registerAsService}. 185894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @hide 186894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 187894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman protected int mCurrentUser; 188894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 189894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** 190894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * This context is required for system services since NotificationListenerService isn't 191894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * started as a real Service and hence no context is available.. 192894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @hide 193894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 194894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman protected Context mSystemContext; 195894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 196894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** 197894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * The {@link Intent} that must be declared as handled by the service. 198894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 199894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION) 200894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public static final String SERVICE_INTERFACE 201894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman = "android.service.notification.NotificationListenerService"; 202894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 203894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** 204894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * If this category is declared in the application manifest for a service of this type, this 205894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * service will be bound when VR mode is enabled, and unbound when VR mode is disabled rather 206894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * than the normal lifecycle for a notification service. 207894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 208894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * {@see android.app.Activity#setVrMode(boolean)} 209894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 210894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman @SdkConstant(SdkConstant.SdkConstantType.INTENT_CATEGORY) 211894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public static final String CATEGORY_VR_NOTIFICATIONS = 212894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "android.intent.category.vr.notifications"; 213894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 214894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman @Override 215894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman protected void attachBaseContext(Context base) { 216894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman super.attachBaseContext(base); 217894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman mHandler = new MyHandler(getMainLooper()); 218894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 219894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 220894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** 221894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Implement this method to learn about new notifications as they are posted by apps. 222894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 223894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @param sbn A data structure encapsulating the original {@link android.app.Notification} 224894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * object as well as its identifying information (tag and id) and source 225894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * (package name). 226894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 227894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public void onNotificationPosted(StatusBarNotification sbn) { 228894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // optional 229894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 230894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 231894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** 232894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Implement this method to learn about new notifications as they are posted by apps. 233894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 234894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @param sbn A data structure encapsulating the original {@link android.app.Notification} 235894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * object as well as its identifying information (tag and id) and source 236894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * (package name). 237894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @param rankingMap The current ranking map that can be used to retrieve ranking information 238894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * for active notifications, including the newly posted one. 239894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 240894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public void onNotificationPosted(StatusBarNotification sbn, RankingMap rankingMap) { 241894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman onNotificationPosted(sbn); 242894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 243894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 244894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** 245894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Implement this method to learn when notifications are removed. 246894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * <P> 247894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * This might occur because the user has dismissed the notification using system UI (or another 248894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * notification listener) or because the app has withdrawn the notification. 249894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * <P> 250894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * NOTE: The {@link StatusBarNotification} object you receive will be "light"; that is, the 251894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * result from {@link StatusBarNotification#getNotification} may be missing some heavyweight 252894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * fields such as {@link android.app.Notification#contentView} and 253894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * {@link android.app.Notification#largeIcon}. However, all other fields on 254894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * {@link StatusBarNotification}, sufficient to match this call with a prior call to 255894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * {@link #onNotificationPosted(StatusBarNotification)}, will be intact. 256894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 257894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @param sbn A data structure encapsulating at least the original information (tag and id) 258894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * and source (package name) used to post the {@link android.app.Notification} that 259894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * was just removed. 260894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 261894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public void onNotificationRemoved(StatusBarNotification sbn) { 262894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // optional 263894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 264894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 265894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** 266894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Implement this method to learn when notifications are removed. 267894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * <P> 268894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * This might occur because the user has dismissed the notification using system UI (or another 269894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * notification listener) or because the app has withdrawn the notification. 270894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * <P> 271894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * NOTE: The {@link StatusBarNotification} object you receive will be "light"; that is, the 272894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * result from {@link StatusBarNotification#getNotification} may be missing some heavyweight 273894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * fields such as {@link android.app.Notification#contentView} and 274894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * {@link android.app.Notification#largeIcon}. However, all other fields on 275894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * {@link StatusBarNotification}, sufficient to match this call with a prior call to 276894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * {@link #onNotificationPosted(StatusBarNotification)}, will be intact. 277894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 278894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @param sbn A data structure encapsulating at least the original information (tag and id) 279894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * and source (package name) used to post the {@link android.app.Notification} that 280894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * was just removed. 281894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @param rankingMap The current ranking map that can be used to retrieve ranking information 282894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * for active notifications. 283894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 284894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 285894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public void onNotificationRemoved(StatusBarNotification sbn, RankingMap rankingMap) { 286894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman onNotificationRemoved(sbn); 287894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 288894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 289894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** 290894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Implement this method to learn about when the listener is enabled and connected to 291894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * the notification manager. You are safe to call {@link #getActiveNotifications()} 292894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * at this time. 293894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 294894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public void onListenerConnected() { 295894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // optional 296894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 297894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 298894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** 299894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Implement this method to be notified when the notification ranking changes. 300894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 301894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @param rankingMap The current ranking map that can be used to retrieve ranking information 302894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * for active notifications. 303894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 304894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public void onNotificationRankingUpdate(RankingMap rankingMap) { 305894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // optional 306894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 307894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 308894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** 309894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Implement this method to be notified when the 310894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * {@link #getCurrentListenerHints() Listener hints} change. 311894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 312894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @param hints The current {@link #getCurrentListenerHints() listener hints}. 313894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 314894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public void onListenerHintsChanged(int hints) { 315894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // optional 316894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 317894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 318894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** 319894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Implement this method to be notified when the 320894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * {@link #getCurrentInterruptionFilter() interruption filter} changed. 321894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 322894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @param interruptionFilter The current 323894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * {@link #getCurrentInterruptionFilter() interruption filter}. 32419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman */ 32519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman public void onInterruptionFilterChanged(int interruptionFilter) { 32619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // optional 32719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 32819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 32919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman /** @hide */ 330894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman protected final INotificationManager getNotificationInterface() { 331894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (mNoMan == null) { 332894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman mNoMan = INotificationManager.Stub.asInterface( 333894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ServiceManager.getService(Context.NOTIFICATION_SERVICE)); 334894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 335894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return mNoMan; 336894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 337894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 338894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** 339894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Inform the notification manager about dismissal of a single notification. 340894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * <p> 341894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Use this if your listener has a user interface that allows the user to dismiss individual 342894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * notifications, similar to the behavior of Android's status bar and notification panel. 343894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * It should be called after the user dismisses a single notification using your UI; 344894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * upon being informed, the notification manager will actually remove the notification 345894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * and you will get an {@link #onNotificationRemoved(StatusBarNotification)} callback. 346894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * <P> 347894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * <b>Note:</b> If your listener allows the user to fire a notification's 348894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * {@link android.app.Notification#contentIntent} by tapping/clicking/etc., you should call 349894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * this method at that time <i>if</i> the Notification in question has the 350894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * {@link android.app.Notification#FLAG_AUTO_CANCEL} flag set. 351894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 352894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @param pkg Package of the notifying app. 353894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @param tag Tag of the notification as specified by the notifying app in 354894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * {@link android.app.NotificationManager#notify(String, int, android.app.Notification)}. 355894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @param id ID of the notification as specified by the notifying app in 356894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * {@link android.app.NotificationManager#notify(String, int, android.app.Notification)}. 357894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * <p> 358894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @deprecated Use {@link #cancelNotification(String key)} 359894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * instead. Beginning with {@link android.os.Build.VERSION_CODES#LOLLIPOP} this method will no longer 360894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * cancel the notification. It will continue to cancel the notification for applications 361894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * whose {@code targetSdkVersion} is earlier than {@link android.os.Build.VERSION_CODES#LOLLIPOP}. 362894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 363894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public final void cancelNotification(String pkg, String tag, int id) { 364894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!isBound()) return; 365894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman try { 366894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman getNotificationInterface().cancelNotificationFromListener( 367894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman mWrapper, pkg, tag, id); 368894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } catch (android.os.RemoteException ex) { 369894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Log.v(TAG, "Unable to contact notification manager", ex); 370894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 371894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 372894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 373894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** 37419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman * Inform the notification manager about dismissal of a single notification. 37519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman * <p> 37619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman * Use this if your listener has a user interface that allows the user to dismiss individual 37719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman * notifications, similar to the behavior of Android's status bar and notification panel. 37819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman * It should be called after the user dismisses a single notification using your UI; 37919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman * upon being informed, the notification manager will actually remove the notification 38019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman * and you will get an {@link #onNotificationRemoved(StatusBarNotification)} callback. 381894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * <P> 382894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * <b>Note:</b> If your listener allows the user to fire a notification's 383894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * {@link android.app.Notification#contentIntent} by tapping/clicking/etc., you should call 384894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * this method at that time <i>if</i> the Notification in question has the 385894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * {@link android.app.Notification#FLAG_AUTO_CANCEL} flag set. 386894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * <p> 387894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @param key Notification to dismiss from {@link StatusBarNotification#getKey()}. 388894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 389894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public final void cancelNotification(String key) { 390894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!isBound()) return; 391894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman try { 392894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman getNotificationInterface().cancelNotificationsFromListener(mWrapper, 393894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman new String[] { key }); 394894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } catch (android.os.RemoteException ex) { 395894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Log.v(TAG, "Unable to contact notification manager", ex); 396894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 397894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 398894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 399894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** 400894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Inform the notification manager about dismissal of all notifications. 401894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * <p> 402894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Use this if your listener has a user interface that allows the user to dismiss all 403894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * notifications, similar to the behavior of Android's status bar and notification panel. 404894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * It should be called after the user invokes the "dismiss all" function of your UI; 405894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * upon being informed, the notification manager will actually remove all active notifications 406894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * and you will get multiple {@link #onNotificationRemoved(StatusBarNotification)} callbacks. 407894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 408894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * {@see #cancelNotification(String, String, int)} 409894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 410894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public final void cancelAllNotifications() { 411894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman cancelNotifications(null /*all*/); 412894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 413894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 414894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** 415894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Inform the notification manager about dismissal of specific notifications. 416894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * <p> 417894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Use this if your listener has a user interface that allows the user to dismiss 418894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * multiple notifications at once. 419894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 420894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @param keys Notifications to dismiss, or {@code null} to dismiss all. 421894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 422894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * {@see #cancelNotification(String, String, int)} 423894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 424894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public final void cancelNotifications(String[] keys) { 425894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!isBound()) return; 426894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman try { 427894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman getNotificationInterface().cancelNotificationsFromListener(mWrapper, keys); 428894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } catch (android.os.RemoteException ex) { 429894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Log.v(TAG, "Unable to contact notification manager", ex); 430894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 431894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 432894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 433894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** 434894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Inform the notification manager that these notifications have been viewed by the 435894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * user. This should only be called when there is sufficient confidence that the user is 436894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * looking at the notifications, such as when the notifications appear on the screen due to 437894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * an explicit user interaction. 438894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @param keys Notifications to mark as seen. 439894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 440894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public final void setNotificationsShown(String[] keys) { 441894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!isBound()) return; 442894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman try { 443894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman getNotificationInterface().setNotificationsShownFromListener(mWrapper, keys); 444894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } catch (android.os.RemoteException ex) { 445894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Log.v(TAG, "Unable to contact notification manager", ex); 446894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 447894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 448894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 449894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** 450894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Sets the notification trim that will be received via {@link #onNotificationPosted}. 451894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 452894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * <p> 453894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Setting a trim other than {@link #TRIM_FULL} enables listeners that don't need access to the 454894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * full notification features right away to reduce their memory footprint. Full notifications 455894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * can be requested on-demand via {@link #getActiveNotifications(int)}. 456894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 457894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * <p> 458894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Set to {@link #TRIM_FULL} initially. 459894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 460894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @hide 461894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 462894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @param trim trim of the notifications to be passed via {@link #onNotificationPosted}. 463894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * See <code>TRIM_*</code> constants. 464894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 465894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman @SystemApi 466894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public final void setOnNotificationPostedTrim(int trim) { 46719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!isBound()) return; 468894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman try { 469894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman getNotificationInterface().setOnNotificationPostedTrimFromListener(mWrapper, trim); 470894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } catch (RemoteException ex) { 471894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Log.v(TAG, "Unable to contact notification manager", ex); 472894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 473894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 474894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 475894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** 476894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Request the list of outstanding notifications (that is, those that are visible to the 477894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * current user). Useful when you don't know what's already been posted. 478894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 479894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @return An array of active notifications, sorted in natural order. 480894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 481894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public StatusBarNotification[] getActiveNotifications() { 482894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return getActiveNotifications(null, TRIM_FULL); 483894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 484894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 485894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** 486894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Request the list of outstanding notifications (that is, those that are visible to the 487894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * current user). Useful when you don't know what's already been posted. 488894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 489894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @hide 490894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 491894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @param trim trim of the notifications to be returned. See <code>TRIM_*</code> constants. 492894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @return An array of active notifications, sorted in natural order. 493894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 494894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman @SystemApi 495894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public StatusBarNotification[] getActiveNotifications(int trim) { 496894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return getActiveNotifications(null, trim); 497894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 498894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 499894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** 500894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Request one or more notifications by key. Useful if you have been keeping track of 501894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * notifications but didn't want to retain the bits, and now need to go back and extract 502894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * more data out of those notifications. 503894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 504894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @param keys the keys of the notifications to request 505894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @return An array of notifications corresponding to the requested keys, in the 506894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * same order as the key list. 507894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 508894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public StatusBarNotification[] getActiveNotifications(String[] keys) { 509894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return getActiveNotifications(keys, TRIM_FULL); 510894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 511894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 512894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** 513894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Request one or more notifications by key. Useful if you have been keeping track of 514894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * notifications but didn't want to retain the bits, and now need to go back and extract 515894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * more data out of those notifications. 516894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 517894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @hide 518894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 519894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @param keys the keys of the notifications to request 520894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @param trim trim of the notifications to be returned. See <code>TRIM_*</code> constants. 521894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @return An array of notifications corresponding to the requested keys, in the 522894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * same order as the key list. 523894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 524894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman @SystemApi 525894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public StatusBarNotification[] getActiveNotifications(String[] keys, int trim) { 526894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!isBound()) 527894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return null; 528894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman try { 529894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ParceledListSlice<StatusBarNotification> parceledList = getNotificationInterface() 530894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman .getActiveNotificationsFromListener(mWrapper, keys, trim); 531894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman List<StatusBarNotification> list = parceledList.getList(); 532894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ArrayList<StatusBarNotification> corruptNotifications = null; 533894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int N = list.size(); 534894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (int i = 0; i < N; i++) { 535894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman StatusBarNotification sbn = list.get(i); 536894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Notification notification = sbn.getNotification(); 537894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman try { 538894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // convert icon metadata to legacy format for older clients 539894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman createLegacyIconExtras(notification); 540894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // populate remote views for older clients. 541894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman maybePopulateRemoteViews(notification); 542894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } catch (IllegalArgumentException e) { 543894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (corruptNotifications == null) { 544894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman corruptNotifications = new ArrayList<>(N); 545894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 546894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman corruptNotifications.add(sbn); 547894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Log.w(TAG, "onNotificationPosted: can't rebuild notification from " + 548894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman sbn.getPackageName()); 549894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 550894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 551894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (corruptNotifications != null) { 552894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman list.removeAll(corruptNotifications); 553894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 554894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return list.toArray(new StatusBarNotification[list.size()]); 555894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } catch (android.os.RemoteException ex) { 556894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Log.v(TAG, "Unable to contact notification manager", ex); 557894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 558894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return null; 559894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 560894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 561894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** 562894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Gets the set of hints representing current state. 563894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 564894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * <p> 565894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * The current state may differ from the requested state if the hint represents state 566894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * shared across all listeners or a feature the notification host does not support or refuses 567894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * to grant. 568894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 569894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @return Zero or more of the HINT_ constants. 570894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 571894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public final int getCurrentListenerHints() { 572894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!isBound()) return 0; 573894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman try { 574894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return getNotificationInterface().getHintsFromListener(mWrapper); 575894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } catch (android.os.RemoteException ex) { 576894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Log.v(TAG, "Unable to contact notification manager", ex); 577894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return 0; 578894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 579894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 580894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 581894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** 582894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Gets the current notification interruption filter active on the host. 583894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 584894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * <p> 585894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * The interruption filter defines which notifications are allowed to interrupt the user 586894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * (e.g. via sound & vibration) and is applied globally. Listeners can find out whether 587894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * a specific notification matched the interruption filter via 588894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * {@link Ranking#matchesInterruptionFilter()}. 589894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * <p> 590894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * The current filter may differ from the previously requested filter if the notification host 591894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * does not support or refuses to apply the requested filter, or if another component changed 592894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * the filter in the meantime. 593894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * <p> 594894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Listen for updates using {@link #onInterruptionFilterChanged(int)}. 595894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 596894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @return One of the INTERRUPTION_FILTER_ constants, or INTERRUPTION_FILTER_UNKNOWN when 597894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * unavailable. 598894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 599894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public final int getCurrentInterruptionFilter() { 600894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!isBound()) return INTERRUPTION_FILTER_UNKNOWN; 601894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman try { 602894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return getNotificationInterface().getInterruptionFilterFromListener(mWrapper); 603894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } catch (android.os.RemoteException ex) { 604894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Log.v(TAG, "Unable to contact notification manager", ex); 605894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return INTERRUPTION_FILTER_UNKNOWN; 606894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 607894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 608894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 609894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** 610894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Sets the desired {@link #getCurrentListenerHints() listener hints}. 611894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 612894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * <p> 613894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * This is merely a request, the host may or may not choose to take action depending 614894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * on other listener requests or other global state. 615894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * <p> 616894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Listen for updates using {@link #onListenerHintsChanged(int)}. 617894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 618894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @param hints One or more of the HINT_ constants. 619894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 620894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public final void requestListenerHints(int hints) { 621894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!isBound()) return; 622894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman try { 623894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman getNotificationInterface().requestHintsFromListener(mWrapper, hints); 624894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } catch (android.os.RemoteException ex) { 625894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Log.v(TAG, "Unable to contact notification manager", ex); 626894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 627894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 628894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 629894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** 630894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Sets the desired {@link #getCurrentInterruptionFilter() interruption filter}. 631894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 632894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * <p> 633894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * This is merely a request, the host may or may not choose to apply the requested 634894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * interruption filter depending on other listener requests or other global state. 635894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * <p> 636894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Listen for updates using {@link #onInterruptionFilterChanged(int)}. 637894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 638894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @param interruptionFilter One of the INTERRUPTION_FILTER_ constants. 639894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 640894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public final void requestInterruptionFilter(int interruptionFilter) { 641894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!isBound()) return; 642894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman try { 643894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman getNotificationInterface() 644894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman .requestInterruptionFilterFromListener(mWrapper, interruptionFilter); 645894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } catch (android.os.RemoteException ex) { 646894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Log.v(TAG, "Unable to contact notification manager", ex); 647894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 648894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 64919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 650894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** 651894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Returns current ranking information. 652894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 653894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * <p> 654894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * The returned object represents the current ranking snapshot and only 655894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * applies for currently active notifications. 656894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * <p> 657894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Generally you should use the RankingMap that is passed with events such 658894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * as {@link #onNotificationPosted(StatusBarNotification, RankingMap)}, 659894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * {@link #onNotificationRemoved(StatusBarNotification, RankingMap)}, and 660894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * so on. This method should only be used when needing access outside of 661894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * such events, for example to retrieve the RankingMap right after 662894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * initialization. 66319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman * 66419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman * @return A {@link RankingMap} object providing access to ranking information 665894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 666894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public RankingMap getCurrentRanking() { 667894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman synchronized (mLock) { 668894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return mRankingMap; 669894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 670894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 67119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 672894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman @Override 673894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public IBinder onBind(Intent intent) { 674894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (mWrapper == null) { 675894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman mWrapper = new NotificationListenerWrapper(); 676894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 677894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return mWrapper; 678894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 679894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 680894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** @hide */ 681894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman protected boolean isBound() { 682894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (mWrapper == null) { 683894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Log.w(TAG, "Notification listener service not yet bound."); 684894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return false; 685894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 686894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 687894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 688894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 689894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** 690894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Directly register this service with the Notification Manager. 691894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 692894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * <p>Only system services may use this call. It will fail for non-system callers. 693894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Apps should ask the user to add their listener in Settings. 694894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 695894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @param context Context required for accessing resources. Since this service isn't 696894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * launched as a real Service when using this method, a context has to be passed in. 697894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @param componentName the component that will consume the notification information 698894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @param currentUser the user to use as the stream filter 699894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @hide 700894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 701894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman @SystemApi 702894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public void registerAsSystemService(Context context, ComponentName componentName, 703894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int currentUser) throws RemoteException { 704894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (mWrapper == null) { 705894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman mWrapper = new NotificationListenerWrapper(); 706894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 707894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman mSystemContext = context; 708894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman INotificationManager noMan = getNotificationInterface(); 709894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman noMan.registerListener(mWrapper, componentName, currentUser); 710894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman mCurrentUser = currentUser; 711894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman mHandler = new MyHandler(context.getMainLooper()); 712894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 713894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 714894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** 715894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Directly unregister this service from the Notification Manager. 716894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 717894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * <P>This method will fail for listeners that were not registered 718894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * with (@link registerAsService). 719894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @hide 720894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 721894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman @SystemApi 722894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public void unregisterAsSystemService() throws RemoteException { 723894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (mWrapper != null) { 724894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman INotificationManager noMan = getNotificationInterface(); 725894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman noMan.unregisterListener(mWrapper, mCurrentUser); 726894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 727894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 728894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 729894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** 730894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Request that the listener be rebound, after a previous call to (@link requestUnbind). 731894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 732894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * <P>This method will fail for listeners that have 733894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * not been granted the permission by the user. 734894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 735894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * <P>The service should wait for the {@link #onListenerConnected()} event 736894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * before performing any operations. 737894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 738894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public static void requestRebind(ComponentName componentName) 739894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman throws RemoteException { 740894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman INotificationManager noMan = INotificationManager.Stub.asInterface( 741894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ServiceManager.getService(Context.NOTIFICATION_SERVICE)); 742894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman noMan.requestBindListener(componentName); 743894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 744894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 745894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** 746894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Request that the service be unbound. 747894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 748894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * <P>This will no longer receive updates until 749894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * {@link #requestRebind(ComponentName)} is called. 750894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * The service will likely be kiled by the system after this call. 75119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman */ 752894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public final void requestUnbind() throws RemoteException { 753894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (mWrapper != null) { 754894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman INotificationManager noMan = getNotificationInterface(); 755894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman noMan.requestUnbindListener(mWrapper); 756894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 757894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 758894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 759894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** Convert new-style Icons to legacy representations for pre-M clients. */ 760894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman private void createLegacyIconExtras(Notification n) { 761894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Icon smallIcon = n.getSmallIcon(); 762894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Icon largeIcon = n.getLargeIcon(); 763894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (smallIcon != null && smallIcon.getType() == Icon.TYPE_RESOURCE) { 764894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman n.extras.putInt(Notification.EXTRA_SMALL_ICON, smallIcon.getResId()); 765894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman n.icon = smallIcon.getResId(); 766894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 767894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (largeIcon != null) { 768894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Drawable d = largeIcon.loadDrawable(getContext()); 769894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (d != null && d instanceof BitmapDrawable) { 770894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman final Bitmap largeIconBits = ((BitmapDrawable) d).getBitmap(); 771894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman n.extras.putParcelable(Notification.EXTRA_LARGE_ICON, largeIconBits); 772894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman n.largeIcon = largeIconBits; 773894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 77419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 775894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 776894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 777894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** 778894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Populates remote views for pre-N targeting apps. 779894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 780894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman private void maybePopulateRemoteViews(Notification notification) { 781894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (getContext().getApplicationInfo().targetSdkVersion < Build.VERSION_CODES.N) { 782894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Builder builder = Builder.recoverBuilder(getContext(), notification); 783894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 784894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Some styles wrap Notification's contentView, bigContentView and headsUpContentView. 785894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // First inflate them all, only then set them to avoid recursive wrapping. 786894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RemoteViews content = builder.createContentView(); 78719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman RemoteViews big = builder.createBigContentView(); 788894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RemoteViews headsUp = builder.createHeadsUpContentView(); 789894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 790894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman notification.contentView = content; 791894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman notification.bigContentView = big; 792894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman notification.headsUpContentView = headsUp; 793894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 794894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 795894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 796894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** @hide */ 797894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman protected class NotificationListenerWrapper extends INotificationListener.Stub { 798894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman @Override 799894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public void onNotificationPosted(IStatusBarNotificationHolder sbnHolder, 800894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NotificationRankingUpdate update) { 801894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman StatusBarNotification sbn; 802894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman try { 803894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman sbn = sbnHolder.get(); 804894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } catch (RemoteException e) { 805894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Log.w(TAG, "onNotificationPosted: Error receiving StatusBarNotification", e); 806894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return; 807894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 808894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 809894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman try { 810894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // convert icon metadata to legacy format for older clients 811894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman createLegacyIconExtras(sbn.getNotification()); 812894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman maybePopulateRemoteViews(sbn.getNotification()); 813894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } catch (IllegalArgumentException e) { 814894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // warn and drop corrupt notification 815894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Log.w(TAG, "onNotificationPosted: can't rebuild notification from " + 816894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman sbn.getPackageName()); 817894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman sbn = null; 818894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 819894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 820894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // protect subclass from concurrent modifications of (@link mNotificationKeys}. 821894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman synchronized (mLock) { 822894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman applyUpdateLocked(update); 823894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (sbn != null) { 824894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SomeArgs args = SomeArgs.obtain(); 825894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman args.arg1 = sbn; 826894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman args.arg2 = mRankingMap; 827894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman mHandler.obtainMessage(MyHandler.MSG_ON_NOTIFICATION_POSTED, 828894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman args).sendToTarget(); 829894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 830894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // still pass along the ranking map, it may contain other information 831894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman mHandler.obtainMessage(MyHandler.MSG_ON_NOTIFICATION_RANKING_UPDATE, 832894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman mRankingMap).sendToTarget(); 833894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 834894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 835894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 836894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 837894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 838894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman @Override 839894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public void onNotificationRemoved(IStatusBarNotificationHolder sbnHolder, 840894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NotificationRankingUpdate update) { 841894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman StatusBarNotification sbn; 842894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman try { 843894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman sbn = sbnHolder.get(); 844894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } catch (RemoteException e) { 845894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Log.w(TAG, "onNotificationRemoved: Error receiving StatusBarNotification", e); 846894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return; 847894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 848894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // protect subclass from concurrent modifications of (@link mNotificationKeys}. 849894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman synchronized (mLock) { 850894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman applyUpdateLocked(update); 851894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SomeArgs args = SomeArgs.obtain(); 852894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman args.arg1 = sbn; 853894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman args.arg2 = mRankingMap; 854894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman mHandler.obtainMessage(MyHandler.MSG_ON_NOTIFICATION_REMOVED, 855894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman args).sendToTarget(); 856894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 857894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 858894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 859894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 860894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman @Override 861894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public void onListenerConnected(NotificationRankingUpdate update) { 862894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // protect subclass from concurrent modifications of (@link mNotificationKeys}. 863894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman synchronized (mLock) { 864894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman applyUpdateLocked(update); 86519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 86619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman mHandler.obtainMessage(MyHandler.MSG_ON_LISTENER_CONNECTED).sendToTarget(); 867894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 868894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 869894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman @Override 870894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public void onNotificationRankingUpdate(NotificationRankingUpdate update) 871894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman throws RemoteException { 872894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // protect subclass from concurrent modifications of (@link mNotificationKeys}. 873894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman synchronized (mLock) { 874894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman applyUpdateLocked(update); 875894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman mHandler.obtainMessage(MyHandler.MSG_ON_NOTIFICATION_RANKING_UPDATE, 876894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman mRankingMap).sendToTarget(); 877894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 878894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 879894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 880894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 881894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman @Override 882894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public void onListenerHintsChanged(int hints) throws RemoteException { 883894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman mHandler.obtainMessage(MyHandler.MSG_ON_LISTENER_HINTS_CHANGED, 884894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman hints, 0).sendToTarget(); 885894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 886894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 887894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman @Override 888894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public void onInterruptionFilterChanged(int interruptionFilter) throws RemoteException { 889894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman mHandler.obtainMessage(MyHandler.MSG_ON_INTERRUPTION_FILTER_CHANGED, 890894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman interruptionFilter, 0).sendToTarget(); 891894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 892894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 893894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman @Override 894894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public void onNotificationEnqueued(IStatusBarNotificationHolder notificationHolder, 895894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int importance, boolean user) throws RemoteException { 896894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // no-op in the listener 897894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 898894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 899894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman @Override 900894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public void onNotificationVisibilityChanged(String key, long time, boolean visible) 901894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman throws RemoteException { 902894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // no-op in the listener 903894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 904894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 905894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman @Override 906894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public void onNotificationClick(String key, long time) throws RemoteException { 907894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // no-op in the listener 908894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 909894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 910894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman @Override 911894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public void onNotificationActionClick(String key, long time, int actionIndex) 912894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman throws RemoteException { 913894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // no-op in the listener 914894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 915894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 916894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman @Override 917894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public void onNotificationRemovedReason(String key, long time, int reason) 918894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman throws RemoteException { 919894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // no-op in the listener 920894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 921894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 922894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 923894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman private void applyUpdateLocked(NotificationRankingUpdate update) { 924894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman mRankingMap = new RankingMap(update); 925894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 926894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 927894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** @hide */ 928894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman protected Context getContext() { 929894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (mSystemContext != null) { 930894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return mSystemContext; 931894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 932894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return this; 933894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 934894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 935894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** 936894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Stores ranking related information on a currently active notification. 937894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 938894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * <p> 939894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Ranking objects aren't automatically updated as notification events 940894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * occur. Instead, ranking information has to be retrieved again via the 941894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * current {@link RankingMap}. 942894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 943894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public static class Ranking { 944894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 945894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** @hide */ 946894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman @IntDef({VISIBILITY_NO_OVERRIDE, IMPORTANCE_UNSPECIFIED, IMPORTANCE_NONE, 947894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman IMPORTANCE_MIN, IMPORTANCE_LOW, IMPORTANCE_DEFAULT, IMPORTANCE_HIGH, 948894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman IMPORTANCE_MAX}) 949894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman @Retention(RetentionPolicy.SOURCE) 950894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public @interface Importance {} 951894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 952894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** Value signifying that the user has not expressed a per-app visibility override value. 953894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @hide */ 954894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public static final int VISIBILITY_NO_OVERRIDE = -1000; 955894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 956894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** 957894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Value signifying that the user has not expressed an importance. 958894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 959894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * This value is for persisting preferences, and should never be associated with 960894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * an actual notification. 961894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 962894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public static final int IMPORTANCE_UNSPECIFIED = -1000; 963894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 964894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** 965894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * A notification with no importance: shows nowhere, is blocked. 966894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 967894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public static final int IMPORTANCE_NONE = 0; 968894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 969894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** 970894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Min notification importance: only shows in the shade, below the fold. 97119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman */ 97219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman public static final int IMPORTANCE_MIN = 1; 97319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 97419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman /** 97519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman * Low notification importance: shows everywhere, but is not intrusive. 97619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman */ 97719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman public static final int IMPORTANCE_LOW = 2; 97819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 97919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman /** 98019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman * Default notification importance: shows everywhere, allowed to makes noise, 98119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman * but does not visually intrude. 98219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman */ 98319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman public static final int IMPORTANCE_DEFAULT = 3; 98419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 98519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman /** 98619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman * Higher notification importance: shows everywhere, allowed to makes noise and peek. 98719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman */ 98819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman public static final int IMPORTANCE_HIGH = 4; 98919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 99019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman /** 99119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman * Highest notification importance: shows everywhere, allowed to makes noise, peek, and 99219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman * use full screen intents. 99319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman */ 99419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman public static final int IMPORTANCE_MAX = 5; 99519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 99619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman private String mKey; 99719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman private int mRank = -1; 99819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman private boolean mIsAmbient; 99919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman private boolean mMatchesInterruptionFilter; 100019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman private int mVisibilityOverride; 100119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman private int mSuppressedVisualEffects; 100219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman private @Importance int mImportance; 100319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman private CharSequence mImportanceExplanation; 100419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 1005894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public Ranking() {} 1006894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1007894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** 1008894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Returns the key of the notification this Ranking applies to. 1009894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 1010894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public String getKey() { 1011894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return mKey; 1012894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1013894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1014894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** 1015894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Returns the rank of the notification. 1016894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 1017894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @return the rank of the notification, that is the 0-based index in 1018894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * the list of active notifications. 1019894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 1020894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public int getRank() { 1021894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return mRank; 1022894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1023894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1024894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** 1025894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Returns whether the notification is an ambient notification, that is 1026894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * a notification that doesn't require the user's immediate attention. 1027894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 1028894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public boolean isAmbient() { 1029894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return mIsAmbient; 1030894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1031894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1032894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** 1033894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Returns the user specificed visibility for the package that posted 1034894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * this notification, or 1035894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * {@link NotificationListenerService.Ranking#VISIBILITY_NO_OVERRIDE} if 1036894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * no such preference has been expressed. 1037894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @hide 1038894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 103919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman public int getVisibilityOverride() { 104019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return mVisibilityOverride; 104119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 104219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 104319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman /** 104419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman * Returns the type(s) of visual effects that should be suppressed for this notification. 104519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman * See {@link #SUPPRESSED_EFFECT_SCREEN_OFF}, {@link #SUPPRESSED_EFFECT_SCREEN_ON}. 104619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman */ 1047894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public int getSuppressedVisualEffects() { 1048894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return mSuppressedVisualEffects; 1049894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1050894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1051894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** 1052894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Returns whether the notification matches the user's interruption 1053894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * filter. 1054894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 1055894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @return {@code true} if the notification is allowed by the filter, or 1056894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * {@code false} if it is blocked. 1057894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 1058894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public boolean matchesInterruptionFilter() { 1059894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return mMatchesInterruptionFilter; 1060894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1061894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1062894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** 1063894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Returns the importance of the notification, which dictates its 1064894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * modes of presentation, see: {@link #IMPORTANCE_DEFAULT}, etc. 1065894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 1066894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @return the rank of the notification 1067894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 1068894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public @Importance int getImportance() { 1069894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return mImportance; 1070894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1071894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1072894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** 1073894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * If the importance has been overriden by user preference, then this will be non-null, 1074894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * and should be displayed to the user. 1075894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 1076894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @return the explanation for the importance, or null if it is the natural importance 1077894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 1078894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public CharSequence getImportanceExplanation() { 1079894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return mImportanceExplanation; 1080894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1081894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1082894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman private void populate(String key, int rank, boolean matchesInterruptionFilter, 1083894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int visibilityOverride, int suppressedVisualEffects, int importance, 1084894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CharSequence explanation) { 1085894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman mKey = key; 1086894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman mRank = rank; 1087894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman mIsAmbient = importance < IMPORTANCE_LOW; 1088894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman mMatchesInterruptionFilter = matchesInterruptionFilter; 1089894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman mVisibilityOverride = visibilityOverride; 1090894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman mSuppressedVisualEffects = suppressedVisualEffects; 1091894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman mImportance = importance; 1092894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman mImportanceExplanation = explanation; 1093894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1094894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1095894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** 1096894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * {@hide} 1097894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 1098894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public static String importanceToString(int importance) { 1099894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (importance) { 1100894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case IMPORTANCE_UNSPECIFIED: 1101894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return "UNSPECIFIED"; 110219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case IMPORTANCE_NONE: 1103894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return "NONE"; 1104894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case IMPORTANCE_MIN: 1105894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return "MIN"; 1106894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case IMPORTANCE_LOW: 1107894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return "LOW"; 1108894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case IMPORTANCE_DEFAULT: 1109894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return "DEFAULT"; 1110894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case IMPORTANCE_HIGH: 1111894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return "HIGH"; 1112894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case IMPORTANCE_MAX: 1113894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return "MAX"; 1114894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: 1115894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return "UNKNOWN(" + String.valueOf(importance) + ")"; 1116894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1117894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1118894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1119894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1120894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** 1121894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Provides access to ranking information on currently active 1122894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * notifications. 1123894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 1124894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * <p> 1125894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Note that this object represents a ranking snapshot that only applies to 1126894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * notifications active at the time of retrieval. 1127894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 1128894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public static class RankingMap implements Parcelable { 1129894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman private final NotificationRankingUpdate mRankingUpdate; 1130894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman private ArrayMap<String,Integer> mRanks; 1131894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman private ArraySet<Object> mIntercepted; 1132894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman private ArrayMap<String, Integer> mVisibilityOverrides; 1133894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman private ArrayMap<String, Integer> mSuppressedVisualEffects; 1134894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman private ArrayMap<String, Integer> mImportance; 1135894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman private ArrayMap<String, String> mImportanceExplanation; 1136894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 113719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman private RankingMap(NotificationRankingUpdate rankingUpdate) { 1138894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman mRankingUpdate = rankingUpdate; 1139894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1140894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1141894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** 1142894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Request the list of notification keys in their current ranking 1143894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * order. 1144894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 1145894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @return An array of active notification keys, in their ranking order. 114619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman */ 1147894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public String[] getOrderedKeys() { 1148894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return mRankingUpdate.getOrderedKeys(); 1149894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 115019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 1151894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /** 1152894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Populates outRanking with ranking information for the notification 1153894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * with the given key. 1154894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * 1155894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @return true if a valid key has been passed and outRanking has 1156894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * been populated; false otherwise 1157894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 1158894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public boolean getRanking(String key, Ranking outRanking) { 1159894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int rank = getRank(key); 116019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman outRanking.populate(key, rank, !isIntercepted(key), 1161894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman getVisibilityOverride(key), getSuppressedVisualEffects(key), 1162894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman getImportance(key), getImportanceExplanation(key)); 1163894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return rank >= 0; 1164894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1165894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1166894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman private int getRank(String key) { 1167894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman synchronized (this) { 1168894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (mRanks == null) { 1169894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman buildRanksLocked(); 1170894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1171894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1172894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Integer rank = mRanks.get(key); 1173894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return rank != null ? rank : -1; 1174894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1175894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1176894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman private boolean isIntercepted(String key) { 1177894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman synchronized (this) { 1178894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (mIntercepted == null) { 1179894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman buildInterceptedSetLocked(); 1180894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1181894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1182894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return mIntercepted.contains(key); 1183894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1184894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1185894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman private int getVisibilityOverride(String key) { 1186894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman synchronized (this) { 1187894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (mVisibilityOverrides == null) { 1188894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman buildVisibilityOverridesLocked(); 1189894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1190894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1191894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Integer override = mVisibilityOverrides.get(key); 1192894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (override == null) { 1193894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return Ranking.VISIBILITY_NO_OVERRIDE; 1194894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1195894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return override.intValue(); 1196894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1197894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1198894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman private int getSuppressedVisualEffects(String key) { 1199894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman synchronized (this) { 1200894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (mSuppressedVisualEffects == null) { 1201894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman buildSuppressedVisualEffectsLocked(); 1202894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1203894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1204894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Integer suppressed = mSuppressedVisualEffects.get(key); 1205894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (suppressed == null) { 1206894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return 0; 1207894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1208894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return suppressed.intValue(); 1209894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1210894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1211894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman private int getImportance(String key) { 1212894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman synchronized (this) { 1213894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (mImportance == null) { 1214894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman buildImportanceLocked(); 1215894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1216894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1217894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Integer importance = mImportance.get(key); 1218894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (importance == null) { 1219894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return Ranking.IMPORTANCE_DEFAULT; 1220894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1221894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return importance.intValue(); 1222894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1223894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1224894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman private String getImportanceExplanation(String key) { 1225894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman synchronized (this) { 1226894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (mImportanceExplanation == null) { 1227894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman buildImportanceExplanationLocked(); 1228894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1229894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1230894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return mImportanceExplanation.get(key); 1231894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1232894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1233894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Locked by 'this' 1234894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman private void buildRanksLocked() { 1235894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman String[] orderedKeys = mRankingUpdate.getOrderedKeys(); 1236894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman mRanks = new ArrayMap<>(orderedKeys.length); 1237894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (int i = 0; i < orderedKeys.length; i++) { 1238894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman String key = orderedKeys[i]; 1239894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman mRanks.put(key, i); 1240894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1241894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1242894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1243894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Locked by 'this' 1244894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman private void buildInterceptedSetLocked() { 1245894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman String[] dndInterceptedKeys = mRankingUpdate.getInterceptedKeys(); 1246894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman mIntercepted = new ArraySet<>(dndInterceptedKeys.length); 1247894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Collections.addAll(mIntercepted, dndInterceptedKeys); 1248894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1249894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1250894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Locked by 'this' 1251894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman private void buildVisibilityOverridesLocked() { 1252894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Bundle visibilityBundle = mRankingUpdate.getVisibilityOverrides(); 1253894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman mVisibilityOverrides = new ArrayMap<>(visibilityBundle.size()); 1254894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (String key: visibilityBundle.keySet()) { 1255894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman mVisibilityOverrides.put(key, visibilityBundle.getInt(key)); 1256894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1257894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1258894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1259894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Locked by 'this' 1260894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman private void buildSuppressedVisualEffectsLocked() { 1261894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Bundle suppressedBundle = mRankingUpdate.getSuppressedVisualEffects(); 1262894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman mSuppressedVisualEffects = new ArrayMap<>(suppressedBundle.size()); 1263894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (String key: suppressedBundle.keySet()) { 1264894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman mSuppressedVisualEffects.put(key, suppressedBundle.getInt(key)); 1265894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1266894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1267894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Locked by 'this' 1268894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman private void buildImportanceLocked() { 1269894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman String[] orderedKeys = mRankingUpdate.getOrderedKeys(); 1270894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int[] importance = mRankingUpdate.getImportance(); 1271894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman mImportance = new ArrayMap<>(orderedKeys.length); 1272894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (int i = 0; i < orderedKeys.length; i++) { 1273894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman String key = orderedKeys[i]; 1274894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman mImportance.put(key, importance[i]); 1275894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1276894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1277894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1278894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Locked by 'this' 1279894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman private void buildImportanceExplanationLocked() { 1280894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Bundle explanationBundle = mRankingUpdate.getImportanceExplanation(); 1281894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman mImportanceExplanation = new ArrayMap<>(explanationBundle.size()); 1282894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (String key: explanationBundle.keySet()) { 1283894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman mImportanceExplanation.put(key, explanationBundle.getString(key)); 1284894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1285894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1286894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1287894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // ----------- Parcelable 1288894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1289894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman @Override 1290894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public int describeContents() { 1291894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return 0; 1292894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1293894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1294894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman @Override 1295894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public void writeToParcel(Parcel dest, int flags) { 1296894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman dest.writeParcelable(mRankingUpdate, flags); 1297894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1298894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1299894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public static final Creator<RankingMap> CREATOR = new Creator<RankingMap>() { 1300894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman @Override 1301894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public RankingMap createFromParcel(Parcel source) { 1302894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NotificationRankingUpdate rankingUpdate = source.readParcelable(null); 1303894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return new RankingMap(rankingUpdate); 1304894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1305894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1306894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman @Override 1307894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public RankingMap[] newArray(int size) { 1308894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return new RankingMap[size]; 1309894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1310 }; 1311 } 1312 1313 private final class MyHandler extends Handler { 1314 public static final int MSG_ON_NOTIFICATION_POSTED = 1; 1315 public static final int MSG_ON_NOTIFICATION_REMOVED = 2; 1316 public static final int MSG_ON_LISTENER_CONNECTED = 3; 1317 public static final int MSG_ON_NOTIFICATION_RANKING_UPDATE = 4; 1318 public static final int MSG_ON_LISTENER_HINTS_CHANGED = 5; 1319 public static final int MSG_ON_INTERRUPTION_FILTER_CHANGED = 6; 1320 1321 public MyHandler(Looper looper) { 1322 super(looper, null, false); 1323 } 1324 1325 @Override 1326 public void handleMessage(Message msg) { 1327 switch (msg.what) { 1328 case MSG_ON_NOTIFICATION_POSTED: { 1329 SomeArgs args = (SomeArgs) msg.obj; 1330 StatusBarNotification sbn = (StatusBarNotification) args.arg1; 1331 RankingMap rankingMap = (RankingMap) args.arg2; 1332 args.recycle(); 1333 onNotificationPosted(sbn, rankingMap); 1334 } break; 1335 1336 case MSG_ON_NOTIFICATION_REMOVED: { 1337 SomeArgs args = (SomeArgs) msg.obj; 1338 StatusBarNotification sbn = (StatusBarNotification) args.arg1; 1339 RankingMap rankingMap = (RankingMap) args.arg2; 1340 args.recycle(); 1341 onNotificationRemoved(sbn, rankingMap); 1342 } break; 1343 1344 case MSG_ON_LISTENER_CONNECTED: { 1345 onListenerConnected(); 1346 } break; 1347 1348 case MSG_ON_NOTIFICATION_RANKING_UPDATE: { 1349 RankingMap rankingMap = (RankingMap) msg.obj; 1350 onNotificationRankingUpdate(rankingMap); 1351 } break; 1352 1353 case MSG_ON_LISTENER_HINTS_CHANGED: { 1354 final int hints = msg.arg1; 1355 onListenerHintsChanged(hints); 1356 } break; 1357 1358 case MSG_ON_INTERRUPTION_FILTER_CHANGED: { 1359 final int interruptionFilter = msg.arg1; 1360 onInterruptionFilterChanged(interruptionFilter); 1361 } break; 1362 } 1363 } 1364 } 1365} 1366