[CS] 5/N: Move WallpaperController to WallpaperRepo.
Bug: 277762009 Bug: 277764509 Test: on fold device, set a wallpaper with and without default unfold transition. Verify WallpaperController has the correct value. Test: atest WallpaperRepositoryImplTest WallpaperControllerTest Change-Id: I85321f996a18cb5f01f14087d4d8cc557bcb6237 Change-Id: I457758e223ab651ea7ba725f3f5a05f20398bf2d
This commit is contained in:
@@ -3564,7 +3564,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
|
||||
}
|
||||
WallpaperInfo info = mWallpaperManager.getWallpaperInfoForUser(
|
||||
mUserTracker.getUserId());
|
||||
mWallpaperController.onWallpaperInfoUpdated(info);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -16,32 +16,34 @@
|
||||
|
||||
package com.android.systemui.util
|
||||
|
||||
import android.app.WallpaperInfo
|
||||
import android.app.WallpaperManager
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import com.android.systemui.dagger.SysUISingleton
|
||||
import com.android.systemui.wallpapers.data.repository.WallpaperRepository
|
||||
import javax.inject.Inject
|
||||
import kotlin.math.max
|
||||
|
||||
private const val TAG = "WallpaperController"
|
||||
|
||||
/**
|
||||
* Controller for wallpaper-related logic.
|
||||
*
|
||||
* Note: New logic should be added to [WallpaperRepository], not this class.
|
||||
*/
|
||||
@SysUISingleton
|
||||
class WallpaperController @Inject constructor(private val wallpaperManager: WallpaperManager) {
|
||||
class WallpaperController @Inject constructor(
|
||||
private val wallpaperManager: WallpaperManager,
|
||||
private val wallpaperRepository: WallpaperRepository,
|
||||
) {
|
||||
|
||||
var rootView: View? = null
|
||||
|
||||
private var notificationShadeZoomOut: Float = 0f
|
||||
private var unfoldTransitionZoomOut: Float = 0f
|
||||
|
||||
private var wallpaperInfo: WallpaperInfo? = null
|
||||
|
||||
fun onWallpaperInfoUpdated(wallpaperInfo: WallpaperInfo?) {
|
||||
this.wallpaperInfo = wallpaperInfo
|
||||
}
|
||||
|
||||
private val shouldUseDefaultUnfoldTransition: Boolean
|
||||
get() = wallpaperInfo?.shouldUseDefaultUnfoldTransition()
|
||||
get() = wallpaperRepository.wallpaperInfo.value?.shouldUseDefaultUnfoldTransition()
|
||||
?: true
|
||||
|
||||
fun setNotificationShadeZoom(zoomOut: Float) {
|
||||
|
||||
@@ -16,9 +16,11 @@
|
||||
|
||||
package com.android.systemui.wallpapers.data.repository
|
||||
|
||||
import android.app.WallpaperInfo
|
||||
import com.android.systemui.dagger.SysUISingleton
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
|
||||
/**
|
||||
@@ -29,5 +31,6 @@ import kotlinx.coroutines.flow.asStateFlow
|
||||
*/
|
||||
@SysUISingleton
|
||||
class NoopWallpaperRepository @Inject constructor() : WallpaperRepository {
|
||||
override val wallpaperInfo: StateFlow<WallpaperInfo?> = MutableStateFlow(null).asStateFlow()
|
||||
override val wallpaperSupportsAmbientMode = MutableStateFlow(false).asStateFlow()
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.systemui.wallpapers.data.repository
|
||||
|
||||
import android.app.WallpaperInfo
|
||||
import android.app.WallpaperManager
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
@@ -36,11 +37,15 @@ import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.filter
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.onStart
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
|
||||
/** A repository storing information about the current wallpaper. */
|
||||
interface WallpaperRepository {
|
||||
/** Emits the current user's current wallpaper. */
|
||||
val wallpaperInfo: StateFlow<WallpaperInfo?>
|
||||
|
||||
/** Emits true if the current user's current wallpaper supports ambient mode. */
|
||||
val wallpaperSupportsAmbientMode: StateFlow<Boolean>
|
||||
}
|
||||
@@ -78,28 +83,35 @@ constructor(
|
||||
// Only update the wallpaper status once the user selection has finished.
|
||||
.filter { it.selectionStatus == SelectionStatus.SELECTION_COMPLETE }
|
||||
|
||||
override val wallpaperSupportsAmbientMode: StateFlow<Boolean> =
|
||||
override val wallpaperInfo: StateFlow<WallpaperInfo?> =
|
||||
if (!wallpaperManager.isWallpaperSupported || !deviceSupportsAodWallpaper) {
|
||||
MutableStateFlow(false).asStateFlow()
|
||||
MutableStateFlow(null).asStateFlow()
|
||||
} else {
|
||||
combine(wallpaperChanged, selectedUser) { _, selectedUser ->
|
||||
doesWallpaperSupportAmbientMode(selectedUser)
|
||||
getWallpaper(selectedUser)
|
||||
}
|
||||
.stateIn(
|
||||
scope,
|
||||
// Always be listening for wallpaper changes.
|
||||
SharingStarted.Eagerly,
|
||||
initialValue =
|
||||
doesWallpaperSupportAmbientMode(userRepository.selectedUser.value),
|
||||
initialValue = getWallpaper(userRepository.selectedUser.value),
|
||||
)
|
||||
}
|
||||
|
||||
private fun doesWallpaperSupportAmbientMode(selectedUser: SelectedUserModel): Boolean {
|
||||
return wallpaperManager
|
||||
.getWallpaperInfoForUser(
|
||||
selectedUser.userInfo.id,
|
||||
override val wallpaperSupportsAmbientMode: StateFlow<Boolean> =
|
||||
wallpaperInfo
|
||||
.map {
|
||||
// If WallpaperInfo is null, it's ImageWallpaper which never supports ambient mode.
|
||||
it?.supportsAmbientMode() == true
|
||||
}
|
||||
.stateIn(
|
||||
scope,
|
||||
// Always be listening for wallpaper changes.
|
||||
SharingStarted.Eagerly,
|
||||
initialValue = wallpaperInfo.value?.supportsAmbientMode() == true,
|
||||
)
|
||||
// If WallpaperInfo is null, it's ImageWallpaper which never supports ambient mode.
|
||||
?.supportsAmbientMode() == true
|
||||
|
||||
private fun getWallpaper(selectedUser: SelectedUserModel): WallpaperInfo? {
|
||||
return wallpaperManager.getWallpaperInfoForUser(selectedUser.userInfo.id)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import android.view.ViewRootImpl
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.util.mockito.eq
|
||||
import com.android.systemui.wallpapers.data.repository.FakeWallpaperRepository
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
@@ -56,6 +57,7 @@ class WallpaperControllerTest : SysuiTestCase() {
|
||||
private lateinit var viewRootImpl: ViewRootImpl
|
||||
@Mock
|
||||
private lateinit var windowToken: IBinder
|
||||
private val wallpaperRepository = FakeWallpaperRepository()
|
||||
|
||||
@JvmField
|
||||
@Rule
|
||||
@@ -69,7 +71,7 @@ class WallpaperControllerTest : SysuiTestCase() {
|
||||
`when`(root.windowToken).thenReturn(windowToken)
|
||||
`when`(root.isAttachedToWindow).thenReturn(true)
|
||||
|
||||
wallaperController = WallpaperController(wallpaperManager)
|
||||
wallaperController = WallpaperController(wallpaperManager, wallpaperRepository)
|
||||
|
||||
wallaperController.rootView = root
|
||||
}
|
||||
@@ -90,9 +92,9 @@ class WallpaperControllerTest : SysuiTestCase() {
|
||||
|
||||
@Test
|
||||
fun setUnfoldTransitionZoom_defaultUnfoldTransitionIsDisabled_doesNotUpdateWallpaperZoom() {
|
||||
wallaperController.onWallpaperInfoUpdated(createWallpaperInfo(
|
||||
wallpaperRepository.wallpaperInfo.value = createWallpaperInfo(
|
||||
useDefaultTransition = false
|
||||
))
|
||||
)
|
||||
|
||||
wallaperController.setUnfoldTransitionZoom(0.5f)
|
||||
|
||||
|
||||
@@ -16,9 +16,11 @@
|
||||
|
||||
package com.android.systemui.wallpapers.data.repository
|
||||
|
||||
import android.app.WallpaperInfo
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
||||
/** Fake implementation of the wallpaper repository. */
|
||||
class FakeWallpaperRepository : WallpaperRepository {
|
||||
override val wallpaperInfo = MutableStateFlow<WallpaperInfo?>(null)
|
||||
override val wallpaperSupportsAmbientMode = MutableStateFlow(false)
|
||||
}
|
||||
|
||||
@@ -64,6 +64,171 @@ class WallpaperRepositoryImplTest : SysuiTestCase() {
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun wallpaperInfo_nullInfo() =
|
||||
testScope.runTest {
|
||||
val latest by collectLastValue(underTest.wallpaperInfo)
|
||||
|
||||
whenever(wallpaperManager.getWallpaperInfoForUser(any())).thenReturn(null)
|
||||
|
||||
fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(
|
||||
context,
|
||||
Intent(Intent.ACTION_WALLPAPER_CHANGED),
|
||||
)
|
||||
|
||||
assertThat(latest).isNull()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun wallpaperInfo_hasInfoFromManager() =
|
||||
testScope.runTest {
|
||||
val latest by collectLastValue(underTest.wallpaperInfo)
|
||||
|
||||
whenever(wallpaperManager.getWallpaperInfoForUser(any())).thenReturn(UNSUPPORTED_WP)
|
||||
|
||||
fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(
|
||||
context,
|
||||
Intent(Intent.ACTION_WALLPAPER_CHANGED),
|
||||
)
|
||||
|
||||
assertThat(latest).isEqualTo(UNSUPPORTED_WP)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun wallpaperInfo_initialValueIsFetched() =
|
||||
testScope.runTest {
|
||||
whenever(wallpaperManager.getWallpaperInfoForUser(USER_WITH_SUPPORTED_WP.id))
|
||||
.thenReturn(SUPPORTED_WP)
|
||||
userRepository.setUserInfos(listOf(USER_WITH_SUPPORTED_WP))
|
||||
userRepository.setSelectedUserInfo(USER_WITH_SUPPORTED_WP)
|
||||
|
||||
// WHEN the repo initially starts up (underTest is lazy), then it fetches the current
|
||||
// value for the wallpaper
|
||||
assertThat(underTest.wallpaperInfo.value).isEqualTo(SUPPORTED_WP)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun wallpaperInfo_updatesOnUserChanged() =
|
||||
testScope.runTest {
|
||||
val latest by collectLastValue(underTest.wallpaperInfo)
|
||||
|
||||
val user3 = UserInfo(/* id= */ 3, /* name= */ "user3", /* flags= */ 0)
|
||||
val user3Wp = mock<WallpaperInfo>()
|
||||
whenever(wallpaperManager.getWallpaperInfoForUser(user3.id)).thenReturn(user3Wp)
|
||||
|
||||
val user4 = UserInfo(/* id= */ 4, /* name= */ "user4", /* flags= */ 0)
|
||||
val user4Wp = mock<WallpaperInfo>()
|
||||
whenever(wallpaperManager.getWallpaperInfoForUser(user4.id)).thenReturn(user4Wp)
|
||||
|
||||
userRepository.setUserInfos(listOf(user3, user4))
|
||||
|
||||
// WHEN user3 is selected
|
||||
userRepository.setSelectedUserInfo(user3)
|
||||
|
||||
// THEN user3's wallpaper is used
|
||||
assertThat(latest).isEqualTo(user3Wp)
|
||||
|
||||
// WHEN the user is switched to user4
|
||||
userRepository.setSelectedUserInfo(user4)
|
||||
|
||||
// THEN user4's wallpaper is used
|
||||
assertThat(latest).isEqualTo(user4Wp)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun wallpaperInfo_doesNotUpdateOnUserChanging() =
|
||||
testScope.runTest {
|
||||
val latest by collectLastValue(underTest.wallpaperInfo)
|
||||
|
||||
val user3 = UserInfo(/* id= */ 3, /* name= */ "user3", /* flags= */ 0)
|
||||
val user3Wp = mock<WallpaperInfo>()
|
||||
whenever(wallpaperManager.getWallpaperInfoForUser(user3.id)).thenReturn(user3Wp)
|
||||
|
||||
val user4 = UserInfo(/* id= */ 4, /* name= */ "user4", /* flags= */ 0)
|
||||
val user4Wp = mock<WallpaperInfo>()
|
||||
whenever(wallpaperManager.getWallpaperInfoForUser(user4.id)).thenReturn(user4Wp)
|
||||
|
||||
userRepository.setUserInfos(listOf(user3, user4))
|
||||
|
||||
// WHEN user3 is selected
|
||||
userRepository.setSelectedUserInfo(user3)
|
||||
|
||||
// THEN user3's wallpaper is used
|
||||
assertThat(latest).isEqualTo(user3Wp)
|
||||
|
||||
// WHEN the user has started switching to user4 but hasn't finished yet
|
||||
userRepository.selectedUser.value =
|
||||
SelectedUserModel(user4, SelectionStatus.SELECTION_IN_PROGRESS)
|
||||
|
||||
// THEN the wallpaper still matches user3
|
||||
assertThat(latest).isEqualTo(user3Wp)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun wallpaperInfo_updatesOnIntent() =
|
||||
testScope.runTest {
|
||||
val latest by collectLastValue(underTest.wallpaperInfo)
|
||||
|
||||
val wp1 = mock<WallpaperInfo>()
|
||||
whenever(wallpaperManager.getWallpaperInfoForUser(any())).thenReturn(wp1)
|
||||
|
||||
assertThat(latest).isEqualTo(wp1)
|
||||
|
||||
// WHEN the info is new and a broadcast is sent
|
||||
val wp2 = mock<WallpaperInfo>()
|
||||
whenever(wallpaperManager.getWallpaperInfoForUser(any())).thenReturn(wp2)
|
||||
fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(
|
||||
context,
|
||||
Intent(Intent.ACTION_WALLPAPER_CHANGED),
|
||||
)
|
||||
|
||||
// THEN the flow updates
|
||||
assertThat(latest).isEqualTo(wp2)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun wallpaperInfo_wallpaperNotSupported_alwaysNull() =
|
||||
testScope.runTest {
|
||||
whenever(wallpaperManager.isWallpaperSupported).thenReturn(false)
|
||||
|
||||
val latest by collectLastValue(underTest.wallpaperInfo)
|
||||
assertThat(latest).isNull()
|
||||
|
||||
// Even WHEN there *is* current wallpaper
|
||||
val wp1 = mock<WallpaperInfo>()
|
||||
whenever(wallpaperManager.getWallpaperInfoForUser(any())).thenReturn(wp1)
|
||||
fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(
|
||||
context,
|
||||
Intent(Intent.ACTION_WALLPAPER_CHANGED),
|
||||
)
|
||||
|
||||
// THEN the value is still null because wallpaper isn't supported
|
||||
assertThat(latest).isNull()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun wallpaperInfo_deviceDoesNotSupportAmbientWallpaper_alwaysFalse() =
|
||||
testScope.runTest {
|
||||
context.orCreateTestableResources.addOverride(
|
||||
com.android.internal.R.bool.config_dozeSupportsAodWallpaper,
|
||||
false
|
||||
)
|
||||
|
||||
val latest by collectLastValue(underTest.wallpaperInfo)
|
||||
assertThat(latest).isNull()
|
||||
|
||||
// Even WHEN there *is* current wallpaper
|
||||
val wp1 = mock<WallpaperInfo>()
|
||||
whenever(wallpaperManager.getWallpaperInfoForUser(any())).thenReturn(wp1)
|
||||
fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(
|
||||
context,
|
||||
Intent(Intent.ACTION_WALLPAPER_CHANGED),
|
||||
)
|
||||
|
||||
// THEN the value is still null because wallpaper isn't supported
|
||||
assertThat(latest).isNull()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun wallpaperSupportsAmbientMode_nullInfo_false() =
|
||||
testScope.runTest {
|
||||
@@ -190,14 +355,12 @@ class WallpaperRepositoryImplTest : SysuiTestCase() {
|
||||
testScope.runTest {
|
||||
val latest by collectLastValue(underTest.wallpaperSupportsAmbientMode)
|
||||
|
||||
val info: WallpaperInfo = mock()
|
||||
whenever(info.supportsAmbientMode()).thenReturn(false)
|
||||
whenever(wallpaperManager.getWallpaperInfoForUser(any())).thenReturn(info)
|
||||
whenever(wallpaperManager.getWallpaperInfoForUser(any())).thenReturn(UNSUPPORTED_WP)
|
||||
|
||||
assertThat(latest).isFalse()
|
||||
|
||||
// WHEN the info now supports ambient mode and a broadcast is sent
|
||||
whenever(info.supportsAmbientMode()).thenReturn(true)
|
||||
whenever(wallpaperManager.getWallpaperInfoForUser(any())).thenReturn(SUPPORTED_WP)
|
||||
fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(
|
||||
context,
|
||||
Intent(Intent.ACTION_WALLPAPER_CHANGED),
|
||||
|
||||
Reference in New Issue
Block a user