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

Commit 4c1af24e authored by Julia Reynolds's avatar Julia Reynolds Committed by Android (Google) Code Review
Browse files

Merge "Fix up bubble actions"

parents 1ef588c5 c3e922b0
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@ import android.os.Handler;
import android.os.Parcelable;
import android.os.RemoteException;
import android.os.UserHandle;
import android.provider.Settings;
import android.service.notification.StatusBarNotification;
import android.text.TextUtils;
import android.util.AttributeSet;
@@ -127,6 +128,8 @@ public class NotificationConversationInfo extends LinearLayout implements
            mBubbleController.onUserDemotedBubbleFromNotification(mEntry);
        } else {
            mBubbleController.onUserCreatedBubbleFromNotification(mEntry);
            Settings.Global.putInt(
                    mContext.getContentResolver(), Settings.Global.NOTIFICATION_BUBBLES, 1);
        }
        closeControls(v, true);
    };
+3 −67
Original line number Diff line number Diff line
@@ -65,8 +65,6 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.systemui.Dependency;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
import com.android.systemui.bubbles.BubbleController;
import com.android.systemui.bubbles.BubbleExperimentConfig;
import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.logging.NotificationCounters;
@@ -102,7 +100,6 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
    // standard controls
    private static final int ACTION_ALERT = 5;

    private TextView mBubbleDescriptionView;
    private TextView mPriorityDescriptionView;
    private TextView mSilentDescriptionView;

@@ -120,7 +117,6 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
    private Set<NotificationChannel> mUniqueChannelsInRow;
    private NotificationChannel mSingleNotificationChannel;
    private int mStartingChannelImportance;
    private boolean mStartedAsBubble;
    private boolean mWasShownHighPriority;
    private boolean mPressedApply;
    private boolean mPresentingChannelEditorDialog = false;
@@ -130,14 +126,8 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
     * level; non-null once the user takes an action which indicates an explicit preference.
     */
    @Nullable private Integer mChosenImportance;
    /**
     * The last bubble setting chosen by the user. Null if the user has not chosen a bubble level;
     * non-null once the user takes an action which indicates an explicit preference.
     */
    @Nullable private Boolean mChosenBubbleEnabled;
    private boolean mIsSingleDefaultChannel;
    private boolean mIsNonblockable;
    private boolean mIsBubbleable;
    private NotificationEntry mEntry;
    private StatusBarNotification mSbn;
    private AnimatorSet mExpandAnimation;
@@ -149,8 +139,6 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
    private NotificationGuts mGutsContainer;
    private Drawable mPkgIcon;

    private BubbleController mBubbleController;

    /** Whether this view is being shown as part of the blocking helper. */
    private boolean mIsForBlockingHelper;

@@ -167,9 +155,6 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
    private OnClickListener mOnAlert = v -> {
        mExitReason = NotificationCounters.BLOCKING_HELPER_KEEP_SHOWING;
        mChosenImportance = IMPORTANCE_DEFAULT;
        if (mStartedAsBubble) {
            mChosenBubbleEnabled = false;
        }
        applyAlertingBehavior(BEHAVIOR_ALERTING, true /* userTriggered */);
    };

@@ -177,18 +162,9 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
    private OnClickListener mOnSilent = v -> {
        mExitReason = NotificationCounters.BLOCKING_HELPER_DELIVER_SILENTLY;
        mChosenImportance = IMPORTANCE_LOW;
        if (mStartedAsBubble) {
            mChosenBubbleEnabled = false;
        }
        applyAlertingBehavior(BEHAVIOR_SILENT, true /* userTriggered */);
    };

    /** Used by standard ui (in an experiment) {@see BubbleExperimentConfig#allowNotifBubbleMenu} */
    private OnClickListener mOnBubble = v -> {
        mExitReason = NotificationCounters.BLOCKING_HELPER_KEEP_SHOWING;
        mChosenBubbleEnabled = true;
        applyAlertingBehavior(BEHAVIOR_BUBBLE, true /* userTriggered */);
    };

    // used by standard ui
    private OnClickListener mOnDismissSettings = v -> {
@@ -255,7 +231,6 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
    protected void onFinishInflate() {
        super.onFinishInflate();

        mBubbleDescriptionView = findViewById(R.id.bubble_summary);
        mPriorityDescriptionView = findViewById(R.id.alert_summary);
        mSilentDescriptionView = findViewById(R.id.silence_summary);
    }
@@ -320,7 +295,6 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
        mMetricsLogger = Dependency.get(MetricsLogger.class);
        mVisualStabilityManager = visualStabilityManager;
        mChannelEditorDialogController = Dependency.get(ChannelEditorDialogController.class);
        mBubbleController = Dependency.get(BubbleController.class);
        mPackageName = pkg;
        mUniqueChannelsInRow = uniqueChannelsInRow;
        mNumUniqueChannelsInRow = uniqueChannelsInRow.size();
@@ -352,9 +326,6 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
                    && numTotalChannels == 1;
        }

        mIsBubbleable = mEntry.getBubbleMetadata() != null;
        mStartedAsBubble = mEntry.isBubble();

        bindHeader();
        bindChannelDetails();

