/*
 * Copyright (C) 2013 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.service.notification;

import android.annotation.CurrentTimeMillisLong;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.SdkConstant;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.app.ActivityManager;
import android.app.INotificationManager;
import android.app.Notification;
import android.app.Notification.Builder;
import android.app.NotificationChannel;
import android.app.NotificationChannelGroup;
import android.app.NotificationManager;
import android.app.Person;
import android.app.Service;
import android.companion.CompanionDeviceManager;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ParceledListSlice;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.util.ArrayMap;
import android.util.Log;
import android.widget.RemoteViews;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.SomeArgs;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * A service that receives calls from the system when new notifications are
 * posted or removed, or their ranking changed.
 * <p>To extend this class, you must declare the service in your manifest file with
 * the {@link android.Manifest.permission#BIND_NOTIFICATION_LISTENER_SERVICE} permission
 * and include an intent filter with the {@link #SERVICE_INTERFACE} action. For example:</p>
 * <pre>
 * &lt;service android:name=".NotificationListener"
 *          android:label="&#64;string/service_name"
 *          android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
 *     &lt;intent-filter>
 *         &lt;action android:name="android.service.notification.NotificationListenerService" />
 *     &lt;/intent-filter>
 * &lt;/service></pre>
 *
 * <p>The service should wait for the {@link #onListenerConnected()} event
 * before performing any operations. The {@link #requestRebind(ComponentName)}
 * method is the <i>only</i> one that is safe to call before {@link #onListenerConnected()}
 * or after {@link #onListenerDisconnected()}.
 * </p>
 * <p> Notification listeners cannot get notification access or be bound by the system on
 * {@linkplain ActivityManager#isLowRamDevice() low-RAM} devices. The system also ignores
 * notification listeners running in a work profile. A
 * {@link android.app.admin.DevicePolicyManager} might block notifications originating from a work
 * profile.</p>
 * <p>
 *     From {@link Build.VERSION_CODES#N} onward all callbacks are called on the main thread. Prior
 *     to N, there is no guarantee on what thread the callback will happen.
 * </p>
 */
public abstract class NotificationListenerService extends Service {

    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    private final String TAG = getClass().getSimpleName();

    /**
     * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
     *     Normal interruption filter.
     */
    public static final int INTERRUPTION_FILTER_ALL
            = NotificationManager.INTERRUPTION_FILTER_ALL;

    /**
     * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
     *     Priority interruption filter.
     */
    public static final int INTERRUPTION_FILTER_PRIORITY
            = NotificationManager.INTERRUPTION_FILTER_PRIORITY;

    /**
     * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
     *     No interruptions filter.
     */
    public static final int INTERRUPTION_FILTER_NONE
            = NotificationManager.INTERRUPTION_FILTER_NONE;

    /**
     * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
     *     Alarms only interruption filter.
     */
    public static final int INTERRUPTION_FILTER_ALARMS
            = NotificationManager.INTERRUPTION_FILTER_ALARMS;

    /** {@link #getCurrentInterruptionFilter() Interruption filter} constant - returned when
     * the value is unavailable for any reason.  For example, before the notification listener
     * is connected.
     *
     * {@see #onListenerConnected()}
     */
    public static final int INTERRUPTION_FILTER_UNKNOWN
            = NotificationManager.INTERRUPTION_FILTER_UNKNOWN;

    /** {@link #getCurrentListenerHints() Listener hints} constant - the primary device UI
     * should disable notification sound, vibrating and other visual or aural effects.
     * This does not change the interruption filter, only the effects. **/
    public static final int HINT_HOST_DISABLE_EFFECTS = 1;

    /** {@link #getCurrentListenerHints() Listener hints} constant - the primary device UI
     * should disable notification sound, but not phone calls.
     * This does not change the interruption filter, only the effects. **/
    public static final int HINT_HOST_DISABLE_NOTIFICATION_EFFECTS = 1 << 1;

    /** {@link #getCurrentListenerHints() Listener hints} constant - the primary device UI
     * should disable phone call sounds, buyt not notification sound.
     * This does not change the interruption filter, only the effects. **/
    public static final int HINT_HOST_DISABLE_CALL_EFFECTS = 1 << 2;

    /**
     * Whether notification suppressed by DND should not interruption visually when the screen is
     * off.
     *
     * @deprecated Use the more specific visual effects in {@link NotificationManager.Policy}.
     */
    @Deprecated
    public static final int SUPPRESSED_EFFECT_SCREEN_OFF =
            NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_OFF;
    /**
     * Whether notification suppressed by DND should not interruption visually when the screen is
     * on.
     *
     * @deprecated Use the more specific visual effects in {@link NotificationManager.Policy}.
     */
    @Deprecated
    public static final int SUPPRESSED_EFFECT_SCREEN_ON =
            NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_ON;


    // Notification cancellation reasons

    /** Notification was canceled by the status bar reporting a notification click. */
    public static final int REASON_CLICK = 1;
    /** Notification was canceled by the status bar reporting a user dismissal. */
    public static final int REASON_CANCEL = 2;
    /** Notification was canceled by the status bar reporting a user dismiss all. */
    public static final int REASON_CANCEL_ALL = 3;
    /** Notification was canceled by the status bar reporting an inflation error. */
    public static final int REASON_ERROR = 4;
    /** Notification was canceled by the package manager modifying the package. */
    public static final int REASON_PACKAGE_CHANGED = 5;
    /** Notification was canceled by the owning user context being stopped. */
    public static final int REASON_USER_STOPPED = 6;
    /** Notification was canceled by the user banning the package. */
    public static final int REASON_PACKAGE_BANNED = 7;
    /** Notification was canceled by the app canceling this specific notification. */
    public static final int REASON_APP_CANCEL = 8;
    /** Notification was canceled by the app cancelling all its notifications. */
    public static final int REASON_APP_CANCEL_ALL = 9;
    /** Notification was canceled by a listener reporting a user dismissal. */
    public static final int REASON_LISTENER_CANCEL = 10;
    /** Notification was canceled by a listener reporting a user dismiss all. */
    public static final int REASON_LISTENER_CANCEL_ALL = 11;
    /** Notification was canceled because it was a member of a canceled group. */
    public static final int REASON_GROUP_SUMMARY_CANCELED = 12;
    /** Notification was canceled because it was an invisible member of a group. */
    public static final int REASON_GROUP_OPTIMIZATION = 13;
    /** Notification was canceled by the device administrator suspending the package. */
    public static final int REASON_PACKAGE_SUSPENDED = 14;
    /** Notification was canceled by the owning managed profile being turned off. */
    public static final int REASON_PROFILE_TURNED_OFF = 15;
    /** Autobundled summary notification was canceled because its group was unbundled */
    public static final int REASON_UNAUTOBUNDLED = 16;
    /** Notification was canceled by the user banning the channel. */
    public static final int REASON_CHANNEL_BANNED = 17;
    /** Notification was snoozed. */
    public static final int REASON_SNOOZED = 18;
    /** Notification was canceled due to timeout */
    public static final int REASON_TIMEOUT = 19;

    /**
     * The full trim of the StatusBarNotification including all its features.
     *
     * @hide
     * @removed
     */
    @SystemApi
    public static final int TRIM_FULL = 0;

    /**
     * A light trim of the StatusBarNotification excluding the following features:
     *
     * <ol>
     *     <li>{@link Notification#tickerView tickerView}</li>
     *     <li>{@link Notification#contentView contentView}</li>
     *     <li>{@link Notification#largeIcon largeIcon}</li>
     *     <li>{@link Notification#bigContentView bigContentView}</li>
     *     <li>{@link Notification#headsUpContentView headsUpContentView}</li>
     *     <li>{@link Notification#EXTRA_LARGE_ICON extras[EXTRA_LARGE_ICON]}</li>
     *     <li>{@link Notification#EXTRA_LARGE_ICON_BIG extras[EXTRA_LARGE_ICON_BIG]}</li>
     *     <li>{@link Notification#EXTRA_PICTURE extras[EXTRA_PICTURE]}</li>
     *     <li>{@link Notification#EXTRA_BIG_TEXT extras[EXTRA_BIG_TEXT]}</li>
     * </ol>
     *
     * @hide
     * @removed
     */
    @SystemApi
    public static final int TRIM_LIGHT = 1;


