/*
 * Copyright (C) 2018 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 com.android.systemui.statusbar.phone;

import static android.service.notification.NotificationListenerService.REASON_CLICK;

import static com.android.systemui.statusbar.phone.CentralSurfaces.getActivityOptions;

import android.app.ActivityManager;
import android.app.KeyguardManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.TaskStackBuilder;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.RemoteException;
import android.os.UserHandle;
import android.provider.Settings;
import android.service.dreams.IDreamManager;
import android.service.notification.StatusBarNotification;
import android.text.TextUtils;
import android.util.EventLog;
import android.view.View;

import androidx.annotation.VisibleForTesting;

import com.android.internal.jank.InteractionJankMonitor;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.statusbar.NotificationVisibility;
import com.android.internal.widget.LockPatternUtils;
import com.android.systemui.ActivityIntentHelper;
import com.android.systemui.EventLogTags;
import com.android.systemui.animation.ActivityLaunchAnimator;
import com.android.systemui.assist.AssistManager;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.NotificationClickNotifier;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationPresenter;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
import com.android.systemui.statusbar.notification.NotifPipelineFlags;
import com.android.systemui.statusbar.notification.NotificationActivityStarter;
import com.android.systemui.statusbar.notification.NotificationEntryListener;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.NotificationLaunchAnimatorControllerProvider;
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRowDragController;
import com.android.systemui.statusbar.notification.row.OnUserInteractionCallback;
import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent;
import com.android.systemui.statusbar.policy.HeadsUpUtil;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.wmshell.BubblesManager;

import java.util.Optional;
import java.util.concurrent.Executor;

import javax.inject.Inject;

import dagger.Lazy;

/**
 * Status bar implementation of {@link NotificationActivityStarter}.
 */
@CentralSurfacesComponent.CentralSurfacesScope
class StatusBarNotificationActivityStarter implements NotificationActivityStarter {

    private final Context mContext;

    private final CommandQueue mCommandQueue;
    private final Handler mMainThreadHandler;
    private final Executor mUiBgExecutor;

    private final NotificationEntryManager mEntryManager;
    private final NotifPipeline mNotifPipeline;
    private final NotificationVisibilityProvider mVisibilityProvider;
    private final HeadsUpManagerPhone mHeadsUpManager;
    private final ActivityStarter mActivityStarter;
    private final NotificationClickNotifier mClickNotifier;
    private final StatusBarStateController mStatusBarStateController;
    private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
    private final KeyguardManager mKeyguardManager;
    private final IDreamManager mDreamManager;
    private final Optional<BubblesManager> mBubblesManagerOptional;
    private final Lazy<AssistManager> mAssistManagerLazy;
    private final NotificationRemoteInputManager mRemoteInputManager;
    private final GroupMembershipManager mGroupMembershipManager;
    private final NotificationLockscreenUserManager mLockscreenUserManager;
    private final ShadeController mShadeController;
    private final KeyguardStateController mKeyguardStateController;
    private final NotificationInterruptStateProvider mNotificationInterruptStateProvider;
    private final LockPatternUtils mLockPatternUtils;
    private final StatusBarRemoteInputCallback mStatusBarRemoteInputCallback;
    private final ActivityIntentHelper mActivityIntentHelper;

    private final NotifPipelineFlags mNotifPipelineFlags;
    private final MetricsLogger mMetricsLogger;
    private final StatusBarNotificationActivityStarterLogger mLogger;

    private final CentralSurfaces mCentralSurfaces;
    private final NotificationPresenter mPresenter;
    private final NotificationPanelViewController mNotificationPanel;
    private final ActivityLaunchAnimator mActivityLaunchAnimator;
    private final NotificationLaunchAnimatorControllerProvider mNotificationAnimationProvider;
    private final OnUserInteractionCallback mOnUserInteractionCallback;

    private boolean mIsCollapsingToShowActivityOverLockscreen;

