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

Commit 245c320d authored by Valentin Iftime's avatar Valentin Iftime
Browse files

Set bundled group summary as clickable

 Allow click events for group summary notifications inside bundles.

Flag: com.android.systemui.notification_bundle_ui

Test: atest ExpandableNotificationRowTest
Bug: 426938002
Change-Id: If057a32eb634e51bbfb810544ad5cd33bcffaf30
parent d3032a4e
Loading
Loading
Loading
Loading
+12 −2
Original line number Diff line number Diff line
@@ -1272,7 +1272,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getActionMasked() != MotionEvent.ACTION_DOWN
                || !isChildInGroup() || isGroupExpanded()) {
                || !isChildInGroup() || isGroupExpanded() || isBundledSummaryClickable()) {
            return super.onTouchEvent(event);
        } else {
            return false;
@@ -1559,9 +1559,19 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
        };
    }

    @VisibleForTesting
    protected boolean isBundledSummaryClickable() {
        if (NotificationBundleUi.isEnabled()) {
            return mIsSummaryWithChildren && !isGroupExpanded() && isChildInGroup();
        } else {
            return false;
        }
    }

    private void updateClickAndFocus() {
        boolean normalChild = !isChildInGroup() || isGroupExpanded();
        boolean clickable = mOnClickListener != null && normalChild;
        boolean clickable = mOnClickListener != null
                && (normalChild || isBundledSummaryClickable());
        if (isFocusable() != normalChild) {
            setFocusable(normalChild);
        }
+12 −5
Original line number Diff line number Diff line
@@ -31,7 +31,6 @@ import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.asynclayoutinflater.view.AsyncLayoutFactory;

import com.android.systemui.Flags;
import com.android.systemui.res.R;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.statusbar.InflationTask;
@@ -128,7 +127,7 @@ public class RowInflaterTask implements InflationTask, AsyncRowInflater.OnInflat
     */
    @VisibleForTesting
    public ExpandableNotificationRow inflateSynchronously(@NonNull Context context,
            @Nullable ViewGroup parent, @NonNull NotificationEntry entry) {
            @Nullable ViewGroup parent, @NonNull PipelineEntry entry) {
        final LayoutInflater inflater = new BasicRowInflater(context);
        inflater.setFactory2(makeRowFactory(entry));
        final ExpandableNotificationRow inflate = (ExpandableNotificationRow) inflater.inflate(
@@ -138,9 +137,17 @@ public class RowInflaterTask implements InflationTask, AsyncRowInflater.OnInflat
        return inflate;
    }

    private RowAsyncLayoutFactory makeRowFactory(NotificationEntry entry) {
    private RowAsyncLayoutFactory makeRowFactory(PipelineEntry entry) {
        if (entry instanceof NotificationEntry) {
            return new RowAsyncLayoutFactory(
                entry, mSystemClock, mLogger, mUserTracker.getUserHandle());
                (NotificationEntry) entry, mSystemClock, mLogger, mUserTracker.getUserHandle());
        } else if (entry instanceof BundleEntry) {
            return new RowAsyncLayoutFactory(
                (BundleEntry) entry, mSystemClock, mLogger, mUserTracker.getUserHandle());
        } else {
            throw new IllegalArgumentException(
                    "Entry must be either NotificationEntry or BundleEntry");
        }
    }

    @VisibleForTesting
+71 −10
Original line number Diff line number Diff line
@@ -37,7 +37,6 @@ import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;

import android.app.Notification;
@@ -53,7 +52,9 @@ import android.platform.test.annotations.EnableFlags;
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;

import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -72,8 +73,11 @@ import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.notification.AboveShelfChangedListener;
import com.android.systemui.statusbar.notification.FeedbackIcon;
import com.android.systemui.statusbar.notification.SourceType;
import com.android.systemui.statusbar.notification.collection.BundleEntryAdapter;
import com.android.systemui.statusbar.notification.collection.BundleSpec;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
import com.android.systemui.statusbar.notification.collection.PipelineEntry;
import com.android.systemui.statusbar.notification.headsup.PinnedStatus;
import com.android.systemui.statusbar.notification.icon.IconPack;
import com.android.systemui.statusbar.notification.promoted.PromotedNotificationUi;
@@ -292,15 +296,11 @@ public class ExpandableNotificationRowTest extends SysuiTestCase {
    @EnableFlags(NotificationBundleUi.FLAG_NAME)
    public void testGroupWithinGroupIntrinsicHeightCalculationWhenGroupExpanded() throws Exception {
        // GIVEN a group within a group
        Notification bundleNotif = new Notification.Builder(mContext, "channel")
                .setSmallIcon(R.drawable.ic_menu)
                .setGroupSummary(true)
                .setGroup("group1")
                .build();
        NotificationEntry bundleEntry = new NotificationEntryBuilder()
                .setNotification(bundleNotif)
                .build();
        ExpandableNotificationRow bundle = mKosmos.createRow(bundleEntry);
        final ExpandableNotificationRow bundle = mKosmos.createRowBundle(
                BundleSpec.Companion.getNEWS());
        final PipelineEntry bundleEntry =
                ((BundleEntryAdapter) bundle.getEntryAdapter()).getEntry();

        Notification groupNotif = new Notification.Builder(mContext, "channel")
                .setSmallIcon(R.drawable.ic_menu)
                .setGroupSummary(true)
@@ -326,6 +326,67 @@ public class ExpandableNotificationRowTest extends SysuiTestCase {
                .isEqualTo(group.getChildrenContainer().getIntrinsicHeight());
    }

    @Test
    @EnableFlags(NotificationBundleUi.FLAG_NAME)
    public void testGroupsInsideBundles_clickableWhenExpanded() throws Exception {
        // GIVEN a group within a group
        final ExpandableNotificationRow bundle = mKosmos.createRowBundle(
                BundleSpec.Companion.getNEWS());
        final PipelineEntry bundleEntry =
                ((BundleEntryAdapter) bundle.getEntryAdapter()).getEntry();

        Notification groupNotif = new Notification.Builder(mContext, "channel")
                .setSmallIcon(R.drawable.ic_menu)
                .setGroupSummary(true)
                .setGroup("groupInBundle")
                .build();
        NotificationEntry groupEntry = new NotificationEntryBuilder()
                .setNotification(groupNotif)
                .setParent(bundleEntry)
                .build();
        ExpandableNotificationRow group = mKosmos.createRow(groupEntry);
        ExpandableNotificationRow child = mKosmos.createRow();

        bundle.addChildNotification(group, 0);
        group.addChildNotification(child, 0);

        OnClickListener l = mock(OnClickListener.class);
        group.setOnClickListener(l);

        // Check that the group summary is clickable before it is expanded
        assertThat(group.isGroupExpanded()).isEqualTo(false);
        assertThat(group.isClickable()).isTrue();
        assertThat(group.isBundledSummaryClickable()).isTrue();
        assertThat(group.isSummaryWithChildren()).isTrue();
        assertThat(child.isClickable()).isFalse();

        // Check that the touch events are handled
        MotionEvent touchDown = MotionEvent.obtain(
                /* downTime= */ 1234,
                /* eventTime= */ 1234,
                MotionEvent.ACTION_DOWN,
                101,
                201,
                0);
        assertThat(group.onTouchEvent(touchDown)).isTrue();
        MotionEvent touchUp = MotionEvent.obtain(
                /* downTime= */ 1235,
                /* eventTime= */ 1235,
                MotionEvent.ACTION_UP,
                101,
                201,
                0);
        assertThat(group.onTouchEvent(touchUp)).isTrue();

        // WHEN group is expanded
        group.expandNotification();
        mKosmos.getGroupExpansionManager().setGroupExpanded(group.getEntryAdapter(), true);

        // THEN group is expanded and is not clickable
        assertThat(group.isGroupExpanded()).isEqualTo(true);
        assertThat(group.isBundledSummaryClickable()).isFalse();
    }

    @Test
    public void testSetSensitiveOnPublicRowDoesNotNotifyOfHeightChange() throws Exception {
        // create a notification row whose public version is identical
+7 −1
Original line number Diff line number Diff line
@@ -85,6 +85,7 @@ import com.android.systemui.statusbar.chips.ui.viewmodel.ongoingActivityChipsVie
import com.android.systemui.statusbar.data.repository.fakeStatusBarModePerDisplayRepository
import com.android.systemui.statusbar.disableflags.data.repository.fakeDisableFlagsRepository
import com.android.systemui.statusbar.disableflags.domain.interactor.disableFlagsInteractor
import com.android.systemui.statusbar.notification.collection.BundleSpec
import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
import com.android.systemui.statusbar.notification.collection.buildNotificationEntry
@@ -100,6 +101,7 @@ import com.android.systemui.statusbar.notification.people.PeopleNotificationIden
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
import com.android.systemui.statusbar.notification.row.createPromotedOngoingRow
import com.android.systemui.statusbar.notification.row.createRow
import com.android.systemui.statusbar.notification.row.createRowBundle
import com.android.systemui.statusbar.notification.row.createRowGroup
import com.android.systemui.statusbar.notification.row.createRowWithEntry
import com.android.systemui.statusbar.notification.row.createRowWithNotif
@@ -269,6 +271,10 @@ class KosmosJavaAdapter() {
        return kosmos.createRowGroup()
    }

    fun createRowBundle(spec: BundleSpec): ExpandableNotificationRow {
        return kosmos.createRowBundle(spec)
    }

    fun createPromotedOngoingRow(): ExpandableNotificationRow {
        return kosmos.createPromotedOngoingRow()
    }
+28 −12
Original line number Diff line number Diff line
@@ -61,9 +61,12 @@ import com.android.systemui.statusbar.notification.BundleInteractionLogger
import com.android.systemui.statusbar.notification.ColorUpdateLogger
import com.android.systemui.statusbar.notification.ConversationNotificationManager
import com.android.systemui.statusbar.notification.ConversationNotificationProcessor
import com.android.systemui.statusbar.notification.collection.BundleEntry
import com.android.systemui.statusbar.notification.collection.BundleSpec
import com.android.systemui.statusbar.notification.collection.GroupEntryBuilder
import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
import com.android.systemui.statusbar.notification.collection.PipelineEntry
import com.android.systemui.statusbar.notification.collection.buildNotificationEntry
import com.android.systemui.statusbar.notification.collection.buildSummaryNotificationEntry
import com.android.systemui.statusbar.notification.collection.mockNotifCollection
@@ -425,13 +428,11 @@ class ExpandableNotificationRowBuilder(
        return generateRow(entry, INFLATION_FLAGS)
    }

    private fun generateRow(
        entry: NotificationEntry,
        @InflationFlag extraInflationFlags: Int,
    ): ExpandableNotificationRow {
        // NOTE: This flag is read when the ExpandableNotificationRow is inflated, so it needs to be
        //  set, but we do not want to override an existing value that is needed by a specific test.
    fun createRowBundle(spec: BundleSpec): ExpandableNotificationRow {
        return generateRow(BundleEntry(spec))
    }

    private fun initRow(entry: PipelineEntry): ExpandableNotificationRow {
        val userTracker = Mockito.mock(UserTracker::class.java, STUB_ONLY)
        whenever(userTracker.userHandle).thenReturn(context.user)

@@ -443,13 +444,7 @@ class ExpandableNotificationRowBuilder(
                Mockito.mock(AsyncRowInflater::class.java, STUB_ONLY),
            )
        val row = rowInflaterTask.inflateSynchronously(context, null, entry)

        val entryAdapter = kosmos.entryAdapterFactory.create(entry)

        entry.row = row
        mIconManager.createIcons(entry)
        mBindPipelineEntryListener.onEntryInit(entry)
        mBindPipeline.manageRow(entry, row)
        row.initialize(
            entryAdapter, // if (NotificationBundleUi.isEnabled) entryAdapter else null,
            entry, // if (NotificationBundleUi.isEnabled) null else entry,
@@ -481,11 +476,32 @@ class ExpandableNotificationRowBuilder(
            Mockito.mock(BundleInteractionLogger::class.java, STUB_ONLY),
        )
        row.setAboveShelfChangedListener {}
        return row
    }

    private fun generateRow(
        entry: NotificationEntry,
        @InflationFlag extraInflationFlags: Int,
    ): ExpandableNotificationRow {
        // NOTE: This flag is read when the ExpandableNotificationRow is inflated, so it needs to be
        //  set, but we do not want to override an existing value that is needed by a specific test.

        val row = initRow(entry)
        entry.row = row
        mIconManager.createIcons(entry)
        mBindPipelineEntryListener.onEntryInit(entry)
        mBindPipeline.manageRow(entry, row)
        mBindStage.getStageParams(entry).requireContentViews(extraInflationFlags)
        inflateAndWait(entry)
        return row
    }

    private fun generateRow(entry: BundleEntry): ExpandableNotificationRow {
        val row = initRow(entry)
        entry.row = row
        return row
    }

    private fun inflateAndWait(entry: NotificationEntry) {
        val countDownLatch = CountDownLatch(1)
        mBindStage.requestRebind(entry) { en: NotificationEntry? -> countDownLatch.countDown() }
Loading