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

Commit e41c394e authored by Mady Mellor's avatar Mady Mellor Committed by Android (Google) Code Review
Browse files

Merge "Auto expand bubbles when foreground with the flag set"

parents f677185a e80930ea
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import static com.android.systemui.statusbar.notification.NotificationAlertingMa
import static java.lang.annotation.RetentionPolicy.SOURCE;

import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningTaskInfo;
import android.app.ActivityTaskManager;
import android.app.IActivityTaskManager;
@@ -64,6 +65,7 @@ import com.android.systemui.statusbar.phone.StatusBarWindowController;
import com.android.systemui.statusbar.policy.ConfigurationController;

import java.lang.annotation.Retention;
import java.util.List;

import javax.inject.Inject;
import javax.inject.Singleton;
@@ -340,6 +342,9 @@ public class BubbleController implements BubbleExpandedView.OnBubbleBlockedListe
            // It's new
            mStackView.addBubble(notif);
        }
        if (shouldAutoExpand(notif)) {
            mStackView.setExpandedBubble(notif);
        }
        updateVisibility();
    }

@@ -522,6 +527,23 @@ public class BubbleController implements BubbleExpandedView.OnBubbleBlockedListe
                || autoBubbleAll;
    }

    private boolean shouldAutoExpand(NotificationEntry entry) {
        Notification.BubbleMetadata metadata = entry.getBubbleMetadata();
        return metadata != null && metadata.getAutoExpandBubble()
                && isForegroundApp(entry.notification.getPackageName());
    }

    /**
     * Return true if the applications with the package name is running in foreground.
     *
     * @param pkgName application package name.
     */
    private boolean isForegroundApp(String pkgName) {
        ActivityManager am = mContext.getSystemService(ActivityManager.class);
        List<RunningTaskInfo> tasks = am.getRunningTasks(1 /* maxNum */);
        return !tasks.isEmpty() && pkgName.equals(tasks.get(0).topActivity.getPackageName());
    }

    /**
     * This task stack listener is responsible for responding to tasks moved to the front
     * which are on the default (main) display. When this happens, expanded bubbles must be
+83 −1
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.systemui.bubbles;

import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
@@ -26,8 +28,13 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.app.IActivityManager;
import android.app.Notification;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.drawable.Icon;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.WindowManager;
@@ -36,6 +43,7 @@ import android.widget.FrameLayout;
import androidx.test.filters.SmallTest;

import com.android.internal.statusbar.NotificationVisibility;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.statusbar.NotificationTestHelper;
import com.android.systemui.statusbar.notification.NotificationEntryListener;
@@ -55,6 +63,9 @@ import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

@SmallTest
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
@@ -83,6 +94,7 @@ public class BubbleControllerTest extends SysuiTestCase {
    private ExpandableNotificationRow mRow;
    private ExpandableNotificationRow mRow2;
    private ExpandableNotificationRow mNoChannelRow;
    private ExpandableNotificationRow mAutoExpandRow;

    @Mock
    private NotificationData mNotificationData;
@@ -104,7 +116,6 @@ public class BubbleControllerTest extends SysuiTestCase {
        mStatusBarView = new FrameLayout(mContext);
        mDependency.injectTestDependency(NotificationEntryManager.class, mNotificationEntryManager);


        // Bubbles get added to status bar window view
        mStatusBarWindowController = new StatusBarWindowController(mContext, mWindowManager,
                mActivityManager, mDozeParameters);
@@ -115,6 +126,9 @@ public class BubbleControllerTest extends SysuiTestCase {
        mRow = mNotificationTestHelper.createBubble(mDeleteIntent);
        mRow2 = mNotificationTestHelper.createBubble(mDeleteIntent);
        mNoChannelRow = mNotificationTestHelper.createBubble(mDeleteIntent);
        Notification.BubbleMetadata metadata = getBuilder().setAutoExpandBubble(true).build();
        mAutoExpandRow = mNotificationTestHelper.createBubble(metadata,
                "com.android.systemui.tests");

        // Return non-null notification data from the NEM
        when(mNotificationEntryManager.getNotificationData()).thenReturn(mNotificationData);
@@ -302,6 +316,63 @@ public class BubbleControllerTest extends SysuiTestCase {
        assertFalse(mBubbleController.hasBubbles());
    }

    @Test
    public void testAutoExpandFailsNotForeground() {
        assertFalse(mBubbleController.isStackExpanded());

        // Add the auto expand bubble
        mEntryListener.onPendingEntryAdded(mAutoExpandRow.getEntry());
        mBubbleController.updateBubble(mAutoExpandRow.getEntry(), true /* updatePosition */);

        // Expansion shouldn't change
        verify(mBubbleExpandListener, never()).onBubbleExpandChanged(false /* expanded */,
                mAutoExpandRow.getEntry().key);
        assertFalse(mBubbleController.isStackExpanded());

        // # of bubbles should change
        verify(mBubbleStateChangeListener).onHasBubblesChanged(true /* hasBubbles */);
    }

    @Test
    public void testAutoExpandSucceedsForeground() {
        final CountDownLatch latch = new CountDownLatch(1);
        BroadcastReceiver receiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                latch.countDown();
            }
        };
        IntentFilter filter = new IntentFilter(BubblesTestActivity.BUBBLE_ACTIVITY_OPENED);
        mContext.registerReceiver(receiver, filter);

        assertFalse(mBubbleController.isStackExpanded());

        // Make ourselves foreground
        Intent i = new Intent(mContext, BubblesTestActivity.class);
        i.setFlags(FLAG_ACTIVITY_NEW_TASK);
        mContext.startActivity(i);

        try {
            latch.await(100, TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // Add the auto expand bubble
        mEntryListener.onPendingEntryAdded(mAutoExpandRow.getEntry());
        mBubbleController.updateBubble(mAutoExpandRow.getEntry(), true /* updatePosition */);

        // Expansion should change
        verify(mBubbleExpandListener).onBubbleExpandChanged(true /* expanded */,
                mAutoExpandRow.getEntry().key);
        assertTrue(mBubbleController.isStackExpanded());

        // # of bubbles should change
        verify(mBubbleStateChangeListener).onHasBubblesChanged(true /* hasBubbles */);
        mContext.unregisterReceiver(receiver);
    }


    @Test
    public void testMarkNewNotificationAsBubble() {
        mEntryListener.onPendingEntryAdded(mRow.getEntry());
@@ -349,4 +420,15 @@ public class BubbleControllerTest extends SysuiTestCase {
            return entry.notification.getNotification().getBubbleMetadata() != null;
        }
    }

    /**
     * @return basic {@link android.app.Notification.BubbleMetadata.Builder}
     */
    private Notification.BubbleMetadata.Builder getBuilder() {
        Intent target = new Intent(mContext, BubblesTestActivity.class);
        PendingIntent bubbleIntent = PendingIntent.getActivity(mContext, 0, target, 0);
        return new Notification.BubbleMetadata.Builder()
                .setIntent(bubbleIntent)
                .setIcon(Icon.createWithResource(mContext, R.drawable.android));
    }
}
+7 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.systemui.bubbles;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;

