diff --git a/src/com/android/launcher3/ButtonDropTarget.java b/src/com/android/launcher3/ButtonDropTarget.java index 1a1c3198f6..bebdbdb351 100644 --- a/src/com/android/launcher3/ButtonDropTarget.java +++ b/src/com/android/launcher3/ButtonDropTarget.java @@ -16,7 +16,7 @@ package com.android.launcher3; -import static com.android.launcher3.LauncherAnimUtils.SPRING_LOADED_EXIT_NEXT_FRAME; +import static com.android.launcher3.LauncherState.NORMAL; import android.animation.AnimatorSet; import android.animation.FloatArrayEvaluator; @@ -231,7 +231,7 @@ public abstract class ButtonDropTarget extends TextView public void run() { completeDrop(d); mDropTargetBar.onDragEnd(); - mLauncher.exitSpringLoadedDragMode(SPRING_LOADED_EXIT_NEXT_FRAME); + mLauncher.getStateManager().goToState(NORMAL); } }; dragLayer.animateView(d.dragView, from, to, scale, 1f, 1f, 0.1f, 0.1f, diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index e3acf70b2e..cd9fffc565 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -19,8 +19,10 @@ package com.android.launcher3; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_NOSENSOR; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; -import static com.android.launcher3.LauncherAnimUtils.SPRING_LOADED_EXIT_NEXT_FRAME; import static com.android.launcher3.LauncherAnimUtils.SPRING_LOADED_EXIT_DELAY; +import static com.android.launcher3.LauncherState.ALL_APPS; +import static com.android.launcher3.LauncherState.NORMAL; +import static com.android.launcher3.LauncherState.OVERVIEW; import static com.android.launcher3.logging.LoggerUtils.newContainerTarget; import static com.android.launcher3.util.RunnableWithId.RUNNABLE_ID_BIND_APPS; import static com.android.launcher3.util.RunnableWithId.RUNNABLE_ID_BIND_WIDGETS; @@ -58,7 +60,6 @@ import android.graphics.drawable.Drawable; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; -import android.os.Handler; import android.os.Parcelable; import android.os.Process; import android.os.StrictMode; @@ -203,7 +204,7 @@ public class Launcher extends BaseActivity // Type: SparseArray private static final String RUNTIME_STATE_WIDGET_PANEL = "launcher.widget_panel"; - private LauncherStateTransitionAnimation mStateTransitionAnimation; + private LauncherStateManager mStateManager; private boolean mIsSafeModeEnabled; @@ -257,7 +258,6 @@ public class Launcher extends BaseActivity private ModelWriter mModelWriter; private IconCache mIconCache; private LauncherAccessibilityDelegate mAccessibilityDelegate; - private final Handler mHandler = new Handler(); private boolean mHasFocus = false; private ObjectAnimator mScrimAnimator; @@ -271,11 +271,6 @@ public class Launcher extends BaseActivity // it from the context. private SharedPreferences mSharedPrefs; - // Exiting spring loaded mode happens with a delay. This runnable object triggers the - // state transition. If another state transition happened during this delay, - // simply unregister this runnable. - private Runnable mExitSpringLoadedModeRunnable; - // Activity result which needs to be processed after workspace has loaded. private ActivityResultInfo mPendingActivityResult; /** @@ -342,7 +337,7 @@ public class Launcher extends BaseActivity mDragController = new DragController(this); mAllAppsController = new AllAppsTransitionController(this); - mStateTransitionAnimation = new LauncherStateTransitionAnimation(this, mAllAppsController); + mStateManager = new LauncherStateManager(this, mAllAppsController); mAppWidgetManager = AppWidgetManagerCompat.getInstance(this); @@ -430,8 +425,8 @@ public class Launcher extends BaseActivity recreate(); } - public LauncherStateTransitionAnimation getStateTransition() { - return mStateTransitionAnimation; + public LauncherStateManager getStateManager() { + return mStateManager; } protected void overrideTheme(boolean isDark, boolean supportsDarkText) { @@ -565,7 +560,7 @@ public class Launcher extends BaseActivity Runnable exitSpringLoaded = new Runnable() { @Override public void run() { - exitSpringLoadedDragMode(SPRING_LOADED_EXIT_DELAY); + mStateManager.goToState(NORMAL, SPRING_LOADED_EXIT_DELAY); } }; @@ -585,11 +580,11 @@ public class Launcher extends BaseActivity } return; } else if (requestCode == REQUEST_PICK_WALLPAPER) { - if (resultCode == RESULT_OK && isInState(LauncherState.OVERVIEW)) { + if (resultCode == RESULT_OK && isInState(OVERVIEW)) { // User could have free-scrolled between pages before picking a wallpaper; make sure // we move to the closest one now. mWorkspace.setCurrentPage(mWorkspace.getPageNearestToCenterOfScreen()); - showWorkspace(false); + mStateManager.goToState(NORMAL, false); } return; } @@ -617,7 +612,7 @@ public class Launcher extends BaseActivity final Runnable onComplete = new Runnable() { @Override public void run() { - exitSpringLoadedDragMode(SPRING_LOADED_EXIT_NEXT_FRAME); + getStateManager().goToState(NORMAL); } }; @@ -745,7 +740,7 @@ public class Launcher extends BaseActivity @Override public void run() { completeAddAppWidget(appWidgetId, requestArgs, layout, null); - exitSpringLoadedDragMode(SPRING_LOADED_EXIT_DELAY); + mStateManager.goToState(NORMAL, SPRING_LOADED_EXIT_DELAY); } }; } else if (resultCode == RESULT_CANCELED) { @@ -990,9 +985,16 @@ public class Launcher extends BaseActivity AbstractFloatingView.closeAllOpenViews(this); // Show the overview mode if we are on the workspace - if (isInState(LauncherState.NORMAL) && !mWorkspace.isSwitchingState()) { - mOverviewPanel.requestFocus(); - showOverviewMode(true, true /* requestButtonFocus */); + if (isInState(NORMAL) && !mWorkspace.isSwitchingState()) { + mStateManager.goToState(OVERVIEW, true /* animate */, new Runnable() { + @Override + public void run() { + // Hitting the menu button when in touch mode does not trigger touch + // mode to be disabled, so if requested, force focus on one of the + // overview panel buttons. + mOverviewPanel.requestFocusFromTouch(); + } + }); } } return true; @@ -1025,15 +1027,11 @@ public class Launcher extends BaseActivity return; } - int stateOrdinal = savedState.getInt(RUNTIME_STATE, LauncherState.NORMAL.ordinal); + int stateOrdinal = savedState.getInt(RUNTIME_STATE, NORMAL.ordinal); LauncherState[] stateValues = LauncherState.values(); LauncherState state = stateValues[stateOrdinal]; if (!state.doNotRestore) { - if (state == LauncherState.ALL_APPS) { - showAppsView(false /* animated */); - } else if (state == LauncherState.OVERVIEW) { - showOverviewMode(false); - } + mStateManager.goToState(state, false /* animated */); } PendingRequestArgs requestArgs = savedState.getParcelable(RUNTIME_STATE_PENDING_REQUEST_ARGS); @@ -1311,10 +1309,7 @@ public class Launcher extends BaseActivity // Reset AllApps to its initial state only if we are not in the middle of // processing a multi-step drop if (mAppsView != null && mPendingRequestArgs == null) { - if (!showWorkspace(false)) { - // If we are already on the workspace, then manually reset all apps - mAppsView.reset(); - } + mStateManager.goToState(NORMAL); } mShouldFadeInScrim = true; } else if (Intent.ACTION_USER_PRESENT.equals(action)) { @@ -1414,7 +1409,7 @@ public class Launcher extends BaseActivity != Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT); // Check this condition before handling isActionMain, as this will get reset. - boolean shouldMoveToDefaultScreen = alreadyOnHome && isInState(LauncherState.NORMAL) + boolean shouldMoveToDefaultScreen = alreadyOnHome && isInState(NORMAL) && AbstractFloatingView.getTopOpenView(this) == null; boolean isActionMain = Intent.ACTION_MAIN.equals(intent.getAction()); @@ -1438,7 +1433,7 @@ public class Launcher extends BaseActivity // In all these cases, only animate if we're already on home AbstractFloatingView.closeAllOpenViews(this, alreadyOnHome); - showWorkspace(alreadyOnHome /* animated */); + mStateManager.goToState(NORMAL, alreadyOnHome /* animated */); final View v = getWindow().peekDecorView(); if (v != null && v.getWindowToken() != null) { @@ -1615,7 +1610,7 @@ public class Launcher extends BaseActivity } // We need to show the workspace after starting the search - showWorkspace(true); + mStateManager.goToState(NORMAL); } /** @@ -1707,7 +1702,7 @@ public class Launcher extends BaseActivity @Override public void run() { // Exit spring loaded mode if necessary after adding the widget - exitSpringLoadedDragMode(SPRING_LOADED_EXIT_DELAY); + mStateManager.goToState(NORMAL, SPRING_LOADED_EXIT_DELAY); } }; completeAddAppWidget(appWidgetId, info, boundWidget, addFlowHandler.getProviderInfo(this)); @@ -1888,9 +1883,9 @@ public class Launcher extends BaseActivity AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(this); if (topView != null) { topView.onBackPressed(); - } else if (!isInState(LauncherState.NORMAL)) { + } else if (!isInState(NORMAL)) { ued.logActionCommand(Action.Command.BACK, mWorkspace.getState().containerType); - showWorkspace(true); + mStateManager.goToState(NORMAL); } else { // Back button is a no-op here, but give at least some feedback for the button press mWorkspace.showOutlinesTemporarily(); @@ -1914,23 +1909,23 @@ public class Launcher extends BaseActivity } if (v instanceof Workspace) { - if (isInState(LauncherState.OVERVIEW)) { + if (isInState(OVERVIEW)) { getUserEventDispatcher().logActionOnContainer(LauncherLogProto.Action.Type.TOUCH, LauncherLogProto.Action.Direction.NONE, LauncherLogProto.ContainerType.OVERVIEW, mWorkspace.getCurrentPage()); - showWorkspace(true); + mStateManager.goToState(NORMAL); } return; } if (v instanceof CellLayout) { - if (isInState(LauncherState.OVERVIEW)) { + if (isInState(OVERVIEW)) { int page = mWorkspace.indexOfChild(v); getUserEventDispatcher().logActionOnContainer(LauncherLogProto.Action.Type.TOUCH, LauncherLogProto.Action.Direction.NONE, LauncherLogProto.ContainerType.OVERVIEW, page); mWorkspace.snapToPageFromOverView(page); - showWorkspace(true); + mStateManager.goToState(NORMAL); } return; } @@ -2002,12 +1997,12 @@ public class Launcher extends BaseActivity */ protected void onClickAllAppsButton(View v) { if (LOGD) Log.d(TAG, "onClickAllAppsButton"); - if (!isInState(LauncherState.ALL_APPS)) { + if (!isInState(ALL_APPS)) { getUserEventDispatcher().logActionOnControl(Action.Touch.TAP, ControlType.ALL_APPS_BUTTON); - showAppsView(true /* animated */); + mStateManager.goToState(ALL_APPS); } else { - showWorkspace(true); + mStateManager.goToState(NORMAL); } } @@ -2333,18 +2328,18 @@ public class Launcher extends BaseActivity public boolean onLongClick(View v) { if (!isDraggingEnabled()) return false; if (isWorkspaceLocked()) return false; - if (!isInState(LauncherState.NORMAL) && !isInState(LauncherState.OVERVIEW)) return false; + if (!isInState(NORMAL) && !isInState(OVERVIEW)) return false; boolean ignoreLongPressToOverview = mDeviceProfile.shouldIgnoreLongPressToOverview(mLastDispatchTouchEventX); if (v instanceof Workspace) { - if (!isInState(LauncherState.OVERVIEW)) { + if (!isInState(OVERVIEW)) { if (!mWorkspace.isTouchActive() && !ignoreLongPressToOverview) { getUserEventDispatcher().logActionOnContainer(Action.Touch.LONGPRESS, Action.Direction.NONE, ContainerType.WORKSPACE, mWorkspace.getCurrentPage()); - showOverviewMode(true); + getStateManager().goToState(OVERVIEW); mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING); return true; @@ -2381,7 +2376,7 @@ public class Launcher extends BaseActivity getUserEventDispatcher().logActionOnContainer(Action.Touch.LONGPRESS, Action.Direction.NONE, ContainerType.WORKSPACE, mWorkspace.getCurrentPage()); - showOverviewMode(true); + getStateManager().goToState(OVERVIEW); } mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING); @@ -2436,134 +2431,16 @@ public class Launcher extends BaseActivity } } - public boolean showWorkspace(boolean animated) { - return showWorkspace(animated, null); - } - - public boolean showWorkspace(boolean animated, Runnable onCompleteRunnable) { - boolean changed = !isInState(LauncherState.NORMAL); - if (changed || mAllAppsController.isTransitioning()) { - mWorkspace.setVisibility(View.VISIBLE); - mStateTransitionAnimation.goToState(LauncherState.NORMAL, animated, onCompleteRunnable); - - // Set focus to the AppsCustomize button - if (mAllAppsButton != null) { - mAllAppsButton.requestFocus(); - } - } - - if (changed) { - // Send an accessibility event to announce the context change - getWindow().getDecorView() - .sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); - } - return changed; - } - - /** - * Shows the overview button. - */ - public void showOverviewMode(boolean animated) { - showOverviewMode(animated, false); - } - - /** - * Shows the overview button, and if {@param requestButtonFocus} is set, will force the focus - * onto one of the overview panel buttons. - */ - void showOverviewMode(boolean animated, boolean requestButtonFocus) { - Runnable postAnimRunnable = null; - if (requestButtonFocus) { - postAnimRunnable = new Runnable() { - @Override - public void run() { - // Hitting the menu button when in touch mode does not trigger touch mode to - // be disabled, so if requested, force focus on one of the overview panel - // buttons. - mOverviewPanel.requestFocusFromTouch(); - } - }; - } - mWorkspace.setVisibility(View.VISIBLE); - mStateTransitionAnimation.goToState(LauncherState.OVERVIEW, animated, postAnimRunnable); - - // If animated from long press, then don't allow any of the controller in the drag - // layer to intercept any remaining touch. - mWorkspace.requestDisallowInterceptTouchEvent(animated); - } - - /** - * Shows the apps view. - * - * @return whether the current from and to state allowed this operation - */ - // TODO: calling method should use the return value so that when {@code false} is returned - // the workspace transition doesn't fall into invalid state. - public boolean showAppsView(boolean animated) { - if (!(isInState(LauncherState.NORMAL) || - (isInState(LauncherState.ALL_APPS) && mAllAppsController.isTransitioning()))) { - return false; - } - - // This is a safe and supported transition to bypass spring_loaded mode. - if (mExitSpringLoadedModeRunnable != null) { - mHandler.removeCallbacks(mExitSpringLoadedModeRunnable); - mExitSpringLoadedModeRunnable = null; - } - - mStateTransitionAnimation.goToState(LauncherState.ALL_APPS, animated, null); - - // Change the state *after* we've called all the transition code - AbstractFloatingView.closeAllOpenViews(this); - - // Send an accessibility event to announce the context change - getWindow().getDecorView() - .sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); - return true; - } - - public void enterSpringLoadedDragMode() { - if (LOGD) Log.d(TAG, String.format("enterSpringLoadedDragMode [mState=%s", - mWorkspace.getState().ordinal)); - if (isInState(LauncherState.SPRING_LOADED)) { - return; - } - mStateTransitionAnimation.goToState(LauncherState.SPRING_LOADED, true, null); - } - - public void exitSpringLoadedDragMode(int delay) { - exitSpringLoadedDragMode(delay, null); - } - - public void exitSpringLoadedDragMode(int delay, final Runnable onCompleteRunnable) { - if (!isInState(LauncherState.SPRING_LOADED)) return; - - if (mExitSpringLoadedModeRunnable != null) { - mHandler.removeCallbacks(mExitSpringLoadedModeRunnable); - } - mExitSpringLoadedModeRunnable = new Runnable() { - @Override - public void run() { - showWorkspace(true, onCompleteRunnable); - mExitSpringLoadedModeRunnable = null; - } - }; - mHandler.postDelayed(mExitSpringLoadedModeRunnable, delay); - } - @Override public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { final boolean result = super.dispatchPopulateAccessibilityEvent(event); final List text = event.getText(); text.clear(); // Populate event with a fake title based on the current state. - if (isInState(LauncherState.ALL_APPS)) { - text.add(getString(R.string.all_apps_button_label)); - } else if (mWorkspace != null) { - text.add(mWorkspace.getCurrentPageDescription()); - } else { - text.add(getString(R.string.all_apps_home_button_label)); - } + // TODO: When can workspace be null? + text.add(mWorkspace == null + ? getString(R.string.all_apps_home_button_label) + : mWorkspace.getState().getDescription(this)); return result; } @@ -3114,7 +2991,7 @@ public class Launcher extends BaseActivity if (mAppsView != null) { Executor pendingExecutor = getPendingExecutor(); - if (pendingExecutor != null && !isInState(LauncherState.ALL_APPS)) { + if (pendingExecutor != null && !isInState(ALL_APPS)) { // Wait until the fade in animation has finished before setting all apps list. pendingExecutor.execute(r); return; @@ -3304,7 +3181,7 @@ public class Launcher extends BaseActivity } private boolean shouldShowDiscoveryBounce() { - return isInState(LauncherState.NORMAL) + return isInState(NORMAL) && !mSharedPrefs.getBoolean(AllAppsState.APPS_VIEW_SHOWN, false) && !UserManagerCompat.getInstance(this).isDemoUser(); } @@ -3364,7 +3241,7 @@ public class Launcher extends BaseActivity List data, Menu menu, int deviceId) { ArrayList shortcutInfos = new ArrayList<>(); - if (isInState(LauncherState.NORMAL)) { + if (isInState(NORMAL)) { shortcutInfos.add(new KeyboardShortcutInfo(getString(R.string.all_apps_button_label), KeyEvent.KEYCODE_A, KeyEvent.META_CTRL_ON)); } @@ -3390,8 +3267,8 @@ public class Launcher extends BaseActivity if (event.hasModifiers(KeyEvent.META_CTRL_ON)) { switch (keyCode) { case KeyEvent.KEYCODE_A: - if (isInState(LauncherState.NORMAL)) { - showAppsView(true); + if (isInState(NORMAL)) { + getStateManager().goToState(ALL_APPS); return true; } break; diff --git a/src/com/android/launcher3/LauncherAnimUtils.java b/src/com/android/launcher3/LauncherAnimUtils.java index 358511046c..dfe51af868 100644 --- a/src/com/android/launcher3/LauncherAnimUtils.java +++ b/src/com/android/launcher3/LauncherAnimUtils.java @@ -38,7 +38,6 @@ public class LauncherAnimUtils { public static final int OVERVIEW_TRANSITION_MS = 250; public static final int SPRING_LOADED_TRANSITION_MS = 150; public static final int SPRING_LOADED_EXIT_DELAY = 500; - public static final int SPRING_LOADED_EXIT_NEXT_FRAME = 0; static WeakHashMap sAnimators = new WeakHashMap(); static Animator.AnimatorListener sEndAnimListener = new Animator.AnimatorListener() { diff --git a/src/com/android/launcher3/LauncherState.java b/src/com/android/launcher3/LauncherState.java index 9d01ed82d4..de3f441c23 100644 --- a/src/com/android/launcher3/LauncherState.java +++ b/src/com/android/launcher3/LauncherState.java @@ -17,8 +17,7 @@ package com.android.launcher3; import static android.view.View.IMPORTANT_FOR_ACCESSIBILITY_AUTO; import static android.view.View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS; - -import static com.android.launcher3.LauncherAnimUtils.ALL_APPS_TRANSITION_MS; +import static android.view.accessibility.AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED; import android.view.View; @@ -121,11 +120,21 @@ public class LauncherState { return new float[] {1, 0}; } - public void onStateEnabled(Launcher launcher) { } + public void onStateEnabled(Launcher launcher) { + dispatchWindowStateChanged(launcher); + } public void onStateDisabled(Launcher launcher) { } public View getFinalFocus(Launcher launcher) { return launcher.getWorkspace(); } + + public String getDescription(Launcher launcher) { + return launcher.getWorkspace().getCurrentPageDescription(); + } + + protected static void dispatchWindowStateChanged(Launcher launcher) { + launcher.getWindow().getDecorView().sendAccessibilityEvent(TYPE_WINDOW_STATE_CHANGED); + } } diff --git a/src/com/android/launcher3/LauncherStateTransitionAnimation.java b/src/com/android/launcher3/LauncherStateManager.java similarity index 78% rename from src/com/android/launcher3/LauncherStateTransitionAnimation.java rename to src/com/android/launcher3/LauncherStateManager.java index eec8b31c41..4298174aa1 100644 --- a/src/com/android/launcher3/LauncherStateTransitionAnimation.java +++ b/src/com/android/launcher3/LauncherStateManager.java @@ -68,23 +68,73 @@ import com.android.launcher3.anim.AnimationSuccessListener; * - From the center workspace * - From another workspace */ -public class LauncherStateTransitionAnimation { +public class LauncherStateManager { - public static final String TAG = "LSTAnimation"; + public static final String TAG = "StateManager"; private final AnimationConfig mConfig = new AnimationConfig(); private final Handler mUiHandler; private final Launcher mLauncher; private final AllAppsTransitionController mAllAppsController; - public LauncherStateTransitionAnimation( + public LauncherStateManager( Launcher l, AllAppsTransitionController allAppsController) { mUiHandler = new Handler(Looper.getMainLooper()); mLauncher = l; mAllAppsController = allAppsController; } + /** + * @see #goToState(LauncherState, boolean, Runnable) + */ + public void goToState(LauncherState state) { + goToState(state, true, 0, null); + } + + /** + * @see #goToState(LauncherState, boolean, Runnable) + */ + public void goToState(LauncherState state, boolean animated) { + goToState(state, animated, 0, null); + } + + /** + * Changes the Launcher state to the provided state. + * + * @param animated false if the state should change immediately without any animation, + * true otherwise + * @paras onCompleteRunnable any action to perform at the end of the transition, of null. + */ public void goToState(LauncherState state, boolean animated, Runnable onCompleteRunnable) { + goToState(state, animated, 0, onCompleteRunnable); + } + + /** + * Changes the Launcher state to the provided state after the given delay. + */ + public void goToState(LauncherState state, long delay, Runnable onCompleteRunnable) { + goToState(state, true, delay, onCompleteRunnable); + } + + /** + * Changes the Launcher state to the provided state after the given delay. + */ + public void goToState(LauncherState state, long delay) { + goToState(state, true, delay, null); + } + + private void goToState(LauncherState state, boolean animated, long delay, + Runnable onCompleteRunnable) { + if (mLauncher.isInState(state) && mConfig.mCurrentAnimation == null + && !mAllAppsController.isTransitioning()) { + + // Run any queued runnable + if (onCompleteRunnable != null) { + onCompleteRunnable.run(); + } + return; + } + // Cancel the current animation mConfig.reset(); @@ -102,7 +152,9 @@ public class LauncherStateTransitionAnimation { AnimatorSet animation = createAnimationToNewWorkspace(state, onCompleteRunnable); Runnable runnable = new StartAnimRunnable(animation, state.getFinalFocus(mLauncher)); - if (mConfig.shouldPost) { + if (delay > 0) { + mUiHandler.postDelayed(runnable, delay); + } else if (mConfig.shouldPost) { mUiHandler.post(runnable); } else { runnable.run(); diff --git a/src/com/android/launcher3/PinchToOverviewListener.java b/src/com/android/launcher3/PinchToOverviewListener.java index 407f0b59d2..fc75fe3f44 100644 --- a/src/com/android/launcher3/PinchToOverviewListener.java +++ b/src/com/android/launcher3/PinchToOverviewListener.java @@ -16,6 +16,9 @@ package com.android.launcher3; +import static com.android.launcher3.LauncherState.NORMAL; +import static com.android.launcher3.LauncherState.OVERVIEW; + import android.animation.Animator; import android.animation.Animator.AnimatorListener; import android.animation.AnimatorListenerAdapter; @@ -75,8 +78,8 @@ public class PinchToOverviewListener @Override public boolean onScaleBegin(ScaleGestureDetector detector) { - if (!mLauncher.isInState(LauncherState.NORMAL) - && !mLauncher.isInState(LauncherState.OVERVIEW)) { + if (!mLauncher.isInState(NORMAL) + && !mLauncher.isInState(OVERVIEW)) { // Don't listen for the pinch gesture if on all apps, widget picker, -1, etc. return false; } @@ -105,9 +108,8 @@ public class PinchToOverviewListener mLauncher.getDragController().cancelDrag(); } - mToState = mLauncher.isInState(LauncherState.OVERVIEW) - ? LauncherState.NORMAL : LauncherState.OVERVIEW; - mCurrentAnimation = mLauncher.getStateTransition() + mToState = mLauncher.isInState(OVERVIEW) ? NORMAL : OVERVIEW; + mCurrentAnimation = mLauncher.getStateManager() .createAnimationToNewWorkspace(mToState, this); mPinchStarted = true; mCurrentScale = 1; @@ -132,11 +134,8 @@ public class PinchToOverviewListener mCurrentAnimation.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { - if (mToState == LauncherState.OVERVIEW) { - mLauncher.showWorkspace(false); - } else { - mLauncher.showOverviewMode(false); - } + mLauncher.getStateManager().goToState( + mToState == OVERVIEW ? NORMAL : OVERVIEW, false); } }); mCurrentAnimation.reverse(); @@ -150,12 +149,11 @@ public class PinchToOverviewListener // If we are zooming out, inverse the mCurrentScale so that animationFraction = [0, 1] // 0 => Animation complete // 1=> Animation started - float animationFraction = mToState == - LauncherState.OVERVIEW ? mCurrentScale : (1 / mCurrentScale); + float animationFraction = mToState == OVERVIEW ? mCurrentScale : (1 / mCurrentScale); float velocity = (1 - detector.getScaleFactor()) / detector.getTimeDelta(); if (Math.abs(velocity) >= FLING_VELOCITY) { - LauncherState toState = velocity > 0 ? LauncherState.OVERVIEW : LauncherState.NORMAL; + LauncherState toState = velocity > 0 ? OVERVIEW : NORMAL; mShouldGoToFinalState = toState == mToState; } else { mShouldGoToFinalState = animationFraction <= ACCEPT_THRESHOLD; diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index 27d860b560..900e5bfa94 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -16,10 +16,12 @@ package com.android.launcher3; -import static com.android.launcher3.LauncherAnimUtils.SPRING_LOADED_EXIT_NEXT_FRAME; import static com.android.launcher3.LauncherAnimUtils.SPRING_LOADED_EXIT_DELAY; import static com.android.launcher3.LauncherAnimUtils.OVERVIEW_TRANSITION_MS; import static com.android.launcher3.LauncherAnimUtils.SPRING_LOADED_TRANSITION_MS; +import static com.android.launcher3.LauncherState.ALL_APPS; +import static com.android.launcher3.LauncherState.NORMAL; +import static com.android.launcher3.LauncherState.SPRING_LOADED; import static com.android.launcher3.Utilities.isAccessibilityEnabled; import android.animation.Animator; @@ -60,7 +62,7 @@ import android.widget.Toast; import com.android.launcher3.Launcher.LauncherOverlay; import com.android.launcher3.LauncherAppWidgetHost.ProviderChangedListener; -import com.android.launcher3.LauncherStateTransitionAnimation.AnimationConfig; +import com.android.launcher3.LauncherStateManager.AnimationConfig; import com.android.launcher3.accessibility.AccessibleDragListenerAdapter; import com.android.launcher3.accessibility.OverviewAccessibilityDelegate; import com.android.launcher3.accessibility.OverviewScreenAccessibilityDelegate; @@ -205,7 +207,7 @@ public class Workspace extends PagedView private final float[] mHotseatAlpha = new float[] {1, 1, 1}; @ViewDebug.ExportedProperty(category = "launcher") - private LauncherState mState = LauncherState.NORMAL; + private LauncherState mState = NORMAL; private boolean mIsSwitchingState = false; boolean mChildrenLayersEnabled = true; @@ -411,7 +413,7 @@ public class Workspace extends PagedView } // Always enter the spring loaded mode - mLauncher.enterSpringLoadedDragMode(); + mLauncher.getStateManager().goToState(SPRING_LOADED); } public void deferRemoveExtraEmptyScreen() { @@ -1342,7 +1344,7 @@ public class Workspace extends PagedView @Override public void announceForAccessibility(CharSequence text) { // Don't announce if apps is on top of us. - if (!mLauncher.isInState(LauncherState.ALL_APPS)) { + if (!mLauncher.isInState(ALL_APPS)) { super.announceForAccessibility(text); } } @@ -1410,12 +1412,12 @@ public class Workspace extends PagedView } public boolean workspaceInModalState() { - return mState != LauncherState.NORMAL; + return mState != NORMAL; } /** Returns whether a drag should be allowed to be started from the current workspace state. */ public boolean workspaceIconsCanBeDragged() { - return mState == LauncherState.NORMAL || mState == LauncherState.SPRING_LOADED; + return mState == NORMAL || mState == SPRING_LOADED; } private void updateChildrenLayersEnabled() { @@ -2014,7 +2016,7 @@ public class Workspace extends PagedView dropTargetLayout, mTargetCell, distance, false, d.dragView) || addToExistingFolderIfNecessary(cell, dropTargetLayout, mTargetCell, distance, d, false)) { - mLauncher.exitSpringLoadedDragMode(SPRING_LOADED_EXIT_DELAY); + mLauncher.getStateManager().goToState(NORMAL, SPRING_LOADED_EXIT_DELAY); return; } @@ -2129,7 +2131,7 @@ public class Workspace extends PagedView // spring-loaded mode so the page meets the icon where it was picked up. mLauncher.getDragController().animateDragViewToOriginalPosition( onCompleteRunnable, cell, SPRING_LOADED_TRANSITION_MS); - mLauncher.exitSpringLoadedDragMode(SPRING_LOADED_EXIT_NEXT_FRAME); + mLauncher.getStateManager().goToState(NORMAL); mLauncher.getDropTargetBar().onDragEnd(); parent.onDropChild(cell); return; @@ -2152,8 +2154,8 @@ public class Workspace extends PagedView } parent.onDropChild(cell); - mLauncher.exitSpringLoadedDragMode( - SPRING_LOADED_EXIT_DELAY, onCompleteRunnable); + mLauncher.getStateManager().goToState( + NORMAL, SPRING_LOADED_EXIT_DELAY, onCompleteRunnable); } if (d.stateAnnouncer != null && !droppedOnOriginalCell) { @@ -2685,7 +2687,7 @@ public class Workspace extends PagedView final long screenId = getIdForScreen(cellLayout); if (!mLauncher.isHotseatLayout(cellLayout) && screenId != getScreenIdForPageIndex(mCurrentPage) - && mState != LauncherState.SPRING_LOADED) { + && mState != SPRING_LOADED) { snapToPage(getPageIndexForScreenId(screenId)); } @@ -2760,7 +2762,7 @@ public class Workspace extends PagedView animationStyle, finalView, true); } else { // This is for other drag/drop cases, like dragging from All Apps - mLauncher.exitSpringLoadedDragMode(SPRING_LOADED_EXIT_DELAY); + mLauncher.getStateManager().goToState(NORMAL, SPRING_LOADED_EXIT_DELAY); View view; diff --git a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java index ff653d7ea7..0ccb8ad91a 100644 --- a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java +++ b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java @@ -32,7 +32,7 @@ import android.view.View; import android.view.accessibility.AccessibilityManager; import android.view.animation.DecelerateInterpolator; -import com.android.launcher3.LauncherStateTransitionAnimation.AnimationConfig; +import com.android.launcher3.LauncherStateManager.AnimationConfig; import com.android.launcher3.anim.AnimationLayerSet; /** diff --git a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java index 583492e5a3..2b3a113f37 100644 --- a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java +++ b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java @@ -1,5 +1,7 @@ package com.android.launcher3.accessibility; +import static com.android.launcher3.LauncherState.NORMAL; + import android.app.AlertDialog; import android.appwidget.AppWidgetProviderInfo; import android.content.DialogInterface; @@ -27,6 +29,7 @@ import com.android.launcher3.Launcher; import com.android.launcher3.LauncherAppWidgetHostView; import com.android.launcher3.LauncherAppWidgetInfo; import com.android.launcher3.LauncherSettings; +import com.android.launcher3.LauncherSettings.Favorites; import com.android.launcher3.PendingAddItemInfo; import com.android.launcher3.R; import com.android.launcher3.ShortcutInfo; @@ -161,14 +164,14 @@ public class LauncherAccessibilityDelegate extends AccessibilityDelegate impleme } else if (action == ADD_TO_WORKSPACE) { final int[] coordinates = new int[2]; final long screenId = findSpaceOnWorkspace(item, coordinates); - mLauncher.showWorkspace(true, new Runnable() { + mLauncher.getStateManager().goToState(NORMAL, true, new Runnable() { @Override public void run() { if (item instanceof AppInfo) { ShortcutInfo info = ((AppInfo) item).makeShortcut(); mLauncher.getModelWriter().addItemToDatabase(info, - LauncherSettings.Favorites.CONTAINER_DESKTOP, + Favorites.CONTAINER_DESKTOP, screenId, coordinates[0], coordinates[1]); ArrayList itemList = new ArrayList<>(); @@ -178,7 +181,7 @@ public class LauncherAccessibilityDelegate extends AccessibilityDelegate impleme PendingAddItemInfo info = (PendingAddItemInfo) item; Workspace workspace = mLauncher.getWorkspace(); workspace.snapToPage(workspace.getPageIndexForScreenId(screenId)); - mLauncher.addPendingItem(info, LauncherSettings.Favorites.CONTAINER_DESKTOP, + mLauncher.addPendingItem(info, Favorites.CONTAINER_DESKTOP, screenId, coordinates, info.spanX, info.spanY); } announceConfirmation(R.string.item_added_to_workspace); diff --git a/src/com/android/launcher3/accessibility/OverviewAccessibilityDelegate.java b/src/com/android/launcher3/accessibility/OverviewAccessibilityDelegate.java index 29dd95c1a4..771353e77b 100644 --- a/src/com/android/launcher3/accessibility/OverviewAccessibilityDelegate.java +++ b/src/com/android/launcher3/accessibility/OverviewAccessibilityDelegate.java @@ -24,6 +24,7 @@ import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction; import com.android.launcher3.Launcher; +import com.android.launcher3.LauncherState; import com.android.launcher3.R; import com.android.launcher3.Utilities; @@ -55,7 +56,7 @@ public class OverviewAccessibilityDelegate extends AccessibilityDelegate { public boolean performAccessibilityAction(View host, int action, Bundle args) { Launcher launcher = Launcher.getLauncher(host.getContext()); if (action == OVERVIEW) { - launcher.showOverviewMode(true); + launcher.getStateManager().goToState(LauncherState.OVERVIEW); return true; } else if (action == WALLPAPERS) { launcher.onClickWallpaperPicker(host); diff --git a/src/com/android/launcher3/accessibility/ShortcutMenuAccessibilityDelegate.java b/src/com/android/launcher3/accessibility/ShortcutMenuAccessibilityDelegate.java index 5b7353aa18..cfb0520293 100644 --- a/src/com/android/launcher3/accessibility/ShortcutMenuAccessibilityDelegate.java +++ b/src/com/android/launcher3/accessibility/ShortcutMenuAccessibilityDelegate.java @@ -16,6 +16,8 @@ package com.android.launcher3.accessibility; +import static com.android.launcher3.LauncherState.NORMAL; + import android.view.View; import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction; @@ -79,9 +81,7 @@ public class ShortcutMenuAccessibilityDelegate extends LauncherAccessibilityDele } }; - if (!mLauncher.showWorkspace(true, onComplete)) { - onComplete.run(); - } + mLauncher.getStateManager().goToState(NORMAL, true, onComplete); return true; } else if (action == DISMISS_NOTIFICATION) { if (!(host instanceof NotificationMainView)) { diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java index 35dfa8122b..d62cd4b5f4 100644 --- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java +++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java @@ -1,5 +1,8 @@ package com.android.launcher3.allapps; +import static com.android.launcher3.LauncherState.ALL_APPS; +import static com.android.launcher3.LauncherState.NORMAL; + import android.animation.Animator; import android.animation.AnimatorInflater; import android.animation.AnimatorListenerAdapter; @@ -19,7 +22,7 @@ import com.android.launcher3.Hotseat; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherAnimUtils; import com.android.launcher3.LauncherState; -import com.android.launcher3.LauncherStateTransitionAnimation.AnimationConfig; +import com.android.launcher3.LauncherStateManager.AnimationConfig; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.Workspace; @@ -193,7 +196,7 @@ public class AllAppsTransitionController implements TouchController, SwipeDetect @Override public void onDragStart(boolean start) { mCaretController.onDragStart(); - mLauncher.getStateTransition().cancelAnimation(); + mLauncher.getStateManager().cancelAnimation(); cancelDiscoveryAnimation(); mShiftStart = mAppsView.getTranslationY(); onProgressAnimationStart(); @@ -230,7 +233,7 @@ public class AllAppsTransitionController implements TouchController, SwipeDetect if (!mLauncher.isInState(LauncherState.ALL_APPS)) { logSwipeOnContainer(Touch.FLING, Direction.UP, containerType); } - mLauncher.showAppsView(true /* animated */); + mLauncher.getStateManager().goToState(ALL_APPS); if (hasSpringAnimationHandler()) { mSpringAnimationHandler.add(mSearchSpring, true /* setDefaultValues */); // The icons are moving upwards, so we go to 0 from 1. (y-axis 1 is below 0.) @@ -241,7 +244,7 @@ public class AllAppsTransitionController implements TouchController, SwipeDetect if (mLauncher.isInState(LauncherState.ALL_APPS)) { logSwipeOnContainer(Touch.FLING, Direction.DOWN, ContainerType.ALLAPPS); } - mLauncher.showWorkspace(true /* animated */); + mLauncher.getStateManager().goToState(NORMAL); } // snap to top or bottom using the release velocity } else { @@ -250,13 +253,13 @@ public class AllAppsTransitionController implements TouchController, SwipeDetect if (mLauncher.isInState(LauncherState.ALL_APPS)) { logSwipeOnContainer(Touch.SWIPE, Direction.DOWN, ContainerType.ALLAPPS); } - mLauncher.showWorkspace(true /* animated */); + mLauncher.getStateManager().goToState(NORMAL); } else { calculateDuration(velocity, Math.abs(mAppsView.getTranslationY())); if (!mLauncher.isInState(LauncherState.ALL_APPS)) { logSwipeOnContainer(Touch.SWIPE, Direction.UP, containerType); } - mLauncher.showAppsView(true /* animated */); + mLauncher.getStateManager().goToState(ALL_APPS); } } } diff --git a/src/com/android/launcher3/dragndrop/DragController.java b/src/com/android/launcher3/dragndrop/DragController.java index 10bd67de8e..94023833ce 100644 --- a/src/com/android/launcher3/dragndrop/DragController.java +++ b/src/com/android/launcher3/dragndrop/DragController.java @@ -17,6 +17,7 @@ package com.android.launcher3.dragndrop; import static com.android.launcher3.LauncherAnimUtils.SPRING_LOADED_EXIT_DELAY; +import static com.android.launcher3.LauncherState.NORMAL; import android.content.ComponentName; import android.content.res.Resources; @@ -263,7 +264,7 @@ public class DragController implements DragDriver.EventListener, TouchController if (!accepted) { // If it was not accepted, cleanup the state. If it was accepted, it is the // responsibility of the drop target to cleanup the state. - mLauncher.exitSpringLoadedDragMode(SPRING_LOADED_EXIT_DELAY); + mLauncher.getStateManager().goToState(NORMAL, SPRING_LOADED_EXIT_DELAY); mDragObject.deferDragViewCleanupPostAnimation = false; } diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java index fcc4f0efc3..2168001ca3 100644 --- a/src/com/android/launcher3/folder/Folder.java +++ b/src/com/android/launcher3/folder/Folder.java @@ -17,6 +17,7 @@ package com.android.launcher3.folder; import static com.android.launcher3.LauncherAnimUtils.SPRING_LOADED_EXIT_DELAY; +import static com.android.launcher3.LauncherState.NORMAL; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; @@ -1243,7 +1244,7 @@ public class Folder extends AbstractFloatingView implements DragSource, View.OnC mInfo.setOption(FolderInfo.FLAG_MULTI_PAGE_ANIMATION, true, mLauncher.getModelWriter()); } - mLauncher.exitSpringLoadedDragMode(SPRING_LOADED_EXIT_DELAY); + mLauncher.getStateManager().goToState(NORMAL, SPRING_LOADED_EXIT_DELAY); if (d.stateAnnouncer != null) { d.stateAnnouncer.completeAction(R.string.item_moved); } diff --git a/src/com/android/launcher3/states/AllAppsState.java b/src/com/android/launcher3/states/AllAppsState.java index 9922d999cd..ee35b4d7c3 100644 --- a/src/com/android/launcher3/states/AllAppsState.java +++ b/src/com/android/launcher3/states/AllAppsState.java @@ -19,8 +19,10 @@ import static com.android.launcher3.LauncherAnimUtils.ALL_APPS_TRANSITION_MS; import android.view.View; +import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherState; +import com.android.launcher3.R; import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; /** @@ -41,6 +43,14 @@ public class AllAppsState extends LauncherState { if (!launcher.getSharedPrefs().getBoolean(APPS_VIEW_SHOWN, false)) { launcher.getSharedPrefs().edit().putBoolean(APPS_VIEW_SHOWN, true).apply(); } + + AbstractFloatingView.closeAllOpenViews(launcher); + dispatchWindowStateChanged(launcher); + } + + @Override + public String getDescription(Launcher launcher) { + return launcher.getString(R.string.all_apps_button_label); } @Override diff --git a/src/com/android/launcher3/util/FlingAnimation.java b/src/com/android/launcher3/util/FlingAnimation.java index ec62764781..fe0571b8ad 100644 --- a/src/com/android/launcher3/util/FlingAnimation.java +++ b/src/com/android/launcher3/util/FlingAnimation.java @@ -1,6 +1,6 @@ package com.android.launcher3.util; -import static com.android.launcher3.LauncherAnimUtils.SPRING_LOADED_EXIT_NEXT_FRAME; +import static com.android.launcher3.LauncherState.NORMAL; import android.animation.TimeInterpolator; import android.animation.ValueAnimator; @@ -97,7 +97,7 @@ public class FlingAnimation implements AnimatorUpdateListener, Runnable { Runnable onAnimationEndRunnable = new Runnable() { @Override public void run() { - mLauncher.exitSpringLoadedDragMode(SPRING_LOADED_EXIT_NEXT_FRAME); + mLauncher.getStateManager().goToState(NORMAL); mDropTarget.completeDrop(mDragObject); } };