@@ -402,7 +373,6 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
            findViewById(R.id.non_configurable_text).setVisibility(GONE);
            findViewById(R.id.non_configurable_multichannel_text).setVisibility(GONE);
            findViewById(R.id.interruptiveness_settings).setVisibility(VISIBLE);
            findViewById(R.id.bubble).setVisibility(mIsBubbleable ? VISIBLE : GONE);
        }

        View turnOffButton = findViewById(R.id.turn_off_notifications);
@@ -416,14 +386,10 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G

        View silent = findViewById(R.id.silence);
        View alert = findViewById(R.id.alert);
        View bubble = findViewById(R.id.bubble);
        silent.setOnClickListener(mOnSilent);
        alert.setOnClickListener(mOnAlert);
        bubble.setOnClickListener(mOnBubble);

        int behavior = mStartedAsBubble
                ? BEHAVIOR_BUBBLE
                : mWasShownHighPriority
        int behavior = mWasShownHighPriority
                        ? BEHAVIOR_ALERTING
                        : BEHAVIOR_SILENT;
        applyAlertingBehavior(behavior, false /* userTriggered */);
@@ -587,14 +553,6 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
                }
            }

            if (mChosenBubbleEnabled != null && mStartedAsBubble != mChosenBubbleEnabled) {
                if (mChosenBubbleEnabled) {
                    mBubbleController.onUserCreatedBubbleFromNotification(mEntry);
                } else {
                    mBubbleController.onUserDemotedBubbleFromNotification(mEntry);
                }
            }

            Handler bgHandler = new Handler(Dependency.get(Dependency.BG_LOOPER));
            bgHandler.post(
                    new UpdateImportanceRunnable(mINotificationManager, mPackageName, mAppUid,
@@ -630,7 +588,6 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
            TransitionManager.beginDelayedTransition(this, transition);
        }

        View bubble = findViewById(R.id.bubble);
        View alert = findViewById(R.id.alert);
        View silence = findViewById(R.id.silence);

@@ -638,33 +595,18 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
            case BEHAVIOR_ALERTING:
                mPriorityDescriptionView.setVisibility(VISIBLE);
                mSilentDescriptionView.setVisibility(GONE);
                mBubbleDescriptionView.setVisibility(GONE);
                post(() -> {
                    alert.setSelected(true);
                    silence.setSelected(false);
                    bubble.setSelected(false);
                });
                break;

            case BEHAVIOR_SILENT:
                mSilentDescriptionView.setVisibility(VISIBLE);
                mPriorityDescriptionView.setVisibility(GONE);
                mBubbleDescriptionView.setVisibility(GONE);
                post(() -> {
                    alert.setSelected(false);
                    silence.setSelected(true);
                    bubble.setSelected(false);
                });
                break;

            case BEHAVIOR_BUBBLE:
                mBubbleDescriptionView.setVisibility(VISIBLE);
                mSilentDescriptionView.setVisibility(GONE);
                mPriorityDescriptionView.setVisibility(GONE);
                post(() -> {
                    alert.setSelected(false);
                    silence.setSelected(false);
                    bubble.setSelected(true);
                });
                break;

@@ -673,9 +615,8 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
        }

        boolean isAChange = mWasShownHighPriority != (behavior == BEHAVIOR_ALERTING);
        boolean isABubbleChange = mStartedAsBubble != (behavior == BEHAVIOR_BUBBLE);
        TextView done = findViewById(R.id.done);
        done.setText((isAChange || isABubbleChange)
        done.setText(isAChange
                ? R.string.inline_ok_button
                : R.string.inline_done_button);
    }
