From 61b224cc8d9ef58f2d426d537081294a6603f102 Mon Sep 17 00:00:00 2001 From: Matt Pietal Date: Wed, 3 Nov 2021 17:20:07 -0400 Subject: [PATCH] [DO NOT MERGE] Unfold refactor 1. Use Optional instead of Lazy to make it easier to test if an object is available or not, which helps remove injection of UnfoldConfiguration everywhere 2. Remove unnecessary items from StatusBar constructor. They do not support StatusBar or otherwise part of the dependency graph. Rather they only need to be initialized. 3. Begin work on unfold animation for keyguard Bug: 201410717 Test: atest SystemUiTests Change-Id: I40e280c904e38d877df424b31a9d1af90c39145e --- .../keyguard/KeyguardUnfoldTransition.kt | 49 ++++++++++++ .../systemui/dagger/SysUIComponent.java | 21 ++++- .../systemui/dagger/SystemUIModule.java | 2 + .../keyguard/KeyguardViewMediator.java | 15 ++-- .../keyguard/dagger/KeyguardModule.java | 10 +-- .../NotificationPanelViewController.java | 13 +++- .../phone/PhoneStatusBarViewController.kt | 24 +++--- .../systemui/statusbar/phone/StatusBar.java | 24 +----- ...tusBarMoveFromCenterAnimationController.kt | 10 +-- .../phone/dagger/StatusBarPhoneModule.java | 14 ---- .../systemui/unfold/SysUIUnfoldModule.kt | 76 +++++++++++++++++++ .../UnfoldLightRevealOverlayAnimation.kt | 3 +- ...sProvider.kt => UnfoldProgressProvider.kt} | 2 +- .../systemui/unfold/UnfoldTransitionModule.kt | 60 +++++++++------ .../UnfoldTransitionWallpaperController.kt | 3 +- .../systemui/util/kotlin/nullability.kt | 7 ++ .../keyguard/KeyguardViewMediatorTest.java | 22 ++++-- .../NotificationPanelViewControllerTest.java | 5 +- .../phone/PhoneStatusBarViewControllerTest.kt | 13 ++-- .../statusbar/phone/StatusBarTest.java | 12 --- 20 files changed, 259 insertions(+), 126 deletions(-) create mode 100644 packages/SystemUI/src/com/android/keyguard/KeyguardUnfoldTransition.kt create mode 100644 packages/SystemUI/src/com/android/systemui/unfold/SysUIUnfoldModule.kt rename packages/SystemUI/src/com/android/systemui/unfold/{ShellUnfoldProgressProvider.kt => UnfoldProgressProvider.kt} (98%) diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUnfoldTransition.kt b/packages/SystemUI/src/com/android/keyguard/KeyguardUnfoldTransition.kt new file mode 100644 index 0000000000000..30aec66db8e6d --- /dev/null +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUnfoldTransition.kt @@ -0,0 +1,49 @@ +/* + * 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.keyguard + +import android.view.ViewGroup +import com.android.systemui.unfold.SysUIUnfoldScope +import com.android.systemui.unfold.UnfoldTransitionProgressProvider +import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener +import javax.inject.Inject + +/** + * Translates items away/towards the hinge when the device is opened/closed. + */ +@SysUIUnfoldScope +class KeyguardUnfoldTransition @Inject constructor( + val unfoldProgressProvider: UnfoldTransitionProgressProvider +) { + init { + unfoldProgressProvider.addCallback( + object : TransitionProgressListener { + override fun onTransitionStarted() { + } + + override fun onTransitionProgress(progress: Float) { + } + + override fun onTransitionFinished() { + } + } + ) + } + + fun setup(parent: ViewGroup) { + } +} diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java index 8993af2174c47..a9fb743bff8d0 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java @@ -25,6 +25,8 @@ import com.android.systemui.dump.DumpManager; import com.android.systemui.keyguard.KeyguardSliceProvider; import com.android.systemui.people.PeopleProvider; import com.android.systemui.statusbar.policy.ConfigurationController; +import com.android.systemui.unfold.SysUIUnfoldComponent; +import com.android.systemui.unfold.util.NaturalRotationUnfoldProgressProvider; import com.android.wm.shell.ShellCommandHandler; import com.android.wm.shell.TaskViewFactory; import com.android.wm.shell.apppairs.AppPairs; @@ -112,7 +114,14 @@ public interface SysUIComponent { * Initializes all the SysUI components. */ default void init() { - // Do nothing + // Initialize components that have no direct tie to the dagger dependency graph, + // but are critical to this component's operation + // TODO(b/205034537): I think this is a good idea? + getSysUIUnfoldComponent().ifPresent(c -> { + c.getUnfoldLightRevealOverlayAnimation().init(); + c.getUnfoldTransitionWallpaperController().init(); + }); + getNaturalRotationUnfoldProgressProvider().ifPresent(o -> o.init()); } /** @@ -149,6 +158,16 @@ public interface SysUIComponent { @SysUISingleton InitController getInitController(); + /** + * For devices with a hinge: access objects within this component + */ + Optional getSysUIUnfoldComponent(); + + /** + * For devices with a hinge: the rotation animation + */ + Optional getNaturalRotationUnfoldProgressProvider(); + /** * Member injection into the supplied argument. */ diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java index d270064b69197..64752f3e0ff39 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java @@ -72,6 +72,7 @@ import com.android.systemui.statusbar.policy.ZenModeController; import com.android.systemui.statusbar.policy.dagger.SmartRepliesInflationModule; import com.android.systemui.statusbar.policy.dagger.StatusBarPolicyModule; import com.android.systemui.tuner.dagger.TunerModule; +import com.android.systemui.unfold.SysUIUnfoldModule; import com.android.systemui.user.UserModule; import com.android.systemui.util.concurrency.SysUIConcurrencyModule; import com.android.systemui.util.dagger.UtilModule; @@ -113,6 +114,7 @@ import dagger.Provides; SmartRepliesInflationModule.class, StatusBarPolicyModule.class, SysUIConcurrencyModule.class, + SysUIUnfoldModule.class, TunerModule.class, UserModule.class, UtilModule.class, diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index f438181bc367e..7f9eae8bd55f9 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -122,13 +122,14 @@ import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager; import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.statusbar.policy.UserSwitcherController; +import com.android.systemui.unfold.SysUIUnfoldComponent; import com.android.systemui.unfold.UnfoldLightRevealOverlayAnimation; -import com.android.systemui.unfold.config.UnfoldTransitionConfig; import com.android.systemui.util.DeviceConfigProxy; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; +import java.util.Optional; import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicInteger; @@ -814,8 +815,7 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable, private DeviceConfigProxy mDeviceConfig; private DozeParameters mDozeParameters; - private final UnfoldTransitionConfig mUnfoldTransitionConfig; - private final Lazy mUnfoldLightRevealAnimation; + private final Optional mUnfoldLightRevealAnimation; private final AtomicInteger mPendingDrawnTasks = new AtomicInteger(); private final KeyguardStateController mKeyguardStateController; @@ -840,8 +840,7 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable, NavigationModeController navigationModeController, KeyguardDisplayManager keyguardDisplayManager, DozeParameters dozeParameters, - UnfoldTransitionConfig unfoldTransitionConfig, - Lazy unfoldLightRevealOverlayAnimation, + Optional unfoldComponent, SysuiStatusBarStateController statusBarStateController, KeyguardStateController keyguardStateController, Lazy keyguardUnlockAnimationControllerLazy, @@ -875,8 +874,8 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable, mInGestureNavigationMode = QuickStepContract.isGesturalMode(mode); })); mDozeParameters = dozeParameters; - mUnfoldTransitionConfig = unfoldTransitionConfig; - mUnfoldLightRevealAnimation = unfoldLightRevealOverlayAnimation; + mUnfoldLightRevealAnimation = unfoldComponent.map( + c -> c.getUnfoldLightRevealOverlayAnimation()); mStatusBarStateController = statusBarStateController; statusBarStateController.addCallback(this); @@ -2560,7 +2559,7 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable, synchronized (KeyguardViewMediator.this) { if (DEBUG) Log.d(TAG, "handleNotifyScreenTurningOn"); - if (mUnfoldTransitionConfig.isEnabled()) { + if (mUnfoldLightRevealAnimation.isPresent()) { mPendingDrawnTasks.set(2); // unfold overlay and keyguard drawn mUnfoldLightRevealAnimation.get() diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java b/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java index 9b0d69b38374e..cae9feeb62eb9 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java @@ -49,11 +49,11 @@ import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController; import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.statusbar.policy.UserSwitcherController; -import com.android.systemui.unfold.UnfoldLightRevealOverlayAnimation; -import com.android.systemui.unfold.config.UnfoldTransitionConfig; +import com.android.systemui.unfold.SysUIUnfoldComponent; import com.android.systemui.util.DeviceConfigProxy; import com.android.systemui.util.sensors.AsyncSensorManager; +import java.util.Optional; import java.util.concurrent.Executor; import dagger.Lazy; @@ -92,8 +92,7 @@ public class KeyguardModule { NavigationModeController navigationModeController, KeyguardDisplayManager keyguardDisplayManager, DozeParameters dozeParameters, - UnfoldTransitionConfig unfoldTransitionConfig, - Lazy unfoldLightRevealOverlayAnimation, + Optional unfoldComponent, SysuiStatusBarStateController statusBarStateController, KeyguardStateController keyguardStateController, Lazy keyguardUnlockAnimationController, @@ -116,8 +115,7 @@ public class KeyguardModule { navigationModeController, keyguardDisplayManager, dozeParameters, - unfoldTransitionConfig, - unfoldLightRevealOverlayAnimation, + unfoldComponent, statusBarStateController, keyguardStateController, keyguardUnlockAnimationController, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java index f6005a834661b..df0f872d979c8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java @@ -99,6 +99,7 @@ import com.android.internal.policy.SystemBarUtils; import com.android.internal.util.LatencyTracker; import com.android.keyguard.KeyguardStatusView; import com.android.keyguard.KeyguardStatusViewController; +import com.android.keyguard.KeyguardUnfoldTransition; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.LockIconViewController; import com.android.keyguard.dagger.KeyguardQsUserSwitchComponent; @@ -178,6 +179,7 @@ import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.statusbar.policy.KeyguardUserSwitcherController; import com.android.systemui.statusbar.policy.KeyguardUserSwitcherView; import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener; +import com.android.systemui.unfold.SysUIUnfoldComponent; import com.android.systemui.util.Utils; import com.android.systemui.util.settings.SecureSettings; import com.android.systemui.wallet.controller.QuickAccessWalletController; @@ -188,6 +190,7 @@ import java.io.PrintWriter; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Optional; import java.util.concurrent.Executor; import java.util.function.Consumer; @@ -605,6 +608,8 @@ public class NotificationPanelViewController extends PanelViewController { private boolean mStatusViewCentered = true; + private Optional mKeyguardUnfoldTransition; + private View.AccessibilityDelegate mAccessibilityDelegate = new View.AccessibilityDelegate() { @Override public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) { @@ -694,6 +699,7 @@ public class NotificationPanelViewController extends PanelViewController { LockscreenGestureLogger lockscreenGestureLogger, PanelExpansionStateManager panelExpansionStateManager, NotificationRemoteInputManager remoteInputManager, + Optional unfoldComponent, ControlsComponent controlsComponent, FeatureFlags featureFlags) { super(view, @@ -809,6 +815,7 @@ public class NotificationPanelViewController extends PanelViewController { } mMaxKeyguardNotifications = resources.getInteger(R.integer.keyguard_max_notification_count); + mKeyguardUnfoldTransition = unfoldComponent.map(c -> c.getKeyguardUnfoldTransition()); updateUserSwitcherFlags(); onFinishInflate(); @@ -839,11 +846,12 @@ public class NotificationPanelViewController extends PanelViewController { .getKeyguardStatusBarViewController(); mKeyguardStatusBarViewController.init(); + mNotificationContainerParent = mView.findViewById(R.id.notification_container_parent); updateViewControllers( mView.findViewById(R.id.keyguard_status_view), userAvatarContainer, keyguardUserSwitcherView); - mNotificationContainerParent = mView.findViewById(R.id.notification_container_parent); + NotificationStackScrollLayout stackScrollLayout = mView.findViewById( R.id.notification_stack_scroller); mNotificationStackScrollLayoutController.attach(stackScrollLayout); @@ -894,6 +902,7 @@ public class NotificationPanelViewController extends PanelViewController { } mTapAgainViewController.init(); + mKeyguardUnfoldTransition.ifPresent(u -> u.setup(mNotificationContainerParent)); } @Override @@ -1137,6 +1146,8 @@ public class NotificationPanelViewController extends PanelViewController { mBarState); } setKeyguardBottomAreaVisibility(mBarState, false); + + mKeyguardUnfoldTransition.ifPresent(u -> u.setup(mNotificationContainerParent)); } private void attachSplitShadeMediaPlayerContainer(FrameLayout container) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt index de21e73f81009..256b069a0080e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt @@ -21,21 +21,21 @@ import android.view.ViewGroup import android.view.ViewTreeObserver import com.android.systemui.R import com.android.systemui.shared.animation.UnfoldMoveFromCenterAnimator -import com.android.systemui.statusbar.CommandQueue +import com.android.systemui.unfold.SysUIUnfoldComponent import com.android.systemui.unfold.UNFOLD_STATUS_BAR -import com.android.systemui.unfold.config.UnfoldTransitionConfig import com.android.systemui.unfold.util.ScopedUnfoldTransitionProgressProvider import com.android.systemui.util.ViewController +import com.android.systemui.util.kotlin.getOrNull +import java.util.Optional import javax.inject.Inject import javax.inject.Named -import dagger.Lazy /** Controller for [PhoneStatusBarView]. */ class PhoneStatusBarViewController private constructor( view: PhoneStatusBarView, @Named(UNFOLD_STATUS_BAR) private val progressProvider: ScopedUnfoldTransitionProgressProvider?, private val moveFromCenterAnimationController: StatusBarMoveFromCenterAnimationController?, - touchEventHandler: PhoneStatusBarView.TouchEventHandler, + touchEventHandler: PhoneStatusBarView.TouchEventHandler ) : ViewController(view) { override fun onViewAttached() { @@ -115,21 +115,21 @@ class PhoneStatusBarViewController private constructor( } class Factory @Inject constructor( + private val unfoldComponent: Optional, @Named(UNFOLD_STATUS_BAR) - private val progressProvider: Lazy, - private val moveFromCenterController: Lazy, - private val unfoldConfig: UnfoldTransitionConfig, + private val progressProvider: Optional ) { fun create( view: PhoneStatusBarView, touchEventHandler: PhoneStatusBarView.TouchEventHandler - ): PhoneStatusBarViewController { - return PhoneStatusBarViewController( + ) = + PhoneStatusBarViewController( view, - if (unfoldConfig.isEnabled) progressProvider.get() else null, - if (unfoldConfig.isEnabled) moveFromCenterController.get() else null, + progressProvider.getOrNull(), + unfoldComponent.map { + it.getStatusBarMoveFromCenterAnimationController() + }.getOrNull(), touchEventHandler ) - } } } 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 c25304e1efb33..c95736699a2a9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -230,10 +230,6 @@ import com.android.systemui.statusbar.policy.KeyguardStateController; 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.unfold.util.NaturalRotationUnfoldProgressProvider; import com.android.systemui.util.DumpUtilsKt; import com.android.systemui.util.WallpaperController; import com.android.systemui.util.concurrency.DelayableExecutor; @@ -540,10 +536,7 @@ public class StatusBar extends SystemUI implements protected final NotificationInterruptStateProvider mNotificationInterruptStateProvider; private final BrightnessSliderController.Factory mBrightnessSliderFactory; private final FeatureFlags mFeatureFlags; - private final UnfoldTransitionConfig mUnfoldTransitionConfig; - private final Lazy mUnfoldLightRevealOverlayAnimation; - private final Lazy mNaturalUnfoldProgressProvider; - private final Lazy mUnfoldWallpaperController; + private final WallpaperController mWallpaperController; private final KeyguardUnlockAnimationController mKeyguardUnlockAnimationController; private final MessageRouter mMessageRouter; @@ -777,10 +770,6 @@ public class StatusBar extends SystemUI implements StatusBarTouchableRegionManager statusBarTouchableRegionManager, NotificationIconAreaController notificationIconAreaController, BrightnessSliderController.Factory brightnessSliderFactory, - UnfoldTransitionConfig unfoldTransitionConfig, - Lazy unfoldLightRevealOverlayAnimation, - Lazy unfoldTransitionWallpaperController, - Lazy naturalRotationUnfoldProgressProvider, WallpaperController wallpaperController, OngoingCallController ongoingCallController, SystemStatusAnimationScheduler animationScheduler, @@ -876,10 +865,6 @@ public class StatusBar extends SystemUI implements mDemoModeController = demoModeController; mNotificationIconAreaController = notificationIconAreaController; mBrightnessSliderFactory = brightnessSliderFactory; - mUnfoldTransitionConfig = unfoldTransitionConfig; - mUnfoldLightRevealOverlayAnimation = unfoldLightRevealOverlayAnimation; - mNaturalUnfoldProgressProvider = naturalRotationUnfoldProgressProvider; - mUnfoldWallpaperController = unfoldTransitionWallpaperController; mWallpaperController = wallpaperController; mOngoingCallController = ongoingCallController; mAnimationScheduler = animationScheduler; @@ -1067,12 +1052,6 @@ public class StatusBar extends SystemUI implements mFalsingManager.addFalsingBeliefListener(mFalsingBeliefListener); - if (mUnfoldTransitionConfig.isEnabled()) { - mUnfoldLightRevealOverlayAnimation.get().init(); - mUnfoldWallpaperController.get().init(); - mNaturalUnfoldProgressProvider.get().init(); - } - mPluginManager.addPluginListener( new PluginListener() { private final ArraySet mOverlays = new ArraySet<>(); @@ -4514,5 +4493,4 @@ public class StatusBar extends SystemUI implements return mStartingSurfaceOptional.get().getBackgroundColor(task); } }; - } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarMoveFromCenterAnimationController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarMoveFromCenterAnimationController.kt index 8ef186c316f91..805ddf5fc1805 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarMoveFromCenterAnimationController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarMoveFromCenterAnimationController.kt @@ -17,19 +17,17 @@ package com.android.systemui.statusbar.phone import android.view.View import android.view.WindowManager -import com.android.systemui.dagger.SysUISingleton import com.android.systemui.shared.animation.UnfoldMoveFromCenterAnimator import com.android.systemui.shared.animation.UnfoldMoveFromCenterAnimator.ViewCenterProvider -import com.android.systemui.unfold.UNFOLD_STATUS_BAR +import com.android.systemui.unfold.SysUIUnfoldScope import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener import com.android.systemui.unfold.util.ScopedUnfoldTransitionProgressProvider import javax.inject.Inject -import javax.inject.Named -@SysUISingleton +@SysUIUnfoldScope class StatusBarMoveFromCenterAnimationController @Inject constructor( - @Named(UNFOLD_STATUS_BAR) private val progressProvider: ScopedUnfoldTransitionProgressProvider, - private val windowManager: WindowManager, + private val progressProvider: ScopedUnfoldTransitionProgressProvider, + private val windowManager: WindowManager ) { private val transitionListener = TransitionListener() 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 4f4342606194c..b677e0b93afe6 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 @@ -95,7 +95,6 @@ import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.statusbar.phone.StatusBarIconController; import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; import com.android.systemui.statusbar.phone.StatusBarLocationPublisher; -import com.android.systemui.statusbar.phone.StatusBarMoveFromCenterAnimationController; import com.android.systemui.statusbar.phone.StatusBarNotificationActivityStarter; import com.android.systemui.statusbar.phone.StatusBarTouchableRegionManager; import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController; @@ -109,10 +108,6 @@ import com.android.systemui.statusbar.policy.KeyguardStateController; 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.unfold.util.NaturalRotationUnfoldProgressProvider; import com.android.systemui.util.WallpaperController; import com.android.systemui.util.concurrency.DelayableExecutor; import com.android.systemui.util.concurrency.MessageRouter; @@ -222,11 +217,6 @@ public interface StatusBarPhoneModule { StatusBarTouchableRegionManager statusBarTouchableRegionManager, NotificationIconAreaController notificationIconAreaController, BrightnessSliderController.Factory brightnessSliderFactory, - UnfoldTransitionConfig unfoldTransitionConfig, - Lazy unfoldLightRevealOverlayAnimation, - Lazy naturalRotationUnfoldProgressProvider, - Lazy unfoldTransitionWallpaperController, - Lazy statusBarMoveFromCenterAnimation, WallpaperController wallpaperController, OngoingCallController ongoingCallController, SystemStatusAnimationScheduler animationScheduler, @@ -324,10 +314,6 @@ public interface StatusBarPhoneModule { statusBarTouchableRegionManager, notificationIconAreaController, brightnessSliderFactory, - unfoldTransitionConfig, - unfoldLightRevealOverlayAnimation, - unfoldTransitionWallpaperController, - naturalRotationUnfoldProgressProvider, wallpaperController, ongoingCallController, animationScheduler, diff --git a/packages/SystemUI/src/com/android/systemui/unfold/SysUIUnfoldModule.kt b/packages/SystemUI/src/com/android/systemui/unfold/SysUIUnfoldModule.kt new file mode 100644 index 0000000000000..cc2c2083cbab2 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/unfold/SysUIUnfoldModule.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.unfold + +import com.android.keyguard.KeyguardUnfoldTransition +import com.android.systemui.unfold.util.ScopedUnfoldTransitionProgressProvider +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.statusbar.phone.StatusBarMoveFromCenterAnimationController +import dagger.BindsInstance +import dagger.Module +import dagger.Provides +import dagger.Subcomponent +import java.util.Optional +import javax.inject.Named +import javax.inject.Scope + +@Scope +@MustBeDocumented +@Retention(AnnotationRetention.RUNTIME) +annotation class SysUIUnfoldScope + +/** + * Creates an injectable [SysUIUnfoldComponent] that provides objects that have been scoped with + * [@SysUIUnfoldScope]. Since [SysUIUnfoldComponent] depends upon: + * * [Optional] + * * [Optional] + * no objects will get constructed if these parameters are empty. + */ +@Module(subcomponents = [SysUIUnfoldComponent::class]) +object SysUIUnfoldModule { + @Provides + @SysUISingleton + fun provideSysUIUnfoldComponent( + provider: Optional, + @Named(UNFOLD_STATUS_BAR) scopedProvider: Optional, + factory: SysUIUnfoldComponent.Factory + ) = + provider.flatMap { + p -> scopedProvider.map { sp -> factory.create(p, sp) } + } +} + +@SysUIUnfoldScope +@Subcomponent +interface SysUIUnfoldComponent { + + @Subcomponent.Factory + interface Factory { + fun create( + @BindsInstance provider: UnfoldTransitionProgressProvider, + @BindsInstance scopedProvider: ScopedUnfoldTransitionProgressProvider + ): SysUIUnfoldComponent + } + + fun getKeyguardUnfoldTransition(): KeyguardUnfoldTransition + + fun getStatusBarMoveFromCenterAnimationController(): StatusBarMoveFromCenterAnimationController + + fun getUnfoldTransitionWallpaperController(): UnfoldTransitionWallpaperController + + fun getUnfoldLightRevealOverlayAnimation(): UnfoldLightRevealOverlayAnimation +} diff --git a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldLightRevealOverlayAnimation.kt b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldLightRevealOverlayAnimation.kt index f0760d4e2187b..51de132108bef 100644 --- a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldLightRevealOverlayAnimation.kt +++ b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldLightRevealOverlayAnimation.kt @@ -31,7 +31,6 @@ import android.view.SurfaceControlViewHost import android.view.SurfaceSession import android.view.WindowManager import android.view.WindowlessWindowManager -import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.dagger.qualifiers.UiBackground import com.android.systemui.statusbar.LightRevealEffect @@ -44,7 +43,7 @@ import java.util.concurrent.Executor import java.util.function.Consumer import javax.inject.Inject -@SysUISingleton +@SysUIUnfoldScope class UnfoldLightRevealOverlayAnimation @Inject constructor( private val context: Context, private val deviceStateManager: DeviceStateManager, diff --git a/packages/SystemUI/src/com/android/systemui/unfold/ShellUnfoldProgressProvider.kt b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldProgressProvider.kt similarity index 98% rename from packages/SystemUI/src/com/android/systemui/unfold/ShellUnfoldProgressProvider.kt rename to packages/SystemUI/src/com/android/systemui/unfold/UnfoldProgressProvider.kt index 4a884359d315c..bd04ad8385b2d 100644 --- a/packages/SystemUI/src/com/android/systemui/unfold/ShellUnfoldProgressProvider.kt +++ b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldProgressProvider.kt @@ -21,7 +21,7 @@ import com.android.wm.shell.unfold.ShellUnfoldProgressProvider import com.android.wm.shell.unfold.ShellUnfoldProgressProvider.UnfoldListener import java.util.concurrent.Executor -class ShellUnfoldProgressProvider( +class UnfoldProgressProvider( private val unfoldProgressProvider: UnfoldTransitionProgressProvider ) : ShellUnfoldProgressProvider { diff --git a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionModule.kt b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionModule.kt index 7e4ec67e6e182..cebc93182f1ee 100644 --- a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionModule.kt +++ b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionModule.kt @@ -43,21 +43,27 @@ class UnfoldTransitionModule { fun provideUnfoldTransitionProgressProvider( context: Context, config: UnfoldTransitionConfig, - screenStatusProvider: LifecycleScreenStatusProvider, + screenStatusProvider: Lazy, deviceStateManager: DeviceStateManager, sensorManager: SensorManager, @Main executor: Executor, @Main handler: Handler - ): UnfoldTransitionProgressProvider = - createUnfoldTransitionProgressProvider( - context, - config, - screenStatusProvider, - deviceStateManager, - sensorManager, - handler, - executor - ) + ) = + if (config.isEnabled) { + Optional.of( + createUnfoldTransitionProgressProvider( + context, + config, + screenStatusProvider.get(), + deviceStateManager, + sensorManager, + handler, + executor + ) + ) + } else { + Optional.empty() + } @Provides @Singleton @@ -69,33 +75,37 @@ class UnfoldTransitionModule { fun provideNaturalRotationProgressProvider( context: Context, windowManager: IWindowManager, - unfoldTransitionProgressProvider: UnfoldTransitionProgressProvider - ): NaturalRotationUnfoldProgressProvider = - NaturalRotationUnfoldProgressProvider( - context, - windowManager, - unfoldTransitionProgressProvider - ) + unfoldTransitionProgressProvider: Optional + ) = + unfoldTransitionProgressProvider.map { + provider -> NaturalRotationUnfoldProgressProvider( + context, + windowManager, + provider + ) + } @Provides @Named(UNFOLD_STATUS_BAR) @Singleton fun provideStatusBarScopedTransitionProvider( - source: NaturalRotationUnfoldProgressProvider - ): ScopedUnfoldTransitionProgressProvider = - ScopedUnfoldTransitionProgressProvider(source) + source: Optional + ) = + source.map { + provider -> ScopedUnfoldTransitionProgressProvider(provider) + } @Provides @Singleton fun provideShellProgressProvider( config: UnfoldTransitionConfig, - provider: Lazy + provider: Optional ): Optional = - if (config.isEnabled) { - Optional.ofNullable(ShellUnfoldProgressProvider(provider.get())) + if (config.isEnabled && provider.isPresent()) { + Optional.of(UnfoldProgressProvider(provider.get())) } else { Optional.empty() } } -const val UNFOLD_STATUS_BAR = "unfold_status_bar" \ No newline at end of file +const val UNFOLD_STATUS_BAR = "unfold_status_bar" diff --git a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionWallpaperController.kt b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionWallpaperController.kt index 4f45aafce416d..a184315ab75cf 100644 --- a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionWallpaperController.kt +++ b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionWallpaperController.kt @@ -16,12 +16,11 @@ 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 +@SysUIUnfoldScope class UnfoldTransitionWallpaperController @Inject constructor( private val unfoldTransitionProgressProvider: UnfoldTransitionProgressProvider, private val wallpaperController: WallpaperController diff --git a/packages/SystemUI/src/com/android/systemui/util/kotlin/nullability.kt b/packages/SystemUI/src/com/android/systemui/util/kotlin/nullability.kt index 92c73a4125771..f3b7e0d24a6ea 100644 --- a/packages/SystemUI/src/com/android/systemui/util/kotlin/nullability.kt +++ b/packages/SystemUI/src/com/android/systemui/util/kotlin/nullability.kt @@ -16,7 +16,14 @@ package com.android.systemui.util.kotlin +import java.util.Optional + /** * If [value] is not null, then returns block(value). Otherwise returns null. */ inline fun transform(value: T?, block: (T) -> R): R? = value?.let(block) + +/** + * Assists type-checking to unpack a Java Optional into T? + */ +inline fun Optional.getOrNull(): T? = orElse(null) diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java index 1bb660e4ccede..6d8645e44fb0e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java @@ -57,17 +57,21 @@ import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController; import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.statusbar.policy.UserSwitcherController; +import com.android.systemui.unfold.SysUIUnfoldComponent; import com.android.systemui.unfold.UnfoldLightRevealOverlayAnimation; -import com.android.systemui.unfold.config.UnfoldTransitionConfig; import com.android.systemui.util.DeviceConfigProxy; import com.android.systemui.util.DeviceConfigProxyFake; import com.android.systemui.util.concurrency.FakeExecutor; import com.android.systemui.util.time.FakeSystemClock; +import java.util.Optional; +import java.util.function.Function; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; +import org.mockito.ArgumentMatchers; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @@ -90,7 +94,8 @@ public class KeyguardViewMediatorTest extends SysuiTestCase { private @Mock NavigationModeController mNavigationModeController; private @Mock KeyguardDisplayManager mKeyguardDisplayManager; private @Mock DozeParameters mDozeParameters; - private @Mock UnfoldTransitionConfig mUnfoldTransitionConfig; + private @Mock Optional mSysUIUnfoldComponent; + private @Mock Optional mUnfoldAnimationOptional; private @Mock UnfoldLightRevealOverlayAnimation mUnfoldAnimation; private @Mock SysuiStatusBarStateController mStatusBarStateController; private @Mock KeyguardStateController mKeyguardStateController; @@ -110,6 +115,12 @@ public class KeyguardViewMediatorTest extends SysuiTestCase { when(mLockPatternUtils.getDevicePolicyManager()).thenReturn(mDevicePolicyManager); when(mPowerManager.newWakeLock(anyInt(), any())).thenReturn(mock(WakeLock.class)); + when(mSysUIUnfoldComponent.map( + ArgumentMatchers.> + any())) + .thenReturn(mUnfoldAnimationOptional); + when(mUnfoldAnimationOptional.isPresent()).thenReturn(true); + when(mUnfoldAnimationOptional.get()).thenReturn(mUnfoldAnimation); mViewMediator = new KeyguardViewMediator( mContext, @@ -128,8 +139,7 @@ public class KeyguardViewMediatorTest extends SysuiTestCase { mNavigationModeController, mKeyguardDisplayManager, mDozeParameters, - mUnfoldTransitionConfig, - () -> mUnfoldAnimation, + mSysUIUnfoldComponent, mStatusBarStateController, mKeyguardStateController, () -> mKeyguardUnlockAnimationController, @@ -161,8 +171,6 @@ public class KeyguardViewMediatorTest extends SysuiTestCase { @TestableLooper.RunWithLooper(setAsMainLooper = true) public void testUnfoldTransitionEnabledDrawnTasksReady_onScreenTurningOn_callsDrawnCallback() throws RemoteException { - when(mUnfoldTransitionConfig.isEnabled()).thenReturn(true); - mViewMediator.onScreenTurningOn(mKeyguardDrawnCallback); TestableLooper.get(this).processAllMessages(); onUnfoldOverlayReady(); @@ -175,7 +183,7 @@ public class KeyguardViewMediatorTest extends SysuiTestCase { @TestableLooper.RunWithLooper(setAsMainLooper = true) public void testUnfoldTransitionDisabledDrawnTasksReady_onScreenTurningOn_callsDrawnCallback() throws RemoteException { - when(mUnfoldTransitionConfig.isEnabled()).thenReturn(false); + when(mUnfoldAnimationOptional.isPresent()).thenReturn(false); mViewMediator.onScreenTurningOn(mKeyguardDrawnCallback); TestableLooper.get(this).processAllMessages(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java index 23378ab6e80a6..6e1f1487f2e79 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java @@ -125,6 +125,7 @@ import com.android.systemui.statusbar.notification.stack.NotificationStackScroll import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.KeyguardStateController; +import com.android.systemui.unfold.SysUIUnfoldComponent; import com.android.systemui.util.concurrency.FakeExecutor; import com.android.systemui.util.settings.SecureSettings; import com.android.systemui.util.time.FakeSystemClock; @@ -140,6 +141,7 @@ import org.mockito.MockitoAnnotations; import org.mockito.stubbing.Answer; import java.util.List; +import java.util.Optional; @SmallTest @RunWith(AndroidTestingRunner.class) @@ -306,7 +308,7 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { private NotificationsQSContainerController mNotificationsQSContainerController; @Mock private FeatureFlags mFeatureFlags; - + private Optional mSysUIUnfoldComponent; private SysuiStatusBarStateController mStatusBarStateController; private NotificationPanelViewController mNotificationPanelViewController; private View.AccessibilityDelegate mAccessibiltyDelegate; @@ -450,6 +452,7 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { mLockscreenGestureLogger, new PanelExpansionStateManager(), mNotificationRemoteInputManager, + mSysUIUnfoldComponent, mControlsComponent, mFeatureFlags); mNotificationPanelViewController.initDependencies( diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt index 310a8baadb786..eea8eb91675c6 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt @@ -26,6 +26,7 @@ import androidx.test.filters.SmallTest import androidx.test.platform.app.InstrumentationRegistry import com.android.systemui.R import com.android.systemui.SysuiTestCase +import com.android.systemui.unfold.SysUIUnfoldComponent import com.android.systemui.unfold.config.UnfoldTransitionConfig import com.android.systemui.unfold.util.ScopedUnfoldTransitionProgressProvider import com.android.systemui.util.mockito.any @@ -39,6 +40,7 @@ import org.mockito.Mockito.mock import org.mockito.Mockito.`when` import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations +import java.util.Optional @SmallTest class PhoneStatusBarViewControllerTest : SysuiTestCase() { @@ -51,10 +53,11 @@ class PhoneStatusBarViewControllerTest : SysuiTestCase() { private lateinit var panelView: ViewGroup @Mock private lateinit var scrimController: ScrimController - @Mock private lateinit var moveFromCenterAnimation: StatusBarMoveFromCenterAnimationController @Mock + private lateinit var sysuiUnfoldComponent: SysUIUnfoldComponent + @Mock private lateinit var progressProvider: ScopedUnfoldTransitionProgressProvider private lateinit var view: PhoneStatusBarView @@ -66,7 +69,8 @@ class PhoneStatusBarViewControllerTest : SysuiTestCase() { fun setUp() { MockitoAnnotations.initMocks(this) `when`(panelViewController.view).thenReturn(panelView) - + `when`(sysuiUnfoldComponent.getStatusBarMoveFromCenterAnimationController()) + .thenReturn(moveFromCenterAnimation) // create the view on main thread as it requires main looper InstrumentationRegistry.getInstrumentation().runOnMainSync { val parent = FrameLayout(mContext) // add parent to keep layout params @@ -112,9 +116,8 @@ class PhoneStatusBarViewControllerTest : SysuiTestCase() { private fun createController(view: PhoneStatusBarView): PhoneStatusBarViewController { return PhoneStatusBarViewController.Factory( - { progressProvider }, - { moveFromCenterAnimation }, - unfoldConfig + Optional.of(sysuiUnfoldComponent), + Optional.of(progressProvider) ).create(view, touchEventHandler) } 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 9202cecf63dbd..c9371c721d1e0 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 @@ -142,10 +142,6 @@ import com.android.systemui.statusbar.policy.KeyguardStateController; 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.unfold.util.NaturalRotationUnfoldProgressProvider; import com.android.systemui.util.WallpaperController; import com.android.systemui.util.concurrency.FakeExecutor; import com.android.systemui.util.concurrency.MessageRouterImpl; @@ -259,10 +255,6 @@ public class StatusBarTest extends SysuiTestCase { @Mock private DemoModeController mDemoModeController; @Mock private Lazy mNotificationShadeDepthControllerLazy; @Mock private BrightnessSliderController.Factory mBrightnessSliderFactory; - @Mock private UnfoldTransitionConfig mUnfoldTransitionConfig; - @Mock private Lazy mUnfoldLightRevealOverlayAnimationLazy; - @Mock private Lazy mNaturalRotationProgressProvider; - @Mock private Lazy mUnfoldWallpaperController; @Mock private WallpaperController mWallpaperController; @Mock private OngoingCallController mOngoingCallController; @Mock private SystemStatusAnimationScheduler mAnimationScheduler; @@ -440,10 +432,6 @@ public class StatusBarTest extends SysuiTestCase { mStatusBarTouchableRegionManager, mNotificationIconAreaController, mBrightnessSliderFactory, - mUnfoldTransitionConfig, - mUnfoldLightRevealOverlayAnimationLazy, - mUnfoldWallpaperController, - mNaturalRotationProgressProvider, mWallpaperController, mOngoingCallController, mAnimationScheduler,