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

Commit 44a4b240 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "[RONs] convert ColorizedFgsCoordinatorTest to kotlin" into main

parents c45cc91b da80c520
Loading
Loading
Loading
Loading
+191 −0
Original line number Diff line number Diff line
@@ -13,197 +13,179 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.statusbar.notification.collection.coordinator;

import static android.app.Notification.FLAG_FOREGROUND_SERVICE;
import static android.app.Notification.FLAG_PROMOTED_ONGOING;
import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
import static android.app.NotificationManager.IMPORTANCE_HIGH;
import static android.app.NotificationManager.IMPORTANCE_MIN;

import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;

import android.app.Notification;
import android.app.PendingIntent;
import android.app.Person;
import android.content.Intent;
import android.graphics.Color;
import android.os.UserHandle;
import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
import android.testing.TestableLooper;

import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;

import com.android.systemui.SysuiTestCase;
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifPromoter;
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner;
import com.android.systemui.statusbar.notification.promoted.PromotedNotificationUi;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
package com.android.systemui.statusbar.notification.collection.coordinator

import android.app.Notification
import android.app.NotificationManager
import android.app.PendingIntent
import android.app.Person
import android.content.Intent
import android.graphics.Color
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
import android.testing.TestableLooper.RunWithLooper
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.kosmos.useUnconfinedTestDispatcher
import com.android.systemui.statusbar.notification.collection.buildEntry
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifPromoter
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner
import com.android.systemui.statusbar.notification.collection.notifPipeline
import com.android.systemui.statusbar.notification.promoted.PromotedNotificationUi
import com.android.systemui.testKosmos
import com.android.systemui.util.mockito.withArgCaptor
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.kotlin.any
import org.mockito.kotlin.never
import org.mockito.kotlin.verify

@SmallTest
@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper
public class ColorizedFgsCoordinatorTest extends SysuiTestCase {

    private static final int NOTIF_USER_ID = 0;
    @Mock private NotifPipeline mNotifPipeline;
@RunWith(AndroidJUnit4::class)
@RunWithLooper
class ColorizedFgsCoordinatorTest : SysuiTestCase() {
    private val kosmos = testKosmos().useUnconfinedTestDispatcher()
    private val notifPipeline
        get() = kosmos.notifPipeline

    private NotificationEntryBuilder mEntryBuilder;
    private ColorizedFgsCoordinator mColorizedFgsCoordinator;
    private NotifSectioner mFgsSection;
    private lateinit var colorizedFgsCoordinator: ColorizedFgsCoordinator
    private lateinit var sectioner: NotifSectioner

    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);
        allowTestableLooperAsMainThread();

        mColorizedFgsCoordinator = new ColorizedFgsCoordinator();
    fun setup() {
        allowTestableLooperAsMainThread()

        mEntryBuilder = new NotificationEntryBuilder()
                .setUser(new UserHandle(NOTIF_USER_ID));

        mColorizedFgsCoordinator.attach(mNotifPipeline);

        mFgsSection = mColorizedFgsCoordinator.getSectioner();
        colorizedFgsCoordinator = ColorizedFgsCoordinator()
        colorizedFgsCoordinator.attach(notifPipeline)
        sectioner = colorizedFgsCoordinator.sectioner
    }