@@ -684,7 +625,6 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
        switch (action) {
            case ACTION_UNDO:
                mChosenImportance = mStartingChannelImportance;
                mChosenBubbleEnabled = mStartedAsBubble;
                break;
            case ACTION_DELIVER_SILENTLY:
                mExitReason = NotificationCounters.BLOCKING_HELPER_DELIVER_SILENTLY;
@@ -767,9 +707,6 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
        if (mChosenImportance != null) {
            mStartingChannelImportance = mChosenImportance;
        }
        if (mChosenBubbleEnabled != null) {
            mStartedAsBubble = mChosenBubbleEnabled;
        }
        mExitReason = NotificationCounters.BLOCKING_HELPER_DISMISSED;

        if (mIsForBlockingHelper) {
@@ -969,9 +906,8 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
    }

    @Retention(SOURCE)
    @IntDef({BEHAVIOR_ALERTING, BEHAVIOR_SILENT, BEHAVIOR_BUBBLE})
    @IntDef({BEHAVIOR_ALERTING, BEHAVIOR_SILENT})
    private @interface AlertingBehavior {}
    private static final int BEHAVIOR_ALERTING = 0;
    private static final int BEHAVIOR_SILENT = 1;
    private static final int BEHAVIOR_BUBBLE = 2;
}
+2 −179
Original line number Diff line number Diff line
@@ -16,7 +16,6 @@

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