    /** @hide */
    @IntDef(prefix = { "NOTIFICATION_CHANNEL_OR_GROUP_" }, value = {
            NOTIFICATION_CHANNEL_OR_GROUP_ADDED,
            NOTIFICATION_CHANNEL_OR_GROUP_UPDATED,
            NOTIFICATION_CHANNEL_OR_GROUP_DELETED
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface ChannelOrGroupModificationTypes {}

    /**
     * Channel or group modification reason provided to
     * {@link #onNotificationChannelModified(String, UserHandle,NotificationChannel, int)} or
     * {@link #onNotificationChannelGroupModified(String, UserHandle, NotificationChannelGroup,
     * int)}- the provided object was created.
     */
    public static final int NOTIFICATION_CHANNEL_OR_GROUP_ADDED = 1;

    /**
     * Channel or group modification reason provided to
     * {@link #onNotificationChannelModified(String, UserHandle, NotificationChannel, int)} or
     * {@link #onNotificationChannelGroupModified(String, UserHandle,NotificationChannelGroup, int)}
     * - the provided object was updated.
     */
    public static final int NOTIFICATION_CHANNEL_OR_GROUP_UPDATED = 2;

    /**
     * Channel or group modification reason provided to
     * {@link #onNotificationChannelModified(String, UserHandle, NotificationChannel, int)} or
     * {@link #onNotificationChannelGroupModified(String, UserHandle, NotificationChannelGroup,
     * int)}- the provided object was deleted.
     */
    public static final int NOTIFICATION_CHANNEL_OR_GROUP_DELETED = 3;

    private final Object mLock = new Object();

    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    private Handler mHandler;

    /** @hide */
    @UnsupportedAppUsage
    protected NotificationListenerWrapper mWrapper = null;
    private boolean isConnected = false;

    @GuardedBy("mLock")
    private RankingMap mRankingMap;

    /**
     * @hide
     */
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    protected INotificationManager mNoMan;

    /**
     * Only valid after a successful call to (@link registerAsService}.
     * @hide
     */
    protected int mCurrentUser;

    /**
     * This context is required for system services since NotificationListenerService isn't
     * started as a real Service and hence no context is available..
     * @hide
     */
    protected Context mSystemContext;

    /**
     * The {@link Intent} that must be declared as handled by the service.
     */
    @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
    public static final String SERVICE_INTERFACE
            = "android.service.notification.NotificationListenerService";

    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        mHandler = new MyHandler(getMainLooper());
    }

    /**
     * Implement this method to learn about new notifications as they are posted by apps.
     *
     * @param sbn A data structure encapsulating the original {@link android.app.Notification}
     *            object as well as its identifying information (tag and id) and source
     *            (package name).
     */
    public void onNotificationPosted(StatusBarNotification sbn) {
        // optional
    }

    /**
     * Implement this method to learn about new notifications as they are posted by apps.
     *
     * @param sbn A data structure encapsulating the original {@link android.app.Notification}
     *            object as well as its identifying information (tag and id) and source
     *            (package name).
     * @param rankingMap The current ranking map that can be used to retrieve ranking information
     *                   for active notifications, including the newly posted one.
     */
    public void onNotificationPosted(StatusBarNotification sbn, RankingMap rankingMap) {
        onNotificationPosted(sbn);
    }

    /**
     * Implement this method to learn when notifications are removed.
     * <p>
     * This might occur because the user has dismissed the notification using system UI (or another
     * notification listener) or because the app has withdrawn the notification.
     * <p>
     * NOTE: The {@link StatusBarNotification} object you receive will be "light"; that is, the
     * result from {@link StatusBarNotification#getNotification} may be missing some heavyweight
     * fields such as {@link android.app.Notification#contentView} and
     * {@link android.app.Notification#largeIcon}. However, all other fields on
     * {@link StatusBarNotification}, sufficient to match this call with a prior call to
     * {@link #onNotificationPosted(StatusBarNotification)}, will be intact.
     *
     * @param sbn A data structure encapsulating at least the original information (tag and id)
     *            and source (package name) used to post the {@link android.app.Notification} that
     *            was just removed.
     */
    public void onNotificationRemoved(StatusBarNotification sbn) {
        // optional
    }

    /**
     * Implement this method to learn when notifications are removed.
     * <p>
     * This might occur because the user has dismissed the notification using system UI (or another
     * notification listener) or because the app has withdrawn the notification.
     * <p>
     * NOTE: The {@link StatusBarNotification} object you receive will be "light"; that is, the
     * result from {@link StatusBarNotification#getNotification} may be missing some heavyweight
     * fields such as {@link android.app.Notification#contentView} and
     * {@link android.app.Notification#largeIcon}. However, all other fields on
     * {@link StatusBarNotification}, sufficient to match this call with a prior call to
     * {@link #onNotificationPosted(StatusBarNotification)}, will be intact.
     *
     * @param sbn A data structure encapsulating at least the original information (tag and id)
     *            and source (package name) used to post the {@link android.app.Notification} that
     *            was just removed.
     * @param rankingMap The current ranking map that can be used to retrieve ranking information
     *                   for active notifications.
     *
     */
    public void onNotificationRemoved(StatusBarNotification sbn, RankingMap rankingMap) {
        onNotificationRemoved(sbn);
    }


    /**
     * Implement this method to learn when notifications are removed and why.
     * <p>
     * This might occur because the user has dismissed the notification using system UI (or another
     * notification listener) or because the app has withdrawn the notification.
     * <p>
     * NOTE: The {@link StatusBarNotification} object you receive will be "light"; that is, the
     * result from {@link StatusBarNotification#getNotification} may be missing some heavyweight
     * fields such as {@link android.app.Notification#contentView} and
     * {@link android.app.Notification#largeIcon}. However, all other fields on
     * {@link StatusBarNotification}, sufficient to match this call with a prior call to
     * {@link #onNotificationPosted(StatusBarNotification)}, will be intact.
     *
     ** @param sbn A data structure encapsulating at least the original information (tag and id)
     *            and source (package name) used to post the {@link android.app.Notification} that
     *            was just removed.
     * @param rankingMap The current ranking map that can be used to retrieve ranking information
     *                   for active notifications.
     * @param reason see {@link #REASON_LISTENER_CANCEL}, etc.
     */
    public void onNotificationRemoved(StatusBarNotification sbn, RankingMap rankingMap,
            int reason) {
        onNotificationRemoved(sbn, rankingMap);
    }

    /**
     * NotificationStats are not populated for notification listeners, so fall back to
     * {@link #onNotificationRemoved(StatusBarNotification, RankingMap, int)}.
     *
     * @hide
     */
    @TestApi
    @SystemApi
    public void onNotificationRemoved(@NonNull StatusBarNotification sbn,
            @NonNull RankingMap rankingMap, @NonNull NotificationStats stats, int reason) {
        onNotificationRemoved(sbn, rankingMap, reason);
    }

    /**
     * Implement this method to learn about when the listener is enabled and connected to
     * the notification manager.  You are safe to call {@link #getActiveNotifications()}
     * at this time.
     */
    public void onListenerConnected() {
        // optional
    }

    /**
     * Implement this method to learn about when the listener is disconnected from the
     * notification manager.You will not receive any events after this call, and may only
     * call {@link #requestRebind(ComponentName)} at this time.
     */
    public void onListenerDisconnected() {
        // optional
    }

    /**
     * Implement this method to be notified when the notification ranking changes.
     *
     * @param rankingMap The current ranking map that can be used to retrieve ranking information
     *                   for active notifications.
     */
    public void onNotificationRankingUpdate(RankingMap rankingMap) {
        // optional
    }

    /**
     * Implement this method to be notified when the
     * {@link #getCurrentListenerHints() Listener hints} change.
     *
     * @param hints The current {@link #getCurrentListenerHints() listener hints}.
     */
    public void onListenerHintsChanged(int hints) {
        // optional
    }

    /**
     * Implement this method to be notified when the behavior of silent notifications in the status
     * bar changes. See {@link NotificationManager#shouldHideSilentStatusBarIcons()}.
     *
     * @param hideSilentStatusIcons whether or not status bar icons should be hidden for silent
     *                              notifications
     */
    public void onSilentStatusBarIconsVisibilityChanged(boolean hideSilentStatusIcons) {
        // optional
    }

    /**
     * Implement this method to learn about notification channel modifications.
     *
     * <p>The caller must have {@link CompanionDeviceManager#getAssociations() an associated
     * device} in order to receive this callback.
     *
     * @param pkg The package the channel belongs to.
     * @param user The user on which the change was made.
     * @param channel The channel that has changed.
     * @param modificationType One of {@link #NOTIFICATION_CHANNEL_OR_GROUP_ADDED},
     *                   {@link #NOTIFICATION_CHANNEL_OR_GROUP_UPDATED},
     *                   {@link #NOTIFICATION_CHANNEL_OR_GROUP_DELETED}.
     */
    public void onNotificationChannelModified(String pkg, UserHandle user,
            NotificationChannel channel, @ChannelOrGroupModificationTypes int modificationType) {
        // optional
    }

    /**
     * Implement this method to learn about notification channel group modifications.
     *
     * <p>The caller must have {@link CompanionDeviceManager#getAssociations() an associated
     * device} in order to receive this callback.
     *
     * @param pkg The package the group belongs to.
     * @param user The user on which the change was made.
     * @param group The group that has changed.
     * @param modificationType One of {@link #NOTIFICATION_CHANNEL_OR_GROUP_ADDED},
     *                   {@link #NOTIFICATION_CHANNEL_OR_GROUP_UPDATED},
     *                   {@link #NOTIFICATION_CHANNEL_OR_GROUP_DELETED}.
     */
    public void onNotificationChannelGroupModified(String pkg, UserHandle user,
            NotificationChannelGroup group, @ChannelOrGroupModificationTypes int modificationType) {
        // optional
    }

    /**
     * Implement this method to be notified when the
     * {@link #getCurrentInterruptionFilter() interruption filter} changed.
     *
     * @param interruptionFilter The current
     *     {@link #getCurrentInterruptionFilter() interruption filter}.
     */
    public void onInterruptionFilterChanged(int interruptionFilter) {
        // optional
    }

    /** @hide */
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    protected final INotificationManager getNotificationInterface() {
        if (mNoMan == null) {
            mNoMan = INotificationManager.Stub.asInterface(
                    ServiceManager.getService(Context.NOTIFICATION_SERVICE));
        }
        return mNoMan;
    }

    /**
     * Inform the notification manager about dismissal of a single notification.
     * <p>
     * Use this if your listener has a user interface that allows the user to dismiss individual
     * notifications, similar to the behavior of Android's status bar and notification panel.
     * It should be called after the user dismisses a single notification using your UI;
     * upon being informed, the notification manager will actually remove the notification
     * and you will get an {@link #onNotificationRemoved(StatusBarNotification)} callback.
     * <p>
     * <b>Note:</b> If your listener allows the user to fire a notification's
     * {@link android.app.Notification#contentIntent} by tapping/clicking/etc., you should call
     * this method at that time <i>if</i> the Notification in question has the
     * {@link android.app.Notification#FLAG_AUTO_CANCEL} flag set.
     *
     * <p>The service should wait for the {@link #onListenerConnected()} event
     * before performing this operation.
     *
     * @param pkg Package of the notifying app.
     * @param tag Tag of the notification as specified by the notifying app in
     *     {@link android.app.NotificationManager#notify(String, int, android.app.Notification)}.
     * @param id  ID of the notification as specified by the notifying app in
     *     {@link android.app.NotificationManager#notify(String, int, android.app.Notification)}.
     * <p>
     * @deprecated Use {@link #cancelNotification(String key)}
     * instead. Beginning with {@link android.os.Build.VERSION_CODES#LOLLIPOP} this method will no longer
     * cancel the notification. It will continue to cancel the notification for applications
     * whose {@code targetSdkVersion} is earlier than {@link android.os.Build.VERSION_CODES#LOLLIPOP}.
     */
    @Deprecated
    public final void cancelNotification(String pkg, String tag, int id) {
        if (!isBound()) return;
        try {
            getNotificationInterface().cancelNotificationFromListener(
                    mWrapper, pkg, tag, id);
        } catch (android.os.RemoteException ex) {
            Log.v(TAG, "Unable to contact notification manager", ex);
        }
    }

    /**
     * Inform the notification manager about dismissal of a single notification.
     * <p>
     * Use this if your listener has a user interface that allows the user to dismiss individual
     * notifications, similar to the behavior of Android's status bar and notification panel.
     * It should be called after the user dismisses a single notification using your UI;
     * upon being informed, the notification manager will actually remove the notification
     * and you will get an {@link #onNotificationRemoved(StatusBarNotification)} callback.
     * <p>
     * <b>Note:</b> If your listener allows the user to fire a notification's
     * {@link android.app.Notification#contentIntent} by tapping/clicking/etc., you should call
     * this method at that time <i>if</i> the Notification in question has the
     * {@link android.app.Notification#FLAG_AUTO_CANCEL} flag set.
     * <p>
     *
     * <p>The service should wait for the {@link #onListenerConnected()} event
     * before performing this operation.
     *
     * @param key Notification to dismiss from {@link StatusBarNotification#getKey()}.
     */
    public final void cancelNotification(String key) {
        if (!isBound()) return;
        try {
            getNotificationInterface().cancelNotificationsFromListener(mWrapper,
                    new String[] { key });
        } catch (android.os.RemoteException ex) {
            Log.v(TAG, "Unable to contact notification manager", ex);
        }
    }

    /**
     * Inform the notification manager about dismissal of all notifications.
     * <p>
     * Use this if your listener has a user interface that allows the user to dismiss all
     * notifications, similar to the behavior of Android's status bar and notification panel.
     * It should be called after the user invokes the "dismiss all" function of your UI;
     * upon being informed, the notification manager will actually remove all active notifications
     * and you will get multiple {@link #onNotificationRemoved(StatusBarNotification)} callbacks.
     *
     * <p>The service should wait for the {@link #onListenerConnected()} event
     * before performing this operation.
     *
     * {@see #cancelNotification(String, String, int)}
     */
    public final void cancelAllNotifications() {
        cancelNotifications(null /*all*/);
    }

    /**
     * Inform the notification manager about dismissal of specific notifications.
     * <p>
     * Use this if your listener has a user interface that allows the user to dismiss
     * multiple notifications at once.
     *
     * <p>The service should wait for the {@link #onListenerConnected()} event
     * before performing this operation.
     *
     * @param keys Notifications to dismiss, or {@code null} to dismiss all.
     *
     * {@see #cancelNotification(String, String, int)}
     */
    public final void cancelNotifications(String[] keys) {
        if (!isBound()) return;
        try {
            getNotificationInterface().cancelNotificationsFromListener(mWrapper, keys);
        } catch (android.os.RemoteException ex) {
            Log.v(TAG, "Unable to contact notification manager", ex);
        }
    }

    /**
     * Inform the notification manager about snoozing a specific notification.
     * <p>
     * Use this if your listener has a user interface that allows the user to snooze a notification
     * until a given {@link SnoozeCriterion}. It should be called after the user snoozes a single
     * notification using your UI; upon being informed, the notification manager will actually
     * remove the notification and you will get an
     * {@link #onNotificationRemoved(StatusBarNotification)} callback. When the snoozing period
     * expires, you will get a {@link #onNotificationPosted(StatusBarNotification, RankingMap)}
     * callback for the notification.
     * @param key The key of the notification to snooze
     * @param snoozeCriterionId The{@link SnoozeCriterion#getId()} of a context to snooze the
     *                          notification until.
     * @hide
     * @removed
     */
    @SystemApi
    public final void snoozeNotification(String key, String snoozeCriterionId) {
        if (!isBound()) return;
        try {
            getNotificationInterface().snoozeNotificationUntilContextFromListener(
                    mWrapper, key, snoozeCriterionId);
        } catch (android.os.RemoteException ex) {
            Log.v(TAG, "Unable to contact notification manager", ex);
        }
    }

    /**
     * Inform the notification manager about snoozing a specific notification.
     * <p>
     * Use this if your listener has a user interface that allows the user to snooze a notification
     * for a time. It should be called after the user snoozes a single notification using
     * your UI; upon being informed, the notification manager will actually remove the notification
     * and you will get an {@link #onNotificationRemoved(StatusBarNotification)} callback. When the
     * snoozing period expires, you will get a
     * {@link #onNotificationPosted(StatusBarNotification, RankingMap)} callback for the
     * notification.
     * @param key The key of the notification to snooze
     * @param durationMs A duration to snooze the notification for, in milliseconds.
     */
    public final void snoozeNotification(String key, long durationMs) {
        if (!isBound()) return;
        try {
            getNotificationInterface().snoozeNotificationUntilFromListener(
                    mWrapper, key, durationMs);
        } catch (android.os.RemoteException ex) {
            Log.v(TAG, "Unable to contact notification manager", ex);
        }
    }


    /**
     * Inform the notification manager that these notifications have been viewed by the
     * user. This should only be called when there is sufficient confidence that the user is
     * looking at the notifications, such as when the notifications appear on the screen due to
     * an explicit user interaction.
     *
     * <p>The service should wait for the {@link #onListenerConnected()} event
     * before performing this operation.
     *
     * @param keys Notifications to mark as seen.
     */
    public final void setNotificationsShown(String[] keys) {
        if (!isBound()) return;
        try {
            getNotificationInterface().setNotificationsShownFromListener(mWrapper, keys);
        } catch (android.os.RemoteException ex) {
            Log.v(TAG, "Unable to contact notification manager", ex);
        }
    }


    /**
     * Updates a notification channel for a given package for a given user. This should only be used
     * to reflect changes a user has made to the channel via the listener's user interface.
     *
     * <p>This method will throw a security exception if you don't have access to notifications
     * for the given user.</p>
     * <p>The caller must have {@link CompanionDeviceManager#getAssociations() an associated
     * device} in order to use this method.
     *
     * @param pkg The package the channel belongs to.
     * @param user The user the channel belongs to.
     * @param channel the channel to update.
     */
    public final void updateNotificationChannel(@NonNull String pkg, @NonNull UserHandle user,
            @NonNull NotificationChannel channel) {
        if (!isBound()) return;
        try {
            getNotificationInterface().updateNotificationChannelFromPrivilegedListener(
                    mWrapper, pkg, user, channel);
        } catch (RemoteException e) {
            Log.v(TAG, "Unable to contact notification manager", e);
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Returns all notification channels belonging to the given package for a given user.
     *
     * <p>This method will throw a security exception if you don't have access to notifications
     * for the given user.</p>
     * <p>The caller must have {@link CompanionDeviceManager#getAssociations() an associated
     * device} or be the {@link NotificationAssistantService notification assistant} in order to
     * use this method.
     *
     * @param pkg The package to retrieve channels for.
     */
    public final List<NotificationChannel> getNotificationChannels(@NonNull String pkg,
            @NonNull UserHandle user) {
        if (!isBound()) return null;
        try {

            return getNotificationInterface().getNotificationChannelsFromPrivilegedListener(
                    mWrapper, pkg, user).getList();
        } catch (RemoteException e) {
            Log.v(TAG, "Unable to contact notification manager", e);
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Returns all notification channel groups belonging to the given package for a given user.
     *
     * <p>This method will throw a security exception if you don't have access to notifications
     * for the given user.</p>
     * <p>The caller must have {@link CompanionDeviceManager#getAssociations() an associated
     * device} or be the {@link NotificationAssistantService notification assistant} in order to
     * use this method.
     *
     * @param pkg The package to retrieve channel groups for.
     */
    public final List<NotificationChannelGroup> getNotificationChannelGroups(@NonNull String pkg,
            @NonNull UserHandle user) {
        if (!isBound()) return null;
        try {

            return getNotificationInterface().getNotificationChannelGroupsFromPrivilegedListener(
                    mWrapper, pkg, user).getList();
        } catch (RemoteException e) {
            Log.v(TAG, "Unable to contact notification manager", e);
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Sets the notification trim that will be received via {@link #onNotificationPosted}.
     *
     * <p>
     * Setting a trim other than {@link #TRIM_FULL} enables listeners that don't need access to the
     * full notification features right away to reduce their memory footprint. Full notifications
     * can be requested on-demand via {@link #getActiveNotifications(int)}.
     *
     * <p>
     * Set to {@link #TRIM_FULL} initially.
     *
     * <p>The service should wait for the {@link #onListenerConnected()} event
     * before performing this operation.
     *
     * @hide
     * @removed
     *
     * @param trim trim of the notifications to be passed via {@link #onNotificationPosted}.
     *             See <code>TRIM_*</code> constants.
     */
    @SystemApi
    public final void setOnNotificationPostedTrim(int trim) {
        if (!isBound()) return;
        try {
            getNotificationInterface().setOnNotificationPostedTrimFromListener(mWrapper, trim);
        } catch (RemoteException ex) {
            Log.v(TAG, "Unable to contact notification manager", ex);
        }
    }

    /**
     * Request the list of outstanding notifications (that is, those that are visible to the
     * current user). Useful when you don't know what's already been posted.
     *
     * <p>The service should wait for the {@link #onListenerConnected()} event
     * before performing this operation.
     *
     * @return An array of active notifications, sorted in natural order.
     */
    public StatusBarNotification[] getActiveNotifications() {
        StatusBarNotification[] activeNotifications = getActiveNotifications(null, TRIM_FULL);
        return activeNotifications != null ? activeNotifications : new StatusBarNotification[0];
    }

    /**
     * Like {@link #getActiveNotifications()}, but returns the list of currently snoozed
     * notifications, for all users this listener has access to.
     *
     * <p>The service should wait for the {@link #onListenerConnected()} event
     * before performing this operation.
     *
     * @return An array of snoozed notifications, sorted in natural order.
     */
    public final StatusBarNotification[] getSnoozedNotifications() {
        try {
            ParceledListSlice<StatusBarNotification> parceledList = getNotificationInterface()
                    .getSnoozedNotificationsFromListener(mWrapper, TRIM_FULL);
            return cleanUpNotificationList(parceledList);
        } catch (android.os.RemoteException ex) {
            Log.v(TAG, "Unable to contact notification manager", ex);
        }
        return null;
    }

    /**
     * Request the list of outstanding notifications (that is, those that are visible to the
     * current user). Useful when you don't know what's already been posted.
     *
     * @hide
     * @removed
     *
     * @param trim trim of the notifications to be returned. See <code>TRIM_*</code> constants.
     * @return An array of active notifications, sorted in natural order.
     */
    @SystemApi
    public StatusBarNotification[] getActiveNotifications(int trim) {
        StatusBarNotification[] activeNotifications = getActiveNotifications(null, trim);
        return activeNotifications != null ? activeNotifications : new StatusBarNotification[0];
    }

    /**
     * Request one or more notifications by key. Useful if you have been keeping track of
     * notifications but didn't want to retain the bits, and now need to go back and extract
     * more data out of those notifications.
     *
     * <p>The service should wait for the {@link #onListenerConnected()} event
     * before performing this operation.
     *
     * @param keys the keys of the notifications to request
     * @return An array of notifications corresponding to the requested keys, in the
     * same order as the key list.
     */
    public StatusBarNotification[] getActiveNotifications(String[] keys) {
        StatusBarNotification[] activeNotifications = getActiveNotifications(keys, TRIM_FULL);
        return activeNotifications != null ? activeNotifications : new StatusBarNotification[0];
    }

    /**
     * Request one or more notifications by key. Useful if you have been keeping track of
     * notifications but didn't want to retain the bits, and now need to go back and extract
     * more data out of those notifications.
     *
     * @hide
     * @removed
     *
     * @param keys the keys of the notifications to request
     * @param trim trim of the notifications to be returned. See <code>TRIM_*</code> constants.
     * @return An array of notifications corresponding to the requested keys, in the
     * same order as the key list.
     */
    @SystemApi
    public StatusBarNotification[] getActiveNotifications(String[] keys, int trim) {
        if (!isBound())
            return null;
        try {
            ParceledListSlice<StatusBarNotification> parceledList = getNotificationInterface()
                    .getActiveNotificationsFromListener(mWrapper, keys, trim);
            return cleanUpNotificationList(parceledList);
        } catch (android.os.RemoteException ex) {
            Log.v(TAG, "Unable to contact notification manager", ex);
        }
        return null;
    }

    private StatusBarNotification[] cleanUpNotificationList(
            ParceledListSlice<StatusBarNotification> parceledList) {
        if (parceledList == null || parceledList.getList() == null) {
            return new StatusBarNotification[0];
        }
        List<StatusBarNotification> list = parceledList.getList();
        ArrayList<StatusBarNotification> corruptNotifications = null;
        int N = list.size();
        for (int i = 0; i < N; i++) {
            StatusBarNotification sbn = list.get(i);
            Notification notification = sbn.getNotification();
            try {
                // convert icon metadata to legacy format for older clients
                createLegacyIconExtras(notification);
                // populate remote views for older clients.
                maybePopulateRemoteViews(notification);
                // populate people for older clients.
                maybePopulatePeople(notification);
            } catch (IllegalArgumentException e) {
                if (corruptNotifications == null) {
                    corruptNotifications = new ArrayList<>(N);
                }
                corruptNotifications.add(sbn);
                Log.w(TAG, "get(Active/Snoozed)Notifications: can't rebuild notification from " +
                        sbn.getPackageName());
            }
        }
        if (corruptNotifications != null) {
            list.removeAll(corruptNotifications);
        }
        return list.toArray(new StatusBarNotification[list.size()]);
    }

    /**
     * Gets the set of hints representing current state.
     *
     * <p>
     * The current state may differ from the requested state if the hint represents state
     * shared across all listeners or a feature the notification host does not support or refuses
     * to grant.
     *
     * <p>The service should wait for the {@link #onListenerConnected()} event
     * before performing this operation.
     *
     * @return Zero or more of the HINT_ constants.
     */
    public final int getCurrentListenerHints() {
        if (!isBound()) return 0;
        try {
            return getNotificationInterface().getHintsFromListener(mWrapper);
        } catch (android.os.RemoteException ex) {
            Log.v(TAG, "Unable to contact notification manager", ex);
            return 0;
        }
    }

    /**
     * Gets the current notification interruption filter active on the host.
     *
     * <p>
     * The interruption filter defines which notifications are allowed to interrupt the user
     * (e.g. via sound &amp; vibration) and is applied globally. Listeners can find out whether
     * a specific notification matched the interruption filter via
     * {@link Ranking#matchesInterruptionFilter()}.
     * <p>
     * The current filter may differ from the previously requested filter if the notification host
     * does not support or refuses to apply the requested filter, or if another component changed
     * the filter in the meantime.
     * <p>
     * Listen for updates using {@link #onInterruptionFilterChanged(int)}.
     *
     * <p>The service should wait for the {@link #onListenerConnected()} event
     * before performing this operation.
     *
     * @return One of the INTERRUPTION_FILTER_ constants, or INTERRUPTION_FILTER_UNKNOWN when
     * unavailable.
     */
    public final int getCurrentInterruptionFilter() {
        if (!isBound()) return INTERRUPTION_FILTER_UNKNOWN;
        try {
            return getNotificationInterface().getInterruptionFilterFromListener(mWrapper);
        } catch (android.os.RemoteException ex) {
            Log.v(TAG, "Unable to contact notification manager", ex);
            return INTERRUPTION_FILTER_UNKNOWN;
        }
    }

    /**
     * Clears listener hints set via {@link #getCurrentListenerHints()}.
     *
     * <p>The service should wait for the {@link #onListenerConnected()} event
     * before performing this operation.
     */
    public final void clearRequestedListenerHints() {
        if (!isBound()) return;
        try {
            getNotificationInterface().clearRequestedListenerHints(mWrapper);
        } catch (android.os.RemoteException ex) {
            Log.v(TAG, "Unable to contact notification manager", ex);
        }
    }

    /**
     * Sets the desired {@link #getCurrentListenerHints() listener hints}.
     *
     * <p>
     * This is merely a request, the host may or may not choose to take action depending
     * on other listener requests or other global state.
     * <p>
     * Listen for updates using {@link #onListenerHintsChanged(int)}.
     *
     * <p>The service should wait for the {@link #onListenerConnected()} event
     * before performing this operation.
     *
     * @param hints One or more of the HINT_ constants.
     */
    public final void requestListenerHints(int hints) {
        if (!isBound()) return;
        try {
            getNotificationInterface().requestHintsFromListener(mWrapper, hints);
        } catch (android.os.RemoteException ex) {
            Log.v(TAG, "Unable to contact notification manager", ex);
        }
    }

    /**
     * Sets the desired {@link #getCurrentInterruptionFilter() interruption filter}.
     *
     * <p>
     * This is merely a request, the host may or may not choose to apply the requested
     * interruption filter depending on other listener requests or other global state.
     * <p>
     * Listen for updates using {@link #onInterruptionFilterChanged(int)}.
     *
     * <p>The service should wait for the {@link #onListenerConnected()} event
     * before performing this operation.
     *
     * @param interruptionFilter One of the INTERRUPTION_FILTER_ constants.
     */
    public final void requestInterruptionFilter(int interruptionFilter) {
        if (!isBound()) return;
        try {
            getNotificationInterface()
                    .requestInterruptionFilterFromListener(mWrapper, interruptionFilter);
        } catch (android.os.RemoteException ex) {
            Log.v(TAG, "Unable to contact notification manager", ex);
        }
    }

    /**
     * Returns current ranking information.
     *
     * <p>
     * The returned object represents the current ranking snapshot and only
     * applies for currently active notifications.
     * <p>
     * Generally you should use the RankingMap that is passed with events such
     * as {@link #onNotificationPosted(StatusBarNotification, RankingMap)},
     * {@link #onNotificationRemoved(StatusBarNotification, RankingMap)}, and
     * so on. This method should only be used when needing access outside of
     * such events, for example to retrieve the RankingMap right after
     * initialization.
     *
     * <p>The service should wait for the {@link #onListenerConnected()} event
     * before performing this operation.
     *
     * @return A {@link RankingMap} object providing access to ranking information
     */
    public RankingMap getCurrentRanking() {
        synchronized (mLock) {
            return mRankingMap;
        }
    }

    /**
     * This is not the lifecycle event you are looking for.
     *
     * <p>The service should wait for the {@link #onListenerConnected()} event
     * before performing any operations.
     */
    @Override
    public IBinder onBind(Intent intent) {
        if (mWrapper == null) {
            mWrapper = new NotificationListenerWrapper();
        }
        return mWrapper;
    }

    /** @hide */
    @UnsupportedAppUsage
    protected boolean isBound() {
        if (mWrapper == null) {
            Log.w(TAG, "Notification listener service not yet bound.");
            return false;
        }
        return true;
    }

    @Override
    public void onDestroy() {
        onListenerDisconnected();
        super.onDestroy();
    }

    /**
     * Directly register this service with the Notification Manager.
     *
     * <p>Only system services may use this call. It will fail for non-system callers.
     * Apps should ask the user to add their listener in Settings.
     *
     * @param context Context required for accessing resources. Since this service isn't
     *    launched as a real Service when using this method, a context has to be passed in.
     * @param componentName the component that will consume the notification information
     * @param currentUser the user to use as the stream filter
     * @hide
     * @removed
     */
    @SystemApi
    public void registerAsSystemService(Context context, ComponentName componentName,
            int currentUser) throws RemoteException {
        if (mWrapper == null) {
            mWrapper = new NotificationListenerWrapper();
        }
        mSystemContext = context;
        INotificationManager noMan = getNotificationInterface();
        mHandler = new MyHandler(context.getMainLooper());
        mCurrentUser = currentUser;
        noMan.registerListener(mWrapper, componentName, currentUser);
    }

    /**
     * Directly unregister this service from the Notification Manager.
     *
     * <p>This method will fail for listeners that were not registered
     * with (@link registerAsService).
     * @hide
     * @removed
     */
    @SystemApi
    public void unregisterAsSystemService() throws RemoteException {
        if (mWrapper != null) {
            INotificationManager noMan = getNotificationInterface();
            noMan.unregisterListener(mWrapper, mCurrentUser);
        }
    }

    /**
     * Request that the listener be rebound, after a previous call to {@link #requestUnbind}.
     *
     * <p>This method will fail for listeners that have
     * not been granted the permission by the user.
     */
    public static void requestRebind(ComponentName componentName) {
        INotificationManager noMan = INotificationManager.Stub.asInterface(
                ServiceManager.getService(Context.NOTIFICATION_SERVICE));
        try {
            noMan.requestBindListener(componentName);
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
    }

    /**
     * Request that the service be unbound.
     *
     * <p>Once this is called, you will no longer receive updates and no method calls are
     * guaranteed to be successful, until you next receive the {@link #onListenerConnected()} event.
     * The service will likely be killed by the system after this call.
     *
     * <p>The service should wait for the {@link #onListenerConnected()} event
     * before performing this operation. I know it's tempting, but you must wait.
     */
    public final void requestUnbind() {
        if (mWrapper != null) {
            INotificationManager noMan = getNotificationInterface();
            try {
                noMan.requestUnbindListener(mWrapper);
                // Disable future messages.
                isConnected = false;
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
        }
    }

    /**
     * Convert new-style Icons to legacy representations for pre-M clients.
     * @hide
     */
    public final void createLegacyIconExtras(Notification n) {
        if (getContext().getApplicationInfo().targetSdkVersion < Build.VERSION_CODES.M) {
            Icon smallIcon = n.getSmallIcon();
            Icon largeIcon = n.getLargeIcon();
            if (smallIcon != null && smallIcon.getType() == Icon.TYPE_RESOURCE) {
                n.extras.putInt(Notification.EXTRA_SMALL_ICON, smallIcon.getResId());
                n.icon = smallIcon.getResId();
            }
            if (largeIcon != null) {
                Drawable d = largeIcon.loadDrawable(getContext());
                if (d != null && d instanceof BitmapDrawable) {
                    final Bitmap largeIconBits = ((BitmapDrawable) d).getBitmap();
                    n.extras.putParcelable(Notification.EXTRA_LARGE_ICON, largeIconBits);
                    n.largeIcon = largeIconBits;
                }
            }
        }
    }

    /**
     * Populates remote views for pre-N targeting apps.
     */
    private void maybePopulateRemoteViews(Notification notification) {
        if (getContext().getApplicationInfo().targetSdkVersion < Build.VERSION_CODES.N) {
            Builder builder = Builder.recoverBuilder(getContext(), notification);

            // Some styles wrap Notification's contentView, bigContentView and headsUpContentView.
            // First inflate them all, only then set them to avoid recursive wrapping.
            RemoteViews content = builder.createContentView();
            RemoteViews big = builder.createBigContentView();
            RemoteViews headsUp = builder.createHeadsUpContentView();

            notification.contentView = content;
            notification.bigContentView = big;
            notification.headsUpContentView = headsUp;
        }
    }

    /**
     * Populates remote views for pre-P targeting apps.
     */
    private void maybePopulatePeople(Notification notification) {
        if (getContext().getApplicationInfo().targetSdkVersion < Build.VERSION_CODES.P) {
            ArrayList<Person> people = notification.extras.getParcelableArrayList(
                    Notification.EXTRA_PEOPLE_LIST);
            if (people != null && people.isEmpty()) {
                int size = people.size();
                String[] peopleArray = new String[size];
                for (int i = 0; i < size; i++) {
                    Person person = people.get(i);
                    peopleArray[i] = person.resolveToLegacyUri();
                }
                notification.extras.putStringArray(Notification.EXTRA_PEOPLE, peopleArray);
            }
        }
    }

    /** @hide */
    protected class NotificationListenerWrapper extends INotificationListener.Stub {
        @Override
        public void onNotificationPosted(IStatusBarNotificationHolder sbnHolder,
                NotificationRankingUpdate update) {
            StatusBarNotification sbn;
            try {
                sbn = sbnHolder.get();
            } catch (RemoteException e) {
                Log.w(TAG, "onNotificationPosted: Error receiving StatusBarNotification", e);
                return;
            }

            try {
                // convert icon metadata to legacy format for older clients
                createLegacyIconExtras(sbn.getNotification());
                maybePopulateRemoteViews(sbn.getNotification());
                maybePopulatePeople(sbn.getNotification());
            } catch (IllegalArgumentException e) {
                // warn and drop corrupt notification
                Log.w(TAG, "onNotificationPosted: can't rebuild notification from " +
                        sbn.getPackageName());
                sbn = null;
            }

            // protect subclass from concurrent modifications of (@link mNotificationKeys}.
            synchronized (mLock) {
                applyUpdateLocked(update);
                if (sbn != null) {
                    SomeArgs args = SomeArgs.obtain();
                    args.arg1 = sbn;
                    args.arg2 = mRankingMap;
                    mHandler.obtainMessage(MyHandler.MSG_ON_NOTIFICATION_POSTED,
                            args).sendToTarget();
                } else {
                    // still pass along the ranking map, it may contain other information
                    mHandler.obtainMessage(MyHandler.MSG_ON_NOTIFICATION_RANKING_UPDATE,
                            mRankingMap).sendToTarget();
                }
            }

        }

        @Override
        public void onNotificationRemoved(IStatusBarNotificationHolder sbnHolder,
                NotificationRankingUpdate update, NotificationStats stats, int reason) {
            StatusBarNotification sbn;
            try {
                sbn = sbnHolder.get();
            } catch (RemoteException e) {
                Log.w(TAG, "onNotificationRemoved: Error receiving StatusBarNotification", e);
                return;
            }
            // protect subclass from concurrent modifications of (@link mNotificationKeys}.
            synchronized (mLock) {
                applyUpdateLocked(update);
                SomeArgs args = SomeArgs.obtain();
                args.arg1 = sbn;
                args.arg2 = mRankingMap;
                args.arg3 = reason;
                args.arg4 = stats;
                mHandler.obtainMessage(MyHandler.MSG_ON_NOTIFICATION_REMOVED,
                        args).sendToTarget();
            }

        }

        @Override
        public void onListenerConnected(NotificationRankingUpdate update) {
            // protect subclass from concurrent modifications of (@link mNotificationKeys}.
            synchronized (mLock) {
                applyUpdateLocked(update);
            }
            isConnected = true;
            mHandler.obtainMessage(MyHandler.MSG_ON_LISTENER_CONNECTED).sendToTarget();
        }

        @Override
        public void onNotificationRankingUpdate(NotificationRankingUpdate update)
                throws RemoteException {
            // protect subclass from concurrent modifications of (@link mNotificationKeys}.
            synchronized (mLock) {
                applyUpdateLocked(update);
                mHandler.obtainMessage(MyHandler.MSG_ON_NOTIFICATION_RANKING_UPDATE,
                        mRankingMap).sendToTarget();
            }

        }

        @Override
        public void onListenerHintsChanged(int hints) throws RemoteException {
            mHandler.obtainMessage(MyHandler.MSG_ON_LISTENER_HINTS_CHANGED,
                    hints, 0).sendToTarget();
        }

        @Override
        public void onInterruptionFilterChanged(int interruptionFilter) throws RemoteException {
            mHandler.obtainMessage(MyHandler.MSG_ON_INTERRUPTION_FILTER_CHANGED,
                    interruptionFilter, 0).sendToTarget();
        }

        @Override
        public void onNotificationEnqueuedWithChannel(
                IStatusBarNotificationHolder notificationHolder, NotificationChannel channel)
                throws RemoteException {
            // no-op in the listener
        }

        @Override
        public void onNotificationsSeen(List<String> keys)
                throws RemoteException {
            // no-op in the listener
        }

        @Override
        public void onNotificationSnoozedUntilContext(
                IStatusBarNotificationHolder notificationHolder, String snoozeCriterionId)
                throws RemoteException {
            // no-op in the listener
        }

        @Override
        public void onNotificationExpansionChanged(
                String key, boolean isUserAction, boolean isExpanded) {
            // no-op in the listener
        }

        @Override
        public void onNotificationDirectReply(String key) {
            // no-op in the listener
        }

        @Override
        public void onSuggestedReplySent(String key, CharSequence reply, int source) {
            // no-op in the listener
        }

        @Override
        public void onActionClicked(String key, Notification.Action action, int source) {
            // no-op in the listener
        }

        @Override
        public void onAllowedAdjustmentsChanged() {
            // no-op in the listener
        }

        @Override
        public void onNotificationChannelModification(String pkgName, UserHandle user,
                NotificationChannel channel,
                @ChannelOrGroupModificationTypes int modificationType) {
            SomeArgs args = SomeArgs.obtain();
            args.arg1 = pkgName;
            args.arg2 = user;
            args.arg3 = channel;
            args.arg4 = modificationType;
            mHandler.obtainMessage(
                    MyHandler.MSG_ON_NOTIFICATION_CHANNEL_MODIFIED, args).sendToTarget();
        }

        @Override
        public void onNotificationChannelGroupModification(String pkgName, UserHandle user,
                NotificationChannelGroup group,
                @ChannelOrGroupModificationTypes int modificationType) {
            SomeArgs args = SomeArgs.obtain();
            args.arg1 = pkgName;
            args.arg2 = user;
            args.arg3 = group;
            args.arg4 = modificationType;
            mHandler.obtainMessage(
                    MyHandler.MSG_ON_NOTIFICATION_CHANNEL_GROUP_MODIFIED, args).sendToTarget();
        }

        @Override
        public void onStatusBarIconsBehaviorChanged(boolean hideSilentStatusIcons) {
            mHandler.obtainMessage(MyHandler.MSG_ON_STATUS_BAR_ICON_BEHAVIOR_CHANGED,
                    hideSilentStatusIcons).sendToTarget();
        }
    }

    /**
     * @hide
     */
    @GuardedBy("mLock")
    public final void applyUpdateLocked(NotificationRankingUpdate update) {
        mRankingMap = update.getRankingMap();
    }

    /** @hide */
    protected Context getContext() {
        if (mSystemContext != null) {
            return mSystemContext;
        }
        return this;
    }

    /**
     * Stores ranking related information on a currently active notification.
     *
     * <p>
     * Ranking objects aren't automatically updated as notification events
     * occur. Instead, ranking information has to be retrieved again via the
     * current {@link RankingMap}.
     */
    public static class Ranking {

        /** Value signifying that the user has not expressed a per-app visibility override value.
         * @hide */
        public static final int VISIBILITY_NO_OVERRIDE = NotificationManager.VISIBILITY_NO_OVERRIDE;

        /**
         * The user is likely to have a negative reaction to this notification.
         */
        public static final int USER_SENTIMENT_NEGATIVE = -1;
        /**
         * It is not known how the user will react to this notification.
         */
        public static final int USER_SENTIMENT_NEUTRAL = 0;
        /**
         * The user is likely to have a positive reaction to this notification.
         */
        public static final int USER_SENTIMENT_POSITIVE = 1;

       /** @hide */
        @IntDef(prefix = { "USER_SENTIMENT_" }, value = {
                USER_SENTIMENT_NEGATIVE, USER_SENTIMENT_NEUTRAL, USER_SENTIMENT_POSITIVE
        })
        @Retention(RetentionPolicy.SOURCE)
        public @interface UserSentiment {}

        private @NonNull String mKey;
        private int mRank = -1;
        private boolean mIsAmbient;
        private boolean mMatchesInterruptionFilter;
        private int mVisibilityOverride;
        private int mSuppressedVisualEffects;
        private @NotificationManager.Importance int mImportance;
        private CharSequence mImportanceExplanation;
        // System specified group key.
        private String mOverrideGroupKey;
        // Notification assistant channel override.
        private NotificationChannel mChannel;
        // Notification assistant people override.
        private ArrayList<String> mOverridePeople;
        // Notification assistant snooze criteria.
        private ArrayList<SnoozeCriterion> mSnoozeCriteria;
        private boolean mShowBadge;
        private @UserSentiment int mUserSentiment = USER_SENTIMENT_NEUTRAL;
        private boolean mHidden;
        private long mLastAudiblyAlertedMs;
        private boolean mNoisy;
        private ArrayList<Notification.Action> mSmartActions;
        private ArrayList<CharSequence> mSmartReplies;
        private boolean mCanBubble;

        private static final int PARCEL_VERSION = 2;

        public Ranking() { }

        // You can parcel it, but it's not Parcelable
        /** @hide */
        @VisibleForTesting
        public void writeToParcel(Parcel out, int flags) {
            final long start = out.dataPosition();
            out.writeInt(PARCEL_VERSION);
            out.writeString(mKey);
            out.writeInt(mRank);
            out.writeBoolean(mIsAmbient);
            out.writeBoolean(mMatchesInterruptionFilter);
            out.writeInt(mVisibilityOverride);
            out.writeInt(mSuppressedVisualEffects);
            out.writeInt(mImportance);
            out.writeCharSequence(mImportanceExplanation);
            out.writeString(mOverrideGroupKey);
            out.writeParcelable(mChannel, flags);
            out.writeStringList(mOverridePeople);
            out.writeTypedList(mSnoozeCriteria, flags);
            out.writeBoolean(mShowBadge);
            out.writeInt(mUserSentiment);
            out.writeBoolean(mHidden);
            out.writeLong(mLastAudiblyAlertedMs);
            out.writeBoolean(mNoisy);
            out.writeTypedList(mSmartActions, flags);
            out.writeCharSequenceList(mSmartReplies);
            out.writeBoolean(mCanBubble);
        }

        /** @hide */
        @VisibleForTesting
        public Ranking(Parcel in) {
            final ClassLoader cl = getClass().getClassLoader();

            final int version = in.readInt();
            if (version != PARCEL_VERSION) {
                throw new IllegalArgumentException("malformed Ranking parcel: " + in + " version "
                        + version + ", expected " + PARCEL_VERSION);
            }
            mKey = in.readString();
            mRank = in.readInt();
            mIsAmbient = in.readBoolean();
            mMatchesInterruptionFilter = in.readBoolean();
            mVisibilityOverride = in.readInt();
            mSuppressedVisualEffects = in.readInt();
            mImportance = in.readInt();
            mImportanceExplanation = in.readCharSequence(); // may be null
            mOverrideGroupKey = in.readString(); // may be null
            mChannel = (NotificationChannel) in.readParcelable(cl); // may be null
            mOverridePeople = in.createStringArrayList();
            mSnoozeCriteria = in.createTypedArrayList(SnoozeCriterion.CREATOR);
            mShowBadge = in.readBoolean();
            mUserSentiment = in.readInt();
            mHidden = in.readBoolean();
            mLastAudiblyAlertedMs = in.readLong();
            mNoisy = in.readBoolean();
            mSmartActions = in.createTypedArrayList(Notification.Action.CREATOR);
            mSmartReplies = in.readCharSequenceList();
            mCanBubble = in.readBoolean();
        }


        /**
         * Returns the key of the notification this Ranking applies to.
         */
        public String getKey() {
            return mKey;
        }

        /**
         * Returns the rank of the notification.
         *
         * @return the rank of the notification, that is the 0-based index in
         *     the list of active notifications.
         */
        public int getRank() {
            return mRank;
        }

        /**
         * Returns whether the notification is an ambient notification, that is
         * a notification that doesn't require the user's immediate attention.
         */
        public boolean isAmbient() {
            return mIsAmbient;
        }

        /**
         * Returns the user specified visibility for the package that posted
         * this notification, or
         * {@link NotificationListenerService.Ranking#VISIBILITY_NO_OVERRIDE} if
         * no such preference has been expressed.
         * @hide
         */
        @UnsupportedAppUsage
        public int getVisibilityOverride() {
            return mVisibilityOverride;
        }

        /**
         * Returns the type(s) of visual effects that should be suppressed for this notification.
         * See {@link NotificationManager.Policy}, e.g.
         * {@link NotificationManager.Policy#SUPPRESSED_EFFECT_LIGHTS}.
         */
        public int getSuppressedVisualEffects() {
            return mSuppressedVisualEffects;
        }

        /**
         * Returns whether the notification matches the user's interruption
         * filter.
         *
         * @return {@code true} if the notification is allowed by the filter, or
         * {@code false} if it is blocked.
         */
        public boolean matchesInterruptionFilter() {
            return mMatchesInterruptionFilter;
        }

        /**
         * Returns the importance of the notification, which dictates its
         * modes of presentation, see: {@link NotificationManager#IMPORTANCE_DEFAULT}, etc.
         *
         * @return the importance of the notification
         */
        public @NotificationManager.Importance int getImportance() {
            return mImportance;
        }

        /**
         * If the importance has been overridden by user preference, then this will be non-null,
         * and should be displayed to the user.
         *
         * @return the explanation for the importance, or null if it is the natural importance
         */
        public CharSequence getImportanceExplanation() {
            return mImportanceExplanation;
        }

        /**
         * If the system has overridden the group key, then this will be non-null, and this
         * key should be used to bundle notifications.
         */
        public String getOverrideGroupKey() {
            return mOverrideGroupKey;
        }

        /**
         * Returns the notification channel this notification was posted to, which dictates
         * notification behavior and presentation.
         */
        public NotificationChannel getChannel() {
            return mChannel;
        }

        /**
         * Returns how the system thinks the user feels about notifications from the
         * channel provided by {@link #getChannel()}. You can use this information to expose
         * controls to help the user block this channel's notifications, if the sentiment is
         * {@link #USER_SENTIMENT_NEGATIVE}, or emphasize this notification if the sentiment is
         * {@link #USER_SENTIMENT_POSITIVE}.
         */
        public int getUserSentiment() {
            return mUserSentiment;
        }

        /**
         * If the {@link NotificationAssistantService} has added people to this notification, then
         * this will be non-null.
         * @hide
         * @removed
         */
        @SystemApi
        public List<String> getAdditionalPeople() {
            return mOverridePeople;
        }

        /**
         * Returns snooze criteria provided by the {@link NotificationAssistantService}. If your
         * user interface displays options for snoozing notifications these criteria should be
         * displayed as well.
         * @hide
         * @removed
         */
        @SystemApi
        public List<SnoozeCriterion> getSnoozeCriteria() {
            return mSnoozeCriteria;
        }

        /**
         * Returns a list of smart {@link Notification.Action} that can be added by the
         * {@link NotificationAssistantService}
         */
        public @NonNull List<Notification.Action> getSmartActions() {
            return mSmartActions;
        }

        /**
         * Returns a list of smart replies that can be added by the
         * {@link NotificationAssistantService}
         */
        public @NonNull List<CharSequence> getSmartReplies() {
            return mSmartReplies;
        }

        /**
         * Returns whether this notification can be displayed as a badge.
         *
         * @return true if the notification can be displayed as a badge, false otherwise.
         */
        public boolean canShowBadge() {
            return mShowBadge;
        }

        /**
         * Returns whether the app that posted this notification is suspended, so this notification
         * should be hidden.
         *
         * @return true if the notification should be hidden, false otherwise.
         */
        public boolean isSuspended() {
            return mHidden;
        }

        /**
         * Returns the last time this notification alerted the user via sound or vibration.
         *
         * @return the time of the last alerting behavior, in milliseconds.
         */
        @CurrentTimeMillisLong
        public long getLastAudiblyAlertedMillis() {
            return mLastAudiblyAlertedMs;
        }

        /**
         * Returns whether the user has allowed bubbles globally, at the app level, and at the
         * channel level for this notification.
         *
         * <p>This does not take into account the current importance of the notification, the
         * current DND state, or whether the posting app is foreground.</p>
         */
        public boolean canBubble() {
            return mCanBubble;
        }

        /** @hide */
        public boolean isNoisy() {
            return mNoisy;
        }

        /**
         * @hide
         */
        @VisibleForTesting
        public void populate(String key, int rank, boolean matchesInterruptionFilter,
                int visibilityOverride, int suppressedVisualEffects, int importance,
                CharSequence explanation, String overrideGroupKey,
                NotificationChannel channel, ArrayList<String> overridePeople,
                ArrayList<SnoozeCriterion> snoozeCriteria, boolean showBadge,
                int userSentiment, boolean hidden, long lastAudiblyAlertedMs,
                boolean noisy, ArrayList<Notification.Action> smartActions,
                ArrayList<CharSequence> smartReplies, boolean canBubble) {
            mKey = key;
            mRank = rank;
            mIsAmbient = importance < NotificationManager.IMPORTANCE_LOW;
            mMatchesInterruptionFilter = matchesInterruptionFilter;
            mVisibilityOverride = visibilityOverride;
            mSuppressedVisualEffects = suppressedVisualEffects;
            mImportance = importance;
            mImportanceExplanation = explanation;
            mOverrideGroupKey = overrideGroupKey;
            mChannel = channel;
            mOverridePeople = overridePeople;
            mSnoozeCriteria = snoozeCriteria;
            mShowBadge = showBadge;
            mUserSentiment = userSentiment;
            mHidden = hidden;
            mLastAudiblyAlertedMs = lastAudiblyAlertedMs;
            mNoisy = noisy;
            mSmartActions = smartActions;
            mSmartReplies = smartReplies;
            mCanBubble = canBubble;
        }

        /**
         * @hide
         */
        public void populate(Ranking other) {
            populate(other.mKey,
                    other.mRank,
                    other.mMatchesInterruptionFilter,
                    other.mVisibilityOverride,
                    other.mSuppressedVisualEffects,
                    other.mImportance,
                    other.mImportanceExplanation,
                    other.mOverrideGroupKey,
                    other.mChannel,
                    other.mOverridePeople,
                    other.mSnoozeCriteria,
                    other.mShowBadge,
                    other.mUserSentiment,
                    other.mHidden,
                    other.mLastAudiblyAlertedMs,
                    other.mNoisy,
                    other.mSmartActions,
                    other.mSmartReplies,
                    other.mCanBubble);
        }

        /**
         * {@hide}
         */
        public static String importanceToString(int importance) {
            switch (importance) {
                case NotificationManager.IMPORTANCE_UNSPECIFIED:
                    return "UNSPECIFIED";
                case NotificationManager.IMPORTANCE_NONE:
                    return "NONE";
                case NotificationManager.IMPORTANCE_MIN:
                    return "MIN";
                case NotificationManager.IMPORTANCE_LOW:
                    return "LOW";
                case NotificationManager.IMPORTANCE_DEFAULT:
                    return "DEFAULT";
                case NotificationManager.IMPORTANCE_HIGH:
                case NotificationManager.IMPORTANCE_MAX:
                    return "HIGH";
                default:
                    return "UNKNOWN(" + String.valueOf(importance) + ")";
            }
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;

            Ranking other = (Ranking) o;
            return Objects.equals(mKey, other.mKey)
                    && Objects.equals(mRank, other.mRank)
                    && Objects.equals(mMatchesInterruptionFilter, other.mMatchesInterruptionFilter)
                    && Objects.equals(mVisibilityOverride, other.mVisibilityOverride)
                    && Objects.equals(mSuppressedVisualEffects, other.mSuppressedVisualEffects)
                    && Objects.equals(mImportance, other.mImportance)
                    && Objects.equals(mImportanceExplanation, other.mImportanceExplanation)
                    && Objects.equals(mOverrideGroupKey, other.mOverrideGroupKey)
                    && Objects.equals(mChannel, other.mChannel)
                    && Objects.equals(mOverridePeople, other.mOverridePeople)
                    && Objects.equals(mSnoozeCriteria, other.mSnoozeCriteria)
                    && Objects.equals(mShowBadge, other.mShowBadge)
                    && Objects.equals(mUserSentiment, other.mUserSentiment)
                    && Objects.equals(mHidden, other.mHidden)
                    && Objects.equals(mLastAudiblyAlertedMs, other.mLastAudiblyAlertedMs)
                    && Objects.equals(mNoisy, other.mNoisy)
                    // Action.equals() doesn't exist so let's just compare list lengths
                    && ((mSmartActions == null ? 0 : mSmartActions.size())
                        == (other.mSmartActions == null ? 0 : other.mSmartActions.size()))
                    && Objects.equals(mSmartReplies, other.mSmartReplies)
                    && Objects.equals(mCanBubble, other.mCanBubble);
        }
    }

    /**
     * Provides access to ranking information on currently active
     * notifications.
     *
     * <p>
     * Note that this object represents a ranking snapshot that only applies to
     * notifications active at the time of retrieval.
     */
    public static class RankingMap implements Parcelable {
        private ArrayList<String> mOrderedKeys = new ArrayList<>();
        // Note: all String keys should be intern'd as pointers into mOrderedKeys
        private ArrayMap<String, Ranking> mRankings = new ArrayMap<>();

        /**
         * @hide
         */
        public RankingMap(Ranking[] rankings) {
            for (int i = 0; i < rankings.length; i++) {
                final String key = rankings[i].getKey();
                mOrderedKeys.add(key);
                mRankings.put(key, rankings[i]);
            }
        }

        // -- parcelable interface --

        private RankingMap(Parcel in) {
            final ClassLoader cl = getClass().getClassLoader();
            final int count = in.readInt();
            mOrderedKeys.ensureCapacity(count);
            mRankings.ensureCapacity(count);
            for (int i = 0; i < count; i++) {
                final Ranking r = new Ranking(in);
                final String key = r.getKey();
                mOrderedKeys.add(key);
                mRankings.put(key, r);
            }
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;

            RankingMap other = (RankingMap) o;

            return mOrderedKeys.equals(other.mOrderedKeys)
                    && mRankings.equals(other.mRankings);

        }

        @Override
        public int describeContents() {
            return 0;
        }

        @Override
        public void writeToParcel(Parcel out, int flags) {
            final int count = mOrderedKeys.size();
            out.writeInt(count);
            for (int i = 0; i < count; i++) {
                mRankings.get(mOrderedKeys.get(i)).writeToParcel(out, flags);
            }
        }

        public static final @android.annotation.NonNull Creator<RankingMap> CREATOR = new Creator<RankingMap>() {
            @Override
            public RankingMap createFromParcel(Parcel source) {
                return new RankingMap(source);
            }

            @Override
            public RankingMap[] newArray(int size) {
                return new RankingMap[size];
            }
        };

        /**
         * Request the list of notification keys in their current ranking
         * order.
         *
         * @return An array of active notification keys, in their ranking order.
         */
        public String[] getOrderedKeys() {
            return mOrderedKeys.toArray(new String[0]);
        }

        /**
         * Populates outRanking with ranking information for the notification
         * with the given key.
         *
         * @return true if a valid key has been passed and outRanking has
         * been populated; false otherwise
         */
        public boolean getRanking(String key, Ranking outRanking) {
            if (mRankings.containsKey(key)) {
                outRanking.populate(mRankings.get(key));
                return true;
            }
            return false;
        }

        /**
         * Get a reference to the actual Ranking object corresponding to the key.
         * Used only by unit tests.
         *
         * @hide
         */
        @VisibleForTesting
        public Ranking getRawRankingObject(String key) {
            return mRankings.get(key);
        }
    }

    private final class MyHandler extends Handler {
        public static final int MSG_ON_NOTIFICATION_POSTED = 1;
        public static final int MSG_ON_NOTIFICATION_REMOVED = 2;
        public static final int MSG_ON_LISTENER_CONNECTED = 3;
        public static final int MSG_ON_NOTIFICATION_RANKING_UPDATE = 4;
        public static final int MSG_ON_LISTENER_HINTS_CHANGED = 5;
        public static final int MSG_ON_INTERRUPTION_FILTER_CHANGED = 6;
        public static final int MSG_ON_NOTIFICATION_CHANNEL_MODIFIED = 7;
        public static final int MSG_ON_NOTIFICATION_CHANNEL_GROUP_MODIFIED = 8;
        public static final int MSG_ON_STATUS_BAR_ICON_BEHAVIOR_CHANGED = 9;

        public MyHandler(Looper looper) {
            super(looper, null, false);
        }

        @Override
        public void handleMessage(Message msg) {
            if (!isConnected) {
                return;
            }
            switch (msg.what) {
                case MSG_ON_NOTIFICATION_POSTED: {
                    SomeArgs args = (SomeArgs) msg.obj;
                    StatusBarNotification sbn = (StatusBarNotification) args.arg1;
                    RankingMap rankingMap = (RankingMap) args.arg2;
                    args.recycle();
                    onNotificationPosted(sbn, rankingMap);
                } break;

                case MSG_ON_NOTIFICATION_REMOVED: {
                    SomeArgs args = (SomeArgs) msg.obj;
                    StatusBarNotification sbn = (StatusBarNotification) args.arg1;
                    RankingMap rankingMap = (RankingMap) args.arg2;
                    int reason = (int) args.arg3;
                    NotificationStats stats = (NotificationStats) args.arg4;
                    args.recycle();
                    onNotificationRemoved(sbn, rankingMap, stats, reason);
                } break;

                case MSG_ON_LISTENER_CONNECTED: {
                    onListenerConnected();
                } break;

                case MSG_ON_NOTIFICATION_RANKING_UPDATE: {
                    RankingMap rankingMap = (RankingMap) msg.obj;
                    onNotificationRankingUpdate(rankingMap);
                } break;

                case MSG_ON_LISTENER_HINTS_CHANGED: {
                    final int hints = msg.arg1;
                    onListenerHintsChanged(hints);
                } break;

                case MSG_ON_INTERRUPTION_FILTER_CHANGED: {
                    final int interruptionFilter = msg.arg1;
                    onInterruptionFilterChanged(interruptionFilter);
                } break;

                case MSG_ON_NOTIFICATION_CHANNEL_MODIFIED: {
                    SomeArgs args = (SomeArgs) msg.obj;
                    String pkgName = (String) args.arg1;
                    UserHandle user= (UserHandle) args.arg2;
                    NotificationChannel channel = (NotificationChannel) args.arg3;
                    int modificationType = (int) args.arg4;
                    onNotificationChannelModified(pkgName, user, channel, modificationType);
                } break;

                case MSG_ON_NOTIFICATION_CHANNEL_GROUP_MODIFIED: {
                    SomeArgs args = (SomeArgs) msg.obj;
                    String pkgName = (String) args.arg1;
                    UserHandle user = (UserHandle) args.arg2;
                    NotificationChannelGroup group = (NotificationChannelGroup) args.arg3;
                    int modificationType = (int) args.arg4;
                    onNotificationChannelGroupModified(pkgName, user, group, modificationType);
                } break;

                case MSG_ON_STATUS_BAR_ICON_BEHAVIOR_CHANGED: {
                    onSilentStatusBarIconsVisibilityChanged((Boolean) msg.obj);
                } break;
            }
        }
    }
}
