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

Commit a6b68a36 authored by Beverly's avatar Beverly
Browse files

Add functionality for new smart action

When user clicks on smart action MARK_CONVERSATION_AS_PRIORITY, open the
conversation notification's notification guts with "Priority"
pre-selected. User will still need to click "apply" for the new priority
to be applied.

Test: manual, atest NotificationConversationInfoTest
Bug: 163614153
Change-Id: Ic22261f6b81274e42f20f1748e1465a03dee8144
parent 4ed03067
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.systemui.statusbar.notification.row;

import static android.app.Notification.Action.SEMANTIC_ACTION_MARK_CONVERSATION_AS_PRIORITY;
import static android.service.notification.NotificationListenerService.REASON_CANCEL;

import static com.android.systemui.statusbar.notification.ActivityLaunchAnimator.ExpandAnimationParameters;
@@ -1785,6 +1786,27 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
        doLongClickCallback(x, y, menuItem);
    }

    /**
     * Perform a smart action which triggers a longpress (expose guts).
     * Based on the semanticAction passed, may update the state of the guts view.
     * @param semanticAction associated with this smart action click
     */
    public void doSmartActionClick(int x, int y, int semanticAction) {
        createMenu();
        NotificationMenuRowPlugin provider = getProvider();
        MenuItem menuItem = null;
        if (provider != null) {
            menuItem = provider.getLongpressMenuItem(mContext);
        }
        if (SEMANTIC_ACTION_MARK_CONVERSATION_AS_PRIORITY == semanticAction
                && menuItem.getGutsView() instanceof NotificationConversationInfo) {
            NotificationConversationInfo info =
                    (NotificationConversationInfo) menuItem.getGutsView();
            info.setSelectedAction(NotificationConversationInfo.ACTION_FAVORITE);
        }
        doLongClickCallback(x, y, menuItem);
    }

    private void doLongClickCallback(int x, int y, MenuItem menuItem) {
        if (mLongPressListener != null && menuItem != null) {
            mLongPressListener.onLongPress(this, x, y, menuItem);
+11 −4
Original line number Diff line number Diff line
@@ -206,6 +206,7 @@ public class NotificationConversationInfo extends LinearLayout implements
    }

    public void bindNotification(
            @Action int selectedAction,
            ShortcutManager shortcutManager,
            PackageManager pm,
            INotificationManager iNotificationManager,
@@ -224,7 +225,8 @@ public class NotificationConversationInfo extends LinearLayout implements
            @Background Handler bgHandler,
            OnConversationSettingsClickListener onConversationSettingsClickListener,
            Optional<BubblesManager> bubblesManagerOptional) {
        mSelectedAction = -1;
        mPressedApply = false;
        mSelectedAction = selectedAction;
        mINotificationManager = iNotificationManager;
        mOnUserInteractionCallback = onUserInteractionCallback;
        mPackageName = pkg;
@@ -297,7 +299,8 @@ public class NotificationConversationInfo extends LinearLayout implements
        settingsButton.setOnClickListener(getSettingsOnClickListener());
        settingsButton.setVisibility(settingsButton.hasOnClickListeners() ? VISIBLE : GONE);

        updateToggleActions(getSelectedAction(), false);
        updateToggleActions(mSelectedAction == -1 ? getPriority() : mSelectedAction,
                false);
    }

    private void bindHeader() {
@@ -406,7 +409,7 @@ public class NotificationConversationInfo extends LinearLayout implements

    @Override
    public void onFinishedClosing() {
        // TODO: do we need to do anything here?
        mSelectedAction = -1;
    }

    @Override
@@ -487,7 +490,7 @@ public class NotificationConversationInfo extends LinearLayout implements
                throw new IllegalArgumentException("Unrecognized behavior: " + mSelectedAction);
        }

        boolean isAChange = getSelectedAction() != selectedAction;
        boolean isAChange = getPriority() != selectedAction;
        TextView done = findViewById(R.id.done);
        done.setText(isAChange
                ? R.string.inline_ok_button
@@ -498,6 +501,10 @@ public class NotificationConversationInfo extends LinearLayout implements
    }

    int getSelectedAction() {
        return mSelectedAction;
    }

    private int getPriority() {
        if (mNotificationChannel.getImportance() <= IMPORTANCE_LOW
                && mNotificationChannel.getImportance() > IMPORTANCE_UNSPECIFIED) {
            return ACTION_MUTE;
+1 −0
Original line number Diff line number Diff line
@@ -474,6 +474,7 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx
                        R.dimen.notification_guts_conversation_icon_size));

        notificationInfoView.bindNotification(
                notificationInfoView.getSelectedAction(),
                mShortcutManager,
                pmUser,
                mNotificationManager,
+10 −1
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.systemui.statusbar.policy

import android.app.Notification
import android.app.Notification.Action.SEMANTIC_ACTION_MARK_CONVERSATION_AS_PRIORITY
import android.app.PendingIntent
import android.app.RemoteInput
import android.content.Context
@@ -310,12 +311,20 @@ interface SmartActionInflater {
        actionIndex: Int,
        action: Notification.Action
    ) =
        if (smartActions.fromAssistant
            && SEMANTIC_ACTION_MARK_CONVERSATION_AS_PRIORITY == action.semanticAction) {
            entry.row.doSmartActionClick(entry.row.x.toInt() / 2,
                entry.row.y.toInt() / 2, SEMANTIC_ACTION_MARK_CONVERSATION_AS_PRIORITY)
            smartReplyController
                .smartActionClicked(entry, actionIndex, action, smartActions.fromAssistant)
        } else {
            activityStarter.startPendingIntentDismissingKeyguard(action.actionIntent, entry.row) {
                smartReplyController
                    .smartActionClicked(entry, actionIndex, action, smartActions.fromAssistant)
                headsUpManager.removeNotification(entry.key, true /* releaseImmediately */)
            }
        }
}

interface SmartReplyInflater {
    fun inflateReplyButton(
+90 −0
Original line number Diff line number Diff line
@@ -241,6 +241,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
    @Test
    public void testBindNotification_SetsShortcutIcon() {
        mNotificationInfo.bindNotification(
                -1,
                mShortcutManager,
                mMockPackageManager,
                mMockINotificationManager,
@@ -265,6 +266,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
    public void testBindNotification_SetsTextApplicationName() {
        when(mMockPackageManager.getApplicationLabel(any())).thenReturn("App Name");
        mNotificationInfo.bindNotification(
                -1,
                mShortcutManager,
                mMockPackageManager,
                mMockINotificationManager,
@@ -289,6 +291,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
    @Test
    public void testBindNotification_SetsTextChannelName() {
        mNotificationInfo.bindNotification(
                -1,
                mShortcutManager,
                mLauncherApps,
                mMockPackageManager,
@@ -316,6 +319,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
        mConversationChannel.setGroup(group.getId());

        mNotificationInfo.bindNotification(
                -1,
                mShortcutManager,
                mMockPackageManager,
                mMockINotificationManager,
@@ -341,6 +345,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
    @Test
    public void testBindNotification_GroupNameHiddenIfNoGroup() {
        mNotificationInfo.bindNotification(
                -1,
                mShortcutManager,
                mMockPackageManager,
                mMockINotificationManager,
@@ -365,6 +370,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
    @Test
    public void testBindNotification_noDelegate() {
        mNotificationInfo.bindNotification(
                -1,
                mShortcutManager,
                mMockPackageManager,
                mMockINotificationManager,
@@ -400,6 +406,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
                .setShortcutInfo(mShortcutInfo)
                .build();
        mNotificationInfo.bindNotification(
                -1,
                mShortcutManager,
                mMockPackageManager,
                mMockINotificationManager,
@@ -425,6 +432,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
    public void testBindNotification_SetsOnClickListenerForSettings() {
        final CountDownLatch latch = new CountDownLatch(1);
        mNotificationInfo.bindNotification(
                -1,
                mShortcutManager,
                mMockPackageManager,
                mMockINotificationManager,
@@ -454,6 +462,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
    @Test
    public void testBindNotification_SettingsButtonInvisibleWhenNoClickListener() {
        mNotificationInfo.bindNotification(
                -1,
                mShortcutManager,
                mMockPackageManager,
                mMockINotificationManager,
@@ -478,6 +487,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
    public void testBindNotification_SettingsButtonInvisibleWhenDeviceUnprovisioned() {
        final CountDownLatch latch = new CountDownLatch(1);
        mNotificationInfo.bindNotification(
                -1,
                mShortcutManager,
                mMockPackageManager,
                mMockINotificationManager,
@@ -506,6 +516,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
        mConversationChannel.setImportance(IMPORTANCE_LOW);
        mConversationChannel.setImportantConversation(true);
        mNotificationInfo.bindNotification(
                -1,
                mShortcutManager,
                mMockPackageManager,
                mMockINotificationManager,
@@ -534,6 +545,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
        mConversationChannel.setImportantConversation(false);
        mConversationChannel.setAllowBubbles(true);
        mNotificationInfo.bindNotification(
                -1,
                mShortcutManager,
                mMockPackageManager,
                mMockINotificationManager,
@@ -565,6 +577,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
        mConversationChannel.setImportantConversation(false);
        mConversationChannel.setAllowBubbles(true);
        mNotificationInfo.bindNotification(
                -1,
                mShortcutManager,
                mMockPackageManager,
                mMockINotificationManager,
@@ -595,6 +608,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
        mConversationChannel.setImportantConversation(false);

        mNotificationInfo.bindNotification(
                -1,
                mShortcutManager,
                mMockPackageManager,
                mMockINotificationManager,
@@ -639,6 +653,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
        mConversationChannel.setImportance(IMPORTANCE_LOW);
        mConversationChannel.setImportantConversation(false);
        mNotificationInfo.bindNotification(
                -1,
                mShortcutManager,
                mMockPackageManager,
                mMockINotificationManager,
@@ -682,6 +697,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
        mConversationChannel.setImportantConversation(false);

        mNotificationInfo.bindNotification(
                -1,
                mShortcutManager,
                mMockPackageManager,
                mMockINotificationManager,
@@ -726,6 +742,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
        mConversationChannel.setImportantConversation(false);

        mNotificationInfo.bindNotification(
                -1,
                mShortcutManager,
                mMockPackageManager,
                mMockINotificationManager,
@@ -763,6 +780,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
        mConversationChannel.setImportance(9);

        mNotificationInfo.bindNotification(
                -1,
                mShortcutManager,
                mMockPackageManager,
                mMockINotificationManager,
@@ -799,6 +817,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
        mConversationChannel.setImportantConversation(true);

        mNotificationInfo.bindNotification(
                -1,
                mShortcutManager,
                mMockPackageManager,
                mMockINotificationManager,
@@ -831,12 +850,76 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
        assertTrue(captor.getValue().isImportantConversation());
    }

    @Test
    public void testDefaultSelectedWhenChannelIsDefault() throws Exception {
        // GIVEN channel importance indicates "Default" priority
        mConversationChannel.setImportance(IMPORTANCE_HIGH);
        mConversationChannel.setImportantConversation(false);

        // WHEN we indicate no selected action
        mNotificationInfo.bindNotification(
                -1, // no action selected by default
                mShortcutManager,
                mMockPackageManager,
                mMockINotificationManager,
                mOnUserInteractionCallback,
                TEST_PACKAGE_NAME,
                mNotificationChannel,
                mEntry,
                mBubbleMetadata,
                null,
                null,
                mIconFactory,
                mContext,
                mBuilderProvider,
                true,
                mTestHandler,
                mTestHandler, null, Optional.of(mBubblesManager));

        // THEN the selected action is -1, so the selected option is "Default" priority
        assertEquals(mNotificationInfo.getSelectedAction(), -1);
        assertTrue(mNotificationInfo.findViewById(R.id.default_behavior).isSelected());
    }

    @Test
    public void testFavoriteSelectedWhenChannelIsDefault() throws Exception {
        // GIVEN channel importance indicates "Default" priority
        mConversationChannel.setImportance(IMPORTANCE_HIGH);
        mConversationChannel.setImportantConversation(false);

        // WHEN we indicate the selected action should be "Favorite"
        mNotificationInfo.bindNotification(
                NotificationConversationInfo.ACTION_FAVORITE, // "Favorite" selected by default
                mShortcutManager,
                mMockPackageManager,
                mMockINotificationManager,
                mOnUserInteractionCallback,
                TEST_PACKAGE_NAME,
                mNotificationChannel,
                mEntry,
                mBubbleMetadata,
                null,
                null,
                mIconFactory,
                mContext,
                mBuilderProvider,
                true,
                mTestHandler,
                mTestHandler, null, Optional.of(mBubblesManager));

        // THEN the selected action is "Favorite", so the selected option is "priority" priority
        assertEquals(mNotificationInfo.getSelectedAction(),
                NotificationConversationInfo.ACTION_FAVORITE);
        assertTrue(mNotificationInfo.findViewById(R.id.priority).isSelected());
    }

    @Test
    public void testDefault_andSave() throws Exception {
        mConversationChannel.setAllowBubbles(true);
        mConversationChannel.setOriginalImportance(IMPORTANCE_HIGH);
        mConversationChannel.setImportantConversation(true);
        mNotificationInfo.bindNotification(
                -1,
                mShortcutManager,
                mMockPackageManager,
                mMockINotificationManager,
@@ -873,6 +956,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
        mConversationChannel.setOriginalImportance(IMPORTANCE_HIGH);
        mConversationChannel.setImportantConversation(false);
        mNotificationInfo.bindNotification(
                -1,
                mShortcutManager,
                mMockPackageManager,
                mMockINotificationManager,
@@ -909,6 +993,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
        mConversationChannel.setOriginalImportance(IMPORTANCE_HIGH);

        mNotificationInfo.bindNotification(
                -1,
                mShortcutManager,
                mMockPackageManager,
                mMockINotificationManager,
@@ -944,6 +1029,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
        mConversationChannel.setAllowBubbles(true);

        mNotificationInfo.bindNotification(
                -1,
                mShortcutManager,
                mMockPackageManager,
                mMockINotificationManager,
@@ -978,6 +1064,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
    @Test
    public void testBindNotification_createsNewChannel() throws Exception {
        mNotificationInfo.bindNotification(
                -1,
                mShortcutManager,
                mMockPackageManager,
                mMockINotificationManager,
@@ -1003,6 +1090,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
    public void testBindNotification_doesNotCreateNewChannelIfExists() throws Exception {
        mNotificationChannel.setConversationId("", CONVERSATION_ID);
        mNotificationInfo.bindNotification(
                -1,
                mShortcutManager,
                mMockPackageManager,
                mMockINotificationManager,
@@ -1038,6 +1126,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {

        // GIVEN the user is changing conversation settings
        mNotificationInfo.bindNotification(
                -1,
                mShortcutManager,
                mMockPackageManager,
                mMockINotificationManager,
@@ -1078,6 +1167,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
        when(b.build()).thenReturn(controller);

        mNotificationInfo.bindNotification(
                -1,
                mShortcutManager,
                mMockPackageManager,
                mMockINotificationManager,