From 176ce85d27b18351edbe59f4bd54d4f0dd5a08f8 Mon Sep 17 00:00:00 2001 From: randypfohl Date: Wed, 8 May 2024 14:50:50 -0700 Subject: [PATCH 1/2] Abstracting StatefulActivity from StateManager Flag: NONE - abstraction with no logic changes. Test: Built and ran locally, for launcher3 and third party launchers Bug: 224595066 Change-Id: I9da15bdd649d3a20e98c6552bb9e9abaec72f97f --- .../DesktopRecentsTransitionController.kt | 4 +- .../uioverrides/QuickstepLauncher.java | 2 +- .../quickstep/FallbackActivityInterface.java | 3 +- .../quickstep/LauncherActivityInterface.java | 4 +- .../quickstep/OverviewCommandHelper.java | 5 +- .../android/quickstep/RecentsActivity.java | 11 ++- .../fallback/FallbackRecentsView.java | 2 +- .../AnimatorControllerWithResistance.java | 4 +- .../quickstep/util/OverviewToHomeAnim.java | 2 +- .../util/QuickstepOnboardingPrefs.java | 3 +- .../util/SplitAnimationController.kt | 6 +- .../quickstep/views/LauncherRecentsView.java | 3 +- .../android/quickstep/views/RecentsView.java | 5 +- src/com/android/launcher3/Launcher.java | 6 +- src/com/android/launcher3/LauncherState.java | 6 +- src/com/android/launcher3/Workspace.java | 2 +- .../allapps/LauncherAllAppsContainerView.java | 8 +- .../launcher3/statemanager/BaseState.java | 2 +- .../launcher3/statemanager/StateManager.java | 34 ++++---- .../statemanager/StatefulActivity.java | 37 ++------ .../statemanager/StatefulContainer.java | 84 +++++++++++++++++++ .../util/CannedAnimationCoordinator.kt | 7 +- 22 files changed, 160 insertions(+), 80 deletions(-) create mode 100644 src/com/android/launcher3/statemanager/StatefulContainer.java diff --git a/quickstep/src/com/android/launcher3/desktop/DesktopRecentsTransitionController.kt b/quickstep/src/com/android/launcher3/desktop/DesktopRecentsTransitionController.kt index 0000c0db2c..9178062c2d 100644 --- a/quickstep/src/com/android/launcher3/desktop/DesktopRecentsTransitionController.kt +++ b/quickstep/src/com/android/launcher3/desktop/DesktopRecentsTransitionController.kt @@ -35,7 +35,7 @@ import java.util.function.Consumer /** Manage recents related operations with desktop tasks */ class DesktopRecentsTransitionController( - private val stateManager: StateManager<*>, + private val stateManager: StateManager<*, *>, private val systemUiProxy: SystemUiProxy, private val appThread: IApplicationThread, private val depthController: DepthController? @@ -64,7 +64,7 @@ class DesktopRecentsTransitionController( private class RemoteDesktopLaunchTransitionRunner( private val desktopTaskView: DesktopTaskView, - private val stateManager: StateManager<*>, + private val stateManager: StateManager<*, *>, private val depthController: DepthController?, private val successCallback: Consumer? ) : RemoteTransitionStub() { diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java index e3a2bab824..2168f7a318 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java +++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java @@ -1118,7 +1118,7 @@ public class QuickstepLauncher extends Launcher implements RecentsViewContainer } @Override - protected void collectStateHandlers(List out) { + public void collectStateHandlers(List> out) { super.collectStateHandlers(out); out.add(getDepthController()); out.add(new RecentsViewStateController(this)); diff --git a/quickstep/src/com/android/quickstep/FallbackActivityInterface.java b/quickstep/src/com/android/quickstep/FallbackActivityInterface.java index 9e896fddc5..89fbf4ad54 100644 --- a/quickstep/src/com/android/quickstep/FallbackActivityInterface.java +++ b/quickstep/src/com/android/quickstep/FallbackActivityInterface.java @@ -154,7 +154,8 @@ public final class FallbackActivityInterface extends @Override public void onExitOverview(RotationTouchHelper deviceState, Runnable exitRunnable) { - final StateManager stateManager = getCreatedContainer().getStateManager(); + final StateManager stateManager = + getCreatedContainer().getStateManager(); if (stateManager.getState() == HOME) { exitRunnable.run(); notifyRecentsOfOrientation(deviceState); diff --git a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java index 08c2e1ca29..c42882714c 100644 --- a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java +++ b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java @@ -36,6 +36,7 @@ import androidx.annotation.UiThread; import com.android.launcher3.DeviceProfile; import com.android.launcher3.Flags; +import com.android.launcher3.Launcher; import com.android.launcher3.LauncherAnimUtils; import com.android.launcher3.LauncherInitListener; import com.android.launcher3.LauncherState; @@ -242,7 +243,8 @@ public final class LauncherActivityInterface extends @Override public void onExitOverview(RotationTouchHelper deviceState, Runnable exitRunnable) { - final StateManager stateManager = getCreatedContainer().getStateManager(); + final StateManager stateManager = + getCreatedContainer().getStateManager(); stateManager.addStateListener( new StateManager.StateListener() { @Override diff --git a/quickstep/src/com/android/quickstep/OverviewCommandHelper.java b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java index 26a7c2f5bf..7da92bce90 100644 --- a/quickstep/src/com/android/quickstep/OverviewCommandHelper.java +++ b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java @@ -228,8 +228,9 @@ public class OverviewCommandHelper { } BaseActivityInterface activityInterface = mOverviewComponentObserver.getActivityInterface(); - RecentsView visibleRecentsView = activityInterface.getVisibleRecentsView(); - RecentsView createdRecentsView; + + RecentsView visibleRecentsView = activityInterface.getVisibleRecentsView(); + RecentsView createdRecentsView; Log.d(TAG, "executeCommand: " + cmd + " - visibleRecentsView: " + visibleRecentsView); diff --git a/quickstep/src/com/android/quickstep/RecentsActivity.java b/quickstep/src/com/android/quickstep/RecentsActivity.java index 3df62dacae..13e98444f4 100644 --- a/quickstep/src/com/android/quickstep/RecentsActivity.java +++ b/quickstep/src/com/android/quickstep/RecentsActivity.java @@ -115,7 +115,7 @@ public final class RecentsActivity extends StatefulActivity implem private TISBindHelper mTISBindHelper; private @Nullable FallbackTaskbarUIController mTaskbarUIController; - private StateManager mStateManager; + private StateManager mStateManager; // Strong refs to runners which are cleared when the activity is destroyed private RemoteAnimationFactory mActivityLaunchAnimationRunner; @@ -386,6 +386,11 @@ public final class RecentsActivity extends StatefulActivity implem } } + @Override + public boolean shouldAnimateStateChange() { + return false; + } + /** * Initialize/update the device profile. */ @@ -462,12 +467,12 @@ public final class RecentsActivity extends StatefulActivity implem }; @Override - protected void collectStateHandlers(List out) { + public void collectStateHandlers(List> out) { out.add(new FallbackRecentsStateController(this)); } @Override - public StateManager getStateManager() { + public StateManager getStateManager() { return mStateManager; } diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java index 485d6c4391..f4a2738fef 100644 --- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java +++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java @@ -93,7 +93,7 @@ public class FallbackRecentsView extends RecentsView getStateManager() { + public StateManager getStateManager() { return mContainer.getStateManager(); } diff --git a/quickstep/src/com/android/quickstep/util/AnimatorControllerWithResistance.java b/quickstep/src/com/android/quickstep/util/AnimatorControllerWithResistance.java index c9647f596e..c7c04ed91c 100644 --- a/quickstep/src/com/android/quickstep/util/AnimatorControllerWithResistance.java +++ b/quickstep/src/com/android/quickstep/util/AnimatorControllerWithResistance.java @@ -39,6 +39,7 @@ import com.android.launcher3.Utilities; import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.anim.PendingAnimation; import com.android.launcher3.statemanager.StateManager; +import com.android.launcher3.statemanager.StatefulActivity; import com.android.launcher3.states.StateAnimationConfig; import com.android.launcher3.touch.AllAppsSwipeController; import com.android.quickstep.DeviceConfigWrapper; @@ -163,7 +164,8 @@ public class AnimatorControllerWithResistance { recentsOrientedState.getContainerInterface().getCreatedContainer(); if (container != null) { RecentsView recentsView = container.getOverviewPanel(); - StateManager stateManager = recentsView.getStateManager(); + StateManager> stateManager = + recentsView.getStateManager(); if (stateManager.isInStableState(LauncherState.BACKGROUND_APP) && stateManager.isInTransition()) { diff --git a/quickstep/src/com/android/quickstep/util/OverviewToHomeAnim.java b/quickstep/src/com/android/quickstep/util/OverviewToHomeAnim.java index 132d1c1390..492c8019ac 100644 --- a/quickstep/src/com/android/quickstep/util/OverviewToHomeAnim.java +++ b/quickstep/src/com/android/quickstep/util/OverviewToHomeAnim.java @@ -62,7 +62,7 @@ public class OverviewToHomeAnim { * {@link WorkspaceRevealAnim}. */ public void animateWithVelocity(float velocity) { - StateManager stateManager = mLauncher.getStateManager(); + StateManager stateManager = mLauncher.getStateManager(); LauncherState startState = stateManager.getState(); if (startState != OVERVIEW) { Log.e(TAG, "animateFromOverviewToHome: unexpected start state " + startState); diff --git a/quickstep/src/com/android/quickstep/util/QuickstepOnboardingPrefs.java b/quickstep/src/com/android/quickstep/util/QuickstepOnboardingPrefs.java index 2a27dea744..cfe5b2cd61 100644 --- a/quickstep/src/com/android/quickstep/util/QuickstepOnboardingPrefs.java +++ b/quickstep/src/com/android/quickstep/util/QuickstepOnboardingPrefs.java @@ -27,6 +27,7 @@ import static com.android.launcher3.util.OnboardingPrefs.HOME_BOUNCE_COUNT; import static com.android.launcher3.util.OnboardingPrefs.HOME_BOUNCE_SEEN; import static com.android.launcher3.util.OnboardingPrefs.HOTSEAT_DISCOVERY_TIP_COUNT; +import com.android.launcher3.Launcher; import com.android.launcher3.LauncherPrefs; import com.android.launcher3.LauncherState; import com.android.launcher3.Utilities; @@ -48,7 +49,7 @@ public class QuickstepOnboardingPrefs { * Sets up the initial onboarding behavior for the launcher */ public static void setup(QuickstepLauncher launcher) { - StateManager stateManager = launcher.getStateManager(); + StateManager stateManager = launcher.getStateManager(); if (!HOME_BOUNCE_SEEN.get(launcher)) { stateManager.addStateListener(new StateListener() { @Override diff --git a/quickstep/src/com/android/quickstep/util/SplitAnimationController.kt b/quickstep/src/com/android/quickstep/util/SplitAnimationController.kt index 8243ededd2..d4b3576c36 100644 --- a/quickstep/src/com/android/quickstep/util/SplitAnimationController.kt +++ b/quickstep/src/com/android/quickstep/util/SplitAnimationController.kt @@ -510,7 +510,7 @@ class SplitAnimationController(val splitSelectStateController: SplitSelectStateC apps: Array?, wallpapers: Array?, nonApps: Array?, - stateManager: StateManager<*>, + stateManager: StateManager<*, *>, depthController: DepthController?, info: TransitionInfo?, t: Transaction?, @@ -589,7 +589,7 @@ class SplitAnimationController(val splitSelectStateController: SplitSelectStateC @VisibleForTesting fun composeRecentsSplitLaunchAnimator( launchingTaskView: GroupedTaskView, - stateManager: StateManager<*>, + stateManager: StateManager<*, *>, depthController: DepthController?, info: TransitionInfo, t: Transaction, @@ -617,7 +617,7 @@ class SplitAnimationController(val splitSelectStateController: SplitSelectStateC apps: Array, wallpapers: Array, nonApps: Array, - stateManager: StateManager<*>, + stateManager: StateManager<*, *>, depthController: DepthController?, finishCallback: Runnable ) { diff --git a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java index 5284b44dde..e48a7c6053 100644 --- a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java +++ b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java @@ -37,6 +37,7 @@ import android.view.MotionEvent; import androidx.annotation.Nullable; import com.android.launcher3.AbstractFloatingView; +import com.android.launcher3.Launcher; import com.android.launcher3.LauncherState; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.desktop.DesktopRecentsTransitionController; @@ -104,7 +105,7 @@ public class LauncherRecentsView extends RecentsView getStateManager() { + public StateManager getStateManager() { return mContainer.getStateManager(); } diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index 9096b75eaa..ff8d7cf324 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -152,6 +152,7 @@ import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.statehandlers.DepthController; import com.android.launcher3.statemanager.BaseState; import com.android.launcher3.statemanager.StateManager; +import com.android.launcher3.statemanager.StatefulContainer; import com.android.launcher3.testing.TestLogging; import com.android.launcher3.testing.shared.TestProtocol; import com.android.launcher3.touch.OverScroll; @@ -2487,7 +2488,9 @@ public abstract class RecentsView getStateManager(); + /** Returns the state manager used in RecentsView **/ + public abstract StateManager> getStateManager(); public void reset() { setCurrentTask(-1); diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index 6c9d4c06ce..4e566abddc 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -312,7 +312,7 @@ public class Launcher extends StatefulActivity private static boolean sIsNewProcess = true; - private StateManager mStateManager; + private StateManager mStateManager; private static final int ON_ACTIVITY_RESULT_ANIMATION_DELAY = 500; @@ -2775,7 +2775,7 @@ public class Launcher extends StatefulActivity } @Override - protected void collectStateHandlers(List out) { + public void collectStateHandlers(List> out) { out.add(getAllAppsController()); out.add(getWorkspace()); } @@ -2996,7 +2996,7 @@ public class Launcher extends StatefulActivity } @Override - public StateManager getStateManager() { + public StateManager getStateManager() { return mStateManager; } diff --git a/src/com/android/launcher3/LauncherState.java b/src/com/android/launcher3/LauncherState.java index d2d56f2d8c..102189b530 100644 --- a/src/com/android/launcher3/LauncherState.java +++ b/src/com/android/launcher3/LauncherState.java @@ -440,7 +440,7 @@ public abstract class LauncherState implements BaseState { */ public void onBackInvoked(Launcher launcher) { if (this != NORMAL) { - StateManager lsm = launcher.getStateManager(); + StateManager lsm = launcher.getStateManager(); LauncherState lastState = lsm.getLastState(); lsm.goToState(lastState, forEndCallback(this::onBackAnimationCompleted)); } @@ -461,7 +461,7 @@ public abstract class LauncherState implements BaseState { */ public void onBackProgressed( Launcher launcher, @FloatRange(from = 0.0, to = 1.0) float backProgress) { - StateManager lsm = launcher.getStateManager(); + StateManager lsm = launcher.getStateManager(); LauncherState toState = lsm.getLastState(); lsm.onBackProgressed(toState, backProgress); } @@ -471,7 +471,7 @@ public abstract class LauncherState implements BaseState { * predictive back gesture. */ public void onBackCancelled(Launcher launcher) { - StateManager lsm = launcher.getStateManager(); + StateManager lsm = launcher.getStateManager(); LauncherState toState = lsm.getLastState(); lsm.onBackCancelled(toState); } diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index 584d08924f..e601a3e298 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -526,7 +526,7 @@ public class Workspace extends PagedView } updateChildrenLayersEnabled(); - StateManager stateManager = mLauncher.getStateManager(); + StateManager stateManager = mLauncher.getStateManager(); stateManager.addStateListener(new StateManager.StateListener() { @Override public void onStateTransitionComplete(LauncherState finalState) { diff --git a/src/com/android/launcher3/allapps/LauncherAllAppsContainerView.java b/src/com/android/launcher3/allapps/LauncherAllAppsContainerView.java index 63a168e4e3..1e0f2892d6 100644 --- a/src/com/android/launcher3/allapps/LauncherAllAppsContainerView.java +++ b/src/com/android/launcher3/allapps/LauncherAllAppsContainerView.java @@ -56,7 +56,7 @@ public class LauncherAllAppsContainerView extends ActivityAllAppsContainerView manager = launcher.getStateManager(); + StateManager manager = launcher.getStateManager(); if (manager.isInTransition() && manager.getTargetState() != null) { return manager.getTargetState().shouldFloatingSearchBarUsePillWhenUnfocused(launcher); } @@ -70,7 +70,7 @@ public class LauncherAllAppsContainerView extends ActivityAllAppsContainerView stateManager = launcher.getStateManager(); + StateManager stateManager = launcher.getStateManager(); // We want to rest at the current state's resting position, unless we are in transition and // the target state's resting position is higher (that way if we are closing the keyboard, @@ -95,7 +95,7 @@ public class LauncherAllAppsContainerView extends ActivityAllAppsContainerView stateManager = mActivityContext.getStateManager(); + StateManager stateManager = mActivityContext.getStateManager(); // Special case to not expand the search bar when exiting All Apps on phones. if (stateManager.getCurrentStableState() == LauncherState.ALL_APPS @@ -117,7 +117,7 @@ public class LauncherAllAppsContainerView extends ActivityAllAppsContainerView stateManager = mActivityContext.getStateManager(); + StateManager stateManager = mActivityContext.getStateManager(); // Special case to not expand the search bar when exiting All Apps on phones. if (stateManager.getCurrentStableState() == LauncherState.ALL_APPS diff --git a/src/com/android/launcher3/statemanager/BaseState.java b/src/com/android/launcher3/statemanager/BaseState.java index a01d402c43..b81729a712 100644 --- a/src/com/android/launcher3/statemanager/BaseState.java +++ b/src/com/android/launcher3/statemanager/BaseState.java @@ -21,7 +21,7 @@ import com.android.launcher3.DeviceProfile; import com.android.launcher3.views.ActivityContext; /** - * Interface representing a state of a StatefulActivity + * Interface representing a state of a StatefulContainer */ public interface BaseState { diff --git a/src/com/android/launcher3/statemanager/StateManager.java b/src/com/android/launcher3/statemanager/StateManager.java index eea1a7d5e9..ac07c0f2cf 100644 --- a/src/com/android/launcher3/statemanager/StateManager.java +++ b/src/com/android/launcher3/statemanager/StateManager.java @@ -26,6 +26,7 @@ import android.animation.Animator; import android.animation.Animator.AnimatorListener; import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; +import android.content.Context; import android.os.Handler; import android.os.Looper; import android.util.Log; @@ -47,8 +48,11 @@ import java.util.stream.Collectors; /** * Class to manage transitions between different states for a StatefulActivity based on different * states + * @param STATE_TYPE Basestate used by the state manager + * @param STATEFUL_CONTAINER container object used to manage state */ -public class StateManager> { +public class StateManager, + STATEFUL_CONTAINER extends Context & StatefulContainer> { public static final String TAG = "StateManager"; // b/279059025, b/325463989 @@ -56,7 +60,7 @@ public class StateManager> { private final AnimationState mConfig = new AnimationState(); private final Handler mUiHandler; - private final StatefulActivity mActivity; + private final STATEFUL_CONTAINER mStatefulContainer; private final ArrayList> mListeners = new ArrayList<>(); private final STATE_TYPE mBaseState; @@ -71,12 +75,12 @@ public class StateManager> { private STATE_TYPE mRestState; - public StateManager(StatefulActivity l, STATE_TYPE baseState) { + public StateManager(STATEFUL_CONTAINER container, STATE_TYPE baseState) { mUiHandler = new Handler(Looper.getMainLooper()); - mActivity = l; + mStatefulContainer = container; mBaseState = baseState; mState = mLastStableState = mCurrentStableState = baseState; - mAtomicAnimationFactory = l.createAtomicAnimationFactory(); + mAtomicAnimationFactory = container.createAtomicAnimationFactory(); } public STATE_TYPE getState() { @@ -109,10 +113,10 @@ public class StateManager> { writer.println(prefix + "\tisInTransition:" + isInTransition()); } - public StateHandler[] getStateHandlers() { + public StateHandler[] getStateHandlers() { if (mStateHandlers == null) { - ArrayList handlers = new ArrayList<>(); - mActivity.collectStateHandlers(handlers); + ArrayList> handlers = new ArrayList<>(); + mStatefulContainer.collectStateHandlers(handlers); mStateHandlers = handlers.toArray(new StateHandler[handlers.size()]); } return mStateHandlers; @@ -130,7 +134,7 @@ public class StateManager> { * Returns true if the state changes should be animated. */ public boolean shouldAnimateStateChange() { - return !mActivity.isForceInvisible() && mActivity.isStarted(); + return mStatefulContainer.shouldAnimateStateChange(); } /** @@ -245,7 +249,7 @@ public class StateManager> { } animated &= areAnimatorsEnabled(); - if (mActivity.isInState(state)) { + if (mStatefulContainer.isInState(state)) { if (mConfig.currentAnimation == null) { // Run any queued runnable if (listener != null) { @@ -302,8 +306,8 @@ public class StateManager> { // Since state mBaseState can be reached from multiple states, just assume that the // transition plays in reverse and use the same duration as previous state. mConfig.duration = state == mBaseState - ? fromState.getTransitionDuration(mActivity, false /* isToState */) - : state.getTransitionDuration(mActivity, true /* isToState */); + ? fromState.getTransitionDuration(mStatefulContainer, false /* isToState */) + : state.getTransitionDuration(mStatefulContainer, true /* isToState */); prepareForAtomicAnimation(fromState, state, mConfig); AnimatorSet animation = createAnimationToNewWorkspaceInternal(state).buildAnim(); if (listener != null) { @@ -336,7 +340,7 @@ public class StateManager> { PendingAnimation builder = new PendingAnimation(config.duration); prepareForAtomicAnimation(fromState, toState, config); - for (StateHandler handler : mActivity.getStateManager().getStateHandlers()) { + for (StateHandler handler : mStatefulContainer.getStateManager().getStateHandlers()) { handler.setStateWithAnimation(toState, config, builder); } return builder.buildAnim(); @@ -402,7 +406,7 @@ public class StateManager> { private void onStateTransitionStart(STATE_TYPE state) { mState = state; - mActivity.onStateSetStart(mState); + mStatefulContainer.onStateSetStart(mState); if (DEBUG) { Log.d(TAG, "onStateTransitionStart - state: " + state); @@ -419,7 +423,7 @@ public class StateManager> { mCurrentStableState = state; } - mActivity.onStateSetEnd(state); + mStatefulContainer.onStateSetEnd(state); if (state == mBaseState) { setRestState(null); } diff --git a/src/com/android/launcher3/statemanager/StatefulActivity.java b/src/com/android/launcher3/statemanager/StatefulActivity.java index 30ba703fd7..28f2def8ab 100644 --- a/src/com/android/launcher3/statemanager/StatefulActivity.java +++ b/src/com/android/launcher3/statemanager/StatefulActivity.java @@ -18,7 +18,6 @@ package com.android.launcher3.statemanager; import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION; import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE; -import static com.android.launcher3.LauncherState.FLAG_CLOSE_POPUPS; import static com.android.launcher3.LauncherState.FLAG_NON_INTERACTIVE; import android.content.res.Configuration; @@ -29,11 +28,9 @@ import android.view.View; import androidx.annotation.CallSuper; -import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.LauncherRootView; import com.android.launcher3.Utilities; -import com.android.launcher3.statemanager.StateManager.AtomicAnimationFactory; import com.android.launcher3.statemanager.StateManager.StateHandler; import com.android.launcher3.util.window.WindowManagerProxy; import com.android.launcher3.views.BaseDragLayer; @@ -45,7 +42,7 @@ import java.util.List; * @param Type of state object */ public abstract class StatefulActivity> - extends BaseDraggingActivity { + extends BaseDraggingActivity implements StatefulContainer { public final Handler mHandler = new Handler(); private final Runnable mHandleDeferredResume = this::handleDeferredResume; @@ -67,19 +64,9 @@ public abstract class StatefulActivity> /** * Create handlers to control the property changes for this activity */ - protected abstract void collectStateHandlers(List out); - /** - * Returns true if the activity is in the provided state - */ - public boolean isInState(STATE_TYPE state) { - return getStateManager().getState() == state; - } - - /** - * Returns the state manager for this activity - */ - public abstract StateManager getStateManager(); + @Override + public abstract void collectStateHandlers(List> out); protected void inflateRootView(int layoutId) { mRootView = (LauncherRootView) LayoutInflater.from(this).inflate(layoutId, null); @@ -106,22 +93,12 @@ public abstract class StatefulActivity> if (mDeferredResumePending) { handleDeferredResume(); } - - if (state.hasFlag(FLAG_CLOSE_POPUPS)) { - AbstractFloatingView.closeAllOpenViews(this, !state.hasFlag(FLAG_NON_INTERACTIVE)); - } + StatefulContainer.super.onStateSetStart(state); } - /** - * Called when transition to state ends - */ - public void onStateSetEnd(STATE_TYPE state) { } - - /** - * Creates a factory for atomic state animations - */ - public AtomicAnimationFactory createAtomicAnimationFactory() { - return new AtomicAnimationFactory(0); + @Override + public boolean shouldAnimateStateChange() { + return !isForceInvisible() && isStarted(); } @Override diff --git a/src/com/android/launcher3/statemanager/StatefulContainer.java b/src/com/android/launcher3/statemanager/StatefulContainer.java new file mode 100644 index 0000000000..0cf0a27685 --- /dev/null +++ b/src/com/android/launcher3/statemanager/StatefulContainer.java @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2024 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.launcher3.statemanager; + + +import static com.android.launcher3.LauncherState.FLAG_CLOSE_POPUPS; +import static com.android.launcher3.statemanager.BaseState.FLAG_NON_INTERACTIVE; + +import androidx.annotation.CallSuper; + +import com.android.launcher3.AbstractFloatingView; +import com.android.launcher3.views.ActivityContext; + +import java.util.List; + +/** + * Interface for a container that can be managed by a state manager. + * + * @param The type of state that the container can be in. + */ +public interface StatefulContainer> extends + ActivityContext { + + /** + * Creates a factory for atomic state animations + */ + default StateManager.AtomicAnimationFactory createAtomicAnimationFactory() { + return new StateManager.AtomicAnimationFactory<>(0); + } + + /** + * Create handlers to control the property changes for this activity + */ + void collectStateHandlers(List> out); + + /** + * Retrieves state manager for given container + */ + StateManager getStateManager(); + + /** + * Called when transition to state ends + * @param state current state of State_Type + */ + default void onStateSetEnd(STATE_TYPE state) { } + + /** + * Called when transition to state starts + * @param state current state of State_Type + */ + @CallSuper + default void onStateSetStart(STATE_TYPE state) { + if (state.hasFlag(FLAG_CLOSE_POPUPS)) { + AbstractFloatingView.closeAllOpenViews(this, !state.hasFlag(FLAG_NON_INTERACTIVE)); + } + } + + /** + * Returns true if the activity is in the provided state + * @param state current state of State_Type + */ + default boolean isInState(STATE_TYPE state) { + return getStateManager().getState() == state; + } + + /** + * Returns true if state change should transition with animation + */ + boolean shouldAnimateStateChange(); +} diff --git a/src/com/android/launcher3/util/CannedAnimationCoordinator.kt b/src/com/android/launcher3/util/CannedAnimationCoordinator.kt index 85f81f57ba..749caacd96 100644 --- a/src/com/android/launcher3/util/CannedAnimationCoordinator.kt +++ b/src/com/android/launcher3/util/CannedAnimationCoordinator.kt @@ -113,10 +113,9 @@ class CannedAnimationCoordinator(private val activity: StatefulActivity<*>) { // flags accordingly animationController = controller.apply { - activity.stateManager.setCurrentAnimation( - this, - USER_CONTROLLED or HANDLE_STATE_APPLY - ) + activity + .stateManager + .setCurrentAnimation(this, USER_CONTROLLED or HANDLE_STATE_APPLY) } recreateAnimation(provider) } From 4b409653464fa6fc446b06a8d9b4a73dc67ef2fa Mon Sep 17 00:00:00 2001 From: randypfohl Date: Fri, 10 May 2024 08:45:56 -0700 Subject: [PATCH 2/2] Fixing tests related to abstraction Flag: NONE - fixing tests Test: built and ran locally, verified test pass in presubmit Bug: 224595066 Change-Id: Ifefab1e1696853c5bd816a361314082073ba8a20 --- .../com/android/quickstep/util/SplitAnimationControllerTest.kt | 2 +- .../android/quickstep/util/SplitSelectStateControllerTest.kt | 3 ++- .../launcher3/taskbar/FallbackTaskbarUIControllerTest.kt | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/util/SplitAnimationControllerTest.kt b/quickstep/tests/multivalentTests/src/com/android/quickstep/util/SplitAnimationControllerTest.kt index 250dc7b924..d40f8ab389 100644 --- a/quickstep/tests/multivalentTests/src/com/android/quickstep/util/SplitAnimationControllerTest.kt +++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/util/SplitAnimationControllerTest.kt @@ -78,7 +78,7 @@ class SplitAnimationControllerTest { private val mockSplitSourceDrawable: Drawable = mock() private val mockSplitSourceView: View = mock() - private val stateManager: StateManager<*> = mock() + private val stateManager: StateManager<*, *> = mock() private val depthController: DepthController = mock() private val transitionInfo: TransitionInfo = mock() private val transaction: Transaction = mock() diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/util/SplitSelectStateControllerTest.kt b/quickstep/tests/multivalentTests/src/com/android/quickstep/util/SplitSelectStateControllerTest.kt index aa08ca4c05..bab84ef28b 100644 --- a/quickstep/tests/multivalentTests/src/com/android/quickstep/util/SplitSelectStateControllerTest.kt +++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/util/SplitSelectStateControllerTest.kt @@ -31,6 +31,7 @@ import com.android.launcher3.logging.StatsLogManager.StatsLogger import com.android.launcher3.model.data.ItemInfo import com.android.launcher3.statehandlers.DepthController import com.android.launcher3.statemanager.StateManager +import com.android.launcher3.statemanager.StatefulActivity import com.android.launcher3.util.ComponentKey import com.android.launcher3.util.SplitConfigurationOptions import com.android.quickstep.RecentsModel @@ -61,7 +62,7 @@ class SplitSelectStateControllerTest { private val depthController: DepthController = mock() private val statsLogManager: StatsLogManager = mock() private val statsLogger: StatsLogger = mock() - private val stateManager: StateManager = mock() + private val stateManager: StateManager> = mock() private val handler: Handler = mock() private val context: RecentsViewContainer = mock() private val recentsModel: RecentsModel = mock() diff --git a/quickstep/tests/src/com/android/launcher3/taskbar/FallbackTaskbarUIControllerTest.kt b/quickstep/tests/src/com/android/launcher3/taskbar/FallbackTaskbarUIControllerTest.kt index f3115c6a52..04012c027d 100644 --- a/quickstep/tests/src/com/android/launcher3/taskbar/FallbackTaskbarUIControllerTest.kt +++ b/quickstep/tests/src/com/android/launcher3/taskbar/FallbackTaskbarUIControllerTest.kt @@ -37,7 +37,7 @@ class FallbackTaskbarUIControllerTest : TaskbarBaseTestCase() { lateinit var stateListener: StateManager.StateListener private val recentsActivity: RecentsActivity = mock() - private val stateManager: StateManager = mock() + private val stateManager: StateManager = mock() @Before override fun setup() {