import static android.app.Notification.FLAG_BUBBLE;
import static android.app.NotificationChannel.USER_LOCKED_IMPORTANCE;
import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
import static android.app.NotificationManager.IMPORTANCE_LOW;
@@ -50,13 +49,10 @@ import android.app.INotificationManager;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationChannelGroup;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.os.IBinder;
import android.os.UserHandle;
import android.provider.Settings;
@@ -76,9 +72,6 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.bubbles.BubbleController;
import com.android.systemui.bubbles.BubblesTestActivity;
import com.android.systemui.statusbar.SbnBuilder;
import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
@@ -116,8 +109,6 @@ public class NotificationInfoTest extends SysuiTestCase {
    private Set<NotificationChannel> mDefaultNotificationChannelSet = new HashSet<>();
    private StatusBarNotification mSbn;
    private NotificationEntry mEntry;
    private StatusBarNotification mBubbleSbn;
    private NotificationEntry mBubbleEntry;

    @Rule
    public MockitoRule mockito = MockitoJUnit.rule();
@@ -131,8 +122,6 @@ public class NotificationInfoTest extends SysuiTestCase {
    private NotificationBlockingHelperManager mBlockingHelperManager;
    @Mock
    private VisualStabilityManager mVisualStabilityManager;
    @Mock
    private BubbleController mBubbleController;

    @Before
    public void setUp() throws Exception {
@@ -143,7 +132,6 @@ public class NotificationInfoTest extends SysuiTestCase {

        mDependency.injectTestDependency(Dependency.BG_LOOPER, mTestableLooper.getLooper());
        mDependency.injectTestDependency(MetricsLogger.class, mMetricsLogger);
        mDependency.injectTestDependency(BubbleController.class, mBubbleController);
        // Inflate the layout
        final LayoutInflater layoutInflater = LayoutInflater.from(mContext);
        mNotificationInfo = (NotificationInfo) layoutInflater.inflate(R.layout.notification_info,
@@ -185,15 +173,6 @@ public class NotificationInfoTest extends SysuiTestCase {
                new Notification(), UserHandle.CURRENT, null, 0);
        mEntry = new NotificationEntryBuilder().setSbn(mSbn).build();

        PendingIntent bubbleIntent = PendingIntent.getActivity(mContext, 0,
                new Intent(mContext, BubblesTestActivity.class), 0);
        mBubbleSbn = new SbnBuilder(mSbn).setBubbleMetadata(
                new Notification.BubbleMetadata.Builder()
                        .setIntent(bubbleIntent)
                        .setIcon(Icon.createWithResource(mContext, R.drawable.android)).build())
                .build();
        mBubbleEntry = new NotificationEntryBuilder().setSbn(mBubbleSbn).build();

        Settings.Secure.putInt(mContext.getContentResolver(),
                NOTIFICATION_NEW_INTERRUPTION_MODEL, 1);
    }
@@ -765,7 +744,7 @@ public class NotificationInfoTest extends SysuiTestCase {
                TEST_PACKAGE_NAME,
                mNotificationChannel,
                mNotificationChannelSet,
                mBubbleEntry,
                mEntry,
                null,
                null,
                null,
@@ -785,7 +764,7 @@ public class NotificationInfoTest extends SysuiTestCase {
                TEST_PACKAGE_NAME,
                mNotificationChannel,
                mNotificationChannelSet,
                mBubbleEntry,
                mEntry,
                null,
                null,
                null,
@@ -796,162 +775,6 @@ public class NotificationInfoTest extends SysuiTestCase {
        assertTrue(mNotificationInfo.findViewById(R.id.silence).isSelected());
    }

    @Test
    public void testBindNotification_bubbleIsSelected() throws Exception {
        mBubbleEntry.getSbn().getNotification().flags |= FLAG_BUBBLE;
        mNotificationInfo.bindNotification(
                mMockPackageManager,
                mMockINotificationManager,
                mVisualStabilityManager,
                TEST_PACKAGE_NAME,
                mNotificationChannel,
                mNotificationChannelSet,
                mBubbleEntry,
                null,
                null,
                null,
                true,
                false,
                IMPORTANCE_DEFAULT,
                true);

        View bubbleView = mNotificationInfo.findViewById(R.id.bubble);
        assertEquals(View.VISIBLE, bubbleView.getVisibility());
        assertTrue(bubbleView.isSelected());
    }

    @Test
    public void testBindNotification_whenCanBubble() throws Exception {
        mNotificationInfo.bindNotification(
                mMockPackageManager,
                mMockINotificationManager,
                mVisualStabilityManager,
                TEST_PACKAGE_NAME,
                mNotificationChannel,
                mNotificationChannelSet,
                mBubbleEntry,
                null,
                null,
                null,
                true,
                false,
                IMPORTANCE_DEFAULT,
                true);

        View bubbleView = mNotificationInfo.findViewById(R.id.bubble);
        assertEquals(View.VISIBLE, bubbleView.getVisibility());
        assertFalse(bubbleView.isSelected());
    }

    @Test
    public void testBindNotification_whenCantBubble() throws Exception {
        mNotificationInfo.bindNotification(
                mMockPackageManager,
                mMockINotificationManager,
                mVisualStabilityManager,
                TEST_PACKAGE_NAME,
                mNotificationChannel,
                mNotificationChannelSet,
                mEntry,
                null,
                null,
                null,
                true,
                false,
                IMPORTANCE_DEFAULT,
                true);
        View bubbleView = mNotificationInfo.findViewById(R.id.bubble);
        assertEquals(View.GONE, bubbleView.getVisibility());
    }

    @Test
    public void testBubble_promotesBubble() throws Exception {
        mNotificationInfo.bindNotification(
                mMockPackageManager,
                mMockINotificationManager,
                mVisualStabilityManager,
                TEST_PACKAGE_NAME,
                mNotificationChannel,
                mNotificationChannelSet,
                mBubbleEntry,
                null,
                null,
                null,
                true,
                false,
                IMPORTANCE_DEFAULT,
                true);

        assertFalse(mBubbleEntry.isBubble());

        // Promote it
        mNotificationInfo.findViewById(R.id.bubble).performClick();
        mNotificationInfo.findViewById(R.id.done).performClick();
        mNotificationInfo.handleCloseControls(true, false);

        verify(mBubbleController, times(1)).onUserCreatedBubbleFromNotification(mBubbleEntry);
    }

    @Test
    public void testAlert_demotesBubble() throws Exception {
        mBubbleEntry.getSbn().getNotification().flags |= FLAG_BUBBLE;

        mNotificationInfo.bindNotification(
                mMockPackageManager,
                mMockINotificationManager,
                mVisualStabilityManager,
                TEST_PACKAGE_NAME,
                mNotificationChannel,
                mNotificationChannelSet,
                mBubbleEntry,
                null,
                null,
                null,
                true,
                false,
                IMPORTANCE_DEFAULT,
                true);

        assertTrue(mBubbleEntry.isBubble());

        // Demote it
        mNotificationInfo.findViewById(R.id.alert).performClick();
        mNotificationInfo.findViewById(R.id.done).performClick();
        mNotificationInfo.handleCloseControls(true, false);

        verify(mBubbleController, times(1)).onUserDemotedBubbleFromNotification(mBubbleEntry);
    }

    @Test
    public void testSilence_demotesBubble() throws Exception {
        mBubbleEntry.getSbn().getNotification().flags |= FLAG_BUBBLE;

        mNotificationInfo.bindNotification(
                mMockPackageManager,
                mMockINotificationManager,
                mVisualStabilityManager,
                TEST_PACKAGE_NAME,
                mNotificationChannel,
                mNotificationChannelSet,
                mBubbleEntry,
                null,
                null,
                null,
                true,
                false,
                IMPORTANCE_DEFAULT,
                true);

        assertTrue(mBubbleEntry.isBubble());

        // Demote it
        mNotificationInfo.findViewById(R.id.silence).performClick();
        mNotificationInfo.findViewById(R.id.done).performClick();
        mNotificationInfo.handleCloseControls(true, false);

        verify(mBubbleController, times(1)).onUserDemotedBubbleFromNotification(mBubbleEntry);
    }

    @Test
    public void testBindNotification_DoesNotUpdateNotificationChannel() throws Exception {
        mNotificationInfo.bindNotification(