Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fec45dac authored by Mark Renouf's avatar Mark Renouf
Browse files

When a Bubble notification is clicked, show the bubble

After checking keyguard and collapsing the shade, ask
BubbleController to show the bubble associated with the
notification, instad of simply sending the contentIntent.

Bug: 123710619
Test: atest StatusBarNotificationActivityStarterTest
Change-Id: I7b43061447de0daa314deec5abad634fd73e9831
parent d9246ef1
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -292,6 +292,17 @@ public class BubbleController implements BubbleExpandedView.OnBubbleBlockedListe
        }
    }

    /**
     * Request the stack expand if needed, then select the specified Bubble as current.
     *
     * @param notificationKey the notification key for the bubble to be selected
     */
    public void expandStackAndSelectBubble(String notificationKey) {
        if (mStackView != null && mBubbleData.getBubble(notificationKey) != null) {
            mStackView.setExpandedBubble(notificationKey);
        }
    }

    /**
     * Tell the stack of bubbles to be dismissed, this will remove all of the bubbles in the stack.
     */
+3 −3
Original line number Diff line number Diff line
@@ -78,8 +78,7 @@ public final class NotificationClicker implements View.OnClickListener {
        row.setJustClicked(true);
        DejankUtils.postAfterTraversal(() -> row.setJustClicked(false));

        // If it was a bubble we should close it
        if (row.getEntry().isBubble()) {
        if (!row.getEntry().isBubble()) {
            mBubbleController.collapseStack();
        }

@@ -95,7 +94,8 @@ public final class NotificationClicker implements View.OnClickListener {
     */
    public void register(ExpandableNotificationRow row, StatusBarNotification sbn) {
        Notification notification = sbn.getNotification();
        if (notification.contentIntent != null || notification.fullScreenIntent != null) {
        if (notification.contentIntent != null || notification.fullScreenIntent != null
                || row.getEntry().isBubble()) {
            row.setOnClickListener(this);
        } else {
            row.setOnClickListener(null);
+3 −2
Original line number Diff line number Diff line
@@ -220,8 +220,6 @@ public class NotificationRowBinderImpl implements NotificationRowBinder {
            StatusBarNotification sbn,
            ExpandableNotificationRow row) {
        row.setIsLowPriority(entry.ambient);
        // bind the click event to the content area
        checkNotNull(mNotificationClicker).register(row, sbn);

        // Extract target SDK version.
        try {
@@ -257,6 +255,9 @@ public class NotificationRowBinderImpl implements NotificationRowBinder {
        row.setNeedsRedaction(
                Dependency.get(NotificationLockscreenUserManager.class).needsRedaction(entry));
        row.inflateViews();

        // bind the click event to the content area
        checkNotNull(mNotificationClicker).register(row, sbn);
    }

    private void logNotificationExpansion(String key, boolean userAction, boolean expanded) {
+2 −1
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import static android.app.StatusBarManager.WindowVisibleState;
import static android.app.StatusBarManager.windowStateToString;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY;

import static com.android.systemui.Dependency.BG_HANDLER;
import static com.android.systemui.Dependency.MAIN_HANDLER;
import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_ASLEEP;
import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_AWAKE;
@@ -1076,7 +1077,7 @@ public class StatusBar extends SystemUI implements DemoMode,
                mLockscreenUserManager, shadeController, mKeyguardMonitor,
                mNotificationInterruptionStateProvider, mMetricsLogger,
                new LockPatternUtils(mContext), Dependency.get(MAIN_HANDLER),
                mActivityIntentHelper);
                Dependency.get(BG_HANDLER), mActivityIntentHelper, mBubbleController);

        mGutsManager.setNotificationActivityStarter(mNotificationActivityStarter);

+47 −15
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@ import com.android.systemui.Dependency;
import com.android.systemui.EventLogTags;
import com.android.systemui.UiOffloadThread;
import com.android.systemui.assist.AssistManager;
import com.android.systemui.bubbles.BubbleController;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.CommandQueue;
@@ -98,7 +99,9 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
    private final CommandQueue mCommandQueue;
    private final IDreamManager mDreamManager;
    private final Handler mMainThreadHandler;
    private final Handler mBackgroundHandler;
    private final ActivityIntentHelper mActivityIntentHelper;
    private final BubbleController mBubbleController;

    private boolean mIsCollapsingToShowActivityOverLockscreen;

@@ -125,7 +128,9 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
            MetricsLogger metricsLogger,
            LockPatternUtils lockPatternUtils,
            Handler mainThreadHandler,
            ActivityIntentHelper activityIntentHelper) {
            Handler backgroundHandler,
            ActivityIntentHelper activityIntentHelper,
            BubbleController bubbleController) {
        mContext = context;
        mNotificationPanel = panel;
        mPresenter = presenter;
@@ -147,6 +152,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
        mAssistManager = assistManager;
        mGroupManager = groupManager;
        mLockPatternUtils = lockPatternUtils;
        mBackgroundHandler = backgroundHandler;
        mEntryManager.addNotificationEntryListener(new NotificationEntryListener() {
            @Override
            public void onPendingEntryAdded(NotificationEntry entry) {
@@ -156,6 +162,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
        mStatusBarRemoteInputCallback = remoteInputCallback;
        mMainThreadHandler = mainThreadHandler;
        mActivityIntentHelper = activityIntentHelper;
        mBubbleController = bubbleController;
    }

    /**
@@ -178,14 +185,24 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
        final PendingIntent intent = notification.contentIntent != null
                ? notification.contentIntent
                : notification.fullScreenIntent;
        final boolean isBubble = row.getEntry().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) {
            Log.e(TAG, "onNotificationClicked called for non-clickable notification!");
            return;
        }

        final String notificationKey = sbn.getKey();

        boolean isActivityIntent = intent.isActivity();
        boolean isActivityIntent = intent != null && intent.isActivity() && !isBubble;
        final boolean afterKeyguardGone = isActivityIntent
                && mActivityIntentHelper.wouldLaunchResolverActivity(intent.getIntent(),
                mLockscreenUserManager.getCurrentUserId());
        final boolean wasOccluded = mShadeController.isOccluded();
        boolean showOverLockscreen = mKeyguardMonitor.isShowing()
        boolean showOverLockscreen = mKeyguardMonitor.isShowing() && intent != null
                && mActivityIntentHelper.wouldShowOverLockscreen(intent.getIntent(),
                mLockscreenUserManager.getCurrentUserId());
        ActivityStarter.OnDismissAction postKeyguardAction =
@@ -244,9 +261,8 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
            mShadeController.addAfterKeyguardGoneRunnable(runnable);
            mShadeController.collapsePanel();
        } else {
            new Thread(runnable).start();
            mBackgroundHandler.postAtFrontOfQueue(runnable);
        }

        return !mNotificationPanel.isFullyCollapsed();
    }

@@ -287,6 +303,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
        }
        Intent fillInIntent = null;
        NotificationEntry entry = row.getEntry();
        final boolean isBubble = entry.isBubble();
        CharSequence remoteInputText = null;
        if (!TextUtils.isEmpty(entry.remoteInputText)) {
            remoteInputText = entry.remoteInputText;
@@ -295,8 +312,12 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
            fillInIntent = new Intent().putExtra(Notification.EXTRA_REMOTE_INPUT_DRAFT,
                    remoteInputText.toString());
        }
        if (isBubble) {
            expandBubbleStackOnMainThread(notificationKey);
        } else {
            startNotificationIntent(intent, fillInIntent, row, wasOccluded, isActivityIntent);
        if (isActivityIntent) {
        }
        if (isActivityIntent || isBubble) {
            mAssistManager.hideAssist();
        }
        if (shouldCollapse()) {
@@ -316,6 +337,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
        } catch (RemoteException ex) {
            // system process is dead if we're here.
        }
        if (!isBubble) {
            if (parentToCancelFinal != null) {
                removeNotification(parentToCancelFinal);
            }
@@ -325,9 +347,19 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
                // Automatically remove all notifications that we may have kept around longer
                removeNotification(sbn);
            }
        }
        mIsCollapsingToShowActivityOverLockscreen = false;
    }

    private void expandBubbleStackOnMainThread(String notificationKey) {
        if (Looper.getMainLooper().isCurrentThread()) {
            mBubbleController.expandStackAndSelectBubble(notificationKey);
        } else {
            mMainThreadHandler.post(
                    () -> mBubbleController.expandStackAndSelectBubble(notificationKey));
        }
    }

    private void startNotificationIntent(PendingIntent intent, Intent fillInIntent,
            ExpandableNotificationRow row, boolean wasOccluded, boolean isActivityIntent) {
        RemoteAnimationAdapter adapter = mActivityLaunchAnimator.getLaunchAnimation(row,
Loading