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

Commit 3335973d authored by Sherry Zhou's avatar Sherry Zhou
Browse files

Update focal area bounds on large screen landscape

Bug: 395730257
Test: atest WallpaperFocalAreaInteractor
Flag: com.android.systemui.shared.extended_wallpaper_effects

Change-Id: I1c21dab3049d801a8cd4a18a3db1325addcee6a5
parent 4d0c46f5
Loading
Loading
Loading
Loading
+4 −51
Original line number Diff line number Diff line
@@ -30,8 +30,6 @@ import com.android.systemui.kosmos.testScope
import com.android.systemui.res.R
import com.android.systemui.shade.data.repository.ShadeRepository
import com.android.systemui.shade.data.repository.shadeRepository
import com.android.systemui.statusbar.notification.data.repository.activeNotificationListRepository
import com.android.systemui.statusbar.notification.data.repository.setActiveNotifs
import com.android.systemui.statusbar.notification.domain.interactor.activeNotificationsInteractor
import com.android.systemui.testKosmos
import com.android.systemui.wallpapers.data.repository.fakeWallpaperFocalAreaRepository
@@ -110,7 +108,7 @@ class WallpaperFocalAreaInteractorTest : SysuiTestCase() {
            )
            val bounds by collectLastValue(underTest.wallpaperFocalAreaBounds)
            kosmos.shadeRepository.setShadeLayoutWide(false)
            kosmos.activeNotificationListRepository.setActiveNotifs(0)

            kosmos.wallpaperFocalAreaRepository.setShortcutAbsoluteTop(1800F)
            kosmos.wallpaperFocalAreaRepository.setNotificationDefaultTop(400F)
            kosmos.wallpaperFocalAreaRepository.setNotificationStackAbsoluteBottom(400F)
@@ -130,7 +128,6 @@ class WallpaperFocalAreaInteractorTest : SysuiTestCase() {
            )
            val bounds by collectLastValue(underTest.wallpaperFocalAreaBounds)
            kosmos.shadeRepository.setShadeLayoutWide(false)
            kosmos.activeNotificationListRepository.setActiveNotifs(1)
            kosmos.wallpaperFocalAreaRepository.setShortcutAbsoluteTop(1800F)
            kosmos.wallpaperFocalAreaRepository.setNotificationDefaultTop(400F)
            kosmos.wallpaperFocalAreaRepository.setNotificationStackAbsoluteBottom(600F)