    @Inject
    StatusBarNotificationActivityStarter(
            Context context,
            CommandQueue commandQueue,
            Handler mainThreadHandler,
            Executor uiBgExecutor,
            NotificationEntryManager entryManager,
            NotifPipeline notifPipeline,
            NotificationVisibilityProvider visibilityProvider,
            HeadsUpManagerPhone headsUpManager,
            ActivityStarter activityStarter,
            NotificationClickNotifier clickNotifier,
            StatusBarStateController statusBarStateController,
            StatusBarKeyguardViewManager statusBarKeyguardViewManager,
            KeyguardManager keyguardManager,
            IDreamManager dreamManager,
            Optional<BubblesManager> bubblesManagerOptional,
            Lazy<AssistManager> assistManagerLazy,
            NotificationRemoteInputManager remoteInputManager,
            GroupMembershipManager groupMembershipManager,
            NotificationLockscreenUserManager lockscreenUserManager,
            ShadeController shadeController,
            KeyguardStateController keyguardStateController,
            NotificationInterruptStateProvider notificationInterruptStateProvider,
            LockPatternUtils lockPatternUtils,
            StatusBarRemoteInputCallback remoteInputCallback,
            ActivityIntentHelper activityIntentHelper,
            NotifPipelineFlags notifPipelineFlags,
            MetricsLogger metricsLogger,
            StatusBarNotificationActivityStarterLogger logger,
            OnUserInteractionCallback onUserInteractionCallback,
            CentralSurfaces centralSurfaces,
            NotificationPresenter presenter,
            NotificationPanelViewController panel,
            ActivityLaunchAnimator activityLaunchAnimator,
            NotificationLaunchAnimatorControllerProvider notificationAnimationProvider) {
        mContext = context;
        mCommandQueue = commandQueue;
        mMainThreadHandler = mainThreadHandler;
        mUiBgExecutor = uiBgExecutor;
        mEntryManager = entryManager;
        mNotifPipeline = notifPipeline;
        mVisibilityProvider = visibilityProvider;
        mHeadsUpManager = headsUpManager;
        mActivityStarter = activityStarter;
        mClickNotifier = clickNotifier;
        mStatusBarStateController = statusBarStateController;
        mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
        mKeyguardManager = keyguardManager;
        mDreamManager = dreamManager;
        mBubblesManagerOptional = bubblesManagerOptional;
        mAssistManagerLazy = assistManagerLazy;
        mRemoteInputManager = remoteInputManager;
        mGroupMembershipManager = groupMembershipManager;
        mLockscreenUserManager = lockscreenUserManager;
        mShadeController = shadeController;
        mKeyguardStateController = keyguardStateController;
        mNotificationInterruptStateProvider = notificationInterruptStateProvider;
        mLockPatternUtils = lockPatternUtils;
        mStatusBarRemoteInputCallback = remoteInputCallback;
        mActivityIntentHelper = activityIntentHelper;
        mNotifPipelineFlags = notifPipelineFlags;
        mMetricsLogger = metricsLogger;
        mLogger = logger;
        mOnUserInteractionCallback = onUserInteractionCallback;
        // TODO: use KeyguardStateController#isOccluded to remove this dependency
        mCentralSurfaces = centralSurfaces;
        mPresenter = presenter;
        mNotificationPanel = panel;
        mActivityLaunchAnimator = activityLaunchAnimator;
        mNotificationAnimationProvider = notificationAnimationProvider;

        if (!mNotifPipelineFlags.isNewPipelineEnabled()) {
            mEntryManager.addNotificationEntryListener(new NotificationEntryListener() {
                @Override
                public void onPendingEntryAdded(NotificationEntry entry) {
                    handleFullScreenIntent(entry);
                }
            });
        } else {
            mNotifPipeline.addCollectionListener(new NotifCollectionListener() {
                @Override
                public void onEntryAdded(NotificationEntry entry) {
                    handleFullScreenIntent(entry);
                }
            });
        }
    }