    @Test
    public void testIncludeFGSInSection_importanceDefault() {
    fun testIncludeFGSInSection_importanceDefault() {
        // GIVEN the notification represents a colorized foreground service with > min importance
        mEntryBuilder
                .setFlag(mContext, FLAG_FOREGROUND_SERVICE, true)
                .setImportance(IMPORTANCE_DEFAULT)
                .modifyNotification(mContext)
                .setColorized(true).setColor(Color.WHITE);
        val entry = buildEntry {
            setFlag(mContext, Notification.FLAG_FOREGROUND_SERVICE, true)
            setImportance(NotificationManager.IMPORTANCE_DEFAULT)
            modifyNotification(mContext).setColorized(true).setColor(Color.WHITE)
        }

        // THEN the entry is in the fgs section
        assertTrue(mFgsSection.isInSection(mEntryBuilder.build()));
        assertTrue(sectioner.isInSection(entry))
    }

    @Test
    public void testDiscludeFGSInSection_importanceMin() {
    fun testDiscludeFGSInSection_importanceMin() {
        // GIVEN the notification represents a colorized foreground service with min importance
        mEntryBuilder
                .setFlag(mContext, FLAG_FOREGROUND_SERVICE, true)
                .setImportance(IMPORTANCE_MIN)
                .modifyNotification(mContext)
                .setColorized(true).setColor(Color.WHITE);
        val entry = buildEntry {
            setFlag(mContext, Notification.FLAG_FOREGROUND_SERVICE, true)
            setImportance(NotificationManager.IMPORTANCE_MIN)
            modifyNotification(mContext).setColorized(true).setColor(Color.WHITE)
        }

        // THEN the entry is NOT in the fgs section
        assertFalse(mFgsSection.isInSection(mEntryBuilder.build()));
        assertFalse(sectioner.isInSection(entry))
    }

    @Test
    public void testDiscludeNonFGSInSection() {
    fun testDiscludeNonFGSInSection() {
        // GIVEN the notification represents a colorized notification with high importance that
        // is NOT a foreground service
        mEntryBuilder
                .setImportance(IMPORTANCE_HIGH)
                .setFlag(mContext, FLAG_FOREGROUND_SERVICE, false)
                .modifyNotification(mContext).setColorized(false);
        val entry = buildEntry {
            setImportance(NotificationManager.IMPORTANCE_HIGH)
            setFlag(mContext, Notification.FLAG_FOREGROUND_SERVICE, false)
            modifyNotification(mContext).setColorized(false)
        }

        // THEN the entry is NOT in the fgs section
        assertFalse(mFgsSection.isInSection(mEntryBuilder.build()));
        assertFalse(sectioner.isInSection(entry))
    }

    @Test
    public void testIncludeCallInSection_importanceDefault() {
    fun testIncludeCallInSection_importanceDefault() {
        // GIVEN the notification represents a call with > min importance
        mEntryBuilder
                .setImportance(IMPORTANCE_DEFAULT)
                .modifyNotification(mContext)
                .setStyle(makeCallStyle());
        val entry = buildEntry {
            setImportance(NotificationManager.IMPORTANCE_DEFAULT)
            modifyNotification(mContext).setStyle(makeCallStyle())
        }

        // THEN the entry is in the fgs section
        assertTrue(mFgsSection.isInSection(mEntryBuilder.build()));
        assertTrue(sectioner.isInSection(entry))
    }

    @Test
    public void testDiscludeCallInSection_importanceMin() {
    fun testDiscludeCallInSection_importanceMin() {
        // GIVEN the notification represents a call with min importance
        mEntryBuilder
                .setImportance(IMPORTANCE_MIN)
                .modifyNotification(mContext)
                .setStyle(makeCallStyle());
        val entry = buildEntry {
            setImportance(NotificationManager.IMPORTANCE_MIN)
            modifyNotification(mContext).setStyle(makeCallStyle())
        }

        // THEN the entry is NOT in the fgs section
        assertFalse(mFgsSection.isInSection(mEntryBuilder.build()));
        assertFalse(sectioner.isInSection(entry))
    }

    @Test
    @EnableFlags(PromotedNotificationUi.FLAG_NAME)
    public void testIncludePromotedOngoingInSection_flagEnabled() {
    fun testIncludePromotedOngoingInSection_flagEnabled() {
        // GIVEN the notification has FLAG_PROMOTED_ONGOING
        mEntryBuilder.setFlag(mContext, FLAG_PROMOTED_ONGOING, true);
        val entry = buildEntry { setFlag(mContext, Notification.FLAG_PROMOTED_ONGOING, true) }

        // THEN the entry is in the fgs section
        assertTrue(mFgsSection.isInSection(mEntryBuilder.build()));
        assertTrue(sectioner.isInSection(entry))
    }

    @Test
    @DisableFlags(PromotedNotificationUi.FLAG_NAME)
    public void testDiscludePromotedOngoingInSection_flagDisabled() {
    fun testDiscludePromotedOngoingInSection_flagDisabled() {
        // GIVEN the notification has FLAG_PROMOTED_ONGOING
        mEntryBuilder.setFlag(mContext, FLAG_PROMOTED_ONGOING, true);
        val entry = buildEntry { setFlag(mContext, Notification.FLAG_PROMOTED_ONGOING, true) }

        // THEN the entry is NOT in the fgs section
        assertFalse(mFgsSection.isInSection(mEntryBuilder.build()));
        assertFalse(sectioner.isInSection(entry))
    }

    @Test
    @EnableFlags(PromotedNotificationUi.FLAG_NAME)
    public void promoterSelectsPromotedOngoing_flagEnabled() {
        ArgumentCaptor<NotifPromoter> captor = ArgumentCaptor.forClass(NotifPromoter.class);
        verify(mNotifPipeline).addPromoter(captor.capture());
        NotifPromoter promoter = captor.getValue();
    fun promoterSelectsPromotedOngoing_flagEnabled() {
        val promoter: NotifPromoter = withArgCaptor { verify(notifPipeline).addPromoter(capture()) }

        // GIVEN the notification has FLAG_PROMOTED_ONGOING
        mEntryBuilder.setFlag(mContext, FLAG_PROMOTED_ONGOING, true);
        val entry = buildEntry { setFlag(mContext, Notification.FLAG_PROMOTED_ONGOING, true) }

        // THEN the entry is promoted to top level
        assertTrue(promoter.shouldPromoteToTopLevel(mEntryBuilder.build()));
        assertTrue(promoter.shouldPromoteToTopLevel(entry))
    }

    @Test
    @EnableFlags(PromotedNotificationUi.FLAG_NAME)
    public void promoterIgnoresNonPromotedOngoing_flagEnabled() {
        ArgumentCaptor<NotifPromoter> captor = ArgumentCaptor.forClass(NotifPromoter.class);
        verify(mNotifPipeline).addPromoter(captor.capture());
        NotifPromoter promoter = captor.getValue();
    fun promoterIgnoresNonPromotedOngoing_flagEnabled() {
        val promoter: NotifPromoter = withArgCaptor { verify(notifPipeline).addPromoter(capture()) }

        // GIVEN the notification does not have FLAG_PROMOTED_ONGOING
        mEntryBuilder.setFlag(mContext, FLAG_PROMOTED_ONGOING, false);
        val entry = buildEntry { setFlag(mContext, Notification.FLAG_PROMOTED_ONGOING, false) }

        // THEN the entry is NOT promoted to top level
        assertFalse(promoter.shouldPromoteToTopLevel(mEntryBuilder.build()));
        assertFalse(promoter.shouldPromoteToTopLevel(entry))
    }

    @Test
    @DisableFlags(PromotedNotificationUi.FLAG_NAME)
    public void noPromoterAdded_flagDisabled() {
        verify(mNotifPipeline, never()).addPromoter(any());
    fun noPromoterAdded_flagDisabled() {
        verify(notifPipeline, never()).addPromoter(any())
    }

    private fun makeCallStyle(): Notification.CallStyle {
        val pendingIntent =
            PendingIntent.getBroadcast(mContext, 0, Intent("action"), PendingIntent.FLAG_IMMUTABLE)
        val person = Person.Builder().setName("person").build()
        return Notification.CallStyle.forOngoingCall(person, pendingIntent)
    }

    private Notification.CallStyle makeCallStyle() {
        final PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0,
                new Intent("action"), PendingIntent.FLAG_IMMUTABLE);
        final Person person = new Person.Builder().setName("person").build();
        return Notification.CallStyle.forIncomingCall(person, pendingIntent, pendingIntent);
    companion object {
        private const val NOTIF_USER_ID = 0
    }
}
+3 −0
Original line number Diff line number Diff line
@@ -33,3 +33,6 @@ inline fun NotificationEntry.modifyEntry(
fun getAttachState(entry: ListEntry): ListAttachState {
    return entry.attachState
}

fun buildEntry(block: NotificationEntryBuilder.() -> Unit) =
    NotificationEntryBuilder().apply(block).build()