import com.android.systemui.R;
@@ -26,9 +27,15 @@ import com.android.systemui.R;
 */
public class BubblesTestActivity extends Activity {

    public static final String BUBBLE_ACTIVITY_OPENED =
            "com.android.systemui.bubbles.BUBBLE_ACTIVITY_OPENED";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        Intent i = new Intent(BUBBLE_ACTIVITY_OPENED);
        sendBroadcast(i);
    }
}
+27 −13
Original line number Diff line number Diff line
@@ -151,23 +151,40 @@ public class NotificationTestHelper {

    /**
     * Returns an {@link ExpandableNotificationRow} that should be shown as a bubble.
     *
     * @param deleteIntent the intent to assign to {@link BubbleMetadata#deleteIntent}
     */
    public ExpandableNotificationRow createBubble() throws Exception {
        return createBubble(null);
    public ExpandableNotificationRow createBubble(@Nullable PendingIntent deleteIntent)
            throws Exception {
        Notification n = createNotification(false /* isGroupSummary */,
                null /* groupKey */, makeBubbleMetadata(deleteIntent));
        return generateRow(n, PKG, UID, USER_HANDLE, 0 /* extraInflationFlags */, IMPORTANCE_HIGH);
    }

    /**
     * Returns an {@link ExpandableNotificationRow} that should be shown as a bubble.
     *
     * @param deleteIntent the intent to assign to {@link BubbleMetadata#deleteIntent}
     * @param bubbleMetadata the {@link BubbleMetadata} to use
     */
    public ExpandableNotificationRow createBubble(@Nullable PendingIntent deleteIntent)
    public ExpandableNotificationRow createBubble(BubbleMetadata bubbleMetadata)
            throws Exception {
        Notification n = createNotification(false /* isGroupSummary */,
                null /* groupKey */, true /* isBubble */, deleteIntent);
                null /* groupKey */, bubbleMetadata);
        return generateRow(n, PKG, UID, USER_HANDLE, 0 /* extraInflationFlags */, IMPORTANCE_HIGH);
    }

    /**
     * Returns an {@link ExpandableNotificationRow} that should be shown as a bubble.
     *
     * @param bubbleMetadata the {@link BubbleMetadata} to use
     */
    public ExpandableNotificationRow createBubble(BubbleMetadata bubbleMetadata, String pkg)
            throws Exception {
        Notification n = createNotification(false /* isGroupSummary */,
                null /* groupKey */, bubbleMetadata);
        return generateRow(n, pkg, UID, USER_HANDLE, 0 /* extraInflationFlags */, IMPORTANCE_HIGH);
    }

    /**
     * Creates a notification row with the given details.
     *
@@ -207,8 +224,7 @@ public class NotificationTestHelper {
     * @return a notification that is in the group specified or standalone if unspecified
     */
    private Notification createNotification(boolean isGroupSummary, @Nullable String groupKey) {
        return createNotification(isGroupSummary, groupKey, false /* isBubble */,
                null /* bubbleDeleteIntent */);
        return createNotification(isGroupSummary, groupKey, null /* bubble metadata */);
    }

    /**
@@ -216,12 +232,11 @@ public class NotificationTestHelper {
     *
     * @param isGroupSummary whether the notification is a group summary
     * @param groupKey the group key for the notification group used across notifications
     * @param isBubble whether this notification should bubble
     * @param bubbleMetadata the bubble metadata to use for this notification if it exists.
     * @return a notification that is in the group specified or standalone if unspecified
     */
    private Notification createNotification(boolean isGroupSummary,
            @Nullable String groupKey, boolean isBubble,
            @Nullable PendingIntent bubbleDeleteIntent) {
            @Nullable String groupKey, @Nullable BubbleMetadata bubbleMetadata) {
        Notification publicVersion = new Notification.Builder(mContext).setSmallIcon(
                R.drawable.ic_person)
                .setCustomContentView(new RemoteViews(mContext.getPackageName(),
@@ -239,9 +254,8 @@ public class NotificationTestHelper {
        if (!TextUtils.isEmpty(groupKey)) {
            notificationBuilder.setGroup(groupKey);
        }
        if (isBubble) {
            BubbleMetadata metadata = makeBubbleMetadata(bubbleDeleteIntent);
            notificationBuilder.setBubbleMetadata(metadata);
        if (bubbleMetadata != null) {
            notificationBuilder.setBubbleMetadata(bubbleMetadata);
        }
        return notificationBuilder.build();
    }