From 0a14f33198d939db9cca92c44b7f2789c32fe001 Mon Sep 17 00:00:00 2001 From: Nick Chameyev Date: Fri, 27 Aug 2021 18:08:01 +0000 Subject: [PATCH] Add should use default unfold transition attribute to wallpaper Adds new attribute to wallpaper XML declaration to indicate whether a wallpaper should receive default zooming transition updates when folding or unfolding. This attribute allows to opt-out from the default behaviour during this transition and implement custom behaviour. Bug: 196933493 Test: atest android.app.cts.WallpaperInfoTest Change-Id: I7cb104bf7dfbbe92de72e505ec31d866a59bae4a --- core/api/current.txt | 2 + core/java/android/app/WallpaperInfo.java | 26 ++++ core/res/res/values/attrs.xml | 11 ++ core/res/res/values/public.xml | 1 + .../NotificationShadeDepthController.kt | 14 +- .../systemui/statusbar/phone/StatusBar.java | 12 ++ .../phone/dagger/StatusBarPhoneModule.java | 6 + .../UnfoldTransitionWallpaperController.kt | 39 +++++ .../systemui/util/WallpaperController.kt | 76 +++++++++ .../NotificationShadeDepthControllerTest.kt | 31 +--- .../statusbar/phone/StatusBarTest.java | 6 + .../systemui/util/WallpaperControllerTest.kt | 144 ++++++++++++++++++ 12 files changed, 333 insertions(+), 35 deletions(-) create mode 100644 packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionWallpaperController.kt create mode 100644 packages/SystemUI/src/com/android/systemui/util/WallpaperController.kt create mode 100644 packages/SystemUI/tests/src/com/android/systemui/util/WallpaperControllerTest.kt diff --git a/core/api/current.txt b/core/api/current.txt index ec8dce0837cd4..3aabe8dd6f200 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -1298,6 +1298,7 @@ package android { field public static final int shortcutLongLabel = 16844074; // 0x101052a field public static final int shortcutShortLabel = 16844073; // 0x1010529 field public static final int shouldDisableView = 16843246; // 0x10101ee + field public static final int shouldUseDefaultUnfoldTransition; field public static final int showAsAction = 16843481; // 0x10102d9 field public static final int showDefault = 16843258; // 0x10101fa field public static final int showDividers = 16843561; // 0x1010329 @@ -6926,6 +6927,7 @@ package android.app { method public android.graphics.drawable.Drawable loadIcon(android.content.pm.PackageManager); method public CharSequence loadLabel(android.content.pm.PackageManager); method public android.graphics.drawable.Drawable loadThumbnail(android.content.pm.PackageManager); + method public boolean shouldUseDefaultUnfoldTransition(); method public boolean supportsMultipleDisplays(); method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator CREATOR; diff --git a/core/java/android/app/WallpaperInfo.java b/core/java/android/app/WallpaperInfo.java index e9b01750b3b10..4dff4e0e84d62 100644 --- a/core/java/android/app/WallpaperInfo.java +++ b/core/java/android/app/WallpaperInfo.java @@ -81,6 +81,7 @@ public final class WallpaperInfo implements Parcelable { final int mContextDescriptionResource; final boolean mShowMetadataInPreview; final boolean mSupportsAmbientMode; + final boolean mShouldUseDefaultUnfoldTransition; final String mSettingsSliceUri; final boolean mSupportMultipleDisplays; @@ -145,6 +146,9 @@ public final class WallpaperInfo implements Parcelable { mSupportsAmbientMode = sa.getBoolean( com.android.internal.R.styleable.Wallpaper_supportsAmbientMode, false); + mShouldUseDefaultUnfoldTransition = sa.getBoolean( + com.android.internal.R.styleable.Wallpaper_shouldUseDefaultUnfoldTransition, + true); mSettingsSliceUri = sa.getString( com.android.internal.R.styleable.Wallpaper_settingsSliceUri); mSupportMultipleDisplays = sa.getBoolean( @@ -171,6 +175,7 @@ public final class WallpaperInfo implements Parcelable { mSupportsAmbientMode = source.readInt() != 0; mSettingsSliceUri = source.readString(); mSupportMultipleDisplays = source.readInt() != 0; + mShouldUseDefaultUnfoldTransition = source.readInt() != 0; mService = ResolveInfo.CREATOR.createFromParcel(source); } @@ -393,6 +398,26 @@ public final class WallpaperInfo implements Parcelable { return mSupportMultipleDisplays; } + /** + * Returns whether this wallpaper should receive default zooming updates when unfolding. + * If set to false the wallpaper will not receive zoom events when folding or unfolding + * a foldable device, so it can implement its own unfold transition. + *

+ * This corresponds to the value {@link + * android.R.styleable#Wallpaper_shouldUseDefaultUnfoldTransition} in the XML description + * of the wallpaper. + *

+ * The default value is {@code true}. + * + * @see android.R.styleable#Wallpaper_shouldUseDefaultUnfoldTransition + * @return {@code true} if wallpaper should receive default fold/unfold transition updates + * + * @attr ref android.R.styleable#Wallpaper_shouldUseDefaultUnfoldTransition + */ + public boolean shouldUseDefaultUnfoldTransition() { + return mShouldUseDefaultUnfoldTransition; + } + public void dump(Printer pw, String prefix) { pw.println(prefix + "Service:"); mService.dump(pw, prefix + " "); @@ -423,6 +448,7 @@ public final class WallpaperInfo implements Parcelable { dest.writeInt(mSupportsAmbientMode ? 1 : 0); dest.writeString(mSettingsSliceUri); dest.writeInt(mSupportMultipleDisplays ? 1 : 0); + dest.writeInt(mShouldUseDefaultUnfoldTransition ? 1 : 0); mService.writeToParcel(dest, flags); } diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index a5f505176d5d1..0a6b02d499e52 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -8371,6 +8371,17 @@ @hide @SystemApi --> + + + diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index b57055ca4338c..7d489049d112f 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -3221,6 +3221,7 @@ + diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt index 2a8771e96e7b6..7aa2dc7e0785b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt @@ -19,7 +19,6 @@ package com.android.systemui.statusbar import android.animation.Animator import android.animation.AnimatorListenerAdapter import android.animation.ValueAnimator -import android.app.WallpaperManager import android.os.SystemClock import android.os.Trace import android.util.IndentingPrintWriter @@ -42,6 +41,7 @@ import com.android.systemui.statusbar.phone.DozeParameters import com.android.systemui.statusbar.phone.PanelExpansionListener import com.android.systemui.statusbar.phone.ScrimController import com.android.systemui.statusbar.policy.KeyguardStateController +import com.android.systemui.util.WallpaperController import java.io.FileDescriptor import java.io.PrintWriter import javax.inject.Inject @@ -58,7 +58,7 @@ class NotificationShadeDepthController @Inject constructor( private val biometricUnlockController: BiometricUnlockController, private val keyguardStateController: KeyguardStateController, private val choreographer: Choreographer, - private val wallpaperManager: WallpaperManager, + private val wallpaperController: WallpaperController, private val notificationShadeWindowController: NotificationShadeWindowController, private val dozeParameters: DozeParameters, dumpManager: DumpManager @@ -215,15 +215,7 @@ class NotificationShadeDepthController @Inject constructor( Trace.traceCounter(Trace.TRACE_TAG_APP, "shade_blur_radius", blur) blurUtils.applyBlur(blurRoot?.viewRootImpl ?: root.viewRootImpl, blur, opaque) lastAppliedBlur = blur - try { - if (root.isAttachedToWindow && root.windowToken != null) { - wallpaperManager.setWallpaperZoomOut(root.windowToken, zoomOut) - } else { - Log.i(TAG, "Won't set zoom. Window not attached $root") - } - } catch (e: IllegalArgumentException) { - Log.w(TAG, "Can't set zoom. Window is gone: ${root.windowToken}", e) - } + wallpaperController.setNotificationShadeZoom(zoomOut) listeners.forEach { it.onWallpaperZoomOutChanged(zoomOut) it.onBlurRadiusChanged(blur) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java index 6b96f3c23a2d8..ee7725f670b05 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -228,7 +228,9 @@ import com.android.systemui.statusbar.policy.UserInfoControllerImpl; import com.android.systemui.statusbar.policy.UserSwitcherController; import com.android.systemui.tuner.TunerService; import com.android.systemui.unfold.UnfoldLightRevealOverlayAnimation; +import com.android.systemui.unfold.UnfoldTransitionWallpaperController; import com.android.systemui.unfold.config.UnfoldTransitionConfig; +import com.android.systemui.util.WallpaperController; import com.android.systemui.util.concurrency.DelayableExecutor; import com.android.systemui.util.concurrency.MessageRouter; import com.android.systemui.volume.VolumeComponent; @@ -537,7 +539,9 @@ public class StatusBar extends SystemUI implements private final FeatureFlags mFeatureFlags; private final UnfoldTransitionConfig mUnfoldTransitionConfig; private final Lazy mUnfoldLightRevealOverlayAnimation; + private final Lazy mUnfoldWallpaperController; private final Lazy mMoveFromCenterAnimation; + private final WallpaperController mWallpaperController; private final KeyguardUnlockAnimationController mKeyguardUnlockAnimationController; private final MessageRouter mMessageRouter; private final WallpaperManager mWallpaperManager; @@ -771,7 +775,9 @@ public class StatusBar extends SystemUI implements BrightnessSlider.Factory brightnessSliderFactory, UnfoldTransitionConfig unfoldTransitionConfig, Lazy unfoldLightRevealOverlayAnimation, + Lazy unfoldTransitionWallpaperController, Lazy statusBarUnfoldAnimationController, + WallpaperController wallpaperController, OngoingCallController ongoingCallController, SystemStatusAnimationScheduler animationScheduler, StatusBarLocationPublisher locationPublisher, @@ -865,6 +871,8 @@ public class StatusBar extends SystemUI implements mBrightnessSliderFactory = brightnessSliderFactory; mUnfoldTransitionConfig = unfoldTransitionConfig; mUnfoldLightRevealOverlayAnimation = unfoldLightRevealOverlayAnimation; + mUnfoldWallpaperController = unfoldTransitionWallpaperController; + mWallpaperController = wallpaperController; mMoveFromCenterAnimation = statusBarUnfoldAnimationController; mOngoingCallController = ongoingCallController; mAnimationScheduler = animationScheduler; @@ -1052,6 +1060,7 @@ public class StatusBar extends SystemUI implements if (mUnfoldTransitionConfig.isEnabled()) { mUnfoldLightRevealOverlayAnimation.get().init(); + mUnfoldWallpaperController.get().init(); } mPluginManager.addPluginListener( @@ -1117,6 +1126,7 @@ public class StatusBar extends SystemUI implements inflateStatusBarWindow(); mNotificationShadeWindowViewController.setService(this, mNotificationShadeWindowController); mNotificationShadeWindowView.setOnTouchListener(getStatusBarWindowTouchListener()); + mWallpaperController.setRootView(mNotificationShadeWindowView); // TODO: Deal with the ugliness that comes from having some of the statusbar broken out // into fragments, but the rest here, it leaves some awkward lifecycle and whatnot. @@ -4294,6 +4304,8 @@ public class StatusBar extends SystemUI implements return; } WallpaperInfo info = mWallpaperManager.getWallpaperInfo(UserHandle.USER_CURRENT); + mWallpaperController.onWallpaperInfoUpdated(info); + final boolean deviceSupportsAodWallpaper = mContext.getResources().getBoolean( com.android.internal.R.bool.config_dozeSupportsAodWallpaper); // If WallpaperInfo is null, it must be ImageWallpaper. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java index c45068e0171b3..13eb75a4d5084 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java @@ -107,7 +107,9 @@ import com.android.systemui.statusbar.policy.UserInfoControllerImpl; import com.android.systemui.statusbar.policy.UserSwitcherController; import com.android.systemui.tuner.TunerService; import com.android.systemui.unfold.UnfoldLightRevealOverlayAnimation; +import com.android.systemui.unfold.UnfoldTransitionWallpaperController; import com.android.systemui.unfold.config.UnfoldTransitionConfig; +import com.android.systemui.util.WallpaperController; import com.android.systemui.util.concurrency.DelayableExecutor; import com.android.systemui.util.concurrency.MessageRouter; import com.android.systemui.volume.VolumeComponent; @@ -216,7 +218,9 @@ public interface StatusBarPhoneModule { BrightnessSlider.Factory brightnessSliderFactory, UnfoldTransitionConfig unfoldTransitionConfig, Lazy unfoldLightRevealOverlayAnimation, + Lazy unfoldTransitionWallpaperController, Lazy statusBarMoveFromCenterAnimation, + WallpaperController wallpaperController, OngoingCallController ongoingCallController, SystemStatusAnimationScheduler animationScheduler, StatusBarLocationPublisher locationPublisher, @@ -312,7 +316,9 @@ public interface StatusBarPhoneModule { brightnessSliderFactory, unfoldTransitionConfig, unfoldLightRevealOverlayAnimation, + unfoldTransitionWallpaperController, statusBarMoveFromCenterAnimation, + wallpaperController, ongoingCallController, animationScheduler, locationPublisher, diff --git a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionWallpaperController.kt b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionWallpaperController.kt new file mode 100644 index 0000000000000..8dd3d6beb9c3f --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionWallpaperController.kt @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.unfold + +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener +import com.android.systemui.util.WallpaperController +import javax.inject.Inject + +@SysUISingleton +class UnfoldTransitionWallpaperController @Inject constructor( + private val unfoldTransitionProgressProvider: UnfoldTransitionProgressProvider, + private val wallpaperController: WallpaperController +) { + + fun init() { + unfoldTransitionProgressProvider.addCallback(TransitionListener()) + } + + private inner class TransitionListener : TransitionProgressListener { + override fun onTransitionProgress(progress: Float) { + wallpaperController.setUnfoldTransitionZoom(progress) + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/util/WallpaperController.kt b/packages/SystemUI/src/com/android/systemui/util/WallpaperController.kt new file mode 100644 index 0000000000000..db2aca873d0c2 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/util/WallpaperController.kt @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +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 javax.inject.Inject +import kotlin.math.max + +private const val TAG = "WallpaperController" + +@SysUISingleton +class WallpaperController @Inject constructor(private val wallpaperManager: WallpaperManager) { + + 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() + ?: true + + fun setNotificationShadeZoom(zoomOut: Float) { + notificationShadeZoomOut = zoomOut + updateZoom() + } + + fun setUnfoldTransitionZoom(zoomOut: Float) { + if (shouldUseDefaultUnfoldTransition) { + unfoldTransitionZoomOut = zoomOut + updateZoom() + } + } + + private fun updateZoom() { + setWallpaperZoom(max(notificationShadeZoomOut, unfoldTransitionZoomOut)) + } + + private fun setWallpaperZoom(zoomOut: Float) { + try { + rootView?.let { root -> + if (root.isAttachedToWindow && root.windowToken != null) { + wallpaperManager.setWallpaperZoomOut(root.windowToken, zoomOut) + } else { + Log.i(TAG, "Won't set zoom. Window not attached $root") + } + } + } catch (e: IllegalArgumentException) { + Log.w(TAG, "Can't set zoom. Window is gone: ${rootView?.windowToken}", e) + } + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt index 465370b59553d..e5ae65f2dd172 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt @@ -16,7 +16,6 @@ package com.android.systemui.statusbar -import android.app.WallpaperManager import android.os.IBinder import android.testing.AndroidTestingRunner import android.testing.TestableLooper.RunWithLooper @@ -32,6 +31,7 @@ import com.android.systemui.statusbar.phone.BiometricUnlockController import com.android.systemui.statusbar.phone.DozeParameters import com.android.systemui.statusbar.phone.ScrimController import com.android.systemui.statusbar.policy.KeyguardStateController +import com.android.systemui.util.WallpaperController import com.android.systemui.util.mockito.eq import com.google.common.truth.Truth.assertThat import org.junit.Before @@ -47,10 +47,8 @@ import org.mockito.Mockito.any import org.mockito.Mockito.anyFloat import org.mockito.Mockito.anyString import org.mockito.Mockito.clearInvocations -import org.mockito.Mockito.doThrow import org.mockito.Mockito.never import org.mockito.Mockito.reset -import org.mockito.Mockito.times import org.mockito.Mockito.verify import org.mockito.junit.MockitoJUnit import java.util.function.Consumer @@ -65,7 +63,7 @@ class NotificationShadeDepthControllerTest : SysuiTestCase() { @Mock private lateinit var biometricUnlockController: BiometricUnlockController @Mock private lateinit var keyguardStateController: KeyguardStateController @Mock private lateinit var choreographer: Choreographer - @Mock private lateinit var wallpaperManager: WallpaperManager + @Mock private lateinit var wallpaperController: WallpaperController @Mock private lateinit var notificationShadeWindowController: NotificationShadeWindowController @Mock private lateinit var dumpManager: DumpManager @Mock private lateinit var root: View @@ -101,7 +99,7 @@ class NotificationShadeDepthControllerTest : SysuiTestCase() { notificationShadeDepthController = NotificationShadeDepthController( statusBarStateController, blurUtils, biometricUnlockController, - keyguardStateController, choreographer, wallpaperManager, + keyguardStateController, choreographer, wallpaperController, notificationShadeWindowController, dozeParameters, dumpManager) notificationShadeDepthController.shadeAnimation = shadeAnimation notificationShadeDepthController.brightnessMirrorSpring = brightnessSpring @@ -209,7 +207,7 @@ class NotificationShadeDepthControllerTest : SysuiTestCase() { notificationShadeDepthController.qsPanelExpansion = 0.25f notificationShadeDepthController.onPanelExpansionChanged(1f, tracking = false) notificationShadeDepthController.updateBlurCallback.doFrame(0) - verify(wallpaperManager).setWallpaperZoomOut(any(), + verify(wallpaperController).setNotificationShadeZoom( eq(Interpolators.getNotificationScrimAlpha(0.25f, false /* notifications */))) } @@ -242,14 +240,14 @@ class NotificationShadeDepthControllerTest : SysuiTestCase() { notificationShadeDepthController.transitionToFullShadeProgress = 1f notificationShadeDepthController.updateBlurCallback.doFrame(0) verify(blurUtils).applyBlur(any(), eq(0), eq(false)) - verify(wallpaperManager).setWallpaperZoomOut(any(), eq(1f)) + verify(wallpaperController).setNotificationShadeZoom(eq(1f)) } @Test fun updateBlurCallback_setsBlurAndZoom() { notificationShadeDepthController.addListener(listener) notificationShadeDepthController.updateBlurCallback.doFrame(0) - verify(wallpaperManager).setWallpaperZoomOut(any(), anyFloat()) + verify(wallpaperController).setNotificationShadeZoom(anyFloat()) verify(listener).onWallpaperZoomOutChanged(anyFloat()) verify(blurUtils).applyBlur(any(), anyInt(), eq(false)) } @@ -278,21 +276,6 @@ class NotificationShadeDepthControllerTest : SysuiTestCase() { verify(blurUtils).applyBlur(any(), eq(0), eq(false)) } - @Test - fun updateBlurCallback_invalidWindow() { - `when`(root.isAttachedToWindow).thenReturn(false) - notificationShadeDepthController.updateBlurCallback.doFrame(0) - verify(wallpaperManager, times(0)).setWallpaperZoomOut(any(), anyFloat()) - } - - @Test - fun updateBlurCallback_exception() { - doThrow(IllegalArgumentException("test exception")).`when`(wallpaperManager) - .setWallpaperZoomOut(any(), anyFloat()) - notificationShadeDepthController.updateBlurCallback.doFrame(0) - verify(wallpaperManager).setWallpaperZoomOut(any(), anyFloat()) - } - @Test fun ignoreShadeBlurUntilHidden_schedulesFrame() { notificationShadeDepthController.blursDisabledForAppLaunch = true @@ -322,7 +305,7 @@ class NotificationShadeDepthControllerTest : SysuiTestCase() { notificationShadeDepthController.updateBlurCallback.doFrame(0) verify(notificationShadeWindowController).setBackgroundBlurRadius(eq(0)) - verify(wallpaperManager).setWallpaperZoomOut(any(), eq(1f)) + verify(wallpaperController).setNotificationShadeZoom(eq(1f)) verify(blurUtils).applyBlur(eq(viewRootImpl), eq(0), eq(false)) } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java index 751bc815bdd68..88a3827d05827 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java @@ -140,7 +140,9 @@ import com.android.systemui.statusbar.policy.UserInfoControllerImpl; import com.android.systemui.statusbar.policy.UserSwitcherController; import com.android.systemui.tuner.TunerService; import com.android.systemui.unfold.UnfoldLightRevealOverlayAnimation; +import com.android.systemui.unfold.UnfoldTransitionWallpaperController; import com.android.systemui.unfold.config.UnfoldTransitionConfig; +import com.android.systemui.util.WallpaperController; import com.android.systemui.util.concurrency.FakeExecutor; import com.android.systemui.util.concurrency.MessageRouterImpl; import com.android.systemui.util.time.FakeSystemClock; @@ -256,6 +258,8 @@ public class StatusBarTest extends SysuiTestCase { @Mock private UnfoldTransitionConfig mUnfoldTransitionConfig; @Mock private Lazy mUnfoldLightRevealOverlayAnimationLazy; @Mock private Lazy mMoveFromCenterAnimationLazy; + @Mock private Lazy mUnfoldWallpaperController; + @Mock private WallpaperController mWallpaperController; @Mock private OngoingCallController mOngoingCallController; @Mock private SystemStatusAnimationScheduler mAnimationScheduler; @Mock private StatusBarLocationPublisher mLocationPublisher; @@ -431,7 +435,9 @@ public class StatusBarTest extends SysuiTestCase { mBrightnessSliderFactory, mUnfoldTransitionConfig, mUnfoldLightRevealOverlayAnimationLazy, + mUnfoldWallpaperController, mMoveFromCenterAnimationLazy, + mWallpaperController, mOngoingCallController, mAnimationScheduler, mLocationPublisher, diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/WallpaperControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/util/WallpaperControllerTest.kt new file mode 100644 index 0000000000000..3cb19e3460dd1 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/util/WallpaperControllerTest.kt @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.util + +import android.app.WallpaperInfo +import android.app.WallpaperManager +import android.os.IBinder +import android.testing.AndroidTestingRunner +import android.testing.TestableLooper.RunWithLooper +import android.view.View +import android.view.ViewRootImpl +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.util.mockito.eq +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.Mockito.`when` +import org.mockito.Mockito.any +import org.mockito.Mockito.anyFloat +import org.mockito.Mockito.clearInvocations +import org.mockito.Mockito.doThrow +import org.mockito.Mockito.times +import org.mockito.Mockito.verify +import org.mockito.Mockito.mock +import org.mockito.Mockito.never +import org.mockito.Mockito.`when` as whenever +import org.mockito.junit.MockitoJUnit + +@RunWith(AndroidTestingRunner::class) +@RunWithLooper +@SmallTest +class WallpaperControllerTest : SysuiTestCase() { + + @Mock + private lateinit var wallpaperManager: WallpaperManager + @Mock + private lateinit var root: View + @Mock + private lateinit var viewRootImpl: ViewRootImpl + @Mock + private lateinit var windowToken: IBinder + + @JvmField + @Rule + val mockitoRule = MockitoJUnit.rule() + + private lateinit var wallaperController: WallpaperController + + @Before + fun setup() { + `when`(root.viewRootImpl).thenReturn(viewRootImpl) + `when`(root.windowToken).thenReturn(windowToken) + `when`(root.isAttachedToWindow).thenReturn(true) + + wallaperController = WallpaperController(wallpaperManager) + + wallaperController.rootView = root + } + + @Test + fun setNotificationShadeZoom_updatesWallpaperManagerZoom() { + wallaperController.setNotificationShadeZoom(0.5f) + + verify(wallpaperManager).setWallpaperZoomOut(any(), eq(0.5f)) + } + + @Test + fun setUnfoldTransitionZoom_updatesWallpaperManagerZoom() { + wallaperController.setUnfoldTransitionZoom(0.5f) + + verify(wallpaperManager).setWallpaperZoomOut(any(), eq(0.5f)) + } + + @Test + fun setUnfoldTransitionZoom_defaultUnfoldTransitionIsDisabled_doesNotUpdateWallpaperZoom() { + wallaperController.onWallpaperInfoUpdated(createWallpaperInfo( + useDefaultUnfoldTransition = false + )) + + wallaperController.setUnfoldTransitionZoom(0.5f) + + verify(wallpaperManager, never()).setWallpaperZoomOut(any(), anyFloat()) + } + + @Test + fun setUnfoldTransitionZoomAndNotificationShadeZoom_updatesWithMaximumZoom() { + wallaperController.setUnfoldTransitionZoom(0.7f) + clearInvocations(wallpaperManager) + + wallaperController.setNotificationShadeZoom(0.5f) + + verify(wallpaperManager).setWallpaperZoomOut(any(), eq(0.7f)) + } + + @Test + fun setNotificationShadeZoomAndThenUnfoldTransition_updatesWithMaximumZoom() { + wallaperController.setNotificationShadeZoom(0.7f) + clearInvocations(wallpaperManager) + + wallaperController.setUnfoldTransitionZoom(0.5f) + + verify(wallpaperManager).setWallpaperZoomOut(any(), eq(0.7f)) + } + + @Test + fun setNotificationZoom_invalidWindow_doesNotSetZoom() { + `when`(root.isAttachedToWindow).thenReturn(false) + + verify(wallpaperManager, times(0)).setWallpaperZoomOut(any(), anyFloat()) + } + + @Test + fun setNotificationZoom_exceptionWhenUpdatingZoom_doesNotFail() { + doThrow(IllegalArgumentException("test exception")).`when`(wallpaperManager) + .setWallpaperZoomOut(any(), anyFloat()) + + wallaperController.setNotificationShadeZoom(0.5f) + + verify(wallpaperManager).setWallpaperZoomOut(any(), anyFloat()) + } + + private fun createWallpaperInfo(useDefaultUnfoldTransition: Boolean = true): WallpaperInfo { + val info = mock(WallpaperInfo::class.java) + whenever(info.shouldUseDefaultUnfoldTransition()).thenReturn(useDefaultUnfoldTransition) + return info + } +}