@@ -139,27 +136,7 @@ class WallpaperFocalAreaInteractorTest : SysuiTestCase() {
        }

    @Test
    fun focalAreaBounds_withNotifications_inUnfoldLandscape() =
        testScope.runTest {
            overrideMockedResources(
                OverrideResources(
                    screenWidth = 2000,
                    screenHeight = 1600,
                    centerAlignFocalArea = false,
                )
            )
            val bounds by collectLastValue(underTest.wallpaperFocalAreaBounds)
            kosmos.shadeRepository.setShadeLayoutWide(true)
            kosmos.activeNotificationListRepository.setActiveNotifs(1)
            kosmos.wallpaperFocalAreaRepository.setShortcutAbsoluteTop(1400F)
            kosmos.wallpaperFocalAreaRepository.setNotificationDefaultTop(400F)
            kosmos.wallpaperFocalAreaRepository.setNotificationStackAbsoluteBottom(600F)

            assertThat(bounds).isEqualTo(RectF(500f, 600F, 1000F, 1100F))
        }

    @Test
    fun focalAreaBounds_withoutNotifications_inUnfoldLandscape() =
    fun focalAreaBounds_inUnfoldLandscape() =
        testScope.runTest {
            overrideMockedResources(
                OverrideResources(
@@ -170,12 +147,11 @@ class WallpaperFocalAreaInteractorTest : SysuiTestCase() {
            )
            val bounds by collectLastValue(underTest.wallpaperFocalAreaBounds)
            kosmos.shadeRepository.setShadeLayoutWide(true)
            kosmos.activeNotificationListRepository.setActiveNotifs(0)
            kosmos.wallpaperFocalAreaRepository.setShortcutAbsoluteTop(1400F)
            kosmos.wallpaperFocalAreaRepository.setNotificationDefaultTop(400F)
            kosmos.wallpaperFocalAreaRepository.setNotificationStackAbsoluteBottom(400F)

            assertThat(bounds).isEqualTo(RectF(1000f, 600F, 1500F, 1100F))
            assertThat(bounds).isEqualTo(RectF(600f, 600F, 1400F, 1100F))
        }

    @Test
@@ -190,7 +166,6 @@ class WallpaperFocalAreaInteractorTest : SysuiTestCase() {
            )
            val bounds by collectLastValue(underTest.wallpaperFocalAreaBounds)
            kosmos.shadeRepository.setShadeLayoutWide(false)
            kosmos.activeNotificationListRepository.setActiveNotifs(1)
            kosmos.wallpaperFocalAreaRepository.setShortcutAbsoluteTop(1800F)
            kosmos.wallpaperFocalAreaRepository.setNotificationDefaultTop(400F)
            kosmos.wallpaperFocalAreaRepository.setNotificationStackAbsoluteBottom(600F)
@@ -210,7 +185,6 @@ class WallpaperFocalAreaInteractorTest : SysuiTestCase() {
            )
            val bounds by collectLastValue(underTest.wallpaperFocalAreaBounds)
            kosmos.shadeRepository.setShadeLayoutWide(false)
            kosmos.activeNotificationListRepository.setActiveNotifs(0)
            kosmos.wallpaperFocalAreaRepository.setShortcutAbsoluteTop(1800F)
            kosmos.wallpaperFocalAreaRepository.setNotificationDefaultTop(400F)
            kosmos.wallpaperFocalAreaRepository.setNotificationStackAbsoluteBottom(600F)
@@ -219,7 +193,7 @@ class WallpaperFocalAreaInteractorTest : SysuiTestCase() {
        }

    @Test
    fun focalAreaBounds_withNotifications_inTabletLandscape() =
    fun focalAreaBounds_inTabletLandscape() =
        testScope.runTest {
            overrideMockedResources(
                OverrideResources(
@@ -230,7 +204,6 @@ class WallpaperFocalAreaInteractorTest : SysuiTestCase() {
            )
            val bounds by collectLastValue(underTest.wallpaperFocalAreaBounds)
            kosmos.shadeRepository.setShadeLayoutWide(true)
            kosmos.activeNotificationListRepository.setActiveNotifs(1)
            kosmos.wallpaperFocalAreaRepository.setShortcutAbsoluteTop(1800F)
            kosmos.wallpaperFocalAreaRepository.setNotificationDefaultTop(200F)
            kosmos.wallpaperFocalAreaRepository.setNotificationStackAbsoluteBottom(200F)
@@ -238,26 +211,6 @@ class WallpaperFocalAreaInteractorTest : SysuiTestCase() {
            assertThat(bounds).isEqualTo(RectF(1000f, 600F, 2000F, 1400F))
        }

    @Test
    fun focalAreaBounds_withoutNotifications_inTabletLandscape() =
        testScope.runTest {
            overrideMockedResources(
                OverrideResources(
                    screenWidth = 3000,
                    screenHeight = 2000,
                    centerAlignFocalArea = true,
                )
            )
            val bounds by collectLastValue(underTest.wallpaperFocalAreaBounds)
            kosmos.shadeRepository.setShadeLayoutWide(true)
            kosmos.activeNotificationListRepository.setActiveNotifs(0)
            kosmos.wallpaperFocalAreaRepository.setShortcutAbsoluteTop(1800F)
            kosmos.wallpaperFocalAreaRepository.setNotificationDefaultTop(400F)
            kosmos.wallpaperFocalAreaRepository.setNotificationStackAbsoluteBottom(400F)

            assertThat(bounds).isEqualTo(RectF(1000f, 600F, 2000F, 1400F))
        }

    @Test
    fun onTap_inFocalBounds() =
        testScope.runTest {
+18 −32
Original line number Diff line number Diff line
@@ -20,8 +20,8 @@ import android.content.Context
import android.content.res.Resources
import android.graphics.PointF
import android.graphics.RectF
import android.util.Log
import android.util.TypedValue
import androidx.annotation.VisibleForTesting
import com.android.app.animation.MathUtils
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
@@ -48,32 +48,16 @@ constructor(
    activeNotificationsInteractor: ActiveNotificationsInteractor,
    val wallpaperRepository: WallpaperRepository,
) {
    // When there's notifications in splitshade, the focal area should be left aligned
    @VisibleForTesting
    val notificationInShadeWideLayout: Flow<Boolean> =
        combine(
            shadeRepository.isShadeLayoutWide,
            activeNotificationsInteractor.areAnyNotificationsPresent,
        ) { isShadeLayoutWide, areAnyNotificationsPresent: Boolean ->
            when {
                !isShadeLayoutWide -> false
                !areAnyNotificationsPresent -> false
                else -> true
            }
        }

    val hasFocalArea = wallpaperRepository.shouldSendFocalArea

    val wallpaperFocalAreaBounds: Flow<RectF> =
        combine(
                shadeRepository.isShadeLayoutWide,
                notificationInShadeWideLayout,
                wallpaperFocalAreaRepository.notificationStackAbsoluteBottom,
                wallpaperFocalAreaRepository.shortcutAbsoluteTop,
                wallpaperFocalAreaRepository.notificationDefaultTop,
            ) {
                isShadeLayoutWide,
                notificationInShadeWideLayout,
                notificationStackAbsoluteBottom,
                shortcutAbsoluteTop,
                notificationDefaultTop ->
@@ -97,28 +81,21 @@ constructor(
                        screenBounds.centerY() + screenBounds.height() / 2F / wallpaperZoomedInScale,
                    )

                val focalAreaMaxWidthDp = getFocalAreaMaxWidthDp(context)
                val maxFocalAreaWidth =
                    TypedValue.applyDimension(
                        TypedValue.COMPLEX_UNIT_DIP,
                        FOCAL_AREA_MAX_WIDTH_DP.toFloat(),
                        focalAreaMaxWidthDp.toFloat(),
                        context.resources.displayMetrics,
                    )

                val (left, right) =
                // tablet landscape
                if (context.resources.getBoolean(R.bool.center_align_focal_area_shape)) {
                // Tablet & unfold foldable landscape
                if (isShadeLayoutWide) {
                        Pair(
                            scaledBounds.centerX() - maxFocalAreaWidth / 2F,
                            scaledBounds.centerX() + maxFocalAreaWidth / 2F,
                        )
                        // unfold foldable landscape
                    } else if (isShadeLayoutWide) {
                        if (notificationInShadeWideLayout) {
                            Pair(scaledBounds.left, scaledBounds.centerX())
                        } else {
                            Pair(scaledBounds.centerX(), scaledBounds.right)
                        }
                        // handheld / portrait
                    } else {
                        val focalAreaWidth = min(scaledBounds.width(), maxFocalAreaWidth)
                        Pair(
@@ -147,7 +124,7 @@ constructor(
                                wallpaperZoomedInScale
                    }
                val bottom = scaledBounds.bottom - scaledBottomMargin
                RectF(left, top, right, bottom)
                RectF(left, top, right, bottom).also { Log.d(TAG, "Focal area changes to $it") }
            }
            .distinctUntilChanged()

@@ -187,8 +164,17 @@ constructor(
            return if (scale == 0f) 1f else scale
        }

        // A max width for focal area shape effects bounds, to avoid
        // it becoming too large in large screen portrait mode
        const val FOCAL_AREA_MAX_WIDTH_DP = 500
        // A max width for focal area shape effects bounds, to avoid it becoming too large,
        // especially in portrait mode
        const val FOCAL_AREA_MAX_WIDTH_DP_TABLET = 500
        const val FOCAL_AREA_MAX_WIDTH_DP_FOLDABLE = 400

        fun getFocalAreaMaxWidthDp(context: Context): Int {
            return if (context.resources.getBoolean(R.bool.center_align_focal_area_shape))
                FOCAL_AREA_MAX_WIDTH_DP_TABLET
            else FOCAL_AREA_MAX_WIDTH_DP_FOLDABLE
        }

        private val TAG = WallpaperFocalAreaInteractor::class.simpleName
    }
}