    /**
     * Called when a notification is clicked.
     *
     * @param entry notification that was clicked
     * @param row row for that notification
     */
    @Override
    public void onNotificationClicked(NotificationEntry entry, ExpandableNotificationRow row) {
        mLogger.logStartingActivityFromClick(entry);

        if (mRemoteInputManager.isRemoteInputActive(entry)
                && !TextUtils.isEmpty(row.getActiveRemoteInputText())) {
            // We have an active remote input typed and the user clicked on the notification.
            // this was probably unintentional, so we're closing the edit text instead.
            mRemoteInputManager.closeRemoteInputs();
            return;
        }
        Notification notification = entry.getSbn().getNotification();
        final PendingIntent intent = notification.contentIntent != null
                ? notification.contentIntent
                : notification.fullScreenIntent;
        final boolean isBubble = entry.isBubble();

        // This code path is now executed for notification without a contentIntent.
        // The only valid case is Bubble notifications. Guard against other cases
        // entering here.
        if (intent == null && !isBubble) {
            mLogger.logNonClickableNotification(entry);
            return;
        }

        boolean isActivityIntent = intent != null && intent.isActivity() && !isBubble;
        final boolean willLaunchResolverActivity = isActivityIntent
                && mActivityIntentHelper.wouldLaunchResolverActivity(intent.getIntent(),
                mLockscreenUserManager.getCurrentUserId());
        final boolean animate = !willLaunchResolverActivity
                && mCentralSurfaces.shouldAnimateLaunch(isActivityIntent);
        boolean showOverLockscreen = mKeyguardStateController.isShowing() && intent != null
                && mActivityIntentHelper.wouldShowOverLockscreen(intent.getIntent(),
                mLockscreenUserManager.getCurrentUserId());
        ActivityStarter.OnDismissAction postKeyguardAction = new ActivityStarter.OnDismissAction() {
            @Override
            public boolean onDismiss() {
                return handleNotificationClickAfterKeyguardDismissed(
                        entry, row, intent, isActivityIntent, animate, showOverLockscreen);
            }

            @Override
            public boolean willRunAnimationOnKeyguard() {
                return animate;
            }
        };
        if (showOverLockscreen) {
            mIsCollapsingToShowActivityOverLockscreen = true;
            postKeyguardAction.onDismiss();
        } else {
            mActivityStarter.dismissKeyguardThenExecute(
                    postKeyguardAction,
                    null,
                    willLaunchResolverActivity);
        }
    }

    private boolean handleNotificationClickAfterKeyguardDismissed(
            NotificationEntry entry,
            ExpandableNotificationRow row,
            PendingIntent intent,
            boolean isActivityIntent,
            boolean animate,
            boolean showOverLockscreen) {
        mLogger.logHandleClickAfterKeyguardDismissed(entry);

        final Runnable runnable = () -> handleNotificationClickAfterPanelCollapsed(
                entry, row, intent, isActivityIntent, animate);

        if (showOverLockscreen) {
            mShadeController.addPostCollapseAction(runnable);
            mShadeController.collapsePanel(true /* animate */);
        } else if (mKeyguardStateController.isShowing()
                && mCentralSurfaces.isOccluded()) {
            mStatusBarKeyguardViewManager.addAfterKeyguardGoneRunnable(runnable);
            mShadeController.collapsePanel();
        } else {
            runnable.run();
        }

        // Always defer the keyguard dismiss when animating.
        return animate || !mNotificationPanel.isFullyCollapsed();
    }

