15feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler/*
25feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler * Copyright (C) 2013 The Android Open Source Project
35feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler *
45feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler * Licensed under the Apache License, Version 2.0 (the "License");
55feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler * you may not use this file except in compliance with the License.
65feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler * You may obtain a copy of the License at
75feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler *
85feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler *      http://www.apache.org/licenses/LICENSE-2.0
95feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler *
105feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler * Unless required by applicable law or agreed to in writing, software
115feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler * distributed under the License is distributed on an "AS IS" BASIS,
125feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler * See the License for the specific language governing permissions and
145feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler * limitations under the License.
155feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler */
165feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler
175feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandlerpackage android.service.notification;
185feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler
1973ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynoldsimport android.annotation.IntDef;
2073ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynoldsimport android.annotation.NonNull;
215feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandlerimport android.annotation.SdkConstant;
227ca33079fda388dd3bd81819b280e578e5d6b38bJulia Reynoldsimport android.annotation.SystemApi;
23503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynoldsimport android.annotation.TestApi;
248149961c0aa22e80e4d44659814844aeb7a63c1eJulia Reynoldsimport android.app.ActivityManager;
255feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandlerimport android.app.INotificationManager;
264600f9b60753adab4e65258a05744a46938fce86Christoph Studerimport android.app.Notification;
274600f9b60753adab4e65258a05744a46938fce86Christoph Studerimport android.app.Notification.Builder;
287ca33079fda388dd3bd81819b280e578e5d6b38bJulia Reynoldsimport android.app.NotificationChannel;
297ca33079fda388dd3bd81819b280e578e5d6b38bJulia Reynoldsimport android.app.NotificationChannelGroup;
30807749301fcbda892dfc8a5832b19acf7d1cf53bJohn Spurlockimport android.app.NotificationManager;
319acd673c0deb2652a55c52b9b80515d84b1945dcSelim Cinekimport android.app.Person;
325feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandlerimport android.app.Service;
3367f9d5070a74a0bf34f0335899a96dedcac26c96Jeff Sharkeyimport android.companion.CompanionDeviceManager;
341941fc718690d6b87db68b6a133c71fb470599d0Chris Wrenimport android.content.ComponentName;
355feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandlerimport android.content.Context;
365feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandlerimport android.content.Intent;
37cee44ba418bef83571349acb2d24ef29833502e0Christoph Studerimport android.content.pm.ParceledListSlice;
387ca33079fda388dd3bd81819b280e578e5d6b38bJulia Reynoldsimport android.graphics.Bitmap;
39f5a7838e19c1cb6437a8b32ba9980ac1ce8804e2Daniel Sandlerimport android.graphics.drawable.BitmapDrawable;
40f5a7838e19c1cb6437a8b32ba9980ac1ce8804e2Daniel Sandlerimport android.graphics.drawable.Drawable;
41f5a7838e19c1cb6437a8b32ba9980ac1ce8804e2Daniel Sandlerimport android.graphics.drawable.Icon;
42d9228f1135e51d9380bad990d7178490ec474dbdJulia Reynoldsimport android.os.Build;
433ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wrenimport android.os.Bundle;
447ca33079fda388dd3bd81819b280e578e5d6b38bJulia Reynoldsimport android.os.Handler;
455feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandlerimport android.os.IBinder;
467ca33079fda388dd3bd81819b280e578e5d6b38bJulia Reynoldsimport android.os.Looper;
477ca33079fda388dd3bd81819b280e578e5d6b38bJulia Reynoldsimport android.os.Message;
4805ad48206a082057e17723d32493c153faa6881eChristoph Studerimport android.os.Parcel;
4905ad48206a082057e17723d32493c153faa6881eChristoph Studerimport android.os.Parcelable;
50f953664dc17dca23bd724bd64f89189c16c83263Chris Wrenimport android.os.RemoteException;
515feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandlerimport android.os.ServiceManager;
52f27d6b2b821bf818810a0e303d536906b889588dJulia Reynoldsimport android.os.UserHandle;
53dda48f12212a24371de0e6ba2e5e637925cd9b5eChristoph Studerimport android.util.ArrayMap;
54dda48f12212a24371de0e6ba2e5e637925cd9b5eChristoph Studerimport android.util.ArraySet;
555feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandlerimport android.util.Log;
565081c0de54d05f559dd8b09d2dd2ef5018378959Adrian Roosimport android.widget.RemoteViews;
577ca33079fda388dd3bd81819b280e578e5d6b38bJulia Reynolds
58b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganovimport com.android.internal.annotations.GuardedBy;
591d958f8c35528ac3f31a69402ff38335d47fcb7fDan Sandlerimport com.android.internal.annotations.VisibleForTesting;
60b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganovimport com.android.internal.os.SomeArgs;
6122f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds
6273ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynoldsimport java.lang.annotation.Retention;
6373ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynoldsimport java.lang.annotation.RetentionPolicy;
6424fb8940b4844e6b121e05c5019361f31d1baf3cChris Wrenimport java.util.ArrayList;
65dda48f12212a24371de0e6ba2e5e637925cd9b5eChristoph Studerimport java.util.Collections;
66cee44ba418bef83571349acb2d24ef29833502e0Christoph Studerimport java.util.List;
67cee44ba418bef83571349acb2d24ef29833502e0Christoph Studer
6804667dae3a5e45257c12d11dbcb4fc353a18d842Scott Main/**
6905ad48206a082057e17723d32493c153faa6881eChristoph Studer * A service that receives calls from the system when new notifications are
7005ad48206a082057e17723d32493c153faa6881eChristoph Studer * posted or removed, or their ranking changed.
7104667dae3a5e45257c12d11dbcb4fc353a18d842Scott Main * <p>To extend this class, you must declare the service in your manifest file with
7267f9d5070a74a0bf34f0335899a96dedcac26c96Jeff Sharkey * the {@link android.Manifest.permission#BIND_NOTIFICATION_LISTENER_SERVICE} permission
7304667dae3a5e45257c12d11dbcb4fc353a18d842Scott Main * and include an intent filter with the {@link #SERVICE_INTERFACE} action. For example:</p>
7404667dae3a5e45257c12d11dbcb4fc353a18d842Scott Main * <pre>
7504667dae3a5e45257c12d11dbcb4fc353a18d842Scott Main * &lt;service android:name=".NotificationListener"
7604667dae3a5e45257c12d11dbcb4fc353a18d842Scott Main *          android:label="&#64;string/service_name"
7704667dae3a5e45257c12d11dbcb4fc353a18d842Scott Main *          android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
7804667dae3a5e45257c12d11dbcb4fc353a18d842Scott Main *     &lt;intent-filter>
7904667dae3a5e45257c12d11dbcb4fc353a18d842Scott Main *         &lt;action android:name="android.service.notification.NotificationListenerService" />
8004667dae3a5e45257c12d11dbcb4fc353a18d842Scott Main *     &lt;/intent-filter>
8104667dae3a5e45257c12d11dbcb4fc353a18d842Scott Main * &lt;/service></pre>
825717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren *
835717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren * <p>The service should wait for the {@link #onListenerConnected()} event
845717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren * before performing any operations. The {@link #requestRebind(ComponentName)}
855717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren * method is the <i>only</i> one that is safe to call before {@link #onListenerConnected()}
865717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren * or after {@link #onListenerDisconnected()}.
875717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren * </p>
888149961c0aa22e80e4d44659814844aeb7a63c1eJulia Reynolds * <p> Notification listeners cannot get notification access or be bound by the system on
89604843bda67a5c576eab5ecfacfc2b8d3b89ba71Benjamin Miller * {@linkplain ActivityManager#isLowRamDevice() low-RAM} devices. The system also ignores
90604843bda67a5c576eab5ecfacfc2b8d3b89ba71Benjamin Miller * notification listeners running in a work profile. A
91604843bda67a5c576eab5ecfacfc2b8d3b89ba71Benjamin Miller * {@link android.app.admin.DevicePolicyManager} might block notifications originating from a work
92604843bda67a5c576eab5ecfacfc2b8d3b89ba71Benjamin Miller * profile.</p>
9304667dae3a5e45257c12d11dbcb4fc353a18d842Scott Main */
945feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandlerpublic abstract class NotificationListenerService extends Service {
953aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds
967e1ffd737e84f0876efa07ba1cb7ea498f10f92fJulia Reynolds    private final String TAG = getClass().getSimpleName();
975feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler
9885a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer    /**
9985a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer     * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
10085a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer     *     Normal interruption filter.
10185a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer     */
102807749301fcbda892dfc8a5832b19acf7d1cf53bJohn Spurlock    public static final int INTERRUPTION_FILTER_ALL
103807749301fcbda892dfc8a5832b19acf7d1cf53bJohn Spurlock            = NotificationManager.INTERRUPTION_FILTER_ALL;
104d8afe3c41e65a8f6ff4283c124ba250c92cf50c6John Spurlock
10585a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer    /**
10685a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer     * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
10785a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer     *     Priority interruption filter.
10885a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer     */
109807749301fcbda892dfc8a5832b19acf7d1cf53bJohn Spurlock    public static final int INTERRUPTION_FILTER_PRIORITY
110807749301fcbda892dfc8a5832b19acf7d1cf53bJohn Spurlock            = NotificationManager.INTERRUPTION_FILTER_PRIORITY;
111d8afe3c41e65a8f6ff4283c124ba250c92cf50c6John Spurlock
11285a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer    /**
11385a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer     * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
11485a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer     *     No interruptions filter.
11585a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer     */
116807749301fcbda892dfc8a5832b19acf7d1cf53bJohn Spurlock    public static final int INTERRUPTION_FILTER_NONE
117807749301fcbda892dfc8a5832b19acf7d1cf53bJohn Spurlock            = NotificationManager.INTERRUPTION_FILTER_NONE;
118d8afe3c41e65a8f6ff4283c124ba250c92cf50c6John Spurlock
1194f1163c83e79da52b2be7ff6b10163441895bc26John Spurlock    /**
1204f1163c83e79da52b2be7ff6b10163441895bc26John Spurlock     * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
1214f1163c83e79da52b2be7ff6b10163441895bc26John Spurlock     *     Alarms only interruption filter.
1224f1163c83e79da52b2be7ff6b10163441895bc26John Spurlock     */
123807749301fcbda892dfc8a5832b19acf7d1cf53bJohn Spurlock    public static final int INTERRUPTION_FILTER_ALARMS
124807749301fcbda892dfc8a5832b19acf7d1cf53bJohn Spurlock            = NotificationManager.INTERRUPTION_FILTER_ALARMS;
1254f1163c83e79da52b2be7ff6b10163441895bc26John Spurlock
126831041036587efbceb395bface176752a6b560bcJohn Spurlock    /** {@link #getCurrentInterruptionFilter() Interruption filter} constant - returned when
127831041036587efbceb395bface176752a6b560bcJohn Spurlock     * the value is unavailable for any reason.  For example, before the notification listener
128831041036587efbceb395bface176752a6b560bcJohn Spurlock     * is connected.
129831041036587efbceb395bface176752a6b560bcJohn Spurlock     *
130831041036587efbceb395bface176752a6b560bcJohn Spurlock     * {@see #onListenerConnected()}
131831041036587efbceb395bface176752a6b560bcJohn Spurlock     */
132807749301fcbda892dfc8a5832b19acf7d1cf53bJohn Spurlock    public static final int INTERRUPTION_FILTER_UNKNOWN
133807749301fcbda892dfc8a5832b19acf7d1cf53bJohn Spurlock            = NotificationManager.INTERRUPTION_FILTER_UNKNOWN;
134831041036587efbceb395bface176752a6b560bcJohn Spurlock
135d8afe3c41e65a8f6ff4283c124ba250c92cf50c6John Spurlock    /** {@link #getCurrentListenerHints() Listener hints} constant - the primary device UI
136d8afe3c41e65a8f6ff4283c124ba250c92cf50c6John Spurlock     * should disable notification sound, vibrating and other visual or aural effects.
13785a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer     * This does not change the interruption filter, only the effects. **/
13885a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer    public static final int HINT_HOST_DISABLE_EFFECTS = 1;
1391fa865f396e94913cfbbd32ce7799c2e8aeb7a08John Spurlock
1407219adadb05d916874e7edff553dfc34bccf94efBryce Lee    /** {@link #getCurrentListenerHints() Listener hints} constant - the primary device UI
1417219adadb05d916874e7edff553dfc34bccf94efBryce Lee     * should disable notification sound, but not phone calls.
1427219adadb05d916874e7edff553dfc34bccf94efBryce Lee     * This does not change the interruption filter, only the effects. **/
1437219adadb05d916874e7edff553dfc34bccf94efBryce Lee    public static final int HINT_HOST_DISABLE_NOTIFICATION_EFFECTS = 1 << 1;
1447219adadb05d916874e7edff553dfc34bccf94efBryce Lee
1457219adadb05d916874e7edff553dfc34bccf94efBryce Lee    /** {@link #getCurrentListenerHints() Listener hints} constant - the primary device UI
1467219adadb05d916874e7edff553dfc34bccf94efBryce Lee     * should disable phone call sounds, buyt not notification sound.
1477219adadb05d916874e7edff553dfc34bccf94efBryce Lee     * This does not change the interruption filter, only the effects. **/
1487219adadb05d916874e7edff553dfc34bccf94efBryce Lee    public static final int HINT_HOST_DISABLE_CALL_EFFECTS = 1 << 2;
1497219adadb05d916874e7edff553dfc34bccf94efBryce Lee
150d560729ce3a6f3d51c03d39768815b4c49f7a8f4Julia Reynolds    /**
151d560729ce3a6f3d51c03d39768815b4c49f7a8f4Julia Reynolds     * Whether notification suppressed by DND should not interruption visually when the screen is
152d560729ce3a6f3d51c03d39768815b4c49f7a8f4Julia Reynolds     * off.
153ccc6ae64ff1dd957fabb24b3c889a69d2d42765dJulia Reynolds     *
154ccc6ae64ff1dd957fabb24b3c889a69d2d42765dJulia Reynolds     * @deprecated Use the more specific visual effects in {@link NotificationManager.Policy}.
155d560729ce3a6f3d51c03d39768815b4c49f7a8f4Julia Reynolds     */
156ccc6ae64ff1dd957fabb24b3c889a69d2d42765dJulia Reynolds    @Deprecated
157d560729ce3a6f3d51c03d39768815b4c49f7a8f4Julia Reynolds    public static final int SUPPRESSED_EFFECT_SCREEN_OFF =
158d560729ce3a6f3d51c03d39768815b4c49f7a8f4Julia Reynolds            NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_OFF;
159d560729ce3a6f3d51c03d39768815b4c49f7a8f4Julia Reynolds    /**
160d560729ce3a6f3d51c03d39768815b4c49f7a8f4Julia Reynolds     * Whether notification suppressed by DND should not interruption visually when the screen is
161d560729ce3a6f3d51c03d39768815b4c49f7a8f4Julia Reynolds     * on.
162ccc6ae64ff1dd957fabb24b3c889a69d2d42765dJulia Reynolds     *
163ccc6ae64ff1dd957fabb24b3c889a69d2d42765dJulia Reynolds     * @deprecated Use the more specific visual effects in {@link NotificationManager.Policy}.
164d560729ce3a6f3d51c03d39768815b4c49f7a8f4Julia Reynolds     */
165ccc6ae64ff1dd957fabb24b3c889a69d2d42765dJulia Reynolds    @Deprecated
166617215874db9c208a74dc97f4133e6b6fc96271cJulia Reynolds    public static final int SUPPRESSED_EFFECT_SCREEN_ON =
167617215874db9c208a74dc97f4133e6b6fc96271cJulia Reynolds            NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_ON;
168f612869ae1190e0885b58a3c33b23d36d7732f06Julia Reynolds
1693aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds
1703aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds    // Notification cancellation reasons
1713aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds
172a11d0b18ec9275ed8d633e4508074226b7372474Julia Reynolds    /** Notification was canceled by the status bar reporting a notification click. */
173f619bc5211b4f214e92ef59a023adf006c4f196fJulia Reynolds    public static final int REASON_CLICK = 1;
1743aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds    /** Notification was canceled by the status bar reporting a user dismissal. */
175f619bc5211b4f214e92ef59a023adf006c4f196fJulia Reynolds    public static final int REASON_CANCEL = 2;
1763aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds    /** Notification was canceled by the status bar reporting a user dismiss all. */
177f619bc5211b4f214e92ef59a023adf006c4f196fJulia Reynolds    public static final int REASON_CANCEL_ALL = 3;
1783aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds    /** Notification was canceled by the status bar reporting an inflation error. */
179f619bc5211b4f214e92ef59a023adf006c4f196fJulia Reynolds    public static final int REASON_ERROR = 4;
1803aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds    /** Notification was canceled by the package manager modifying the package. */
1813aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds    public static final int REASON_PACKAGE_CHANGED = 5;
1823aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds    /** Notification was canceled by the owning user context being stopped. */
1833aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds    public static final int REASON_USER_STOPPED = 6;
1843aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds    /** Notification was canceled by the user banning the package. */
1853aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds    public static final int REASON_PACKAGE_BANNED = 7;
1863aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds    /** Notification was canceled by the app canceling this specific notification. */
1873aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds    public static final int REASON_APP_CANCEL = 8;
1883aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds    /** Notification was canceled by the app cancelling all its notifications. */
1893aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds    public static final int REASON_APP_CANCEL_ALL = 9;
1903aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds    /** Notification was canceled by a listener reporting a user dismissal. */
1913aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds    public static final int REASON_LISTENER_CANCEL = 10;
1923aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds    /** Notification was canceled by a listener reporting a user dismiss all. */
1933aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds    public static final int REASON_LISTENER_CANCEL_ALL = 11;
1943aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds    /** Notification was canceled because it was a member of a canceled group. */
1953aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds    public static final int REASON_GROUP_SUMMARY_CANCELED = 12;
1963aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds    /** Notification was canceled because it was an invisible member of a group. */
1973aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds    public static final int REASON_GROUP_OPTIMIZATION = 13;
1983aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds    /** Notification was canceled by the device administrator suspending the package. */
1993aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds    public static final int REASON_PACKAGE_SUSPENDED = 14;
2003aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds    /** Notification was canceled by the owning managed profile being turned off. */
2013aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds    public static final int REASON_PROFILE_TURNED_OFF = 15;
2023aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds    /** Autobundled summary notification was canceled because its group was unbundled */
2033aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds    public static final int REASON_UNAUTOBUNDLED = 16;
2043aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds    /** Notification was canceled by the user banning the channel. */
2053aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds    public static final int REASON_CHANNEL_BANNED = 17;
2063aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds    /** Notification was snoozed. */
2073aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds    public static final int REASON_SNOOZED = 18;
2082a128746b3466e75b6040147fa831fe12cc2ccbbJulia Reynolds    /** Notification was canceled due to timeout */
2092a128746b3466e75b6040147fa831fe12cc2ccbbJulia Reynolds    public static final int REASON_TIMEOUT = 19;
2103aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds
211b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer    /**
212b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer     * The full trim of the StatusBarNotification including all its features.
213b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer     *
214b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer     * @hide
2157ca33079fda388dd3bd81819b280e578e5d6b38bJulia Reynolds     * @removed
216b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer     */
217b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer    @SystemApi
218b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer    public static final int TRIM_FULL = 0;
219b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer
220b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer    /**
221b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer     * A light trim of the StatusBarNotification excluding the following features:
222b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer     *
223b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer     * <ol>
224b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer     *     <li>{@link Notification#tickerView tickerView}</li>
225b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer     *     <li>{@link Notification#contentView contentView}</li>
226b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer     *     <li>{@link Notification#largeIcon largeIcon}</li>
227b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer     *     <li>{@link Notification#bigContentView bigContentView}</li>
228b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer     *     <li>{@link Notification#headsUpContentView headsUpContentView}</li>
229b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer     *     <li>{@link Notification#EXTRA_LARGE_ICON extras[EXTRA_LARGE_ICON]}</li>
230b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer     *     <li>{@link Notification#EXTRA_LARGE_ICON_BIG extras[EXTRA_LARGE_ICON_BIG]}</li>
231b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer     *     <li>{@link Notification#EXTRA_PICTURE extras[EXTRA_PICTURE]}</li>
232223f44e1d2cc56fa965cdb9f112afae1c498cbbdChristoph Studer     *     <li>{@link Notification#EXTRA_BIG_TEXT extras[EXTRA_BIG_TEXT]}</li>
233b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer     * </ol>
234b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer     *
235b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer     * @hide
2367ca33079fda388dd3bd81819b280e578e5d6b38bJulia Reynolds     * @removed
237b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer     */
238b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer    @SystemApi
239b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer    public static final int TRIM_LIGHT = 1;
240b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer
24173ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds
24273ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds    /** @hide */
243ce8db9911494225fcd99711d7df85a130de5a6ceJeff Sharkey    @IntDef(prefix = { "NOTIFICATION_CHANNEL_OR_GROUP_" }, value = {
244ce8db9911494225fcd99711d7df85a130de5a6ceJeff Sharkey            NOTIFICATION_CHANNEL_OR_GROUP_ADDED,
245ce8db9911494225fcd99711d7df85a130de5a6ceJeff Sharkey            NOTIFICATION_CHANNEL_OR_GROUP_UPDATED,
246ce8db9911494225fcd99711d7df85a130de5a6ceJeff Sharkey            NOTIFICATION_CHANNEL_OR_GROUP_DELETED
247ce8db9911494225fcd99711d7df85a130de5a6ceJeff Sharkey    })
24873ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds    @Retention(RetentionPolicy.SOURCE)
24973ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds    public @interface ChannelOrGroupModificationTypes {}
25073ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds
25173ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds    /**
25273ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds     * Channel or group modification reason provided to
253f27d6b2b821bf818810a0e303d536906b889588dJulia Reynolds     * {@link #onNotificationChannelModified(String, UserHandle,NotificationChannel, int)} or
254f27d6b2b821bf818810a0e303d536906b889588dJulia Reynolds     * {@link #onNotificationChannelGroupModified(String, UserHandle, NotificationChannelGroup,
255f27d6b2b821bf818810a0e303d536906b889588dJulia Reynolds     * int)}- the provided object was created.
25673ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds     */
25773ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds    public static final int NOTIFICATION_CHANNEL_OR_GROUP_ADDED = 1;
25873ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds
25973ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds    /**
26073ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds     * Channel or group modification reason provided to
261f27d6b2b821bf818810a0e303d536906b889588dJulia Reynolds     * {@link #onNotificationChannelModified(String, UserHandle, NotificationChannel, int)} or
262f27d6b2b821bf818810a0e303d536906b889588dJulia Reynolds     * {@link #onNotificationChannelGroupModified(String, UserHandle,NotificationChannelGroup, int)}
263f27d6b2b821bf818810a0e303d536906b889588dJulia Reynolds     * - the provided object was updated.
26473ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds     */
26573ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds    public static final int NOTIFICATION_CHANNEL_OR_GROUP_UPDATED = 2;
26673ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds
26773ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds    /**
26873ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds     * Channel or group modification reason provided to
269f27d6b2b821bf818810a0e303d536906b889588dJulia Reynolds     * {@link #onNotificationChannelModified(String, UserHandle, NotificationChannel, int)} or
270f27d6b2b821bf818810a0e303d536906b889588dJulia Reynolds     * {@link #onNotificationChannelGroupModified(String, UserHandle, NotificationChannelGroup,
271f27d6b2b821bf818810a0e303d536906b889588dJulia Reynolds     * int)}- the provided object was deleted.
27273ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds     */
27373ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds    public static final int NOTIFICATION_CHANNEL_OR_GROUP_DELETED = 3;
27473ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds
275b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov    private final Object mLock = new Object();
276b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov
277b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov    private Handler mHandler;
278b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov
27951017d0e23ce9855fabcf786a2067ceb19121fbcChris Wren    /** @hide */
28051017d0e23ce9855fabcf786a2067ceb19121fbcChris Wren    protected NotificationListenerWrapper mWrapper = null;
2815717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren    private boolean isConnected = false;
282b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov
283b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov    @GuardedBy("mLock")
284d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer    private RankingMap mRankingMap;
2855feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler
286503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds    /**
287503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds     * @hide
288503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds     */
289503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds    protected INotificationManager mNoMan;
2905feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler
291e0ba7eb365ac19fdc11c3f820349f0352761b9f4Chris Wren    /**
292e0ba7eb365ac19fdc11c3f820349f0352761b9f4Chris Wren     * Only valid after a successful call to (@link registerAsService}.
293e0ba7eb365ac19fdc11c3f820349f0352761b9f4Chris Wren     * @hide
294e0ba7eb365ac19fdc11c3f820349f0352761b9f4Chris Wren     */
295e0ba7eb365ac19fdc11c3f820349f0352761b9f4Chris Wren    protected int mCurrentUser;
2964600f9b60753adab4e65258a05744a46938fce86Christoph Studer
297e0ba7eb365ac19fdc11c3f820349f0352761b9f4Chris Wren    /**
298e0ba7eb365ac19fdc11c3f820349f0352761b9f4Chris Wren     * This context is required for system services since NotificationListenerService isn't
299e0ba7eb365ac19fdc11c3f820349f0352761b9f4Chris Wren     * started as a real Service and hence no context is available..
300e0ba7eb365ac19fdc11c3f820349f0352761b9f4Chris Wren     * @hide
301e0ba7eb365ac19fdc11c3f820349f0352761b9f4Chris Wren     */
302e0ba7eb365ac19fdc11c3f820349f0352761b9f4Chris Wren    protected Context mSystemContext;
3034600f9b60753adab4e65258a05744a46938fce86Christoph Studer
3045feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler    /**
3055feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler     * The {@link Intent} that must be declared as handled by the service.
3065feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler     */
3075feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler    @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
3085feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler    public static final String SERVICE_INTERFACE
3095feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler            = "android.service.notification.NotificationListenerService";
3105feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler
311b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov    @Override
312b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov    protected void attachBaseContext(Context base) {
313b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov        super.attachBaseContext(base);
314b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov        mHandler = new MyHandler(getMainLooper());
315b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov    }
316b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov
317dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk    /**
3185feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler     * Implement this method to learn about new notifications as they are posted by apps.
3195feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler     *
3205feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler     * @param sbn A data structure encapsulating the original {@link android.app.Notification}
3215feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler     *            object as well as its identifying information (tag and id) and source
3225feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler     *            (package name).
3235feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler     */
324d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer    public void onNotificationPosted(StatusBarNotification sbn) {
325d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer        // optional
326d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer    }
327d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer
328d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer    /**
329d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer     * Implement this method to learn about new notifications as they are posted by apps.
330d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer     *
331d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer     * @param sbn A data structure encapsulating the original {@link android.app.Notification}
332d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer     *            object as well as its identifying information (tag and id) and source
333d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer     *            (package name).
334d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer     * @param rankingMap The current ranking map that can be used to retrieve ranking information
335d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer     *                   for active notifications, including the newly posted one.
336d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer     */
337d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer    public void onNotificationPosted(StatusBarNotification sbn, RankingMap rankingMap) {
338d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer        onNotificationPosted(sbn);
339d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer    }
340d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer
341d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer    /**
342d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer     * Implement this method to learn when notifications are removed.
3435717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     * <p>
344d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer     * This might occur because the user has dismissed the notification using system UI (or another
345d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer     * notification listener) or because the app has withdrawn the notification.
3465717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     * <p>
347d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer     * NOTE: The {@link StatusBarNotification} object you receive will be "light"; that is, the
348d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer     * result from {@link StatusBarNotification#getNotification} may be missing some heavyweight
349d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer     * fields such as {@link android.app.Notification#contentView} and
350d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer     * {@link android.app.Notification#largeIcon}. However, all other fields on
351d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer     * {@link StatusBarNotification}, sufficient to match this call with a prior call to
352d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer     * {@link #onNotificationPosted(StatusBarNotification)}, will be intact.
353d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer     *
354d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer     * @param sbn A data structure encapsulating at least the original information (tag and id)
355d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer     *            and source (package name) used to post the {@link android.app.Notification} that
356d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer     *            was just removed.
357d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer     */
358d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer    public void onNotificationRemoved(StatusBarNotification sbn) {
359d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer        // optional
360d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer    }
3615feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler
3625feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler    /**
3635feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler     * Implement this method to learn when notifications are removed.
3645717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     * <p>
3655feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler     * This might occur because the user has dismissed the notification using system UI (or another
3665feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler     * notification listener) or because the app has withdrawn the notification.
3675717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     * <p>
3681a497d3a2b1496c12949e47e55f8e46d8f585be5Daniel Sandler     * NOTE: The {@link StatusBarNotification} object you receive will be "light"; that is, the
36904667dae3a5e45257c12d11dbcb4fc353a18d842Scott Main     * result from {@link StatusBarNotification#getNotification} may be missing some heavyweight
3701a497d3a2b1496c12949e47e55f8e46d8f585be5Daniel Sandler     * fields such as {@link android.app.Notification#contentView} and
3711a497d3a2b1496c12949e47e55f8e46d8f585be5Daniel Sandler     * {@link android.app.Notification#largeIcon}. However, all other fields on
3721a497d3a2b1496c12949e47e55f8e46d8f585be5Daniel Sandler     * {@link StatusBarNotification}, sufficient to match this call with a prior call to
3731a497d3a2b1496c12949e47e55f8e46d8f585be5Daniel Sandler     * {@link #onNotificationPosted(StatusBarNotification)}, will be intact.
3745feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler     *
3751a497d3a2b1496c12949e47e55f8e46d8f585be5Daniel Sandler     * @param sbn A data structure encapsulating at least the original information (tag and id)
3761a497d3a2b1496c12949e47e55f8e46d8f585be5Daniel Sandler     *            and source (package name) used to post the {@link android.app.Notification} that
3771a497d3a2b1496c12949e47e55f8e46d8f585be5Daniel Sandler     *            was just removed.
378d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer     * @param rankingMap The current ranking map that can be used to retrieve ranking information
379d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer     *                   for active notifications.
380d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer     *
3815feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler     */
382d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer    public void onNotificationRemoved(StatusBarNotification sbn, RankingMap rankingMap) {
383d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer        onNotificationRemoved(sbn);
384d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer    }
3855feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler
3863aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds
3873aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds    /**
3883aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds     * Implement this method to learn when notifications are removed and why.
3893aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds     * <p>
3903aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds     * This might occur because the user has dismissed the notification using system UI (or another
3913aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds     * notification listener) or because the app has withdrawn the notification.
3923aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds     * <p>
3933aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds     * NOTE: The {@link StatusBarNotification} object you receive will be "light"; that is, the
3943aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds     * result from {@link StatusBarNotification#getNotification} may be missing some heavyweight
3953aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds     * fields such as {@link android.app.Notification#contentView} and
3963aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds     * {@link android.app.Notification#largeIcon}. However, all other fields on
3973aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds     * {@link StatusBarNotification}, sufficient to match this call with a prior call to
3983aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds     * {@link #onNotificationPosted(StatusBarNotification)}, will be intact.
3993aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds     *
4003aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds     ** @param sbn A data structure encapsulating at least the original information (tag and id)
4013aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds     *            and source (package name) used to post the {@link android.app.Notification} that
4023aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds     *            was just removed.
4033aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds     * @param rankingMap The current ranking map that can be used to retrieve ranking information
4043aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds     *                   for active notifications.
4053aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds     * @param reason see {@link #REASON_LISTENER_CANCEL}, etc.
4063aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds     */
4073aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds    public void onNotificationRemoved(StatusBarNotification sbn, RankingMap rankingMap,
4083aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds            int reason) {
4093aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds        onNotificationRemoved(sbn, rankingMap);
4103aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds    }
4113aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds
412a4294297d46cc0b9f45897bc688c267502cce3efJohn Spurlock    /**
413503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds     * NotificationStats are not populated for notification listeners, so fall back to
414503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds     * {@link #onNotificationRemoved(StatusBarNotification, RankingMap, int)}.
415503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds     *
416503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds     * @hide
417503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds     */
418503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds    @TestApi
419503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds    public void onNotificationRemoved(StatusBarNotification sbn, RankingMap rankingMap,
420503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds            NotificationStats stats, int reason) {
421503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds        onNotificationRemoved(sbn, rankingMap, reason);
422503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds    }
423503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds
424503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds    /**
425a4294297d46cc0b9f45897bc688c267502cce3efJohn Spurlock     * Implement this method to learn about when the listener is enabled and connected to
426cee44ba418bef83571349acb2d24ef29833502e0Christoph Studer     * the notification manager.  You are safe to call {@link #getActiveNotifications()}
427a4294297d46cc0b9f45897bc688c267502cce3efJohn Spurlock     * at this time.
428a4294297d46cc0b9f45897bc688c267502cce3efJohn Spurlock     */
429cee44ba418bef83571349acb2d24ef29833502e0Christoph Studer    public void onListenerConnected() {
430a4294297d46cc0b9f45897bc688c267502cce3efJohn Spurlock        // optional
431a4294297d46cc0b9f45897bc688c267502cce3efJohn Spurlock    }
432a4294297d46cc0b9f45897bc688c267502cce3efJohn Spurlock
433f953664dc17dca23bd724bd64f89189c16c83263Chris Wren    /**
4345717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     * Implement this method to learn about when the listener is disconnected from the
4355717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     * notification manager.You will not receive any events after this call, and may only
4365717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     * call {@link #requestRebind(ComponentName)} at this time.
4375717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     */
4385717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren    public void onListenerDisconnected() {
4395717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren        // optional
4405717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren    }
4415717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren
4425717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren    /**
44305ad48206a082057e17723d32493c153faa6881eChristoph Studer     * Implement this method to be notified when the notification ranking changes.
444d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer     *
445d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer     * @param rankingMap The current ranking map that can be used to retrieve ranking information
446d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer     *                   for active notifications.
447f953664dc17dca23bd724bd64f89189c16c83263Chris Wren     */
448d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer    public void onNotificationRankingUpdate(RankingMap rankingMap) {
449f953664dc17dca23bd724bd64f89189c16c83263Chris Wren        // optional
450f953664dc17dca23bd724bd64f89189c16c83263Chris Wren    }
451f953664dc17dca23bd724bd64f89189c16c83263Chris Wren
4521fa865f396e94913cfbbd32ce7799c2e8aeb7a08John Spurlock    /**
4531fa865f396e94913cfbbd32ce7799c2e8aeb7a08John Spurlock     * Implement this method to be notified when the
454d8afe3c41e65a8f6ff4283c124ba250c92cf50c6John Spurlock     * {@link #getCurrentListenerHints() Listener hints} change.
4551fa865f396e94913cfbbd32ce7799c2e8aeb7a08John Spurlock     *
456d8afe3c41e65a8f6ff4283c124ba250c92cf50c6John Spurlock     * @param hints The current {@link #getCurrentListenerHints() listener hints}.
4571fa865f396e94913cfbbd32ce7799c2e8aeb7a08John Spurlock     */
458d8afe3c41e65a8f6ff4283c124ba250c92cf50c6John Spurlock    public void onListenerHintsChanged(int hints) {
4591fa865f396e94913cfbbd32ce7799c2e8aeb7a08John Spurlock        // optional
4601fa865f396e94913cfbbd32ce7799c2e8aeb7a08John Spurlock    }
4611fa865f396e94913cfbbd32ce7799c2e8aeb7a08John Spurlock
46285a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer    /**
46373ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds     * Implement this method to learn about notification channel modifications.
46473ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds     *
46573ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds     * <p>The caller must have {@link CompanionDeviceManager#getAssociations() an associated
46673ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds     * device} in order to receive this callback.
46773ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds     *
46873ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds     * @param pkg The package the channel belongs to.
469f27d6b2b821bf818810a0e303d536906b889588dJulia Reynolds     * @param user The user on which the change was made.
47073ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds     * @param channel The channel that has changed.
47173ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds     * @param modificationType One of {@link #NOTIFICATION_CHANNEL_OR_GROUP_ADDED},
47273ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds     *                   {@link #NOTIFICATION_CHANNEL_OR_GROUP_UPDATED},
47373ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds     *                   {@link #NOTIFICATION_CHANNEL_OR_GROUP_DELETED}.
47473ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds     */
475f27d6b2b821bf818810a0e303d536906b889588dJulia Reynolds    public void onNotificationChannelModified(String pkg, UserHandle user,
476f27d6b2b821bf818810a0e303d536906b889588dJulia Reynolds            NotificationChannel channel, @ChannelOrGroupModificationTypes int modificationType) {
47773ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds        // optional
47873ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds    }
47973ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds
48073ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds    /**
48173ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds     * Implement this method to learn about notification channel group modifications.
48273ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds     *
48373ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds     * <p>The caller must have {@link CompanionDeviceManager#getAssociations() an associated
48473ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds     * device} in order to receive this callback.
48573ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds     *
48673ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds     * @param pkg The package the group belongs to.
487f27d6b2b821bf818810a0e303d536906b889588dJulia Reynolds     * @param user The user on which the change was made.
48873ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds     * @param group The group that has changed.
48973ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds     * @param modificationType One of {@link #NOTIFICATION_CHANNEL_OR_GROUP_ADDED},
49073ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds     *                   {@link #NOTIFICATION_CHANNEL_OR_GROUP_UPDATED},
49173ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds     *                   {@link #NOTIFICATION_CHANNEL_OR_GROUP_DELETED}.
49273ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds     */
493f27d6b2b821bf818810a0e303d536906b889588dJulia Reynolds    public void onNotificationChannelGroupModified(String pkg, UserHandle user,
494f27d6b2b821bf818810a0e303d536906b889588dJulia Reynolds            NotificationChannelGroup group, @ChannelOrGroupModificationTypes int modificationType) {
49573ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds        // optional
49673ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds    }
49773ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds
49873ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds    /**
49985a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer     * Implement this method to be notified when the
50085a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer     * {@link #getCurrentInterruptionFilter() interruption filter} changed.
50185a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer     *
50285a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer     * @param interruptionFilter The current
50385a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer     *     {@link #getCurrentInterruptionFilter() interruption filter}.
50485a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer     */
50585a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer    public void onInterruptionFilterChanged(int interruptionFilter) {
50685a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer        // optional
50785a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer    }
50885a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer
50951017d0e23ce9855fabcf786a2067ceb19121fbcChris Wren    /** @hide */
51051017d0e23ce9855fabcf786a2067ceb19121fbcChris Wren    protected final INotificationManager getNotificationInterface() {
5115feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler        if (mNoMan == null) {
5125feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler            mNoMan = INotificationManager.Stub.asInterface(
5135feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler                    ServiceManager.getService(Context.NOTIFICATION_SERVICE));
5145feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler        }
5155feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler        return mNoMan;
5165feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler    }
5175feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler
5185feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler    /**
5195feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler     * Inform the notification manager about dismissal of a single notification.
5205feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler     * <p>
5215feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler     * Use this if your listener has a user interface that allows the user to dismiss individual
5225feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler     * notifications, similar to the behavior of Android's status bar and notification panel.
5235feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler     * It should be called after the user dismisses a single notification using your UI;
5245feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler     * upon being informed, the notification manager will actually remove the notification
5255feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler     * and you will get an {@link #onNotificationRemoved(StatusBarNotification)} callback.
5265717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     * <p>
5275feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler     * <b>Note:</b> If your listener allows the user to fire a notification's
5285feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler     * {@link android.app.Notification#contentIntent} by tapping/clicking/etc., you should call
5295feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler     * this method at that time <i>if</i> the Notification in question has the
5305feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler     * {@link android.app.Notification#FLAG_AUTO_CANCEL} flag set.
5315feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler     *
5325717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     * <p>The service should wait for the {@link #onListenerConnected()} event
5335717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     * before performing this operation.
5345717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     *
5355feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler     * @param pkg Package of the notifying app.
5365feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler     * @param tag Tag of the notification as specified by the notifying app in
5375feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler     *     {@link android.app.NotificationManager#notify(String, int, android.app.Notification)}.
5385feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler     * @param id  ID of the notification as specified by the notifying app in
5395feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler     *     {@link android.app.NotificationManager#notify(String, int, android.app.Notification)}.
540a263e4e438746f91fb78857bd569ba4f796a346dKenny Guy     * <p>
541a263e4e438746f91fb78857bd569ba4f796a346dKenny Guy     * @deprecated Use {@link #cancelNotification(String key)}
542955d8d69ea6caabce1461dc25b339b9bf9dc61a6Dianne Hackborn     * instead. Beginning with {@link android.os.Build.VERSION_CODES#LOLLIPOP} this method will no longer
543a263e4e438746f91fb78857bd569ba4f796a346dKenny Guy     * cancel the notification. It will continue to cancel the notification for applications
544955d8d69ea6caabce1461dc25b339b9bf9dc61a6Dianne Hackborn     * whose {@code targetSdkVersion} is earlier than {@link android.os.Build.VERSION_CODES#LOLLIPOP}.
5455feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler     */
546514c5ef8d5774d8820ed1bf90fe53af1606cf106Aurimas Liutikas    @Deprecated
547e6f7f2e3a01b8deb00e03ccfa93751c315f14ef0Daniel Sandler    public final void cancelNotification(String pkg, String tag, int id) {
548da9a3bed8e1aa7d7867291a123466bb0a3be5bb0John Spurlock        if (!isBound()) return;
5495feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler        try {
550a263e4e438746f91fb78857bd569ba4f796a346dKenny Guy            getNotificationInterface().cancelNotificationFromListener(
551a263e4e438746f91fb78857bd569ba4f796a346dKenny Guy                    mWrapper, pkg, tag, id);
552a263e4e438746f91fb78857bd569ba4f796a346dKenny Guy        } catch (android.os.RemoteException ex) {
553a263e4e438746f91fb78857bd569ba4f796a346dKenny Guy            Log.v(TAG, "Unable to contact notification manager", ex);
554a263e4e438746f91fb78857bd569ba4f796a346dKenny Guy        }
555a263e4e438746f91fb78857bd569ba4f796a346dKenny Guy    }
556a263e4e438746f91fb78857bd569ba4f796a346dKenny Guy
557a263e4e438746f91fb78857bd569ba4f796a346dKenny Guy    /**
558a263e4e438746f91fb78857bd569ba4f796a346dKenny Guy     * Inform the notification manager about dismissal of a single notification.
559a263e4e438746f91fb78857bd569ba4f796a346dKenny Guy     * <p>
560a263e4e438746f91fb78857bd569ba4f796a346dKenny Guy     * Use this if your listener has a user interface that allows the user to dismiss individual
561a263e4e438746f91fb78857bd569ba4f796a346dKenny Guy     * notifications, similar to the behavior of Android's status bar and notification panel.
562a263e4e438746f91fb78857bd569ba4f796a346dKenny Guy     * It should be called after the user dismisses a single notification using your UI;
563a263e4e438746f91fb78857bd569ba4f796a346dKenny Guy     * upon being informed, the notification manager will actually remove the notification
564a263e4e438746f91fb78857bd569ba4f796a346dKenny Guy     * and you will get an {@link #onNotificationRemoved(StatusBarNotification)} callback.
5655717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     * <p>
566a263e4e438746f91fb78857bd569ba4f796a346dKenny Guy     * <b>Note:</b> If your listener allows the user to fire a notification's
567a263e4e438746f91fb78857bd569ba4f796a346dKenny Guy     * {@link android.app.Notification#contentIntent} by tapping/clicking/etc., you should call
568a263e4e438746f91fb78857bd569ba4f796a346dKenny Guy     * this method at that time <i>if</i> the Notification in question has the
569a263e4e438746f91fb78857bd569ba4f796a346dKenny Guy     * {@link android.app.Notification#FLAG_AUTO_CANCEL} flag set.
570a263e4e438746f91fb78857bd569ba4f796a346dKenny Guy     * <p>
5715717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     *
5725717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     * <p>The service should wait for the {@link #onListenerConnected()} event
5735717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     * before performing this operation.
5745717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     *
575a263e4e438746f91fb78857bd569ba4f796a346dKenny Guy     * @param key Notification to dismiss from {@link StatusBarNotification#getKey()}.
576a263e4e438746f91fb78857bd569ba4f796a346dKenny Guy     */
577a263e4e438746f91fb78857bd569ba4f796a346dKenny Guy    public final void cancelNotification(String key) {
578a263e4e438746f91fb78857bd569ba4f796a346dKenny Guy        if (!isBound()) return;
579a263e4e438746f91fb78857bd569ba4f796a346dKenny Guy        try {
580a263e4e438746f91fb78857bd569ba4f796a346dKenny Guy            getNotificationInterface().cancelNotificationsFromListener(mWrapper,
581f5a7838e19c1cb6437a8b32ba9980ac1ce8804e2Daniel Sandler                    new String[] { key });
5825feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler        } catch (android.os.RemoteException ex) {
5835feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler            Log.v(TAG, "Unable to contact notification manager", ex);
5845feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler        }
5855feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler    }
5865feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler
5875feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler    /**
5885feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler     * Inform the notification manager about dismissal of all notifications.
5895feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler     * <p>
5905feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler     * Use this if your listener has a user interface that allows the user to dismiss all
5915feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler     * notifications, similar to the behavior of Android's status bar and notification panel.
5925feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler     * It should be called after the user invokes the "dismiss all" function of your UI;
5935feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler     * upon being informed, the notification manager will actually remove all active notifications
5945feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler     * and you will get multiple {@link #onNotificationRemoved(StatusBarNotification)} callbacks.
5955feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler     *
5965717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     * <p>The service should wait for the {@link #onListenerConnected()} event
5975717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     * before performing this operation.
5985717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     *
599e6f7f2e3a01b8deb00e03ccfa93751c315f14ef0Daniel Sandler     * {@see #cancelNotification(String, String, int)}
6005feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler     */
601e6f7f2e3a01b8deb00e03ccfa93751c315f14ef0Daniel Sandler    public final void cancelAllNotifications() {
602a4294297d46cc0b9f45897bc688c267502cce3efJohn Spurlock        cancelNotifications(null /*all*/);
603a4294297d46cc0b9f45897bc688c267502cce3efJohn Spurlock    }
604a4294297d46cc0b9f45897bc688c267502cce3efJohn Spurlock
605a4294297d46cc0b9f45897bc688c267502cce3efJohn Spurlock    /**
606a4294297d46cc0b9f45897bc688c267502cce3efJohn Spurlock     * Inform the notification manager about dismissal of specific notifications.
607a4294297d46cc0b9f45897bc688c267502cce3efJohn Spurlock     * <p>
608a4294297d46cc0b9f45897bc688c267502cce3efJohn Spurlock     * Use this if your listener has a user interface that allows the user to dismiss
609a4294297d46cc0b9f45897bc688c267502cce3efJohn Spurlock     * multiple notifications at once.
610a4294297d46cc0b9f45897bc688c267502cce3efJohn Spurlock     *
6115717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     * <p>The service should wait for the {@link #onListenerConnected()} event
6125717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     * before performing this operation.
6135717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     *
614a4294297d46cc0b9f45897bc688c267502cce3efJohn Spurlock     * @param keys Notifications to dismiss, or {@code null} to dismiss all.
615a4294297d46cc0b9f45897bc688c267502cce3efJohn Spurlock     *
616a4294297d46cc0b9f45897bc688c267502cce3efJohn Spurlock     * {@see #cancelNotification(String, String, int)}
617a4294297d46cc0b9f45897bc688c267502cce3efJohn Spurlock     */
618a4294297d46cc0b9f45897bc688c267502cce3efJohn Spurlock    public final void cancelNotifications(String[] keys) {
619da9a3bed8e1aa7d7867291a123466bb0a3be5bb0John Spurlock        if (!isBound()) return;
6205feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler        try {
621a4294297d46cc0b9f45897bc688c267502cce3efJohn Spurlock            getNotificationInterface().cancelNotificationsFromListener(mWrapper, keys);
6225feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler        } catch (android.os.RemoteException ex) {
6235feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler            Log.v(TAG, "Unable to contact notification manager", ex);
6245feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler        }
62572f1cbb3b988d6daa61c45a69aa9f8024c029b06Julia Reynolds    }
62672f1cbb3b988d6daa61c45a69aa9f8024c029b06Julia Reynolds
62772f1cbb3b988d6daa61c45a69aa9f8024c029b06Julia Reynolds    /**
62872f1cbb3b988d6daa61c45a69aa9f8024c029b06Julia Reynolds     * Inform the notification manager about snoozing a specific notification.
62972f1cbb3b988d6daa61c45a69aa9f8024c029b06Julia Reynolds     * <p>
63072f1cbb3b988d6daa61c45a69aa9f8024c029b06Julia Reynolds     * Use this if your listener has a user interface that allows the user to snooze a notification
6317967230de20aeb6993d8332347752c8e508769e4Julia Reynolds     * until a given {@link SnoozeCriterion}. It should be called after the user snoozes a single
6327967230de20aeb6993d8332347752c8e508769e4Julia Reynolds     * notification using your UI; upon being informed, the notification manager will actually
6337967230de20aeb6993d8332347752c8e508769e4Julia Reynolds     * remove the notification and you will get an
6347967230de20aeb6993d8332347752c8e508769e4Julia Reynolds     * {@link #onNotificationRemoved(StatusBarNotification)} callback. When the snoozing period
6357967230de20aeb6993d8332347752c8e508769e4Julia Reynolds     * expires, you will get a {@link #onNotificationPosted(StatusBarNotification, RankingMap)}
6367967230de20aeb6993d8332347752c8e508769e4Julia Reynolds     * callback for the notification.
6377967230de20aeb6993d8332347752c8e508769e4Julia Reynolds     * @param key The key of the notification to snooze
6387967230de20aeb6993d8332347752c8e508769e4Julia Reynolds     * @param snoozeCriterionId The{@link SnoozeCriterion#getId()} of a context to snooze the
6397967230de20aeb6993d8332347752c8e508769e4Julia Reynolds     *                          notification until.
6401327d3c3fabc9b4ffeb20e589f7b2350567b681fJulia Reynolds     * @hide
6417ca33079fda388dd3bd81819b280e578e5d6b38bJulia Reynolds     * @removed
6427967230de20aeb6993d8332347752c8e508769e4Julia Reynolds     */
6431327d3c3fabc9b4ffeb20e589f7b2350567b681fJulia Reynolds    @SystemApi
6447967230de20aeb6993d8332347752c8e508769e4Julia Reynolds    public final void snoozeNotification(String key, String snoozeCriterionId) {
6457967230de20aeb6993d8332347752c8e508769e4Julia Reynolds        if (!isBound()) return;
6467967230de20aeb6993d8332347752c8e508769e4Julia Reynolds        try {
6477967230de20aeb6993d8332347752c8e508769e4Julia Reynolds            getNotificationInterface().snoozeNotificationUntilContextFromListener(
6487967230de20aeb6993d8332347752c8e508769e4Julia Reynolds                    mWrapper, key, snoozeCriterionId);
6497967230de20aeb6993d8332347752c8e508769e4Julia Reynolds        } catch (android.os.RemoteException ex) {
6507967230de20aeb6993d8332347752c8e508769e4Julia Reynolds            Log.v(TAG, "Unable to contact notification manager", ex);
6517967230de20aeb6993d8332347752c8e508769e4Julia Reynolds        }
6527967230de20aeb6993d8332347752c8e508769e4Julia Reynolds    }
6537967230de20aeb6993d8332347752c8e508769e4Julia Reynolds
6547967230de20aeb6993d8332347752c8e508769e4Julia Reynolds    /**
6557967230de20aeb6993d8332347752c8e508769e4Julia Reynolds     * Inform the notification manager about snoozing a specific notification.
6567967230de20aeb6993d8332347752c8e508769e4Julia Reynolds     * <p>
6577967230de20aeb6993d8332347752c8e508769e4Julia Reynolds     * Use this if your listener has a user interface that allows the user to snooze a notification
6585098977b20699c2ed32a621524abd5a1b2ab7de4Julia Reynolds     * for a time. It should be called after the user snoozes a single notification using
65972f1cbb3b988d6daa61c45a69aa9f8024c029b06Julia Reynolds     * your UI; upon being informed, the notification manager will actually remove the notification
66072f1cbb3b988d6daa61c45a69aa9f8024c029b06Julia Reynolds     * and you will get an {@link #onNotificationRemoved(StatusBarNotification)} callback. When the
66172f1cbb3b988d6daa61c45a69aa9f8024c029b06Julia Reynolds     * snoozing period expires, you will get a
66272f1cbb3b988d6daa61c45a69aa9f8024c029b06Julia Reynolds     * {@link #onNotificationPosted(StatusBarNotification, RankingMap)} callback for the
66372f1cbb3b988d6daa61c45a69aa9f8024c029b06Julia Reynolds     * notification.
66472f1cbb3b988d6daa61c45a69aa9f8024c029b06Julia Reynolds     * @param key The key of the notification to snooze
6655098977b20699c2ed32a621524abd5a1b2ab7de4Julia Reynolds     * @param durationMs A duration to snooze the notification for, in milliseconds.
66672f1cbb3b988d6daa61c45a69aa9f8024c029b06Julia Reynolds     */
6675098977b20699c2ed32a621524abd5a1b2ab7de4Julia Reynolds    public final void snoozeNotification(String key, long durationMs) {
66872f1cbb3b988d6daa61c45a69aa9f8024c029b06Julia Reynolds        if (!isBound()) return;
66972f1cbb3b988d6daa61c45a69aa9f8024c029b06Julia Reynolds        try {
670b6c1f99bd96d2f38980f4473baf3aa908d059db2Julia Reynolds            getNotificationInterface().snoozeNotificationUntilFromListener(
6715098977b20699c2ed32a621524abd5a1b2ab7de4Julia Reynolds                    mWrapper, key, durationMs);
672b6c1f99bd96d2f38980f4473baf3aa908d059db2Julia Reynolds        } catch (android.os.RemoteException ex) {
673b6c1f99bd96d2f38980f4473baf3aa908d059db2Julia Reynolds            Log.v(TAG, "Unable to contact notification manager", ex);
674b6c1f99bd96d2f38980f4473baf3aa908d059db2Julia Reynolds        }
675b6c1f99bd96d2f38980f4473baf3aa908d059db2Julia Reynolds    }
676b6c1f99bd96d2f38980f4473baf3aa908d059db2Julia Reynolds
6775feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler
67825cf8cee6f304a286d321204e448b18ce733a60cDaniel Sandler    /**
679f47e51ec605fccf7fed9e50d1adc98fbd4e8b340Amith Yamasani     * Inform the notification manager that these notifications have been viewed by the
680c6ecbce42b8a529447ff327a7902d9da0aeb4310Amith Yamasani     * user. This should only be called when there is sufficient confidence that the user is
681c6ecbce42b8a529447ff327a7902d9da0aeb4310Amith Yamasani     * looking at the notifications, such as when the notifications appear on the screen due to
682c6ecbce42b8a529447ff327a7902d9da0aeb4310Amith Yamasani     * an explicit user interaction.
6835717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     *
6845717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     * <p>The service should wait for the {@link #onListenerConnected()} event
6855717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     * before performing this operation.
6865717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     *
687f47e51ec605fccf7fed9e50d1adc98fbd4e8b340Amith Yamasani     * @param keys Notifications to mark as seen.
688f47e51ec605fccf7fed9e50d1adc98fbd4e8b340Amith Yamasani     */
689f47e51ec605fccf7fed9e50d1adc98fbd4e8b340Amith Yamasani    public final void setNotificationsShown(String[] keys) {
690f47e51ec605fccf7fed9e50d1adc98fbd4e8b340Amith Yamasani        if (!isBound()) return;
691f47e51ec605fccf7fed9e50d1adc98fbd4e8b340Amith Yamasani        try {
692f47e51ec605fccf7fed9e50d1adc98fbd4e8b340Amith Yamasani            getNotificationInterface().setNotificationsShownFromListener(mWrapper, keys);
693f47e51ec605fccf7fed9e50d1adc98fbd4e8b340Amith Yamasani        } catch (android.os.RemoteException ex) {
694f47e51ec605fccf7fed9e50d1adc98fbd4e8b340Amith Yamasani            Log.v(TAG, "Unable to contact notification manager", ex);
695f47e51ec605fccf7fed9e50d1adc98fbd4e8b340Amith Yamasani        }
696f47e51ec605fccf7fed9e50d1adc98fbd4e8b340Amith Yamasani    }
697f47e51ec605fccf7fed9e50d1adc98fbd4e8b340Amith Yamasani
69873ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds
69973ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds    /**
700f27d6b2b821bf818810a0e303d536906b889588dJulia Reynolds     * Updates a notification channel for a given package for a given user. This should only be used
701f27d6b2b821bf818810a0e303d536906b889588dJulia Reynolds     * to reflect changes a user has made to the channel via the listener's user interface.
70273ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds     *
703f27d6b2b821bf818810a0e303d536906b889588dJulia Reynolds     * <p>This method will throw a security exception if you don't have access to notifications
704f27d6b2b821bf818810a0e303d536906b889588dJulia Reynolds     * for the given user.</p>
70573ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds     * <p>The caller must have {@link CompanionDeviceManager#getAssociations() an associated
70673ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds     * device} in order to use this method.
70773ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds     *
70873ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds     * @param pkg The package the channel belongs to.
709f27d6b2b821bf818810a0e303d536906b889588dJulia Reynolds     * @param user The user the channel belongs to.
71073ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds     * @param channel the channel to update.
71173ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds     */
712f27d6b2b821bf818810a0e303d536906b889588dJulia Reynolds    public final void updateNotificationChannel(@NonNull String pkg, @NonNull UserHandle user,
71373ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds            @NonNull NotificationChannel channel) {
71473ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds        if (!isBound()) return;
71573ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds        try {
71673ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds            getNotificationInterface().updateNotificationChannelFromPrivilegedListener(
717f27d6b2b821bf818810a0e303d536906b889588dJulia Reynolds                    mWrapper, pkg, user, channel);
71873ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds        } catch (RemoteException e) {
71973ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds            Log.v(TAG, "Unable to contact notification manager", e);
72073ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds            throw e.rethrowFromSystemServer();
72173ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds        }
72273ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds    }
72373ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds
72473ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds    /**
725f27d6b2b821bf818810a0e303d536906b889588dJulia Reynolds     * Returns all notification channels belonging to the given package for a given user.
72673ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds     *
727f27d6b2b821bf818810a0e303d536906b889588dJulia Reynolds     * <p>This method will throw a security exception if you don't have access to notifications
728f27d6b2b821bf818810a0e303d536906b889588dJulia Reynolds     * for the given user.</p>
72973ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds     * <p>The caller must have {@link CompanionDeviceManager#getAssociations() an associated
73073ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds     * device} in order to use this method.
73173ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds     *
73273ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds     * @param pkg The package to retrieve channels for.
73373ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds     */
734f27d6b2b821bf818810a0e303d536906b889588dJulia Reynolds    public final List<NotificationChannel> getNotificationChannels(@NonNull String pkg,
735f27d6b2b821bf818810a0e303d536906b889588dJulia Reynolds            @NonNull UserHandle user) {
73673ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds        if (!isBound()) return null;
73773ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds        try {
73873ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds
73973ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds            return getNotificationInterface().getNotificationChannelsFromPrivilegedListener(
740f27d6b2b821bf818810a0e303d536906b889588dJulia Reynolds                    mWrapper, pkg, user).getList();
74173ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds        } catch (RemoteException e) {
74273ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds            Log.v(TAG, "Unable to contact notification manager", e);
74373ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds            throw e.rethrowFromSystemServer();
74473ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds        }
74573ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds    }
74673ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds
74773ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds    /**
748f27d6b2b821bf818810a0e303d536906b889588dJulia Reynolds     * Returns all notification channel groups belonging to the given package for a given user.
74973ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds     *
750f27d6b2b821bf818810a0e303d536906b889588dJulia Reynolds     * <p>This method will throw a security exception if you don't have access to notifications
751f27d6b2b821bf818810a0e303d536906b889588dJulia Reynolds     * for the given user.</p>
75273ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds     * <p>The caller must have {@link CompanionDeviceManager#getAssociations() an associated
75373ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds     * device} in order to use this method.
75473ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds     *
75573ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds     * @param pkg The package to retrieve channel groups for.
75673ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds     */
757f27d6b2b821bf818810a0e303d536906b889588dJulia Reynolds    public final List<NotificationChannelGroup> getNotificationChannelGroups(@NonNull String pkg,
758f27d6b2b821bf818810a0e303d536906b889588dJulia Reynolds            @NonNull UserHandle user) {
75973ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds        if (!isBound()) return null;
76073ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds        try {
76173ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds
76273ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds            return getNotificationInterface().getNotificationChannelGroupsFromPrivilegedListener(
763f27d6b2b821bf818810a0e303d536906b889588dJulia Reynolds                    mWrapper, pkg, user).getList();
76473ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds        } catch (RemoteException e) {
76573ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds            Log.v(TAG, "Unable to contact notification manager", e);
76673ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds            throw e.rethrowFromSystemServer();
76773ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds        }
76873ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds    }
76973ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds
770f47e51ec605fccf7fed9e50d1adc98fbd4e8b340Amith Yamasani    /**
771b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer     * Sets the notification trim that will be received via {@link #onNotificationPosted}.
772b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer     *
773b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer     * <p>
774b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer     * Setting a trim other than {@link #TRIM_FULL} enables listeners that don't need access to the
775b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer     * full notification features right away to reduce their memory footprint. Full notifications
776b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer     * can be requested on-demand via {@link #getActiveNotifications(int)}.
777b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer     *
778b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer     * <p>
779b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer     * Set to {@link #TRIM_FULL} initially.
780b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer     *
7815717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     * <p>The service should wait for the {@link #onListenerConnected()} event
7825717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     * before performing this operation.
7835717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     *
784b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer     * @hide
7857ca33079fda388dd3bd81819b280e578e5d6b38bJulia Reynolds     * @removed
786b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer     *
787b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer     * @param trim trim of the notifications to be passed via {@link #onNotificationPosted}.
788b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer     *             See <code>TRIM_*</code> constants.
789b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer     */
790b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer    @SystemApi
791b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer    public final void setOnNotificationPostedTrim(int trim) {
792b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer        if (!isBound()) return;
793b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer        try {
794b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer            getNotificationInterface().setOnNotificationPostedTrimFromListener(mWrapper, trim);
795b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer        } catch (RemoteException ex) {
796b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer            Log.v(TAG, "Unable to contact notification manager", ex);
797b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer        }
798b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer    }
799b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer
800b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer    /**
80125cf8cee6f304a286d321204e448b18ce733a60cDaniel Sandler     * Request the list of outstanding notifications (that is, those that are visible to the
802a4294297d46cc0b9f45897bc688c267502cce3efJohn Spurlock     * current user). Useful when you don't know what's already been posted.
80325cf8cee6f304a286d321204e448b18ce733a60cDaniel Sandler     *
8045717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     * <p>The service should wait for the {@link #onListenerConnected()} event
8055717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     * before performing this operation.
8065717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     *
807f953664dc17dca23bd724bd64f89189c16c83263Chris Wren     * @return An array of active notifications, sorted in natural order.
80825cf8cee6f304a286d321204e448b18ce733a60cDaniel Sandler     */
80925cf8cee6f304a286d321204e448b18ce733a60cDaniel Sandler    public StatusBarNotification[] getActiveNotifications() {
81094a38b35e907fc560d4beec3bfb78360411609a3Julia Reynolds        StatusBarNotification[] activeNotifications = getActiveNotifications(null, TRIM_FULL);
81194a38b35e907fc560d4beec3bfb78360411609a3Julia Reynolds        return activeNotifications != null ? activeNotifications : new StatusBarNotification[0];
812b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer    }
813b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer
814b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer    /**
815cf63ff1532e793560f62e1c75f3402b48b0f09baJulia Reynolds     * Like {@link #getActiveNotifications()}, but returns the list of currently snoozed
816cf63ff1532e793560f62e1c75f3402b48b0f09baJulia Reynolds     * notifications, for all users this listener has access to.
817cf63ff1532e793560f62e1c75f3402b48b0f09baJulia Reynolds     *
818cf63ff1532e793560f62e1c75f3402b48b0f09baJulia Reynolds     * <p>The service should wait for the {@link #onListenerConnected()} event
819cf63ff1532e793560f62e1c75f3402b48b0f09baJulia Reynolds     * before performing this operation.
820cf63ff1532e793560f62e1c75f3402b48b0f09baJulia Reynolds     *
821a11d0b18ec9275ed8d633e4508074226b7372474Julia Reynolds     * @return An array of snoozed notifications, sorted in natural order.
822cf63ff1532e793560f62e1c75f3402b48b0f09baJulia Reynolds     */
823cf63ff1532e793560f62e1c75f3402b48b0f09baJulia Reynolds    public final StatusBarNotification[] getSnoozedNotifications() {
824cf63ff1532e793560f62e1c75f3402b48b0f09baJulia Reynolds        try {
825cf63ff1532e793560f62e1c75f3402b48b0f09baJulia Reynolds            ParceledListSlice<StatusBarNotification> parceledList = getNotificationInterface()
826cf63ff1532e793560f62e1c75f3402b48b0f09baJulia Reynolds                    .getSnoozedNotificationsFromListener(mWrapper, TRIM_FULL);
827cf63ff1532e793560f62e1c75f3402b48b0f09baJulia Reynolds            return cleanUpNotificationList(parceledList);
828cf63ff1532e793560f62e1c75f3402b48b0f09baJulia Reynolds        } catch (android.os.RemoteException ex) {
829cf63ff1532e793560f62e1c75f3402b48b0f09baJulia Reynolds            Log.v(TAG, "Unable to contact notification manager", ex);
830cf63ff1532e793560f62e1c75f3402b48b0f09baJulia Reynolds        }
831cf63ff1532e793560f62e1c75f3402b48b0f09baJulia Reynolds        return null;
832cf63ff1532e793560f62e1c75f3402b48b0f09baJulia Reynolds    }
833cf63ff1532e793560f62e1c75f3402b48b0f09baJulia Reynolds
834cf63ff1532e793560f62e1c75f3402b48b0f09baJulia Reynolds    /**
835b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer     * Request the list of outstanding notifications (that is, those that are visible to the
836b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer     * current user). Useful when you don't know what's already been posted.
837b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer     *
838b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer     * @hide
8397ca33079fda388dd3bd81819b280e578e5d6b38bJulia Reynolds     * @removed
840b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer     *
841b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer     * @param trim trim of the notifications to be returned. See <code>TRIM_*</code> constants.
842b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer     * @return An array of active notifications, sorted in natural order.
843b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer     */
844b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer    @SystemApi
845b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer    public StatusBarNotification[] getActiveNotifications(int trim) {
84694a38b35e907fc560d4beec3bfb78360411609a3Julia Reynolds        StatusBarNotification[] activeNotifications = getActiveNotifications(null, trim);
84794a38b35e907fc560d4beec3bfb78360411609a3Julia Reynolds        return activeNotifications != null ? activeNotifications : new StatusBarNotification[0];
848ea75fddbb452638f286c2fcdbddff145ee1a85cbDan Sandler    }
849ea75fddbb452638f286c2fcdbddff145ee1a85cbDan Sandler
850ea75fddbb452638f286c2fcdbddff145ee1a85cbDan Sandler    /**
851ea75fddbb452638f286c2fcdbddff145ee1a85cbDan Sandler     * Request one or more notifications by key. Useful if you have been keeping track of
852ea75fddbb452638f286c2fcdbddff145ee1a85cbDan Sandler     * notifications but didn't want to retain the bits, and now need to go back and extract
853ea75fddbb452638f286c2fcdbddff145ee1a85cbDan Sandler     * more data out of those notifications.
854ea75fddbb452638f286c2fcdbddff145ee1a85cbDan Sandler     *
8555717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     * <p>The service should wait for the {@link #onListenerConnected()} event
8565717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     * before performing this operation.
8575717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     *
858b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer     * @param keys the keys of the notifications to request
859ea75fddbb452638f286c2fcdbddff145ee1a85cbDan Sandler     * @return An array of notifications corresponding to the requested keys, in the
860ea75fddbb452638f286c2fcdbddff145ee1a85cbDan Sandler     * same order as the key list.
861ea75fddbb452638f286c2fcdbddff145ee1a85cbDan Sandler     */
862ea75fddbb452638f286c2fcdbddff145ee1a85cbDan Sandler    public StatusBarNotification[] getActiveNotifications(String[] keys) {
86394a38b35e907fc560d4beec3bfb78360411609a3Julia Reynolds        StatusBarNotification[] activeNotifications = getActiveNotifications(keys, TRIM_FULL);
86494a38b35e907fc560d4beec3bfb78360411609a3Julia Reynolds        return activeNotifications != null ? activeNotifications : new StatusBarNotification[0];
865b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer    }
866b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer
867b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer    /**
868b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer     * Request one or more notifications by key. Useful if you have been keeping track of
869b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer     * notifications but didn't want to retain the bits, and now need to go back and extract
870b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer     * more data out of those notifications.
871b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer     *
872b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer     * @hide
8737ca33079fda388dd3bd81819b280e578e5d6b38bJulia Reynolds     * @removed
874b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer     *
875b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer     * @param keys the keys of the notifications to request
876b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer     * @param trim trim of the notifications to be returned. See <code>TRIM_*</code> constants.
877b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer     * @return An array of notifications corresponding to the requested keys, in the
878b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer     * same order as the key list.
879b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer     */
880b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer    @SystemApi
881b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer    public StatusBarNotification[] getActiveNotifications(String[] keys, int trim) {
882b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer        if (!isBound())
883b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer            return null;
884a4294297d46cc0b9f45897bc688c267502cce3efJohn Spurlock        try {
885b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer            ParceledListSlice<StatusBarNotification> parceledList = getNotificationInterface()
886b82bc785c966b59621a3a2523ba7cdf84a73697bChristoph Studer                    .getActiveNotificationsFromListener(mWrapper, keys, trim);
887cf63ff1532e793560f62e1c75f3402b48b0f09baJulia Reynolds            return cleanUpNotificationList(parceledList);
888a4294297d46cc0b9f45897bc688c267502cce3efJohn Spurlock        } catch (android.os.RemoteException ex) {
889a4294297d46cc0b9f45897bc688c267502cce3efJohn Spurlock            Log.v(TAG, "Unable to contact notification manager", ex);
890a4294297d46cc0b9f45897bc688c267502cce3efJohn Spurlock        }
891a4294297d46cc0b9f45897bc688c267502cce3efJohn Spurlock        return null;
892a4294297d46cc0b9f45897bc688c267502cce3efJohn Spurlock    }
893a4294297d46cc0b9f45897bc688c267502cce3efJohn Spurlock
894cf63ff1532e793560f62e1c75f3402b48b0f09baJulia Reynolds    private StatusBarNotification[] cleanUpNotificationList(
895cf63ff1532e793560f62e1c75f3402b48b0f09baJulia Reynolds            ParceledListSlice<StatusBarNotification> parceledList) {
89694a38b35e907fc560d4beec3bfb78360411609a3Julia Reynolds        if (parceledList == null || parceledList.getList() == null) {
89794a38b35e907fc560d4beec3bfb78360411609a3Julia Reynolds            return new StatusBarNotification[0];
89894a38b35e907fc560d4beec3bfb78360411609a3Julia Reynolds        }
899cf63ff1532e793560f62e1c75f3402b48b0f09baJulia Reynolds        List<StatusBarNotification> list = parceledList.getList();
900cf63ff1532e793560f62e1c75f3402b48b0f09baJulia Reynolds        ArrayList<StatusBarNotification> corruptNotifications = null;
901cf63ff1532e793560f62e1c75f3402b48b0f09baJulia Reynolds        int N = list.size();
902cf63ff1532e793560f62e1c75f3402b48b0f09baJulia Reynolds        for (int i = 0; i < N; i++) {
903cf63ff1532e793560f62e1c75f3402b48b0f09baJulia Reynolds            StatusBarNotification sbn = list.get(i);
904cf63ff1532e793560f62e1c75f3402b48b0f09baJulia Reynolds            Notification notification = sbn.getNotification();
905cf63ff1532e793560f62e1c75f3402b48b0f09baJulia Reynolds            try {
906cf63ff1532e793560f62e1c75f3402b48b0f09baJulia Reynolds                // convert icon metadata to legacy format for older clients
907cf63ff1532e793560f62e1c75f3402b48b0f09baJulia Reynolds                createLegacyIconExtras(notification);
908cf63ff1532e793560f62e1c75f3402b48b0f09baJulia Reynolds                // populate remote views for older clients.
909cf63ff1532e793560f62e1c75f3402b48b0f09baJulia Reynolds                maybePopulateRemoteViews(notification);
910e7238dd12595cb6be953aed4271636df90de17fcSelim Cinek                // populate people for older clients.
911e7238dd12595cb6be953aed4271636df90de17fcSelim Cinek                maybePopulatePeople(notification);
912cf63ff1532e793560f62e1c75f3402b48b0f09baJulia Reynolds            } catch (IllegalArgumentException e) {
913cf63ff1532e793560f62e1c75f3402b48b0f09baJulia Reynolds                if (corruptNotifications == null) {
914cf63ff1532e793560f62e1c75f3402b48b0f09baJulia Reynolds                    corruptNotifications = new ArrayList<>(N);
915cf63ff1532e793560f62e1c75f3402b48b0f09baJulia Reynolds                }
916cf63ff1532e793560f62e1c75f3402b48b0f09baJulia Reynolds                corruptNotifications.add(sbn);
917cf63ff1532e793560f62e1c75f3402b48b0f09baJulia Reynolds                Log.w(TAG, "get(Active/Snoozed)Notifications: can't rebuild notification from " +
918cf63ff1532e793560f62e1c75f3402b48b0f09baJulia Reynolds                        sbn.getPackageName());
919cf63ff1532e793560f62e1c75f3402b48b0f09baJulia Reynolds            }
920cf63ff1532e793560f62e1c75f3402b48b0f09baJulia Reynolds        }
921cf63ff1532e793560f62e1c75f3402b48b0f09baJulia Reynolds        if (corruptNotifications != null) {
922cf63ff1532e793560f62e1c75f3402b48b0f09baJulia Reynolds            list.removeAll(corruptNotifications);
923cf63ff1532e793560f62e1c75f3402b48b0f09baJulia Reynolds        }
924cf63ff1532e793560f62e1c75f3402b48b0f09baJulia Reynolds        return list.toArray(new StatusBarNotification[list.size()]);
925cf63ff1532e793560f62e1c75f3402b48b0f09baJulia Reynolds    }
926cf63ff1532e793560f62e1c75f3402b48b0f09baJulia Reynolds
927a4294297d46cc0b9f45897bc688c267502cce3efJohn Spurlock    /**
928d8afe3c41e65a8f6ff4283c124ba250c92cf50c6John Spurlock     * Gets the set of hints representing current state.
9291fa865f396e94913cfbbd32ce7799c2e8aeb7a08John Spurlock     *
9301fa865f396e94913cfbbd32ce7799c2e8aeb7a08John Spurlock     * <p>
931d8afe3c41e65a8f6ff4283c124ba250c92cf50c6John Spurlock     * The current state may differ from the requested state if the hint represents state
9321fa865f396e94913cfbbd32ce7799c2e8aeb7a08John Spurlock     * shared across all listeners or a feature the notification host does not support or refuses
9331fa865f396e94913cfbbd32ce7799c2e8aeb7a08John Spurlock     * to grant.
9341fa865f396e94913cfbbd32ce7799c2e8aeb7a08John Spurlock     *
9355717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     * <p>The service should wait for the {@link #onListenerConnected()} event
9365717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     * before performing this operation.
9375717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     *
93885a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer     * @return Zero or more of the HINT_ constants.
9391fa865f396e94913cfbbd32ce7799c2e8aeb7a08John Spurlock     */
940d8afe3c41e65a8f6ff4283c124ba250c92cf50c6John Spurlock    public final int getCurrentListenerHints() {
94185a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer        if (!isBound()) return 0;
94285a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer        try {
94385a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer            return getNotificationInterface().getHintsFromListener(mWrapper);
94485a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer        } catch (android.os.RemoteException ex) {
94585a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer            Log.v(TAG, "Unable to contact notification manager", ex);
94685a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer            return 0;
94785a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer        }
94885a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer    }
94985a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer
95085a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer    /**
95185a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer     * Gets the current notification interruption filter active on the host.
95285a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer     *
95385a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer     * <p>
95485a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer     * The interruption filter defines which notifications are allowed to interrupt the user
95585a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer     * (e.g. via sound &amp; vibration) and is applied globally. Listeners can find out whether
95685a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer     * a specific notification matched the interruption filter via
95785a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer     * {@link Ranking#matchesInterruptionFilter()}.
95885a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer     * <p>
95985a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer     * The current filter may differ from the previously requested filter if the notification host
96085a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer     * does not support or refuses to apply the requested filter, or if another component changed
96185a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer     * the filter in the meantime.
96285a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer     * <p>
96385a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer     * Listen for updates using {@link #onInterruptionFilterChanged(int)}.
96485a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer     *
9655717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     * <p>The service should wait for the {@link #onListenerConnected()} event
9665717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     * before performing this operation.
9675717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     *
968831041036587efbceb395bface176752a6b560bcJohn Spurlock     * @return One of the INTERRUPTION_FILTER_ constants, or INTERRUPTION_FILTER_UNKNOWN when
969831041036587efbceb395bface176752a6b560bcJohn Spurlock     * unavailable.
97085a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer     */
97185a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer    public final int getCurrentInterruptionFilter() {
972831041036587efbceb395bface176752a6b560bcJohn Spurlock        if (!isBound()) return INTERRUPTION_FILTER_UNKNOWN;
9731fa865f396e94913cfbbd32ce7799c2e8aeb7a08John Spurlock        try {
974957ed70273b2cf2bc65cd96ac0e91a35e58a0b6dChris Wren            return getNotificationInterface().getInterruptionFilterFromListener(mWrapper);
9751fa865f396e94913cfbbd32ce7799c2e8aeb7a08John Spurlock        } catch (android.os.RemoteException ex) {
9761fa865f396e94913cfbbd32ce7799c2e8aeb7a08John Spurlock            Log.v(TAG, "Unable to contact notification manager", ex);
977831041036587efbceb395bface176752a6b560bcJohn Spurlock            return INTERRUPTION_FILTER_UNKNOWN;
9781fa865f396e94913cfbbd32ce7799c2e8aeb7a08John Spurlock        }
9791fa865f396e94913cfbbd32ce7799c2e8aeb7a08John Spurlock    }
9801fa865f396e94913cfbbd32ce7799c2e8aeb7a08John Spurlock
9811fa865f396e94913cfbbd32ce7799c2e8aeb7a08John Spurlock    /**
982d8afe3c41e65a8f6ff4283c124ba250c92cf50c6John Spurlock     * Sets the desired {@link #getCurrentListenerHints() listener hints}.
9831fa865f396e94913cfbbd32ce7799c2e8aeb7a08John Spurlock     *
9841fa865f396e94913cfbbd32ce7799c2e8aeb7a08John Spurlock     * <p>
98585a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer     * This is merely a request, the host may or may not choose to take action depending
9861fa865f396e94913cfbbd32ce7799c2e8aeb7a08John Spurlock     * on other listener requests or other global state.
9871fa865f396e94913cfbbd32ce7799c2e8aeb7a08John Spurlock     * <p>
988d8afe3c41e65a8f6ff4283c124ba250c92cf50c6John Spurlock     * Listen for updates using {@link #onListenerHintsChanged(int)}.
9891fa865f396e94913cfbbd32ce7799c2e8aeb7a08John Spurlock     *
9905717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     * <p>The service should wait for the {@link #onListenerConnected()} event
9915717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     * before performing this operation.
9925717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     *
993d8afe3c41e65a8f6ff4283c124ba250c92cf50c6John Spurlock     * @param hints One or more of the HINT_ constants.
9941fa865f396e94913cfbbd32ce7799c2e8aeb7a08John Spurlock     */
995d8afe3c41e65a8f6ff4283c124ba250c92cf50c6John Spurlock    public final void requestListenerHints(int hints) {
9961fa865f396e94913cfbbd32ce7799c2e8aeb7a08John Spurlock        if (!isBound()) return;
9971fa865f396e94913cfbbd32ce7799c2e8aeb7a08John Spurlock        try {
998d8afe3c41e65a8f6ff4283c124ba250c92cf50c6John Spurlock            getNotificationInterface().requestHintsFromListener(mWrapper, hints);
9991fa865f396e94913cfbbd32ce7799c2e8aeb7a08John Spurlock        } catch (android.os.RemoteException ex) {
10001fa865f396e94913cfbbd32ce7799c2e8aeb7a08John Spurlock            Log.v(TAG, "Unable to contact notification manager", ex);
10011fa865f396e94913cfbbd32ce7799c2e8aeb7a08John Spurlock        }
10021fa865f396e94913cfbbd32ce7799c2e8aeb7a08John Spurlock    }
10031fa865f396e94913cfbbd32ce7799c2e8aeb7a08John Spurlock
10041fa865f396e94913cfbbd32ce7799c2e8aeb7a08John Spurlock    /**
100585a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer     * Sets the desired {@link #getCurrentInterruptionFilter() interruption filter}.
100685a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer     *
100785a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer     * <p>
100885a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer     * This is merely a request, the host may or may not choose to apply the requested
100985a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer     * interruption filter depending on other listener requests or other global state.
101085a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer     * <p>
101185a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer     * Listen for updates using {@link #onInterruptionFilterChanged(int)}.
101285a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer     *
10135717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     * <p>The service should wait for the {@link #onListenerConnected()} event
10145717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     * before performing this operation.
10155717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     *
101685a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer     * @param interruptionFilter One of the INTERRUPTION_FILTER_ constants.
101785a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer     */
101885a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer    public final void requestInterruptionFilter(int interruptionFilter) {
101985a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer        if (!isBound()) return;
102085a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer        try {
102185a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer            getNotificationInterface()
102285a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer                    .requestInterruptionFilterFromListener(mWrapper, interruptionFilter);
102385a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer        } catch (android.os.RemoteException ex) {
102485a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer            Log.v(TAG, "Unable to contact notification manager", ex);
102585a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer        }
102685a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer    }
102785a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer
102885a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer    /**
102905ad48206a082057e17723d32493c153faa6881eChristoph Studer     * Returns current ranking information.
103005ad48206a082057e17723d32493c153faa6881eChristoph Studer     *
103105ad48206a082057e17723d32493c153faa6881eChristoph Studer     * <p>
103205ad48206a082057e17723d32493c153faa6881eChristoph Studer     * The returned object represents the current ranking snapshot and only
1033d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer     * applies for currently active notifications.
1034d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer     * <p>
1035d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer     * Generally you should use the RankingMap that is passed with events such
1036d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer     * as {@link #onNotificationPosted(StatusBarNotification, RankingMap)},
1037d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer     * {@link #onNotificationRemoved(StatusBarNotification, RankingMap)}, and
1038d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer     * so on. This method should only be used when needing access outside of
1039d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer     * such events, for example to retrieve the RankingMap right after
1040d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer     * initialization.
1041a4294297d46cc0b9f45897bc688c267502cce3efJohn Spurlock     *
10425717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     * <p>The service should wait for the {@link #onListenerConnected()} event
10435717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     * before performing this operation.
10445717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     *
1045d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer     * @return A {@link RankingMap} object providing access to ranking information
1046a4294297d46cc0b9f45897bc688c267502cce3efJohn Spurlock     */
1047d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer    public RankingMap getCurrentRanking() {
1048b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov        synchronized (mLock) {
1049b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov            return mRankingMap;
1050b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov        }
105125cf8cee6f304a286d321204e448b18ce733a60cDaniel Sandler    }
105225cf8cee6f304a286d321204e448b18ce733a60cDaniel Sandler
10535717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren    /**
10545717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     * This is not the lifecycle event you are looking for.
10555717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     *
10565717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     * <p>The service should wait for the {@link #onListenerConnected()} event
10575717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     * before performing any operations.
10585717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     */
10595feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler    @Override
10605feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler    public IBinder onBind(Intent intent) {
10615feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler        if (mWrapper == null) {
106251017d0e23ce9855fabcf786a2067ceb19121fbcChris Wren            mWrapper = new NotificationListenerWrapper();
10635feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler        }
10645feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler        return mWrapper;
10655feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler    }
10665feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler
106751017d0e23ce9855fabcf786a2067ceb19121fbcChris Wren    /** @hide */
106851017d0e23ce9855fabcf786a2067ceb19121fbcChris Wren    protected boolean isBound() {
1069da9a3bed8e1aa7d7867291a123466bb0a3be5bb0John Spurlock        if (mWrapper == null) {
1070da9a3bed8e1aa7d7867291a123466bb0a3be5bb0John Spurlock            Log.w(TAG, "Notification listener service not yet bound.");
1071da9a3bed8e1aa7d7867291a123466bb0a3be5bb0John Spurlock            return false;
1072da9a3bed8e1aa7d7867291a123466bb0a3be5bb0John Spurlock        }
1073da9a3bed8e1aa7d7867291a123466bb0a3be5bb0John Spurlock        return true;
1074da9a3bed8e1aa7d7867291a123466bb0a3be5bb0John Spurlock    }
1075da9a3bed8e1aa7d7867291a123466bb0a3be5bb0John Spurlock
10765717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren    @Override
10775717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren    public void onDestroy() {
10785717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren        onListenerDisconnected();
10795717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren        super.onDestroy();
10805717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren    }
10815717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren
10821941fc718690d6b87db68b6a133c71fb470599d0Chris Wren    /**
10831941fc718690d6b87db68b6a133c71fb470599d0Chris Wren     * Directly register this service with the Notification Manager.
10841941fc718690d6b87db68b6a133c71fb470599d0Chris Wren     *
10851941fc718690d6b87db68b6a133c71fb470599d0Chris Wren     * <p>Only system services may use this call. It will fail for non-system callers.
10861941fc718690d6b87db68b6a133c71fb470599d0Chris Wren     * Apps should ask the user to add their listener in Settings.
10871941fc718690d6b87db68b6a133c71fb470599d0Chris Wren     *
10884600f9b60753adab4e65258a05744a46938fce86Christoph Studer     * @param context Context required for accessing resources. Since this service isn't
10894600f9b60753adab4e65258a05744a46938fce86Christoph Studer     *    launched as a real Service when using this method, a context has to be passed in.
10901941fc718690d6b87db68b6a133c71fb470599d0Chris Wren     * @param componentName the component that will consume the notification information
10911941fc718690d6b87db68b6a133c71fb470599d0Chris Wren     * @param currentUser the user to use as the stream filter
10921941fc718690d6b87db68b6a133c71fb470599d0Chris Wren     * @hide
10937ca33079fda388dd3bd81819b280e578e5d6b38bJulia Reynolds     * @removed
10941941fc718690d6b87db68b6a133c71fb470599d0Chris Wren     */
10955c507c1371d273cdff61d2395d47bd54fa26d614Jeff Brown    @SystemApi
10964600f9b60753adab4e65258a05744a46938fce86Christoph Studer    public void registerAsSystemService(Context context, ComponentName componentName,
10974600f9b60753adab4e65258a05744a46938fce86Christoph Studer            int currentUser) throws RemoteException {
10981941fc718690d6b87db68b6a133c71fb470599d0Chris Wren        if (mWrapper == null) {
109951017d0e23ce9855fabcf786a2067ceb19121fbcChris Wren            mWrapper = new NotificationListenerWrapper();
11001941fc718690d6b87db68b6a133c71fb470599d0Chris Wren        }
11010efdb88ccc9d650e7a644b9be8f63792f2c66841Chris Wren        mSystemContext = context;
11021941fc718690d6b87db68b6a133c71fb470599d0Chris Wren        INotificationManager noMan = getNotificationInterface();
1103b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov        mHandler = new MyHandler(context.getMainLooper());
1104b66a16d9751d5e0f2b6816367e7d8919d707c692Chris Wren        mCurrentUser = currentUser;
1105b66a16d9751d5e0f2b6816367e7d8919d707c692Chris Wren        noMan.registerListener(mWrapper, componentName, currentUser);
11061941fc718690d6b87db68b6a133c71fb470599d0Chris Wren    }
11071941fc718690d6b87db68b6a133c71fb470599d0Chris Wren
11081941fc718690d6b87db68b6a133c71fb470599d0Chris Wren    /**
11091941fc718690d6b87db68b6a133c71fb470599d0Chris Wren     * Directly unregister this service from the Notification Manager.
11101941fc718690d6b87db68b6a133c71fb470599d0Chris Wren     *
11115717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     * <p>This method will fail for listeners that were not registered
11121941fc718690d6b87db68b6a133c71fb470599d0Chris Wren     * with (@link registerAsService).
11131941fc718690d6b87db68b6a133c71fb470599d0Chris Wren     * @hide
11147ca33079fda388dd3bd81819b280e578e5d6b38bJulia Reynolds     * @removed
11151941fc718690d6b87db68b6a133c71fb470599d0Chris Wren     */
11165c507c1371d273cdff61d2395d47bd54fa26d614Jeff Brown    @SystemApi
11171941fc718690d6b87db68b6a133c71fb470599d0Chris Wren    public void unregisterAsSystemService() throws RemoteException {
11181941fc718690d6b87db68b6a133c71fb470599d0Chris Wren        if (mWrapper != null) {
11191941fc718690d6b87db68b6a133c71fb470599d0Chris Wren            INotificationManager noMan = getNotificationInterface();
11201941fc718690d6b87db68b6a133c71fb470599d0Chris Wren            noMan.unregisterListener(mWrapper, mCurrentUser);
11211941fc718690d6b87db68b6a133c71fb470599d0Chris Wren        }
11221941fc718690d6b87db68b6a133c71fb470599d0Chris Wren    }
11231941fc718690d6b87db68b6a133c71fb470599d0Chris Wren
1124ab41eecf22352f54167ce9a272a397715ffd0015Chris Wren    /**
112554de77470de4f605eef7f4b4e01718b301fe275eElliot Waite     * Request that the listener be rebound, after a previous call to {@link #requestUnbind}.
1126ab41eecf22352f54167ce9a272a397715ffd0015Chris Wren     *
11275717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     * <p>This method will fail for listeners that have
1128ab41eecf22352f54167ce9a272a397715ffd0015Chris Wren     * not been granted the permission by the user.
1129ab41eecf22352f54167ce9a272a397715ffd0015Chris Wren     */
1130cf548bfad62b06fd9ad1cf2f1a67bd57a8471c28Chris Wren    public static void requestRebind(ComponentName componentName) {
1131ab41eecf22352f54167ce9a272a397715ffd0015Chris Wren        INotificationManager noMan = INotificationManager.Stub.asInterface(
1132ab41eecf22352f54167ce9a272a397715ffd0015Chris Wren                ServiceManager.getService(Context.NOTIFICATION_SERVICE));
1133cf548bfad62b06fd9ad1cf2f1a67bd57a8471c28Chris Wren        try {
1134cf548bfad62b06fd9ad1cf2f1a67bd57a8471c28Chris Wren            noMan.requestBindListener(componentName);
1135cf548bfad62b06fd9ad1cf2f1a67bd57a8471c28Chris Wren        } catch (RemoteException ex) {
1136cf548bfad62b06fd9ad1cf2f1a67bd57a8471c28Chris Wren            throw ex.rethrowFromSystemServer();
1137cf548bfad62b06fd9ad1cf2f1a67bd57a8471c28Chris Wren        }
1138ab41eecf22352f54167ce9a272a397715ffd0015Chris Wren    }
1139ab41eecf22352f54167ce9a272a397715ffd0015Chris Wren
1140ab41eecf22352f54167ce9a272a397715ffd0015Chris Wren    /**
1141ab41eecf22352f54167ce9a272a397715ffd0015Chris Wren     * Request that the service be unbound.
1142ab41eecf22352f54167ce9a272a397715ffd0015Chris Wren     *
11430ffc13b9f2fb29c7d23cdafb31c3efef13b14639Julia Reynolds     * <p>Once this is called, you will no longer receive updates and no method calls are
11440ffc13b9f2fb29c7d23cdafb31c3efef13b14639Julia Reynolds     * guaranteed to be successful, until you next receive the {@link #onListenerConnected()} event.
11450ffc13b9f2fb29c7d23cdafb31c3efef13b14639Julia Reynolds     * The service will likely be killed by the system after this call.
11465717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     *
11475717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     * <p>The service should wait for the {@link #onListenerConnected()} event
11485717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren     * before performing this operation. I know it's tempting, but you must wait.
1149ab41eecf22352f54167ce9a272a397715ffd0015Chris Wren     */
1150cf548bfad62b06fd9ad1cf2f1a67bd57a8471c28Chris Wren    public final void requestUnbind() {
1151ab41eecf22352f54167ce9a272a397715ffd0015Chris Wren        if (mWrapper != null) {
1152ab41eecf22352f54167ce9a272a397715ffd0015Chris Wren            INotificationManager noMan = getNotificationInterface();
1153cf548bfad62b06fd9ad1cf2f1a67bd57a8471c28Chris Wren            try {
1154cf548bfad62b06fd9ad1cf2f1a67bd57a8471c28Chris Wren                noMan.requestUnbindListener(mWrapper);
1155cf548bfad62b06fd9ad1cf2f1a67bd57a8471c28Chris Wren                // Disable future messages.
1156cf548bfad62b06fd9ad1cf2f1a67bd57a8471c28Chris Wren                isConnected = false;
1157cf548bfad62b06fd9ad1cf2f1a67bd57a8471c28Chris Wren            } catch (RemoteException ex) {
1158cf548bfad62b06fd9ad1cf2f1a67bd57a8471c28Chris Wren                throw ex.rethrowFromSystemServer();
1159cf548bfad62b06fd9ad1cf2f1a67bd57a8471c28Chris Wren            }
1160ab41eecf22352f54167ce9a272a397715ffd0015Chris Wren        }
1161ab41eecf22352f54167ce9a272a397715ffd0015Chris Wren    }
1162ab41eecf22352f54167ce9a272a397715ffd0015Chris Wren
1163f5a7838e19c1cb6437a8b32ba9980ac1ce8804e2Daniel Sandler    /** Convert new-style Icons to legacy representations for pre-M clients. */
1164f5a7838e19c1cb6437a8b32ba9980ac1ce8804e2Daniel Sandler    private void createLegacyIconExtras(Notification n) {
1165f5a7838e19c1cb6437a8b32ba9980ac1ce8804e2Daniel Sandler        Icon smallIcon = n.getSmallIcon();
1166f5a7838e19c1cb6437a8b32ba9980ac1ce8804e2Daniel Sandler        Icon largeIcon = n.getLargeIcon();
116799a37f137dd3ad15db1cc9b310591e1d50c601b5Dan Sandler        if (smallIcon != null && smallIcon.getType() == Icon.TYPE_RESOURCE) {
1168f5a7838e19c1cb6437a8b32ba9980ac1ce8804e2Daniel Sandler            n.extras.putInt(Notification.EXTRA_SMALL_ICON, smallIcon.getResId());
1169f5a7838e19c1cb6437a8b32ba9980ac1ce8804e2Daniel Sandler            n.icon = smallIcon.getResId();
1170f5a7838e19c1cb6437a8b32ba9980ac1ce8804e2Daniel Sandler        }
1171f5a7838e19c1cb6437a8b32ba9980ac1ce8804e2Daniel Sandler        if (largeIcon != null) {
1172f5a7838e19c1cb6437a8b32ba9980ac1ce8804e2Daniel Sandler            Drawable d = largeIcon.loadDrawable(getContext());
1173f5a7838e19c1cb6437a8b32ba9980ac1ce8804e2Daniel Sandler            if (d != null && d instanceof BitmapDrawable) {
1174f5a7838e19c1cb6437a8b32ba9980ac1ce8804e2Daniel Sandler                final Bitmap largeIconBits = ((BitmapDrawable) d).getBitmap();
1175f5a7838e19c1cb6437a8b32ba9980ac1ce8804e2Daniel Sandler                n.extras.putParcelable(Notification.EXTRA_LARGE_ICON, largeIconBits);
1176f5a7838e19c1cb6437a8b32ba9980ac1ce8804e2Daniel Sandler                n.largeIcon = largeIconBits;
1177f5a7838e19c1cb6437a8b32ba9980ac1ce8804e2Daniel Sandler            }
1178f5a7838e19c1cb6437a8b32ba9980ac1ce8804e2Daniel Sandler        }
1179f5a7838e19c1cb6437a8b32ba9980ac1ce8804e2Daniel Sandler    }
1180f5a7838e19c1cb6437a8b32ba9980ac1ce8804e2Daniel Sandler
1181d9228f1135e51d9380bad990d7178490ec474dbdJulia Reynolds    /**
1182d9228f1135e51d9380bad990d7178490ec474dbdJulia Reynolds     * Populates remote views for pre-N targeting apps.
1183d9228f1135e51d9380bad990d7178490ec474dbdJulia Reynolds     */
1184d9228f1135e51d9380bad990d7178490ec474dbdJulia Reynolds    private void maybePopulateRemoteViews(Notification notification) {
1185d9228f1135e51d9380bad990d7178490ec474dbdJulia Reynolds        if (getContext().getApplicationInfo().targetSdkVersion < Build.VERSION_CODES.N) {
1186d9228f1135e51d9380bad990d7178490ec474dbdJulia Reynolds            Builder builder = Builder.recoverBuilder(getContext(), notification);
11875081c0de54d05f559dd8b09d2dd2ef5018378959Adrian Roos
11885081c0de54d05f559dd8b09d2dd2ef5018378959Adrian Roos            // Some styles wrap Notification's contentView, bigContentView and headsUpContentView.
11895081c0de54d05f559dd8b09d2dd2ef5018378959Adrian Roos            // First inflate them all, only then set them to avoid recursive wrapping.
11905081c0de54d05f559dd8b09d2dd2ef5018378959Adrian Roos            RemoteViews content = builder.createContentView();
11915081c0de54d05f559dd8b09d2dd2ef5018378959Adrian Roos            RemoteViews big = builder.createBigContentView();
11925081c0de54d05f559dd8b09d2dd2ef5018378959Adrian Roos            RemoteViews headsUp = builder.createHeadsUpContentView();
11935081c0de54d05f559dd8b09d2dd2ef5018378959Adrian Roos
11945081c0de54d05f559dd8b09d2dd2ef5018378959Adrian Roos            notification.contentView = content;
11955081c0de54d05f559dd8b09d2dd2ef5018378959Adrian Roos            notification.bigContentView = big;
11965081c0de54d05f559dd8b09d2dd2ef5018378959Adrian Roos            notification.headsUpContentView = headsUp;
1197d9228f1135e51d9380bad990d7178490ec474dbdJulia Reynolds        }
1198d9228f1135e51d9380bad990d7178490ec474dbdJulia Reynolds    }
1199d9228f1135e51d9380bad990d7178490ec474dbdJulia Reynolds
1200e7238dd12595cb6be953aed4271636df90de17fcSelim Cinek    /**
1201e7238dd12595cb6be953aed4271636df90de17fcSelim Cinek     * Populates remote views for pre-P targeting apps.
1202e7238dd12595cb6be953aed4271636df90de17fcSelim Cinek     */
1203e7238dd12595cb6be953aed4271636df90de17fcSelim Cinek    private void maybePopulatePeople(Notification notification) {
1204e7238dd12595cb6be953aed4271636df90de17fcSelim Cinek        if (getContext().getApplicationInfo().targetSdkVersion < Build.VERSION_CODES.P) {
12059acd673c0deb2652a55c52b9b80515d84b1945dcSelim Cinek            ArrayList<Person> people = notification.extras.getParcelableArrayList(
1206e7238dd12595cb6be953aed4271636df90de17fcSelim Cinek                    Notification.EXTRA_PEOPLE_LIST);
1207e7238dd12595cb6be953aed4271636df90de17fcSelim Cinek            if (people != null && people.isEmpty()) {
1208e7238dd12595cb6be953aed4271636df90de17fcSelim Cinek                int size = people.size();
1209e7238dd12595cb6be953aed4271636df90de17fcSelim Cinek                String[] peopleArray = new String[size];
1210e7238dd12595cb6be953aed4271636df90de17fcSelim Cinek                for (int i = 0; i < size; i++) {
12119acd673c0deb2652a55c52b9b80515d84b1945dcSelim Cinek                    Person person = people.get(i);
1212e7238dd12595cb6be953aed4271636df90de17fcSelim Cinek                    peopleArray[i] = person.resolveToLegacyUri();
1213e7238dd12595cb6be953aed4271636df90de17fcSelim Cinek                }
1214e7238dd12595cb6be953aed4271636df90de17fcSelim Cinek                notification.extras.putStringArray(Notification.EXTRA_PEOPLE, peopleArray);
1215e7238dd12595cb6be953aed4271636df90de17fcSelim Cinek            }
1216e7238dd12595cb6be953aed4271636df90de17fcSelim Cinek        }
1217e7238dd12595cb6be953aed4271636df90de17fcSelim Cinek    }
1218e7238dd12595cb6be953aed4271636df90de17fcSelim Cinek
121951017d0e23ce9855fabcf786a2067ceb19121fbcChris Wren    /** @hide */
122051017d0e23ce9855fabcf786a2067ceb19121fbcChris Wren    protected class NotificationListenerWrapper extends INotificationListener.Stub {
12215feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler        @Override
122284a00ea9e3df3ff051d3e86945d2befea32072eeGriff Hazen        public void onNotificationPosted(IStatusBarNotificationHolder sbnHolder,
122305ad48206a082057e17723d32493c153faa6881eChristoph Studer                NotificationRankingUpdate update) {
122484a00ea9e3df3ff051d3e86945d2befea32072eeGriff Hazen            StatusBarNotification sbn;
122584a00ea9e3df3ff051d3e86945d2befea32072eeGriff Hazen            try {
122684a00ea9e3df3ff051d3e86945d2befea32072eeGriff Hazen                sbn = sbnHolder.get();
122784a00ea9e3df3ff051d3e86945d2befea32072eeGriff Hazen            } catch (RemoteException e) {
122884a00ea9e3df3ff051d3e86945d2befea32072eeGriff Hazen                Log.w(TAG, "onNotificationPosted: Error receiving StatusBarNotification", e);
122984a00ea9e3df3ff051d3e86945d2befea32072eeGriff Hazen                return;
123084a00ea9e3df3ff051d3e86945d2befea32072eeGriff Hazen            }
12314600f9b60753adab4e65258a05744a46938fce86Christoph Studer
123224fb8940b4844e6b121e05c5019361f31d1baf3cChris Wren            try {
123324fb8940b4844e6b121e05c5019361f31d1baf3cChris Wren                // convert icon metadata to legacy format for older clients
123424fb8940b4844e6b121e05c5019361f31d1baf3cChris Wren                createLegacyIconExtras(sbn.getNotification());
1235d9228f1135e51d9380bad990d7178490ec474dbdJulia Reynolds                maybePopulateRemoteViews(sbn.getNotification());
12365390e7d7ac0ccba9b8e6b9abf30a95c83e2382d3Selim Cinek                maybePopulatePeople(sbn.getNotification());
123724fb8940b4844e6b121e05c5019361f31d1baf3cChris Wren            } catch (IllegalArgumentException e) {
12381ed71f3722830271602d2d3b2bbd1ba692f75835Andreas Gampe                // warn and drop corrupt notification
123924fb8940b4844e6b121e05c5019361f31d1baf3cChris Wren                Log.w(TAG, "onNotificationPosted: can't rebuild notification from " +
124024fb8940b4844e6b121e05c5019361f31d1baf3cChris Wren                        sbn.getPackageName());
12411ed71f3722830271602d2d3b2bbd1ba692f75835Andreas Gampe                sbn = null;
124224fb8940b4844e6b121e05c5019361f31d1baf3cChris Wren            }
1243f5a7838e19c1cb6437a8b32ba9980ac1ce8804e2Daniel Sandler
124405ad48206a082057e17723d32493c153faa6881eChristoph Studer            // protect subclass from concurrent modifications of (@link mNotificationKeys}.
1245b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov            synchronized (mLock) {
1246b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov                applyUpdateLocked(update);
1247b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov                if (sbn != null) {
1248b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov                    SomeArgs args = SomeArgs.obtain();
1249b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov                    args.arg1 = sbn;
1250b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov                    args.arg2 = mRankingMap;
1251b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov                    mHandler.obtainMessage(MyHandler.MSG_ON_NOTIFICATION_POSTED,
1252b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov                            args).sendToTarget();
1253b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov                } else {
1254b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov                    // still pass along the ranking map, it may contain other information
1255b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov                    mHandler.obtainMessage(MyHandler.MSG_ON_NOTIFICATION_RANKING_UPDATE,
1256b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov                            mRankingMap).sendToTarget();
1257f953664dc17dca23bd724bd64f89189c16c83263Chris Wren                }
1258c133ab8258f8e976f402d57456b1f06d11a78b03John Spurlock            }
1259b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov
12605feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler        }
1261b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov
12625feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler        @Override
126384a00ea9e3df3ff051d3e86945d2befea32072eeGriff Hazen        public void onNotificationRemoved(IStatusBarNotificationHolder sbnHolder,
1264503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds                NotificationRankingUpdate update, NotificationStats stats, int reason) {
126584a00ea9e3df3ff051d3e86945d2befea32072eeGriff Hazen            StatusBarNotification sbn;
126684a00ea9e3df3ff051d3e86945d2befea32072eeGriff Hazen            try {
126784a00ea9e3df3ff051d3e86945d2befea32072eeGriff Hazen                sbn = sbnHolder.get();
126884a00ea9e3df3ff051d3e86945d2befea32072eeGriff Hazen            } catch (RemoteException e) {
126984a00ea9e3df3ff051d3e86945d2befea32072eeGriff Hazen                Log.w(TAG, "onNotificationRemoved: Error receiving StatusBarNotification", e);
127084a00ea9e3df3ff051d3e86945d2befea32072eeGriff Hazen                return;
127184a00ea9e3df3ff051d3e86945d2befea32072eeGriff Hazen            }
127205ad48206a082057e17723d32493c153faa6881eChristoph Studer            // protect subclass from concurrent modifications of (@link mNotificationKeys}.
1273b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov            synchronized (mLock) {
1274b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov                applyUpdateLocked(update);
1275b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov                SomeArgs args = SomeArgs.obtain();
1276b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov                args.arg1 = sbn;
1277b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov                args.arg2 = mRankingMap;
12783aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds                args.arg3 = reason;
1279503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds                args.arg4 = stats;
1280b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov                mHandler.obtainMessage(MyHandler.MSG_ON_NOTIFICATION_REMOVED,
1281b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov                        args).sendToTarget();
1282c133ab8258f8e976f402d57456b1f06d11a78b03John Spurlock            }
1283b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov
12845feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler        }
1285b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov
1286a4294297d46cc0b9f45897bc688c267502cce3efJohn Spurlock        @Override
128705ad48206a082057e17723d32493c153faa6881eChristoph Studer        public void onListenerConnected(NotificationRankingUpdate update) {
128805ad48206a082057e17723d32493c153faa6881eChristoph Studer            // protect subclass from concurrent modifications of (@link mNotificationKeys}.
1289b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov            synchronized (mLock) {
1290b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov                applyUpdateLocked(update);
1291a4294297d46cc0b9f45897bc688c267502cce3efJohn Spurlock            }
12925717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren            isConnected = true;
1293b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov            mHandler.obtainMessage(MyHandler.MSG_ON_LISTENER_CONNECTED).sendToTarget();
1294a4294297d46cc0b9f45897bc688c267502cce3efJohn Spurlock        }
1295b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov
1296f953664dc17dca23bd724bd64f89189c16c83263Chris Wren        @Override
129705ad48206a082057e17723d32493c153faa6881eChristoph Studer        public void onNotificationRankingUpdate(NotificationRankingUpdate update)
1298f953664dc17dca23bd724bd64f89189c16c83263Chris Wren                throws RemoteException {
129905ad48206a082057e17723d32493c153faa6881eChristoph Studer            // protect subclass from concurrent modifications of (@link mNotificationKeys}.
1300b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov            synchronized (mLock) {
1301b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov                applyUpdateLocked(update);
1302b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov                mHandler.obtainMessage(MyHandler.MSG_ON_NOTIFICATION_RANKING_UPDATE,
1303b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov                        mRankingMap).sendToTarget();
1304f953664dc17dca23bd724bd64f89189c16c83263Chris Wren            }
1305b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov
1306f953664dc17dca23bd724bd64f89189c16c83263Chris Wren        }
1307b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov
13081fa865f396e94913cfbbd32ce7799c2e8aeb7a08John Spurlock        @Override
1309d8afe3c41e65a8f6ff4283c124ba250c92cf50c6John Spurlock        public void onListenerHintsChanged(int hints) throws RemoteException {
1310b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov            mHandler.obtainMessage(MyHandler.MSG_ON_LISTENER_HINTS_CHANGED,
1311b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov                    hints, 0).sendToTarget();
13121fa865f396e94913cfbbd32ce7799c2e8aeb7a08John Spurlock        }
131385a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer
131485a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer        @Override
131585a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer        public void onInterruptionFilterChanged(int interruptionFilter) throws RemoteException {
1316b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov            mHandler.obtainMessage(MyHandler.MSG_ON_INTERRUPTION_FILTER_CHANGED,
1317b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov                    interruptionFilter, 0).sendToTarget();
131885a384b4256121eb85b7e72bcd50f3348f365d41Christoph Studer        }
131951017d0e23ce9855fabcf786a2067ceb19121fbcChris Wren
132051017d0e23ce9855fabcf786a2067ceb19121fbcChris Wren        @Override
1321ceecfcf5ccd4790f9ab3a08c3cb7ce4baa2c1eb1Julia Reynolds        public void onNotificationEnqueued(IStatusBarNotificationHolder notificationHolder)
1322ceecfcf5ccd4790f9ab3a08c3cb7ce4baa2c1eb1Julia Reynolds                throws RemoteException {
132351017d0e23ce9855fabcf786a2067ceb19121fbcChris Wren            // no-op in the listener
132451017d0e23ce9855fabcf786a2067ceb19121fbcChris Wren        }
132551017d0e23ce9855fabcf786a2067ceb19121fbcChris Wren
132651017d0e23ce9855fabcf786a2067ceb19121fbcChris Wren        @Override
13277967230de20aeb6993d8332347752c8e508769e4Julia Reynolds        public void onNotificationSnoozedUntilContext(
13287967230de20aeb6993d8332347752c8e508769e4Julia Reynolds                IStatusBarNotificationHolder notificationHolder, String snoozeCriterionId)
132951017d0e23ce9855fabcf786a2067ceb19121fbcChris Wren                throws RemoteException {
133051017d0e23ce9855fabcf786a2067ceb19121fbcChris Wren            // no-op in the listener
133151017d0e23ce9855fabcf786a2067ceb19121fbcChris Wren        }
133251017d0e23ce9855fabcf786a2067ceb19121fbcChris Wren
133373ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds        @Override
1334f27d6b2b821bf818810a0e303d536906b889588dJulia Reynolds        public void onNotificationChannelModification(String pkgName, UserHandle user,
1335f27d6b2b821bf818810a0e303d536906b889588dJulia Reynolds                NotificationChannel channel,
133673ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds                @ChannelOrGroupModificationTypes int modificationType) {
133773ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds            SomeArgs args = SomeArgs.obtain();
133873ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds            args.arg1 = pkgName;
1339f27d6b2b821bf818810a0e303d536906b889588dJulia Reynolds            args.arg2 = user;
1340f27d6b2b821bf818810a0e303d536906b889588dJulia Reynolds            args.arg3 = channel;
1341f27d6b2b821bf818810a0e303d536906b889588dJulia Reynolds            args.arg4 = modificationType;
134273ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds            mHandler.obtainMessage(
134373ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds                    MyHandler.MSG_ON_NOTIFICATION_CHANNEL_MODIFIED, args).sendToTarget();
134473ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds        }
134573ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds
134673ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds        @Override
1347f27d6b2b821bf818810a0e303d536906b889588dJulia Reynolds        public void onNotificationChannelGroupModification(String pkgName, UserHandle user,
134873ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds                NotificationChannelGroup group,
134973ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds                @ChannelOrGroupModificationTypes int modificationType) {
135073ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds            SomeArgs args = SomeArgs.obtain();
135173ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds            args.arg1 = pkgName;
1352f27d6b2b821bf818810a0e303d536906b889588dJulia Reynolds            args.arg2 = user;
1353f27d6b2b821bf818810a0e303d536906b889588dJulia Reynolds            args.arg3 = group;
1354f27d6b2b821bf818810a0e303d536906b889588dJulia Reynolds            args.arg4 = modificationType;
135573ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds            mHandler.obtainMessage(
135673ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds                    MyHandler.MSG_ON_NOTIFICATION_CHANNEL_GROUP_MODIFIED, args).sendToTarget();
135773ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds        }
1358f953664dc17dca23bd724bd64f89189c16c83263Chris Wren    }
1359f953664dc17dca23bd724bd64f89189c16c83263Chris Wren
136022f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds    /**
136122f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds     * @hide
136222f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds     */
13633f24e69dbed74fd7724c0a4714ce612f1cb5bc5cAndreas Gampe    @GuardedBy("mLock")
136422f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds    public final void applyUpdateLocked(NotificationRankingUpdate update) {
1365d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer        mRankingMap = new RankingMap(update);
1366d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer    }
1367d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer
1368b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov    /** @hide */
1369b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov    protected Context getContext() {
13704600f9b60753adab4e65258a05744a46938fce86Christoph Studer        if (mSystemContext != null) {
13714600f9b60753adab4e65258a05744a46938fce86Christoph Studer            return mSystemContext;
13724600f9b60753adab4e65258a05744a46938fce86Christoph Studer        }
13734600f9b60753adab4e65258a05744a46938fce86Christoph Studer        return this;
13744600f9b60753adab4e65258a05744a46938fce86Christoph Studer    }
13754600f9b60753adab4e65258a05744a46938fce86Christoph Studer
1376d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer    /**
13771d599da8424cef8d07cb4c533bd212d992d8f676Christoph Studer     * Stores ranking related information on a currently active notification.
1378d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer     *
1379d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer     * <p>
13801d599da8424cef8d07cb4c533bd212d992d8f676Christoph Studer     * Ranking objects aren't automatically updated as notification events
13811d599da8424cef8d07cb4c533bd212d992d8f676Christoph Studer     * occur. Instead, ranking information has to be retrieved again via the
13821d599da8424cef8d07cb4c533bd212d992d8f676Christoph Studer     * current {@link RankingMap}.
1383d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer     */
1384d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer    public static class Ranking {
13850edb50c4bf0a4ae7a40f241c92fa57483ca73552Julia Reynolds
13863ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren        /** Value signifying that the user has not expressed a per-app visibility override value.
13873ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren         * @hide */
13885ab5c748a850da558a0bcdf9e680228aae4a7646Chris Wren        public static final int VISIBILITY_NO_OVERRIDE = NotificationManager.VISIBILITY_NO_OVERRIDE;
13893ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren
1390503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds        /**
1391503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds         * The user is likely to have a negative reaction to this notification.
1392503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds         */
1393503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds        public static final int USER_SENTIMENT_NEGATIVE = -1;
1394503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds        /**
1395503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds         * It is not known how the user will react to this notification.
1396503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds         */
1397503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds        public static final int USER_SENTIMENT_NEUTRAL = 0;
1398503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds        /**
1399503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds         * The user is likely to have a positive reaction to this notification.
1400503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds         */
1401503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds        public static final int USER_SENTIMENT_POSITIVE = 1;
1402503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds
1403503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds        /** @hide */
1404503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds        @IntDef(prefix = { "USER_SENTIMENT_" }, value = {
1405503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds                USER_SENTIMENT_NEGATIVE, USER_SENTIMENT_NEUTRAL, USER_SENTIMENT_POSITIVE
1406503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds        })
1407503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds        @Retention(RetentionPolicy.SOURCE)
1408503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds        public @interface UserSentiment {}
1409503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds
14101d599da8424cef8d07cb4c533bd212d992d8f676Christoph Studer        private String mKey;
14111d599da8424cef8d07cb4c533bd212d992d8f676Christoph Studer        private int mRank = -1;
14121d599da8424cef8d07cb4c533bd212d992d8f676Christoph Studer        private boolean mIsAmbient;
1413ce7d6d292b2309eff95d4206b09858f13fff5213Christoph Studer        private boolean mMatchesInterruptionFilter;
14143ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren        private int mVisibilityOverride;
1415f612869ae1190e0885b58a3c33b23d36d7732f06Julia Reynolds        private int mSuppressedVisualEffects;
14165ab5c748a850da558a0bcdf9e680228aae4a7646Chris Wren        private @NotificationManager.Importance int mImportance;
1417bdf3376616c276ed18a51185351b44fd16eeae29Chris Wren        private CharSequence mImportanceExplanation;
1418e46bb37acf6d3cfb9974672ace93f5381f70ad99Julia Reynolds        // System specified group key.
1419e46bb37acf6d3cfb9974672ace93f5381f70ad99Julia Reynolds        private String mOverrideGroupKey;
142022f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds        // Notification assistant channel override.
1421924eed1ca6d3fec5dae7eb0f9c11b8f23f628697Julia Reynolds        private NotificationChannel mChannel;
142222f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds        // Notification assistant people override.
142322f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds        private ArrayList<String> mOverridePeople;
142422f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds        // Notification assistant snooze criteria.
142522f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds        private ArrayList<SnoozeCriterion> mSnoozeCriteria;
1426924eed1ca6d3fec5dae7eb0f9c11b8f23f628697Julia Reynolds        private boolean mShowBadge;
1427503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds        private @UserSentiment int mUserSentiment = USER_SENTIMENT_NEUTRAL;
14285a20a5ed2f67f8bc829a50a5ce03e56a50323831Beverly        private boolean mHidden;
1429d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer
14301d599da8424cef8d07cb4c533bd212d992d8f676Christoph Studer        public Ranking() {}
1431d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer
1432d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer        /**
1433d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer         * Returns the key of the notification this Ranking applies to.
1434d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer         */
1435d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer        public String getKey() {
1436d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer            return mKey;
1437d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer        }
1438d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer
1439d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer        /**
1440d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer         * Returns the rank of the notification.
1441d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer         *
1442d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer         * @return the rank of the notification, that is the 0-based index in
1443d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer         *     the list of active notifications.
1444d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer         */
1445d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer        public int getRank() {
1446d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer            return mRank;
1447d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer        }
1448d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer
1449d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer        /**
1450d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer         * Returns whether the notification is an ambient notification, that is
1451d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer         * a notification that doesn't require the user's immediate attention.
1452d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer         */
1453d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer        public boolean isAmbient() {
1454d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer            return mIsAmbient;
1455d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer        }
1456d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer
1457d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer        /**
1458924eed1ca6d3fec5dae7eb0f9c11b8f23f628697Julia Reynolds         * Returns the user specified visibility for the package that posted
14593ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren         * this notification, or
14603ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren         * {@link NotificationListenerService.Ranking#VISIBILITY_NO_OVERRIDE} if
14613ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren         * no such preference has been expressed.
14623ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren         * @hide
14633ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren         */
14643ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren        public int getVisibilityOverride() {
14653ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren            return mVisibilityOverride;
14663ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren        }
14673ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren
1468f612869ae1190e0885b58a3c33b23d36d7732f06Julia Reynolds        /**
1469f612869ae1190e0885b58a3c33b23d36d7732f06Julia Reynolds         * Returns the type(s) of visual effects that should be suppressed for this notification.
1470ccc6ae64ff1dd957fabb24b3c889a69d2d42765dJulia Reynolds         * See {@link NotificationManager.Policy}, e.g.
1471ccc6ae64ff1dd957fabb24b3c889a69d2d42765dJulia Reynolds         * {@link NotificationManager.Policy#SUPPRESSED_EFFECT_LIGHTS}.
1472f612869ae1190e0885b58a3c33b23d36d7732f06Julia Reynolds         */
1473f612869ae1190e0885b58a3c33b23d36d7732f06Julia Reynolds        public int getSuppressedVisualEffects() {
1474f612869ae1190e0885b58a3c33b23d36d7732f06Julia Reynolds            return mSuppressedVisualEffects;
1475f612869ae1190e0885b58a3c33b23d36d7732f06Julia Reynolds        }
1476f612869ae1190e0885b58a3c33b23d36d7732f06Julia Reynolds
1477ce7d6d292b2309eff95d4206b09858f13fff5213Christoph Studer        /**
1478ce7d6d292b2309eff95d4206b09858f13fff5213Christoph Studer         * Returns whether the notification matches the user's interruption
1479ce7d6d292b2309eff95d4206b09858f13fff5213Christoph Studer         * filter.
14800fef44de68c022a35aa34b6f36f8a183c827c684Chris Wren         *
14810fef44de68c022a35aa34b6f36f8a183c827c684Chris Wren         * @return {@code true} if the notification is allowed by the filter, or
14820fef44de68c022a35aa34b6f36f8a183c827c684Chris Wren         * {@code false} if it is blocked.
1483ce7d6d292b2309eff95d4206b09858f13fff5213Christoph Studer         */
1484ce7d6d292b2309eff95d4206b09858f13fff5213Christoph Studer        public boolean matchesInterruptionFilter() {
1485ce7d6d292b2309eff95d4206b09858f13fff5213Christoph Studer            return mMatchesInterruptionFilter;
14861d599da8424cef8d07cb4c533bd212d992d8f676Christoph Studer        }
14871d599da8424cef8d07cb4c533bd212d992d8f676Christoph Studer
14889fa689f8b614d32f36b5f2de2e3065f4ad6b2358Chris Wren        /**
14899fa689f8b614d32f36b5f2de2e3065f4ad6b2358Chris Wren         * Returns the importance of the notification, which dictates its
14905ab5c748a850da558a0bcdf9e680228aae4a7646Chris Wren         * modes of presentation, see: {@link NotificationManager#IMPORTANCE_DEFAULT}, etc.
14919fa689f8b614d32f36b5f2de2e3065f4ad6b2358Chris Wren         *
1492924eed1ca6d3fec5dae7eb0f9c11b8f23f628697Julia Reynolds         * @return the importance of the notification
14939fa689f8b614d32f36b5f2de2e3065f4ad6b2358Chris Wren         */
14945ab5c748a850da558a0bcdf9e680228aae4a7646Chris Wren        public @NotificationManager.Importance int getImportance() {
1495bdf3376616c276ed18a51185351b44fd16eeae29Chris Wren            return mImportance;
14969fa689f8b614d32f36b5f2de2e3065f4ad6b2358Chris Wren        }
14979fa689f8b614d32f36b5f2de2e3065f4ad6b2358Chris Wren
14989fa689f8b614d32f36b5f2de2e3065f4ad6b2358Chris Wren        /**
149922f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds         * If the importance has been overridden by user preference, then this will be non-null,
15009fa689f8b614d32f36b5f2de2e3065f4ad6b2358Chris Wren         * and should be displayed to the user.
15019fa689f8b614d32f36b5f2de2e3065f4ad6b2358Chris Wren         *
15029fa689f8b614d32f36b5f2de2e3065f4ad6b2358Chris Wren         * @return the explanation for the importance, or null if it is the natural importance
15039fa689f8b614d32f36b5f2de2e3065f4ad6b2358Chris Wren         */
15049fa689f8b614d32f36b5f2de2e3065f4ad6b2358Chris Wren        public CharSequence getImportanceExplanation() {
1505bdf3376616c276ed18a51185351b44fd16eeae29Chris Wren            return mImportanceExplanation;
15069fa689f8b614d32f36b5f2de2e3065f4ad6b2358Chris Wren        }
15079fa689f8b614d32f36b5f2de2e3065f4ad6b2358Chris Wren
1508e46bb37acf6d3cfb9974672ace93f5381f70ad99Julia Reynolds        /**
150922f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds         * If the system has overridden the group key, then this will be non-null, and this
1510e46bb37acf6d3cfb9974672ace93f5381f70ad99Julia Reynolds         * key should be used to bundle notifications.
1511e46bb37acf6d3cfb9974672ace93f5381f70ad99Julia Reynolds         */
1512e46bb37acf6d3cfb9974672ace93f5381f70ad99Julia Reynolds        public String getOverrideGroupKey() {
1513e46bb37acf6d3cfb9974672ace93f5381f70ad99Julia Reynolds            return mOverrideGroupKey;
1514e46bb37acf6d3cfb9974672ace93f5381f70ad99Julia Reynolds        }
1515e46bb37acf6d3cfb9974672ace93f5381f70ad99Julia Reynolds
151622f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds        /**
1517924eed1ca6d3fec5dae7eb0f9c11b8f23f628697Julia Reynolds         * Returns the notification channel this notification was posted to, which dictates
1518924eed1ca6d3fec5dae7eb0f9c11b8f23f628697Julia Reynolds         * notification behavior and presentation.
151922f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds         */
152022f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds        public NotificationChannel getChannel() {
1521924eed1ca6d3fec5dae7eb0f9c11b8f23f628697Julia Reynolds            return mChannel;
152222f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds        }
152322f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds
152422f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds        /**
1525503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds         * Returns how the system thinks the user feels about notifications from the
1526503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds         * channel provided by {@link #getChannel()}. You can use this information to expose
1527503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds         * controls to help the user block this channel's notifications, if the sentiment is
1528503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds         * {@link #USER_SENTIMENT_NEGATIVE}, or emphasize this notification if the sentiment is
1529503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds         * {@link #USER_SENTIMENT_POSITIVE}.
1530503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds         */
1531503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds        public int getUserSentiment() {
1532503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds            return mUserSentiment;
1533503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds        }
1534503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds
1535503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds        /**
153622f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds         * If the {@link NotificationAssistantService} has added people to this notification, then
153722f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds         * this will be non-null.
15381327d3c3fabc9b4ffeb20e589f7b2350567b681fJulia Reynolds         * @hide
15397ca33079fda388dd3bd81819b280e578e5d6b38bJulia Reynolds         * @removed
154022f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds         */
15411327d3c3fabc9b4ffeb20e589f7b2350567b681fJulia Reynolds        @SystemApi
154222f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds        public List<String> getAdditionalPeople() {
154322f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds            return mOverridePeople;
154422f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds        }
154522f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds
154622f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds        /**
154722f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds         * Returns snooze criteria provided by the {@link NotificationAssistantService}. If your
154822f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds         * user interface displays options for snoozing notifications these criteria should be
154922f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds         * displayed as well.
15501327d3c3fabc9b4ffeb20e589f7b2350567b681fJulia Reynolds         * @hide
15517ca33079fda388dd3bd81819b280e578e5d6b38bJulia Reynolds         * @removed
155222f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds         */
15531327d3c3fabc9b4ffeb20e589f7b2350567b681fJulia Reynolds        @SystemApi
155422f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds        public List<SnoozeCriterion> getSnoozeCriteria() {
155522f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds            return mSnoozeCriteria;
155622f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds        }
155722f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds
1558924eed1ca6d3fec5dae7eb0f9c11b8f23f628697Julia Reynolds        /**
1559924eed1ca6d3fec5dae7eb0f9c11b8f23f628697Julia Reynolds         * Returns whether this notification can be displayed as a badge.
1560924eed1ca6d3fec5dae7eb0f9c11b8f23f628697Julia Reynolds         *
1561924eed1ca6d3fec5dae7eb0f9c11b8f23f628697Julia Reynolds         * @return true if the notification can be displayed as a badge, false otherwise.
1562924eed1ca6d3fec5dae7eb0f9c11b8f23f628697Julia Reynolds         */
1563924eed1ca6d3fec5dae7eb0f9c11b8f23f628697Julia Reynolds        public boolean canShowBadge() {
1564924eed1ca6d3fec5dae7eb0f9c11b8f23f628697Julia Reynolds            return mShowBadge;
1565924eed1ca6d3fec5dae7eb0f9c11b8f23f628697Julia Reynolds        }
1566924eed1ca6d3fec5dae7eb0f9c11b8f23f628697Julia Reynolds
15671d958f8c35528ac3f31a69402ff38335d47fcb7fDan Sandler        /**
15685a20a5ed2f67f8bc829a50a5ce03e56a50323831Beverly         * Returns whether the app that posted this notification is suspended, so this notification
15695a20a5ed2f67f8bc829a50a5ce03e56a50323831Beverly         * should be hidden.
15705a20a5ed2f67f8bc829a50a5ce03e56a50323831Beverly         *
15715a20a5ed2f67f8bc829a50a5ce03e56a50323831Beverly         * @return true if the notification should be hidden, false otherwise.
15725a20a5ed2f67f8bc829a50a5ce03e56a50323831Beverly         */
15735a20a5ed2f67f8bc829a50a5ce03e56a50323831Beverly        public boolean isSuspended() {
15745a20a5ed2f67f8bc829a50a5ce03e56a50323831Beverly            return mHidden;
15755a20a5ed2f67f8bc829a50a5ce03e56a50323831Beverly        }
15765a20a5ed2f67f8bc829a50a5ce03e56a50323831Beverly
15775a20a5ed2f67f8bc829a50a5ce03e56a50323831Beverly        /**
15781d958f8c35528ac3f31a69402ff38335d47fcb7fDan Sandler         * @hide
15791d958f8c35528ac3f31a69402ff38335d47fcb7fDan Sandler         */
15801d958f8c35528ac3f31a69402ff38335d47fcb7fDan Sandler        @VisibleForTesting
15811d958f8c35528ac3f31a69402ff38335d47fcb7fDan Sandler        public void populate(String key, int rank, boolean matchesInterruptionFilter,
15820421e6d58635f347f785ae4c78e8b2a5da327138Julia Reynolds                int visibilityOverride, int suppressedVisualEffects, int importance,
158322f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds                CharSequence explanation, String overrideGroupKey,
1584924eed1ca6d3fec5dae7eb0f9c11b8f23f628697Julia Reynolds                NotificationChannel channel, ArrayList<String> overridePeople,
1585503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds                ArrayList<SnoozeCriterion> snoozeCriteria, boolean showBadge,
15865a20a5ed2f67f8bc829a50a5ce03e56a50323831Beverly                int userSentiment, boolean hidden) {
15871d599da8424cef8d07cb4c533bd212d992d8f676Christoph Studer            mKey = key;
15881d599da8424cef8d07cb4c533bd212d992d8f676Christoph Studer            mRank = rank;
158985769915e7ef10bef2b5338ed8f04d9b787924fbJulia Reynolds            mIsAmbient = importance < NotificationManager.IMPORTANCE_LOW;
1590ce7d6d292b2309eff95d4206b09858f13fff5213Christoph Studer            mMatchesInterruptionFilter = matchesInterruptionFilter;
15913ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren            mVisibilityOverride = visibilityOverride;
1592f612869ae1190e0885b58a3c33b23d36d7732f06Julia Reynolds            mSuppressedVisualEffects = suppressedVisualEffects;
1593bdf3376616c276ed18a51185351b44fd16eeae29Chris Wren            mImportance = importance;
1594bdf3376616c276ed18a51185351b44fd16eeae29Chris Wren            mImportanceExplanation = explanation;
1595e46bb37acf6d3cfb9974672ace93f5381f70ad99Julia Reynolds            mOverrideGroupKey = overrideGroupKey;
1596924eed1ca6d3fec5dae7eb0f9c11b8f23f628697Julia Reynolds            mChannel = channel;
159722f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds            mOverridePeople = overridePeople;
159822f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds            mSnoozeCriteria = snoozeCriteria;
1599924eed1ca6d3fec5dae7eb0f9c11b8f23f628697Julia Reynolds            mShowBadge = showBadge;
1600503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds            mUserSentiment = userSentiment;
16015a20a5ed2f67f8bc829a50a5ce03e56a50323831Beverly            mHidden = hidden;
1602d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer        }
16035d25ee7a006fda7150ba251cff92c27130611f88Julia Reynolds
16045d25ee7a006fda7150ba251cff92c27130611f88Julia Reynolds        /**
16055d25ee7a006fda7150ba251cff92c27130611f88Julia Reynolds         * {@hide}
16065d25ee7a006fda7150ba251cff92c27130611f88Julia Reynolds         */
16075d25ee7a006fda7150ba251cff92c27130611f88Julia Reynolds        public static String importanceToString(int importance) {
16085d25ee7a006fda7150ba251cff92c27130611f88Julia Reynolds            switch (importance) {
160985769915e7ef10bef2b5338ed8f04d9b787924fbJulia Reynolds                case NotificationManager.IMPORTANCE_UNSPECIFIED:
16105d25ee7a006fda7150ba251cff92c27130611f88Julia Reynolds                    return "UNSPECIFIED";
161185769915e7ef10bef2b5338ed8f04d9b787924fbJulia Reynolds                case NotificationManager.IMPORTANCE_NONE:
16125d25ee7a006fda7150ba251cff92c27130611f88Julia Reynolds                    return "NONE";
161385769915e7ef10bef2b5338ed8f04d9b787924fbJulia Reynolds                case NotificationManager.IMPORTANCE_MIN:
1614f0f629ffe44716b8d900929135142f0ebb9325f4Julia Reynolds                    return "MIN";
161585769915e7ef10bef2b5338ed8f04d9b787924fbJulia Reynolds                case NotificationManager.IMPORTANCE_LOW:
16165d25ee7a006fda7150ba251cff92c27130611f88Julia Reynolds                    return "LOW";
161785769915e7ef10bef2b5338ed8f04d9b787924fbJulia Reynolds                case NotificationManager.IMPORTANCE_DEFAULT:
16185d25ee7a006fda7150ba251cff92c27130611f88Julia Reynolds                    return "DEFAULT";
161985769915e7ef10bef2b5338ed8f04d9b787924fbJulia Reynolds                case NotificationManager.IMPORTANCE_HIGH:
162085769915e7ef10bef2b5338ed8f04d9b787924fbJulia Reynolds                case NotificationManager.IMPORTANCE_MAX:
16215d25ee7a006fda7150ba251cff92c27130611f88Julia Reynolds                    return "HIGH";
16225d25ee7a006fda7150ba251cff92c27130611f88Julia Reynolds                default:
16235d25ee7a006fda7150ba251cff92c27130611f88Julia Reynolds                    return "UNKNOWN(" + String.valueOf(importance) + ")";
16245d25ee7a006fda7150ba251cff92c27130611f88Julia Reynolds            }
16255d25ee7a006fda7150ba251cff92c27130611f88Julia Reynolds        }
162605ad48206a082057e17723d32493c153faa6881eChristoph Studer    }
162705ad48206a082057e17723d32493c153faa6881eChristoph Studer
162805ad48206a082057e17723d32493c153faa6881eChristoph Studer    /**
162905ad48206a082057e17723d32493c153faa6881eChristoph Studer     * Provides access to ranking information on currently active
163005ad48206a082057e17723d32493c153faa6881eChristoph Studer     * notifications.
163105ad48206a082057e17723d32493c153faa6881eChristoph Studer     *
163205ad48206a082057e17723d32493c153faa6881eChristoph Studer     * <p>
163305ad48206a082057e17723d32493c153faa6881eChristoph Studer     * Note that this object represents a ranking snapshot that only applies to
163405ad48206a082057e17723d32493c153faa6881eChristoph Studer     * notifications active at the time of retrieval.
163505ad48206a082057e17723d32493c153faa6881eChristoph Studer     */
1636d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer    public static class RankingMap implements Parcelable {
163705ad48206a082057e17723d32493c153faa6881eChristoph Studer        private final NotificationRankingUpdate mRankingUpdate;
1638dda48f12212a24371de0e6ba2e5e637925cd9b5eChristoph Studer        private ArrayMap<String,Integer> mRanks;
1639dda48f12212a24371de0e6ba2e5e637925cd9b5eChristoph Studer        private ArraySet<Object> mIntercepted;
16403ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren        private ArrayMap<String, Integer> mVisibilityOverrides;
1641f612869ae1190e0885b58a3c33b23d36d7732f06Julia Reynolds        private ArrayMap<String, Integer> mSuppressedVisualEffects;
1642bdf3376616c276ed18a51185351b44fd16eeae29Chris Wren        private ArrayMap<String, Integer> mImportance;
1643bdf3376616c276ed18a51185351b44fd16eeae29Chris Wren        private ArrayMap<String, String> mImportanceExplanation;
1644e46bb37acf6d3cfb9974672ace93f5381f70ad99Julia Reynolds        private ArrayMap<String, String> mOverrideGroupKeys;
1645924eed1ca6d3fec5dae7eb0f9c11b8f23f628697Julia Reynolds        private ArrayMap<String, NotificationChannel> mChannels;
164622f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds        private ArrayMap<String, ArrayList<String>> mOverridePeople;
164722f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds        private ArrayMap<String, ArrayList<SnoozeCriterion>> mSnoozeCriteria;
1648924eed1ca6d3fec5dae7eb0f9c11b8f23f628697Julia Reynolds        private ArrayMap<String, Boolean> mShowBadge;
1649503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds        private ArrayMap<String, Integer> mUserSentiment;
16505a20a5ed2f67f8bc829a50a5ce03e56a50323831Beverly        private ArrayMap<String, Boolean> mHidden;
165105ad48206a082057e17723d32493c153faa6881eChristoph Studer
1652d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer        private RankingMap(NotificationRankingUpdate rankingUpdate) {
165305ad48206a082057e17723d32493c153faa6881eChristoph Studer            mRankingUpdate = rankingUpdate;
165405ad48206a082057e17723d32493c153faa6881eChristoph Studer        }
165505ad48206a082057e17723d32493c153faa6881eChristoph Studer
165605ad48206a082057e17723d32493c153faa6881eChristoph Studer        /**
165705ad48206a082057e17723d32493c153faa6881eChristoph Studer         * Request the list of notification keys in their current ranking
165805ad48206a082057e17723d32493c153faa6881eChristoph Studer         * order.
165905ad48206a082057e17723d32493c153faa6881eChristoph Studer         *
166005ad48206a082057e17723d32493c153faa6881eChristoph Studer         * @return An array of active notification keys, in their ranking order.
166105ad48206a082057e17723d32493c153faa6881eChristoph Studer         */
166205ad48206a082057e17723d32493c153faa6881eChristoph Studer        public String[] getOrderedKeys() {
166305ad48206a082057e17723d32493c153faa6881eChristoph Studer            return mRankingUpdate.getOrderedKeys();
166405ad48206a082057e17723d32493c153faa6881eChristoph Studer        }
166505ad48206a082057e17723d32493c153faa6881eChristoph Studer
166605ad48206a082057e17723d32493c153faa6881eChristoph Studer        /**
16671d599da8424cef8d07cb4c533bd212d992d8f676Christoph Studer         * Populates outRanking with ranking information for the notification
16681d599da8424cef8d07cb4c533bd212d992d8f676Christoph Studer         * with the given key.
166905ad48206a082057e17723d32493c153faa6881eChristoph Studer         *
16701d599da8424cef8d07cb4c533bd212d992d8f676Christoph Studer         * @return true if a valid key has been passed and outRanking has
16711d599da8424cef8d07cb4c533bd212d992d8f676Christoph Studer         *     been populated; false otherwise
167205ad48206a082057e17723d32493c153faa6881eChristoph Studer         */
16731d599da8424cef8d07cb4c533bd212d992d8f676Christoph Studer        public boolean getRanking(String key, Ranking outRanking) {
16741d599da8424cef8d07cb4c533bd212d992d8f676Christoph Studer            int rank = getRank(key);
16750421e6d58635f347f785ae4c78e8b2a5da327138Julia Reynolds            outRanking.populate(key, rank, !isIntercepted(key),
1676bdf3376616c276ed18a51185351b44fd16eeae29Chris Wren                    getVisibilityOverride(key), getSuppressedVisualEffects(key),
167722f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds                    getImportance(key), getImportanceExplanation(key), getOverrideGroupKey(key),
1678924eed1ca6d3fec5dae7eb0f9c11b8f23f628697Julia Reynolds                    getChannel(key), getOverridePeople(key), getSnoozeCriteria(key),
16795a20a5ed2f67f8bc829a50a5ce03e56a50323831Beverly                    getShowBadge(key), getUserSentiment(key), getHidden(key));
16801d599da8424cef8d07cb4c533bd212d992d8f676Christoph Studer            return rank >= 0;
168105ad48206a082057e17723d32493c153faa6881eChristoph Studer        }
168205ad48206a082057e17723d32493c153faa6881eChristoph Studer
16831d599da8424cef8d07cb4c533bd212d992d8f676Christoph Studer        private int getRank(String key) {
1684dda48f12212a24371de0e6ba2e5e637925cd9b5eChristoph Studer            synchronized (this) {
1685dda48f12212a24371de0e6ba2e5e637925cd9b5eChristoph Studer                if (mRanks == null) {
1686dda48f12212a24371de0e6ba2e5e637925cd9b5eChristoph Studer                    buildRanksLocked();
168705ad48206a082057e17723d32493c153faa6881eChristoph Studer                }
168805ad48206a082057e17723d32493c153faa6881eChristoph Studer            }
1689dda48f12212a24371de0e6ba2e5e637925cd9b5eChristoph Studer            Integer rank = mRanks.get(key);
1690dda48f12212a24371de0e6ba2e5e637925cd9b5eChristoph Studer            return rank != null ? rank : -1;
16911d599da8424cef8d07cb4c533bd212d992d8f676Christoph Studer        }
16921d599da8424cef8d07cb4c533bd212d992d8f676Christoph Studer
16931d599da8424cef8d07cb4c533bd212d992d8f676Christoph Studer        private boolean isIntercepted(String key) {
1694dda48f12212a24371de0e6ba2e5e637925cd9b5eChristoph Studer            synchronized (this) {
1695dda48f12212a24371de0e6ba2e5e637925cd9b5eChristoph Studer                if (mIntercepted == null) {
1696dda48f12212a24371de0e6ba2e5e637925cd9b5eChristoph Studer                    buildInterceptedSetLocked();
16971d599da8424cef8d07cb4c533bd212d992d8f676Christoph Studer                }
16981d599da8424cef8d07cb4c533bd212d992d8f676Christoph Studer            }
1699dda48f12212a24371de0e6ba2e5e637925cd9b5eChristoph Studer            return mIntercepted.contains(key);
1700dda48f12212a24371de0e6ba2e5e637925cd9b5eChristoph Studer        }
1701dda48f12212a24371de0e6ba2e5e637925cd9b5eChristoph Studer
17023ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren        private int getVisibilityOverride(String key) {
17033ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren            synchronized (this) {
17043ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren                if (mVisibilityOverrides == null) {
17053ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren                    buildVisibilityOverridesLocked();
17063ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren                }
17073ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren            }
1708f612869ae1190e0885b58a3c33b23d36d7732f06Julia Reynolds            Integer override = mVisibilityOverrides.get(key);
1709f612869ae1190e0885b58a3c33b23d36d7732f06Julia Reynolds            if (override == null) {
17103ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren                return Ranking.VISIBILITY_NO_OVERRIDE;
17113ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren            }
1712f612869ae1190e0885b58a3c33b23d36d7732f06Julia Reynolds            return override.intValue();
1713f612869ae1190e0885b58a3c33b23d36d7732f06Julia Reynolds        }
1714f612869ae1190e0885b58a3c33b23d36d7732f06Julia Reynolds
1715f612869ae1190e0885b58a3c33b23d36d7732f06Julia Reynolds        private int getSuppressedVisualEffects(String key) {
1716f612869ae1190e0885b58a3c33b23d36d7732f06Julia Reynolds            synchronized (this) {
1717f612869ae1190e0885b58a3c33b23d36d7732f06Julia Reynolds                if (mSuppressedVisualEffects == null) {
1718f612869ae1190e0885b58a3c33b23d36d7732f06Julia Reynolds                    buildSuppressedVisualEffectsLocked();
1719f612869ae1190e0885b58a3c33b23d36d7732f06Julia Reynolds                }
1720f612869ae1190e0885b58a3c33b23d36d7732f06Julia Reynolds            }
1721f612869ae1190e0885b58a3c33b23d36d7732f06Julia Reynolds            Integer suppressed = mSuppressedVisualEffects.get(key);
1722f612869ae1190e0885b58a3c33b23d36d7732f06Julia Reynolds            if (suppressed == null) {
1723f612869ae1190e0885b58a3c33b23d36d7732f06Julia Reynolds                return 0;
1724f612869ae1190e0885b58a3c33b23d36d7732f06Julia Reynolds            }
1725f612869ae1190e0885b58a3c33b23d36d7732f06Julia Reynolds            return suppressed.intValue();
17263ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren        }
17273ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren
1728bdf3376616c276ed18a51185351b44fd16eeae29Chris Wren        private int getImportance(String key) {
1729bdf3376616c276ed18a51185351b44fd16eeae29Chris Wren            synchronized (this) {
1730bdf3376616c276ed18a51185351b44fd16eeae29Chris Wren                if (mImportance == null) {
1731bdf3376616c276ed18a51185351b44fd16eeae29Chris Wren                    buildImportanceLocked();
1732bdf3376616c276ed18a51185351b44fd16eeae29Chris Wren                }
1733bdf3376616c276ed18a51185351b44fd16eeae29Chris Wren            }
1734bdf3376616c276ed18a51185351b44fd16eeae29Chris Wren            Integer importance = mImportance.get(key);
1735bdf3376616c276ed18a51185351b44fd16eeae29Chris Wren            if (importance == null) {
173685769915e7ef10bef2b5338ed8f04d9b787924fbJulia Reynolds                return NotificationManager.IMPORTANCE_DEFAULT;
1737bdf3376616c276ed18a51185351b44fd16eeae29Chris Wren            }
1738bdf3376616c276ed18a51185351b44fd16eeae29Chris Wren            return importance.intValue();
1739bdf3376616c276ed18a51185351b44fd16eeae29Chris Wren        }
1740bdf3376616c276ed18a51185351b44fd16eeae29Chris Wren
1741bdf3376616c276ed18a51185351b44fd16eeae29Chris Wren        private String getImportanceExplanation(String key) {
1742bdf3376616c276ed18a51185351b44fd16eeae29Chris Wren            synchronized (this) {
1743bdf3376616c276ed18a51185351b44fd16eeae29Chris Wren                if (mImportanceExplanation == null) {
1744bdf3376616c276ed18a51185351b44fd16eeae29Chris Wren                    buildImportanceExplanationLocked();
1745bdf3376616c276ed18a51185351b44fd16eeae29Chris Wren                }
1746bdf3376616c276ed18a51185351b44fd16eeae29Chris Wren            }
1747bdf3376616c276ed18a51185351b44fd16eeae29Chris Wren            return mImportanceExplanation.get(key);
1748bdf3376616c276ed18a51185351b44fd16eeae29Chris Wren        }
1749bdf3376616c276ed18a51185351b44fd16eeae29Chris Wren
1750e46bb37acf6d3cfb9974672ace93f5381f70ad99Julia Reynolds        private String getOverrideGroupKey(String key) {
1751e46bb37acf6d3cfb9974672ace93f5381f70ad99Julia Reynolds            synchronized (this) {
1752e46bb37acf6d3cfb9974672ace93f5381f70ad99Julia Reynolds                if (mOverrideGroupKeys == null) {
1753e46bb37acf6d3cfb9974672ace93f5381f70ad99Julia Reynolds                    buildOverrideGroupKeys();
1754e46bb37acf6d3cfb9974672ace93f5381f70ad99Julia Reynolds                }
1755e46bb37acf6d3cfb9974672ace93f5381f70ad99Julia Reynolds            }
1756e46bb37acf6d3cfb9974672ace93f5381f70ad99Julia Reynolds            return mOverrideGroupKeys.get(key);
1757e46bb37acf6d3cfb9974672ace93f5381f70ad99Julia Reynolds        }
1758e46bb37acf6d3cfb9974672ace93f5381f70ad99Julia Reynolds
1759924eed1ca6d3fec5dae7eb0f9c11b8f23f628697Julia Reynolds        private NotificationChannel getChannel(String key) {
176022f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds            synchronized (this) {
1761924eed1ca6d3fec5dae7eb0f9c11b8f23f628697Julia Reynolds                if (mChannels == null) {
1762924eed1ca6d3fec5dae7eb0f9c11b8f23f628697Julia Reynolds                    buildChannelsLocked();
176322f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds                }
176422f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds            }
1765924eed1ca6d3fec5dae7eb0f9c11b8f23f628697Julia Reynolds            return mChannels.get(key);
176622f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds        }
176722f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds
176822f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds        private ArrayList<String> getOverridePeople(String key) {
176922f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds            synchronized (this) {
177022f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds                if (mOverridePeople == null) {
177122f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds                    buildOverridePeopleLocked();
177222f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds                }
177322f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds            }
177422f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds            return mOverridePeople.get(key);
177522f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds        }
177622f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds
177722f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds        private ArrayList<SnoozeCriterion> getSnoozeCriteria(String key) {
177822f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds            synchronized (this) {
177922f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds                if (mSnoozeCriteria == null) {
178022f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds                    buildSnoozeCriteriaLocked();
178122f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds                }
178222f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds            }
178322f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds            return mSnoozeCriteria.get(key);
178422f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds        }
178522f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds
1786924eed1ca6d3fec5dae7eb0f9c11b8f23f628697Julia Reynolds        private boolean getShowBadge(String key) {
1787924eed1ca6d3fec5dae7eb0f9c11b8f23f628697Julia Reynolds            synchronized (this) {
1788924eed1ca6d3fec5dae7eb0f9c11b8f23f628697Julia Reynolds                if (mShowBadge == null) {
1789924eed1ca6d3fec5dae7eb0f9c11b8f23f628697Julia Reynolds                    buildShowBadgeLocked();
1790924eed1ca6d3fec5dae7eb0f9c11b8f23f628697Julia Reynolds                }
1791924eed1ca6d3fec5dae7eb0f9c11b8f23f628697Julia Reynolds            }
1792924eed1ca6d3fec5dae7eb0f9c11b8f23f628697Julia Reynolds            Boolean showBadge = mShowBadge.get(key);
1793924eed1ca6d3fec5dae7eb0f9c11b8f23f628697Julia Reynolds            return showBadge == null ? false : showBadge.booleanValue();
1794924eed1ca6d3fec5dae7eb0f9c11b8f23f628697Julia Reynolds        }
1795924eed1ca6d3fec5dae7eb0f9c11b8f23f628697Julia Reynolds
1796503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds        private int getUserSentiment(String key) {
1797503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds            synchronized (this) {
1798503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds                if (mUserSentiment == null) {
1799503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds                    buildUserSentimentLocked();
1800503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds                }
1801503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds            }
1802503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds            Integer userSentiment = mUserSentiment.get(key);
1803503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds            return userSentiment == null
1804503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds                    ? Ranking.USER_SENTIMENT_NEUTRAL : userSentiment.intValue();
1805503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds        }
1806503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds
18075a20a5ed2f67f8bc829a50a5ce03e56a50323831Beverly        private boolean getHidden(String key) {
18085a20a5ed2f67f8bc829a50a5ce03e56a50323831Beverly            synchronized (this) {
18095a20a5ed2f67f8bc829a50a5ce03e56a50323831Beverly                if (mHidden == null) {
18105a20a5ed2f67f8bc829a50a5ce03e56a50323831Beverly                    buildHiddenLocked();
18115a20a5ed2f67f8bc829a50a5ce03e56a50323831Beverly                }
18125a20a5ed2f67f8bc829a50a5ce03e56a50323831Beverly            }
18135a20a5ed2f67f8bc829a50a5ce03e56a50323831Beverly            Boolean hidden = mHidden.get(key);
18145a20a5ed2f67f8bc829a50a5ce03e56a50323831Beverly            return hidden == null ? false : hidden.booleanValue();
18155a20a5ed2f67f8bc829a50a5ce03e56a50323831Beverly        }
18165a20a5ed2f67f8bc829a50a5ce03e56a50323831Beverly
1817dda48f12212a24371de0e6ba2e5e637925cd9b5eChristoph Studer        // Locked by 'this'
1818dda48f12212a24371de0e6ba2e5e637925cd9b5eChristoph Studer        private void buildRanksLocked() {
1819dda48f12212a24371de0e6ba2e5e637925cd9b5eChristoph Studer            String[] orderedKeys = mRankingUpdate.getOrderedKeys();
1820dda48f12212a24371de0e6ba2e5e637925cd9b5eChristoph Studer            mRanks = new ArrayMap<>(orderedKeys.length);
1821dda48f12212a24371de0e6ba2e5e637925cd9b5eChristoph Studer            for (int i = 0; i < orderedKeys.length; i++) {
1822dda48f12212a24371de0e6ba2e5e637925cd9b5eChristoph Studer                String key = orderedKeys[i];
1823dda48f12212a24371de0e6ba2e5e637925cd9b5eChristoph Studer                mRanks.put(key, i);
1824dda48f12212a24371de0e6ba2e5e637925cd9b5eChristoph Studer            }
1825dda48f12212a24371de0e6ba2e5e637925cd9b5eChristoph Studer        }
1826dda48f12212a24371de0e6ba2e5e637925cd9b5eChristoph Studer
1827dda48f12212a24371de0e6ba2e5e637925cd9b5eChristoph Studer        // Locked by 'this'
1828dda48f12212a24371de0e6ba2e5e637925cd9b5eChristoph Studer        private void buildInterceptedSetLocked() {
1829dda48f12212a24371de0e6ba2e5e637925cd9b5eChristoph Studer            String[] dndInterceptedKeys = mRankingUpdate.getInterceptedKeys();
1830dda48f12212a24371de0e6ba2e5e637925cd9b5eChristoph Studer            mIntercepted = new ArraySet<>(dndInterceptedKeys.length);
1831dda48f12212a24371de0e6ba2e5e637925cd9b5eChristoph Studer            Collections.addAll(mIntercepted, dndInterceptedKeys);
183205ad48206a082057e17723d32493c153faa6881eChristoph Studer        }
183305ad48206a082057e17723d32493c153faa6881eChristoph Studer
18343ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren        // Locked by 'this'
18353ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren        private void buildVisibilityOverridesLocked() {
18363ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren            Bundle visibilityBundle = mRankingUpdate.getVisibilityOverrides();
18373ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren            mVisibilityOverrides = new ArrayMap<>(visibilityBundle.size());
18383ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren            for (String key: visibilityBundle.keySet()) {
18393ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren               mVisibilityOverrides.put(key, visibilityBundle.getInt(key));
18403ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren            }
18413ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren        }
18423ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren
1843f612869ae1190e0885b58a3c33b23d36d7732f06Julia Reynolds        // Locked by 'this'
1844f612869ae1190e0885b58a3c33b23d36d7732f06Julia Reynolds        private void buildSuppressedVisualEffectsLocked() {
1845f612869ae1190e0885b58a3c33b23d36d7732f06Julia Reynolds            Bundle suppressedBundle = mRankingUpdate.getSuppressedVisualEffects();
1846f612869ae1190e0885b58a3c33b23d36d7732f06Julia Reynolds            mSuppressedVisualEffects = new ArrayMap<>(suppressedBundle.size());
1847f612869ae1190e0885b58a3c33b23d36d7732f06Julia Reynolds            for (String key: suppressedBundle.keySet()) {
1848f612869ae1190e0885b58a3c33b23d36d7732f06Julia Reynolds                mSuppressedVisualEffects.put(key, suppressedBundle.getInt(key));
1849f612869ae1190e0885b58a3c33b23d36d7732f06Julia Reynolds            }
1850f612869ae1190e0885b58a3c33b23d36d7732f06Julia Reynolds        }
1851bdf3376616c276ed18a51185351b44fd16eeae29Chris Wren        // Locked by 'this'
1852bdf3376616c276ed18a51185351b44fd16eeae29Chris Wren        private void buildImportanceLocked() {
1853bdf3376616c276ed18a51185351b44fd16eeae29Chris Wren            String[] orderedKeys = mRankingUpdate.getOrderedKeys();
1854bdf3376616c276ed18a51185351b44fd16eeae29Chris Wren            int[] importance = mRankingUpdate.getImportance();
1855bdf3376616c276ed18a51185351b44fd16eeae29Chris Wren            mImportance = new ArrayMap<>(orderedKeys.length);
1856bdf3376616c276ed18a51185351b44fd16eeae29Chris Wren            for (int i = 0; i < orderedKeys.length; i++) {
1857bdf3376616c276ed18a51185351b44fd16eeae29Chris Wren                String key = orderedKeys[i];
1858bdf3376616c276ed18a51185351b44fd16eeae29Chris Wren                mImportance.put(key, importance[i]);
1859bdf3376616c276ed18a51185351b44fd16eeae29Chris Wren            }
1860bdf3376616c276ed18a51185351b44fd16eeae29Chris Wren        }
1861bdf3376616c276ed18a51185351b44fd16eeae29Chris Wren
1862bdf3376616c276ed18a51185351b44fd16eeae29Chris Wren        // Locked by 'this'
1863bdf3376616c276ed18a51185351b44fd16eeae29Chris Wren        private void buildImportanceExplanationLocked() {
1864bdf3376616c276ed18a51185351b44fd16eeae29Chris Wren            Bundle explanationBundle = mRankingUpdate.getImportanceExplanation();
1865bdf3376616c276ed18a51185351b44fd16eeae29Chris Wren            mImportanceExplanation = new ArrayMap<>(explanationBundle.size());
1866bdf3376616c276ed18a51185351b44fd16eeae29Chris Wren            for (String key: explanationBundle.keySet()) {
1867bdf3376616c276ed18a51185351b44fd16eeae29Chris Wren                mImportanceExplanation.put(key, explanationBundle.getString(key));
1868bdf3376616c276ed18a51185351b44fd16eeae29Chris Wren            }
1869bdf3376616c276ed18a51185351b44fd16eeae29Chris Wren        }
1870f612869ae1190e0885b58a3c33b23d36d7732f06Julia Reynolds
1871e46bb37acf6d3cfb9974672ace93f5381f70ad99Julia Reynolds        // Locked by 'this'
1872e46bb37acf6d3cfb9974672ace93f5381f70ad99Julia Reynolds        private void buildOverrideGroupKeys() {
1873e46bb37acf6d3cfb9974672ace93f5381f70ad99Julia Reynolds            Bundle overrideGroupKeys = mRankingUpdate.getOverrideGroupKeys();
1874e46bb37acf6d3cfb9974672ace93f5381f70ad99Julia Reynolds            mOverrideGroupKeys = new ArrayMap<>(overrideGroupKeys.size());
1875e46bb37acf6d3cfb9974672ace93f5381f70ad99Julia Reynolds            for (String key: overrideGroupKeys.keySet()) {
1876e46bb37acf6d3cfb9974672ace93f5381f70ad99Julia Reynolds                mOverrideGroupKeys.put(key, overrideGroupKeys.getString(key));
187722f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds            }
187822f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds        }
187922f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds
188022f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds        // Locked by 'this'
1881924eed1ca6d3fec5dae7eb0f9c11b8f23f628697Julia Reynolds        private void buildChannelsLocked() {
1882924eed1ca6d3fec5dae7eb0f9c11b8f23f628697Julia Reynolds            Bundle channels = mRankingUpdate.getChannels();
1883924eed1ca6d3fec5dae7eb0f9c11b8f23f628697Julia Reynolds            mChannels = new ArrayMap<>(channels.size());
1884924eed1ca6d3fec5dae7eb0f9c11b8f23f628697Julia Reynolds            for (String key : channels.keySet()) {
1885924eed1ca6d3fec5dae7eb0f9c11b8f23f628697Julia Reynolds                mChannels.put(key, channels.getParcelable(key));
188622f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds            }
188722f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds        }
188822f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds
188922f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds        // Locked by 'this'
189022f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds        private void buildOverridePeopleLocked() {
189122f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds            Bundle overridePeople = mRankingUpdate.getOverridePeople();
189222f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds            mOverridePeople = new ArrayMap<>(overridePeople.size());
189322f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds            for (String key : overridePeople.keySet()) {
189422f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds                mOverridePeople.put(key, overridePeople.getStringArrayList(key));
189522f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds            }
189622f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds        }
189722f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds
189822f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds        // Locked by 'this'
189922f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds        private void buildSnoozeCriteriaLocked() {
190022f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds            Bundle snoozeCriteria = mRankingUpdate.getSnoozeCriteria();
190122f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds            mSnoozeCriteria = new ArrayMap<>(snoozeCriteria.size());
190222f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds            for (String key : snoozeCriteria.keySet()) {
190322f02b3e4acd7c6983f4d4d58b85069d5ec920abJulia Reynolds                mSnoozeCriteria.put(key, snoozeCriteria.getParcelableArrayList(key));
1904924eed1ca6d3fec5dae7eb0f9c11b8f23f628697Julia Reynolds            }
1905924eed1ca6d3fec5dae7eb0f9c11b8f23f628697Julia Reynolds        }
1906924eed1ca6d3fec5dae7eb0f9c11b8f23f628697Julia Reynolds
1907924eed1ca6d3fec5dae7eb0f9c11b8f23f628697Julia Reynolds        // Locked by 'this'
1908924eed1ca6d3fec5dae7eb0f9c11b8f23f628697Julia Reynolds        private void buildShowBadgeLocked() {
1909924eed1ca6d3fec5dae7eb0f9c11b8f23f628697Julia Reynolds            Bundle showBadge = mRankingUpdate.getShowBadge();
1910924eed1ca6d3fec5dae7eb0f9c11b8f23f628697Julia Reynolds            mShowBadge = new ArrayMap<>(showBadge.size());
1911924eed1ca6d3fec5dae7eb0f9c11b8f23f628697Julia Reynolds            for (String key : showBadge.keySet()) {
1912924eed1ca6d3fec5dae7eb0f9c11b8f23f628697Julia Reynolds                mShowBadge.put(key, showBadge.getBoolean(key));
1913e46bb37acf6d3cfb9974672ace93f5381f70ad99Julia Reynolds            }
1914e46bb37acf6d3cfb9974672ace93f5381f70ad99Julia Reynolds        }
1915e46bb37acf6d3cfb9974672ace93f5381f70ad99Julia Reynolds
1916503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds        // Locked by 'this'
1917503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds        private void buildUserSentimentLocked() {
1918503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds            Bundle userSentiment = mRankingUpdate.getUserSentiment();
1919503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds            mUserSentiment = new ArrayMap<>(userSentiment.size());
1920503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds            for (String key : userSentiment.keySet()) {
1921503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds                mUserSentiment.put(key, userSentiment.getInt(key));
1922503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds            }
1923503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds        }
1924503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds
19255a20a5ed2f67f8bc829a50a5ce03e56a50323831Beverly        // Locked by 'this'
19265a20a5ed2f67f8bc829a50a5ce03e56a50323831Beverly        private void buildHiddenLocked() {
19275a20a5ed2f67f8bc829a50a5ce03e56a50323831Beverly            Bundle hidden = mRankingUpdate.getHidden();
19285a20a5ed2f67f8bc829a50a5ce03e56a50323831Beverly            mHidden = new ArrayMap<>(hidden.size());
19295a20a5ed2f67f8bc829a50a5ce03e56a50323831Beverly            for (String key : hidden.keySet()) {
19305a20a5ed2f67f8bc829a50a5ce03e56a50323831Beverly                mHidden.put(key, hidden.getBoolean(key));
19315a20a5ed2f67f8bc829a50a5ce03e56a50323831Beverly            }
19325a20a5ed2f67f8bc829a50a5ce03e56a50323831Beverly        }
19335a20a5ed2f67f8bc829a50a5ce03e56a50323831Beverly
193405ad48206a082057e17723d32493c153faa6881eChristoph Studer        // ----------- Parcelable
193505ad48206a082057e17723d32493c153faa6881eChristoph Studer
193605ad48206a082057e17723d32493c153faa6881eChristoph Studer        @Override
193705ad48206a082057e17723d32493c153faa6881eChristoph Studer        public int describeContents() {
193805ad48206a082057e17723d32493c153faa6881eChristoph Studer            return 0;
193905ad48206a082057e17723d32493c153faa6881eChristoph Studer        }
194005ad48206a082057e17723d32493c153faa6881eChristoph Studer
194105ad48206a082057e17723d32493c153faa6881eChristoph Studer        @Override
194205ad48206a082057e17723d32493c153faa6881eChristoph Studer        public void writeToParcel(Parcel dest, int flags) {
194305ad48206a082057e17723d32493c153faa6881eChristoph Studer            dest.writeParcelable(mRankingUpdate, flags);
194405ad48206a082057e17723d32493c153faa6881eChristoph Studer        }
194505ad48206a082057e17723d32493c153faa6881eChristoph Studer
1946d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer        public static final Creator<RankingMap> CREATOR = new Creator<RankingMap>() {
194705ad48206a082057e17723d32493c153faa6881eChristoph Studer            @Override
1948d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer            public RankingMap createFromParcel(Parcel source) {
194905ad48206a082057e17723d32493c153faa6881eChristoph Studer                NotificationRankingUpdate rankingUpdate = source.readParcelable(null);
1950d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer                return new RankingMap(rankingUpdate);
195105ad48206a082057e17723d32493c153faa6881eChristoph Studer            }
195205ad48206a082057e17723d32493c153faa6881eChristoph Studer
195305ad48206a082057e17723d32493c153faa6881eChristoph Studer            @Override
1954d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer            public RankingMap[] newArray(int size) {
1955d0694b6735a9d91794e6096961231e07364ba3faChristoph Studer                return new RankingMap[size];
195605ad48206a082057e17723d32493c153faa6881eChristoph Studer            }
195705ad48206a082057e17723d32493c153faa6881eChristoph Studer        };
19585feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler    }
1959b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov
1960b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov    private final class MyHandler extends Handler {
1961b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov        public static final int MSG_ON_NOTIFICATION_POSTED = 1;
1962b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov        public static final int MSG_ON_NOTIFICATION_REMOVED = 2;
1963b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov        public static final int MSG_ON_LISTENER_CONNECTED = 3;
1964b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov        public static final int MSG_ON_NOTIFICATION_RANKING_UPDATE = 4;
1965b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov        public static final int MSG_ON_LISTENER_HINTS_CHANGED = 5;
1966b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov        public static final int MSG_ON_INTERRUPTION_FILTER_CHANGED = 6;
196773ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds        public static final int MSG_ON_NOTIFICATION_CHANNEL_MODIFIED = 7;
196873ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds        public static final int MSG_ON_NOTIFICATION_CHANNEL_GROUP_MODIFIED = 8;
1969b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov
1970b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov        public MyHandler(Looper looper) {
1971b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov            super(looper, null, false);
1972b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov        }
1973b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov
1974b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov        @Override
1975b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov        public void handleMessage(Message msg) {
19765717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren            if (!isConnected) {
19775717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren                return;
19785717bd6ddb9f6c2fca6626ebb34f78feb1ae684aChris Wren            }
1979b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov            switch (msg.what) {
1980b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov                case MSG_ON_NOTIFICATION_POSTED: {
1981b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov                    SomeArgs args = (SomeArgs) msg.obj;
1982b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov                    StatusBarNotification sbn = (StatusBarNotification) args.arg1;
1983b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov                    RankingMap rankingMap = (RankingMap) args.arg2;
1984b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov                    args.recycle();
1985b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov                    onNotificationPosted(sbn, rankingMap);
1986b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov                } break;
1987b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov
1988b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov                case MSG_ON_NOTIFICATION_REMOVED: {
1989b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov                    SomeArgs args = (SomeArgs) msg.obj;
1990b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov                    StatusBarNotification sbn = (StatusBarNotification) args.arg1;
1991b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov                    RankingMap rankingMap = (RankingMap) args.arg2;
19923aa5f1eec08e6c3233f13935ea45c833433a2d27Julia Reynolds                    int reason = (int) args.arg3;
1993503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds                    NotificationStats stats = (NotificationStats) args.arg4;
1994b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov                    args.recycle();
1995503ed9404e30d0a965d137c67cbac863ef303b70Julia Reynolds                    onNotificationRemoved(sbn, rankingMap, stats, reason);
1996b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov                } break;
1997b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov
1998b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov                case MSG_ON_LISTENER_CONNECTED: {
1999b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov                    onListenerConnected();
2000b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov                } break;
2001b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov
2002b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov                case MSG_ON_NOTIFICATION_RANKING_UPDATE: {
2003b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov                    RankingMap rankingMap = (RankingMap) msg.obj;
2004b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov                    onNotificationRankingUpdate(rankingMap);
2005b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov                } break;
2006b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov
2007b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov                case MSG_ON_LISTENER_HINTS_CHANGED: {
2008b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov                    final int hints = msg.arg1;
2009b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov                    onListenerHintsChanged(hints);
2010b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov                } break;
2011b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov
2012b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov                case MSG_ON_INTERRUPTION_FILTER_CHANGED: {
2013b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov                    final int interruptionFilter = msg.arg1;
2014b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov                    onInterruptionFilterChanged(interruptionFilter);
2015b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov                } break;
201673ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds
201773ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds                case MSG_ON_NOTIFICATION_CHANNEL_MODIFIED: {
201873ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds                    SomeArgs args = (SomeArgs) msg.obj;
201973ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds                    String pkgName = (String) args.arg1;
2020f27d6b2b821bf818810a0e303d536906b889588dJulia Reynolds                    UserHandle user= (UserHandle) args.arg2;
2021f27d6b2b821bf818810a0e303d536906b889588dJulia Reynolds                    NotificationChannel channel = (NotificationChannel) args.arg3;
2022f27d6b2b821bf818810a0e303d536906b889588dJulia Reynolds                    int modificationType = (int) args.arg4;
2023f27d6b2b821bf818810a0e303d536906b889588dJulia Reynolds                    onNotificationChannelModified(pkgName, user, channel, modificationType);
202473ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds                } break;
202573ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds
202673ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds                case MSG_ON_NOTIFICATION_CHANNEL_GROUP_MODIFIED: {
202773ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds                    SomeArgs args = (SomeArgs) msg.obj;
202873ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds                    String pkgName = (String) args.arg1;
2029f27d6b2b821bf818810a0e303d536906b889588dJulia Reynolds                    UserHandle user = (UserHandle) args.arg2;
2030f27d6b2b821bf818810a0e303d536906b889588dJulia Reynolds                    NotificationChannelGroup group = (NotificationChannelGroup) args.arg3;
2031f27d6b2b821bf818810a0e303d536906b889588dJulia Reynolds                    int modificationType = (int) args.arg4;
2032f27d6b2b821bf818810a0e303d536906b889588dJulia Reynolds                    onNotificationChannelGroupModified(pkgName, user, group, modificationType);
203373ed76bc6f92ecee9ae2e3172ec54c081443953bJulia Reynolds                } break;
2034b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov            }
2035b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov        }
2036b8f53ee812b75b526c3b481b62334e45609fa70eSvet Ganov    }
20375feceebb892d4cb5777cea3c6174b206705d456bDaniel Sandler}
2038