    private void handleNotificationClickAfterPanelCollapsed(
            NotificationEntry entry,
            ExpandableNotificationRow row,
            PendingIntent intent,
            boolean isActivityIntent,
            boolean animate) {
        String notificationKey = entry.getKey();
        mLogger.logHandleClickAfterPanelCollapsed(entry);

        try {
            // The intent we are sending is for the application, which
            // won't have permission to immediately start an activity after
            // the user switches to home.  We know it is safe to do at this
            // point, so make sure new activity switches are now allowed.
            ActivityManager.getService().resumeAppSwitches();
        } catch (RemoteException e) {
        }
        // If we are launching a work activity and require to launch
        // separate work challenge, we defer the activity action and cancel
        // notification until work challenge is unlocked.
        if (isActivityIntent) {
            final int userId = intent.getCreatorUserHandle().getIdentifier();
            if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)
                    && mKeyguardManager.isDeviceLocked(userId)) {
                // TODO(b/28935539): should allow certain activities to
                // bypass work challenge
                if (mStatusBarRemoteInputCallback.startWorkChallengeIfNecessary(userId,
                        intent.getIntentSender(), notificationKey)) {
                    removeHunAfterClick(row);
                    // Show work challenge, do not run PendingIntent and
                    // remove notification
                    collapseOnMainThread();
                    return;
                }
            }
        }
        Intent fillInIntent = null;
        CharSequence remoteInputText = null;
        if (!TextUtils.isEmpty(entry.remoteInputText)) {
            remoteInputText = entry.remoteInputText;
        }
        if (!TextUtils.isEmpty(remoteInputText)
                && !mRemoteInputManager.isSpinning(notificationKey)) {
            fillInIntent = new Intent().putExtra(Notification.EXTRA_REMOTE_INPUT_DRAFT,
                    remoteInputText.toString());
        }
        final boolean canBubble = entry.canBubble();
        if (canBubble) {
            mLogger.logExpandingBubble(entry);
            removeHunAfterClick(row);
            expandBubbleStackOnMainThread(entry);
        } else {
            startNotificationIntent(intent, fillInIntent, entry, row, animate, isActivityIntent);
        }
        if (isActivityIntent || canBubble) {
            mAssistManagerLazy.get().hideAssist();
        }

        final NotificationVisibility nv = mVisibilityProvider.obtain(entry, true);

        if (!canBubble && (shouldAutoCancel(entry.getSbn())
                || mRemoteInputManager.isNotificationKeptForRemoteInputHistory(notificationKey))) {
            final Runnable removeNotification =
                    mOnUserInteractionCallback.registerFutureDismissal(entry, REASON_CLICK);
            // Immediately remove notification from visually showing.
            // We have to post the removal to the UI thread for synchronization.
            mMainThreadHandler.post(() -> {
                if (mPresenter.isCollapsing()) {
                    // To avoid lags we're only performing the remove after the shade is collapsed
                    mShadeController.addPostCollapseAction(removeNotification);
                } else {
                    removeNotification.run();
                }
            });
        }

        // inform NMS that the notification was clicked
        mClickNotifier.onNotificationClick(notificationKey, nv);

        mIsCollapsingToShowActivityOverLockscreen = false;
    }

    /**
     * Called when a notification is dropped on proper target window.
     * Intent that is included in this entry notification,
     * will be sent by {@link ExpandableNotificationRowDragController}
     *
     * @param entry notification entry that is dropped.
     */
    @Override
    public void onDragSuccess(NotificationEntry entry) {
        // this method is not responsible for intent sending.
        // will focus follow operation only after drag-and-drop that notification.
        final NotificationVisibility nv = mVisibilityProvider.obtain(entry, true);

        String notificationKey = entry.getKey();
        if (shouldAutoCancel(entry.getSbn())
                || mRemoteInputManager.isNotificationKeptForRemoteInputHistory(notificationKey)) {
            final Runnable removeNotification =
                    mOnUserInteractionCallback.registerFutureDismissal(entry, REASON_CLICK);
            // Immediately remove notification from visually showing.
            // We have to post the removal to the UI thread for synchronization.
            mMainThreadHandler.post(() -> {
                if (mPresenter.isCollapsing()) {
                    // To avoid lags we're only performing the remove
                    // after the shade is collapsed
                    mShadeController.addPostCollapseAction(removeNotification);
                } else {
                    removeNotification.run();
                }
            });
        }

        // inform NMS that the notification was clicked
        mClickNotifier.onNotificationClick(notificationKey, nv);

        mIsCollapsingToShowActivityOverLockscreen = false;
    }

    private void expandBubbleStackOnMainThread(NotificationEntry entry) {
        if (!mBubblesManagerOptional.isPresent()) {
            return;
        }

        if (Looper.getMainLooper().isCurrentThread()) {
            expandBubbleStack(entry);
        } else {
            mMainThreadHandler.post(() -> expandBubbleStack(entry));
        }
    }

    private void expandBubbleStack(NotificationEntry entry) {
        mBubblesManagerOptional.get().expandStackAndSelectBubble(entry);
        mShadeController.collapsePanel();
    }

    private void startNotificationIntent(
            PendingIntent intent,
            Intent fillInIntent,
            NotificationEntry entry,
            ExpandableNotificationRow row,
            boolean animate,
            boolean isActivityIntent) {
        mLogger.logStartNotificationIntent(entry);
        try {
            ActivityLaunchAnimator.Controller animationController =
                    new StatusBarLaunchAnimatorController(
                            mNotificationAnimationProvider.getAnimatorController(row, null),
                            mCentralSurfaces,
                            isActivityIntent);
            mActivityLaunchAnimator.startPendingIntentWithAnimation(
                    animationController,
                    animate,
                    intent.getCreatorPackage(),
                    (adapter) -> {
                        long eventTime = row.getAndResetLastActionUpTime();
                        Bundle options = eventTime > 0
                                ? getActivityOptions(
                                mCentralSurfaces.getDisplayId(),
                                adapter,
                                mKeyguardStateController.isShowing(),
                                eventTime)
                                : getActivityOptions(mCentralSurfaces.getDisplayId(), adapter);
                        int result = intent.sendAndReturnResult(mContext, 0, fillInIntent, null,
                                null, null, options);
                        mLogger.logSendPendingIntent(entry, intent, result);
                        return result;
                    });
        } catch (PendingIntent.CanceledException e) {
            // the stack trace isn't very helpful here.
            // Just log the exception message.
            mLogger.logSendingIntentFailed(e);
            // TODO: Dismiss Keyguard.
        }
    }

    @Override
    public void startNotificationGutsIntent(final Intent intent, final int appUid,
            ExpandableNotificationRow row) {
        boolean animate = mCentralSurfaces.shouldAnimateLaunch(true /* isActivityIntent */);
        ActivityStarter.OnDismissAction onDismissAction = new ActivityStarter.OnDismissAction() {
            @Override
            public boolean onDismiss() {
                AsyncTask.execute(() -> {
                    ActivityLaunchAnimator.Controller animationController =
                            new StatusBarLaunchAnimatorController(
                                    mNotificationAnimationProvider.getAnimatorController(row),
                                    mCentralSurfaces, true /* isActivityIntent */);

                    mActivityLaunchAnimator.startIntentWithAnimation(
                            animationController, animate, intent.getPackage(),
                            (adapter) -> TaskStackBuilder.create(mContext)
                                    .addNextIntentWithParentStack(intent)
                                    .startActivities(getActivityOptions(
                                            mCentralSurfaces.getDisplayId(),
                                            adapter),
                                            new UserHandle(UserHandle.getUserId(appUid))));
                });
                return true;
            }

            @Override
            public boolean willRunAnimationOnKeyguard() {
                return animate;
            }
        };
        mActivityStarter.dismissKeyguardThenExecute(onDismissAction, null,
                false /* afterKeyguardGone */);
    }

    @Override
    public void startHistoryIntent(View view, boolean showHistory) {
        boolean animate = mCentralSurfaces.shouldAnimateLaunch(true /* isActivityIntent */);
        ActivityStarter.OnDismissAction onDismissAction = new ActivityStarter.OnDismissAction() {
            @Override
            public boolean onDismiss() {
                AsyncTask.execute(() -> {
                    Intent intent = showHistory ? new Intent(
                            Settings.ACTION_NOTIFICATION_HISTORY) : new Intent(
                            Settings.ACTION_NOTIFICATION_SETTINGS);
                    TaskStackBuilder tsb = TaskStackBuilder.create(mContext)
                            .addNextIntent(new Intent(Settings.ACTION_NOTIFICATION_SETTINGS));
                    if (showHistory) {
                        tsb.addNextIntent(intent);
                    }

                    ActivityLaunchAnimator.Controller viewController =
                            ActivityLaunchAnimator.Controller.fromView(view,
                                    InteractionJankMonitor.CUJ_SHADE_APP_LAUNCH_FROM_HISTORY_BUTTON
                            );
                    ActivityLaunchAnimator.Controller animationController =
                            viewController == null ? null
                                : new StatusBarLaunchAnimatorController(viewController,
                                        mCentralSurfaces,
                                    true /* isActivityIntent */);

                    mActivityLaunchAnimator.startIntentWithAnimation(animationController, animate,
                            intent.getPackage(),
                            (adapter) -> tsb.startActivities(
                                    getActivityOptions(mCentralSurfaces.getDisplayId(), adapter),
                                    UserHandle.CURRENT));
                });
                return true;
            }

            @Override
            public boolean willRunAnimationOnKeyguard() {
                return animate;
            }
        };
        mActivityStarter.dismissKeyguardThenExecute(onDismissAction, null,
                false /* afterKeyguardGone */);
    }

    private void removeHunAfterClick(ExpandableNotificationRow row) {
        String key = row.getEntry().getSbn().getKey();
        if (mHeadsUpManager != null && mHeadsUpManager.isAlerting(key)) {
            // Release the HUN notification to the shade.
            if (mPresenter.isPresenterFullyCollapsed()) {
                HeadsUpUtil.setNeedsHeadsUpDisappearAnimationAfterClick(row, true);
            }

            // In most cases, when FLAG_AUTO_CANCEL is set, the notification will
            // become canceled shortly by NoMan, but we can't assume that.
            mHeadsUpManager.removeNotification(key, true /* releaseImmediately */);
        }
    }

    @VisibleForTesting
    void handleFullScreenIntent(NotificationEntry entry) {
        if (mNotificationInterruptStateProvider.shouldLaunchFullScreenIntentWhenAdded(entry)) {
            if (shouldSuppressFullScreenIntent(entry)) {
                mLogger.logFullScreenIntentSuppressedByDnD(entry);
            } else if (entry.getImportance() < NotificationManager.IMPORTANCE_HIGH) {
                mLogger.logFullScreenIntentNotImportantEnough(entry);
            } else {
                // Stop screensaver if the notification has a fullscreen intent.
                // (like an incoming phone call)
                mUiBgExecutor.execute(() -> {
                    try {
                        mDreamManager.awaken();
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                });

                // not immersive & a fullscreen alert should be shown
                final PendingIntent fullscreenIntent =
                        entry.getSbn().getNotification().fullScreenIntent;
                mLogger.logSendingFullScreenIntent(entry, fullscreenIntent);
                try {
                    EventLog.writeEvent(EventLogTags.SYSUI_FULLSCREEN_NOTIFICATION,
                            entry.getKey());
                    mCentralSurfaces.wakeUpForFullScreenIntent();
                    fullscreenIntent.send();
                    entry.notifyFullScreenIntentLaunched();
                    mMetricsLogger.count("note_fullscreen", 1);
                } catch (PendingIntent.CanceledException e) {
                    // ignore
                }
            }
        }
    }

    @Override
    public boolean isCollapsingToShowActivityOverLockscreen() {
        return mIsCollapsingToShowActivityOverLockscreen;
    }

    private static boolean shouldAutoCancel(StatusBarNotification sbn) {
        int flags = sbn.getNotification().flags;
        if ((flags & Notification.FLAG_AUTO_CANCEL) != Notification.FLAG_AUTO_CANCEL) {
            return false;
        }
        if ((flags & Notification.FLAG_FOREGROUND_SERVICE) != 0) {
            return false;
        }
        return true;
    }

    private void collapseOnMainThread() {
        if (Looper.getMainLooper().isCurrentThread()) {
            mShadeController.collapsePanel();
        } else {
            mMainThreadHandler.post(mShadeController::collapsePanel);
        }
    }

    private boolean shouldSuppressFullScreenIntent(NotificationEntry entry) {
        if (mPresenter.isDeviceInVrMode()) {
            return true;
        }

        return entry.shouldSuppressFullScreenIntent();
    }
}
