From c99cb174c3369c8c192efc12d97dd8e9f6d189b9 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Thu, 19 Oct 2017 16:15:09 -0700 Subject: [PATCH] Moving some state specific logic to subclass of LauncherState Bug: 67678570 Change-Id: I1316f91c9f19bd572e4a0da67a22fa8921e1dcf9 --- res/values/config.xml | 2 - src/com/android/launcher3/DeviceProfile.java | 2 +- src/com/android/launcher3/Launcher.java | 60 +----- src/com/android/launcher3/LauncherState.java | 24 ++- src/com/android/launcher3/PagedView.java | 5 +- src/com/android/launcher3/Utilities.java | 6 + src/com/android/launcher3/Workspace.java | 178 ++++++------------ .../WorkspaceStateTransitionAnimation.java | 21 +-- .../launcher3/states/OverviewState.java | 78 ++++++++ .../launcher3/states/SpringLoadedState.java | 108 +++++++++++ 10 files changed, 277 insertions(+), 207 deletions(-) create mode 100644 src/com/android/launcher3/states/OverviewState.java create mode 100644 src/com/android/launcher3/states/SpringLoadedState.java diff --git a/res/values/config.xml b/res/values/config.xml index c0bf360385..7a33ae6535 100644 --- a/res/values/config.xml +++ b/res/values/config.xml @@ -50,8 +50,6 @@ 90 - - 70 diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java index 8f7e8822b4..8aaad1367e 100644 --- a/src/com/android/launcher3/DeviceProfile.java +++ b/src/com/android/launcher3/DeviceProfile.java @@ -570,7 +570,7 @@ public class DeviceProfile { } } - int getOverviewModeButtonBarHeight() { + public int getOverviewModeButtonBarHeight() { int zoneHeight = (int) (overviewModeIconZoneRatio * availableHeightPx); return Utilities.boundToRange(zoneHeight, overviewModeMinIconZoneHeightPx, diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index 46eb263c63..b06081b812 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -16,6 +16,9 @@ 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.logging.LoggerUtils.newContainerTarget; @@ -47,7 +50,6 @@ import android.content.IntentFilter; import android.content.IntentSender; import android.content.SharedPreferences; import android.content.SharedPreferences.OnSharedPreferenceChangeListener; -import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.database.sqlite.SQLiteDatabase; import android.graphics.Point; @@ -264,10 +266,6 @@ public class Launcher extends BaseActivity private PopupDataProvider mPopupDataProvider; - // Determines how long to wait after a rotation before restoring the screen orientation to - // match the sensor state. - private static final int RESTORE_SCREEN_ORIENTATION_DELAY = 500; - private final ArrayList mSynchronouslyBoundPages = new ArrayList<>(); // We only want to get the SharedPreferences once since it does an FS stat each time we get @@ -291,18 +289,8 @@ public class Launcher extends BaseActivity public ViewGroupFocusHelper mFocusHandler; private boolean mRotationEnabled = false; - private boolean mAppLaunchSuccess; - @Thunk void setOrientation() { - if (mRotationEnabled) { - unlockScreenOrientation(true); - } else { - setRequestedOrientation( - ActivityInfo.SCREEN_ORIENTATION_NOSENSOR); - } - } - private RotationPrefChangeHandler mRotationPrefChangeHandler; @Override @@ -416,7 +404,8 @@ public class Launcher extends BaseActivity // On large interfaces, or on devices that a user has specifically enabled screen rotation, // we want the screen to auto-rotate based on the current orientation - setOrientation(); + setRequestedOrientation(mRotationEnabled + ? SCREEN_ORIENTATION_UNSPECIFIED : SCREEN_ORIENTATION_NOSENSOR); setContentView(mLauncherView); @@ -1896,11 +1885,8 @@ public class Launcher extends BaseActivity AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(this); if (topView != null) { topView.onBackPressed(); - } else if (isInState(LauncherState.ALL_APPS)) { - ued.logActionCommand(Action.Command.BACK, ContainerType.ALLAPPS); - showWorkspace(true); - } else if (isInState(LauncherState.OVERVIEW)) { - ued.logActionCommand(Action.Command.BACK, ContainerType.OVERVIEW); + } else if (!isInState(LauncherState.NORMAL)) { + ued.logActionCommand(Action.Command.BACK, mWorkspace.getState().containerType); showWorkspace(true); } else { // Back button is a no-op here, but give at least some feedback for the button press @@ -2381,7 +2367,7 @@ public class Launcher extends BaseActivity if (!mDragController.isDragging()) { if (itemUnderLongClick == null) { // User long pressed on empty space - if (isInState(LauncherState.OVERVIEW)) { + if (mWorkspace.isPageRearrangeEnabled()) { mWorkspace.startReordering(v); getUserEventDispatcher().logActionOnContainer(Action.Touch.LONGPRESS, Action.Direction.NONE, ContainerType.OVERVIEW); @@ -2544,15 +2530,6 @@ public class Launcher extends BaseActivity return; } - // Lock the orientation: - if (mRotationEnabled) { - setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED); - } - - // Prevent any Un/InstallShortcutReceivers from updating the db while we are - // in spring loaded mode - InstallShortcutReceiver.enableInstallQueue(InstallShortcutReceiver.FLAG_DRAG_AND_DROP); - mStateTransitionAnimation.startAnimationToWorkspace( LauncherState.SPRING_LOADED, true /* animated */, null /* onCompleteRunnable */); @@ -2565,13 +2542,6 @@ public class Launcher extends BaseActivity public void exitSpringLoadedDragMode(int delay, final Runnable onCompleteRunnable) { if (!isInState(LauncherState.SPRING_LOADED)) return; - // Unlock rotation lock - unlockScreenOrientation(false); - - // Re-enable any Un/InstallShortcutReceiver and now process any queued items - InstallShortcutReceiver.disableAndFlushInstallQueue( - InstallShortcutReceiver.FLAG_DRAG_AND_DROP, this); - if (mExitSpringLoadedModeRunnable != null) { mHandler.removeCallbacks(mExitSpringLoadedModeRunnable); } @@ -3333,18 +3303,8 @@ public class Launcher extends BaseActivity mModel.refreshAndBindWidgetsAndShortcuts(packageUser); } - public void unlockScreenOrientation(boolean immediate) { - if (mRotationEnabled) { - if (immediate) { - setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); - } else { - mHandler.postDelayed(new Runnable() { - public void run() { - setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); - } - }, RESTORE_SCREEN_ORIENTATION_DELAY); - } - } + public boolean isRotationEnabled () { + return mRotationEnabled; } private void markAppsViewShown() { diff --git a/src/com/android/launcher3/LauncherState.java b/src/com/android/launcher3/LauncherState.java index 4619f4e58e..0ac27e5385 100644 --- a/src/com/android/launcher3/LauncherState.java +++ b/src/com/android/launcher3/LauncherState.java @@ -19,9 +19,9 @@ 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 com.android.launcher3.LauncherAnimUtils.OVERVIEW_TRANSITION_MS; -import static com.android.launcher3.LauncherAnimUtils.SPRING_LOADED_TRANSITION_MS; +import com.android.launcher3.states.OverviewState; +import com.android.launcher3.states.SpringLoadedState; import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; import java.util.Arrays; @@ -40,19 +40,15 @@ public class LauncherState { private static final LauncherState[] sAllStates = new LauncherState[4]; - public static LauncherState NORMAL = new LauncherState(0, ContainerType.WORKSPACE, + public static final LauncherState NORMAL = new LauncherState(0, ContainerType.WORKSPACE, 0, FLAG_DO_NOT_RESTORE); - public static LauncherState ALL_APPS = new LauncherState(1, ContainerType.ALLAPPS, + public static final LauncherState ALL_APPS = new LauncherState(1, ContainerType.ALLAPPS, ALL_APPS_TRANSITION_MS, FLAG_DISABLE_ACCESSIBILITY); - public static LauncherState SPRING_LOADED = new LauncherState(2, ContainerType.WORKSPACE, - SPRING_LOADED_TRANSITION_MS, - FLAG_SHOW_SCRIM | FLAG_MULTI_PAGE | FLAG_DISABLE_ACCESSIBILITY | FLAG_DO_NOT_RESTORE); + public static final LauncherState SPRING_LOADED = new SpringLoadedState(2); - public static LauncherState OVERVIEW = new LauncherState(3, ContainerType.OVERVIEW, - OVERVIEW_TRANSITION_MS, - FLAG_SHOW_SCRIM | FLAG_MULTI_PAGE | FLAG_HIDE_HOTSEAT | FLAG_DO_NOT_RESTORE); + public static final LauncherState OVERVIEW = new OverviewState(3); public final int ordinal; @@ -101,4 +97,12 @@ public class LauncherState { public static LauncherState[] values() { return Arrays.copyOf(sAllStates, sAllStates.length); } + + public float[] getWorkspaceScaleAndTranslation(Launcher launcher) { + return new float[] {1, 0}; + } + + public void onStateEnabled(Launcher launcher) { } + + public void onStateDisabled(Launcher launcher) { } } diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java index 87f3ddaf47..5258fba927 100644 --- a/src/com/android/launcher3/PagedView.java +++ b/src/com/android/launcher3/PagedView.java @@ -1341,12 +1341,11 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc /** * return true if freescroll has been enabled, false otherwise */ - public boolean enableFreeScroll() { + protected void enableFreeScroll() { setEnableFreeScroll(true); - return true; } - public void disableFreeScroll() { + protected void disableFreeScroll() { setEnableFreeScroll(false); } diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java index 71677782df..e6bc770663 100644 --- a/src/com/android/launcher3/Utilities.java +++ b/src/com/android/launcher3/Utilities.java @@ -614,6 +614,12 @@ public final class Utilities { return c == null || c.isEmpty(); } + public static boolean isAccessibilityEnabled(Context context) { + AccessibilityManager accessibilityManager = (AccessibilityManager) + context.getSystemService(Context.ACCESSIBILITY_SERVICE); + return accessibilityManager.isEnabled(); + } + public static void sendCustomAccessibilityEvent(View target, int type, String text) { AccessibilityManager accessibilityManager = (AccessibilityManager) target.getContext().getSystemService(Context.ACCESSIBILITY_SERVICE); diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index 671ba07720..173ff6d4a8 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -20,6 +20,7 @@ import static com.android.launcher3.LauncherAnimUtils.SPRING_LOADED_EXIT_NEXT_FR 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.Utilities.isAccessibilityEnabled; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; @@ -82,6 +83,7 @@ import com.android.launcher3.graphics.DragPreviewProvider; import com.android.launcher3.graphics.PreloadIconDrawable; import com.android.launcher3.popup.PopupContainerWithArrow; import com.android.launcher3.shortcuts.ShortcutDragPreviewProvider; +import com.android.launcher3.states.OverviewState; import com.android.launcher3.userevent.nano.LauncherLogProto.Action; import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; import com.android.launcher3.userevent.nano.LauncherLogProto.Target; @@ -173,16 +175,11 @@ public class Workspace extends PagedView @Thunk final Launcher mLauncher; @Thunk DragController mDragController; - // These are temporary variables to prevent having to allocate a new object just to - // return an (x, y) value from helper functions. Do NOT use them to maintain other state. - private static final Rect sTempRect = new Rect(); - private final int[] mTempXY = new int[2]; @Thunk float[] mDragViewVisualCenter = new float[2]; private final float[] mTempTouchCoordinates = new float[2]; private SpringLoadedDragController mSpringLoadedDragController; - private final float mOverviewModeShrinkFactor; // Direction used for moving the workspace and hotseat UI public enum Direction { @@ -271,6 +268,8 @@ public class Workspace extends PagedView boolean mOverlayShown = false; private boolean mForceDrawAdjacentPages = false; + private boolean mPageRearrangeEnabled = false; + // Total over scrollX in the overlay direction. private float mOverlayTranslation; @@ -307,8 +306,6 @@ public class Workspace extends PagedView mWallpaperManager = WallpaperManager.getInstance(context); mWallpaperOffset = new WallpaperOffsetInterpolator(this); - mOverviewModeShrinkFactor = - res.getInteger(R.integer.config_workspaceOverviewShrinkPercentage) / 100f; setOnHierarchyChangeListener(this); setHapticFeedbackEnabled(false); @@ -448,7 +445,8 @@ public class Workspace extends PagedView setClipChildren(false); setClipToPadding(false); - setMinScale(mOverviewModeShrinkFactor); + // TODO: Remove this + setMinScale(OverviewState.SCALE_FACTOR); setupLayoutTransition(); mMaxDistanceForFolderCreation = (0.55f * grid.iconSizePx); @@ -1126,7 +1124,7 @@ public class Workspace extends PagedView enableHwLayersOnVisiblePages(); } - private void showPageIndicatorAtCurrentScroll() { + public void showPageIndicatorAtCurrentScroll() { if (mPageIndicator != null) { mPageIndicator.setScroll(getScrollX(), computeMaxScrollX()); } @@ -1282,7 +1280,7 @@ public class Workspace extends PagedView } }); - final boolean accessibilityEnabled = isAccessibilityEnabled(); + final boolean accessibilityEnabled = isAccessibilityEnabled(mLauncher); animator.addUpdateListener( new AlphaUpdateListener(mLauncher.getHotseat(), accessibilityEnabled)); animator.addUpdateListener( @@ -1291,12 +1289,6 @@ public class Workspace extends PagedView } } - protected boolean isAccessibilityEnabled() { - AccessibilityManager am = (AccessibilityManager) - mLauncher.getSystemService(Context.ACCESSIBILITY_SERVICE); - return am.isEnabled(); - } - @Override protected void notifyPageSwitchListener(int prevPage) { super.notifyPageSwitchListener(prevPage); @@ -1428,8 +1420,8 @@ public class Workspace extends PagedView } private void updateChildrenLayersEnabled() { - boolean small = mState == LauncherState.OVERVIEW || mIsSwitchingState; - boolean enableChildrenLayers = small || isPageInTransition(); + boolean enableChildrenLayers = + isPageRearrangeEnabled() || mIsSwitchingState || isPageInTransition(); if (enableChildrenLayers != mChildrenLayersEnabled) { mChildrenLayersEnabled = enableChildrenLayers; @@ -1551,59 +1543,33 @@ public class Workspace extends PagedView snapToPage(whichPage, OVERVIEW_TRANSITION_MS, new ZoomInInterpolator()); } - int getOverviewModeTranslationY() { - DeviceProfile grid = mLauncher.getDeviceProfile(); - int overviewButtonBarHeight = grid.getOverviewModeButtonBarHeight(); + private void onStartStateTransition(LauncherState state) { + // Change the internal state only when the transition actually starts + mState.onStateDisabled(mLauncher); + mState = state; + mState.onStateEnabled(mLauncher); - int scaledHeight = (int) (mOverviewModeShrinkFactor * getNormalChildHeight()); - Rect workspacePadding = grid.getWorkspacePadding(sTempRect); - int workspaceTop = mInsets.top + workspacePadding.top; - int workspaceBottom = getViewportHeight() - mInsets.bottom - workspacePadding.bottom; - int overviewTop = mInsets.top; - int overviewBottom = getViewportHeight() - mInsets.bottom - overviewButtonBarHeight; - int workspaceOffsetTopEdge = workspaceTop + ((workspaceBottom - workspaceTop) - scaledHeight) / 2; - int overviewOffsetTopEdge = overviewTop + (overviewBottom - overviewTop - scaledHeight) / 2; - return -workspaceOffsetTopEdge + overviewOffsetTopEdge; + mIsSwitchingState = true; + mTransitionProgress = 0; + + updateChildrenLayersEnabled(); } - float getSpringLoadedTranslationY() { - DeviceProfile grid = mLauncher.getDeviceProfile(); - if (grid.isVerticalBarLayout() || getChildCount() == 0) { - return 0; - } + private void onEndStateTransition() { + mIsSwitchingState = false; + mForceDrawAdjacentPages = false; + mTransitionProgress = 1; - float scaledHeight = grid.workspaceSpringLoadShrinkFactor * getNormalChildHeight(); - float shrunkTop = mInsets.top + grid.dropTargetBarSizePx; - float shrunkBottom = getViewportHeight() - mInsets.bottom - - grid.getWorkspacePadding(sTempRect).bottom - - grid.workspaceSpringLoadedBottomSpace; - float totalShrunkSpace = shrunkBottom - shrunkTop; - - float desiredCellTop = shrunkTop + (totalShrunkSpace - scaledHeight) / 2; - - float halfHeight = getHeight() / 2; - float myCenter = getTop() + halfHeight; - float cellTopFromCenter = halfHeight - getChildAt(0).getTop(); - float actualCellTop = myCenter - cellTopFromCenter * grid.workspaceSpringLoadShrinkFactor; - return (desiredCellTop - actualCellTop) / grid.workspaceSpringLoadShrinkFactor; + updateChildrenLayersEnabled(); + updateAccessibilityFlags(); } - float getOverviewModeShrinkFactor() { - return mOverviewModeShrinkFactor; - } - - /** * Sets the current workspace {@link LauncherState} and updates the UI without any animations */ public void setState(LauncherState toState) { - // Update the current state - mState = toState; + onStartStateTransition(toState); mStateTransitionAnimation.setState(mState); - - updateAccessibilityFlags(); - onPrepareStateTransition(mState.hasMultipleVisiblePages); - onStartStateTransition(); onEndStateTransition(); } @@ -1612,20 +1578,18 @@ public class Workspace extends PagedView */ public void setStateWithAnimation(LauncherState toState, AnimationLayerSet layerViews, AnimatorSet anim, AnimationConfig config) { - final LauncherState fromState = mState; + StateTransitionListener listener = new StateTransitionListener(toState); + mStateTransitionAnimation.setStateWithAnimation(mState, toState, anim, layerViews, config); - // Update the current state - mState = toState; - mStateTransitionAnimation.setStateWithAnimation( - fromState, toState, anim, layerViews, config); + // Invalidate the pages now, so that we have the visible pages before the + // animation is started + if (toState.hasMultipleVisiblePages) { + mForceDrawAdjacentPages = true; + } + invalidate(); // This will call dispatchDraw(), which calls getVisiblePages(). - updateAccessibilityFlags(); - onPrepareStateTransition(mState.hasMultipleVisiblePages); - - StateTransitionListener listener = new StateTransitionListener(); ValueAnimator stepAnimator = ValueAnimator.ofFloat(0, 1); stepAnimator.addUpdateListener(listener); - anim.play(stepAnimator); anim.addListener(listener); } @@ -1646,7 +1610,7 @@ public class Workspace extends PagedView } private void updateAccessibilityFlags(CellLayout page, int pageNo) { - if (mState == LauncherState.OVERVIEW) { + if (isPageRearrangeEnabled()) { page.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES); page.getShortcutsAndWidgets().setImportantForAccessibility( IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS); @@ -1668,43 +1632,19 @@ public class Workspace extends PagedView } } - public void onPrepareStateTransition(boolean multiplePagesVisible) { - mIsSwitchingState = true; - mTransitionProgress = 0; - - if (multiplePagesVisible) { - mForceDrawAdjacentPages = true; + public void setPageRearrangeEnabled(boolean isEnabled) { + if (mPageRearrangeEnabled != isEnabled) { + mPageRearrangeEnabled = isEnabled; + if (isEnabled) { + enableFreeScroll(); + } else { + disableFreeScroll(); + } } - invalidate(); // This will call dispatchDraw(), which calls getVisiblePages(). - - updateChildrenLayersEnabled(); } - private void onStartStateTransition() { - if (mState == LauncherState.SPRING_LOADED) { - // Show the page indicator at the same time as the rest of the transition. - showPageIndicatorAtCurrentScroll(); - } - getPageIndicator().setShouldAutoHide(mState != LauncherState.SPRING_LOADED); - } - - public void onEndStateTransition() { - mIsSwitchingState = false; - updateChildrenLayersEnabled(); - mForceDrawAdjacentPages = false; - mTransitionProgress = 1; - - if (mState == LauncherState.OVERVIEW) { - enableFreeScroll(); - } else { - disableFreeScroll(); - } - - ViewGroup overviewPanel = mLauncher.getOverviewPanel(); - if (isAccessibilityEnabled() && overviewPanel.getVisibility() == View.VISIBLE) { - overviewPanel.getChildAt(0).performAccessibilityAction( - AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null); - } + public boolean isPageRearrangeEnabled() { + return mPageRearrangeEnabled; } public void startDrag(CellLayout.CellInfo cellInfo, DragOptions options) { @@ -1803,8 +1743,8 @@ public class Workspace extends PagedView } private boolean transitionStateShouldAllowDrop() { - return ((!isSwitchingState() || mTransitionProgress > ALLOW_DROP_TRANSITION_PROGRESS) && - (mState == LauncherState.NORMAL || mState == LauncherState.SPRING_LOADED)); + return (!isSwitchingState() || mTransitionProgress > ALLOW_DROP_TRANSITION_PROGRESS) && + workspaceIconsCanBeDragged(); } /** @@ -3022,10 +2962,6 @@ public class Workspace extends PagedView } } - public WorkspaceStateTransitionAnimation getStateTransitionAnimation() { - return mStateTransitionAnimation; - } - /** * Return the current CellInfo describing our current drag; this method exists * so that Launcher can sync this object with the correct info when the activity is created/ @@ -3563,16 +3499,6 @@ public class Workspace extends PagedView } } - @Override - public boolean enableFreeScroll() { - if (getState() == LauncherState.OVERVIEW) { - return super.enableFreeScroll(); - } else { - Log.w(TAG, "enableFreeScroll called but not in overview: state=" + getState()); - return false; - } - } - /** * Used as a workaround to ensure that the AppWidgetService receives the * PACKAGE_ADDED broadcast before updating widgets. @@ -3629,6 +3555,13 @@ public class Workspace extends PagedView private class StateTransitionListener extends AnimatorListenerAdapter implements AnimatorUpdateListener { + + private final LauncherState mToState; + + StateTransitionListener(LauncherState toState) { + mToState = toState; + } + @Override public void onAnimationUpdate(ValueAnimator anim) { mTransitionProgress = anim.getAnimatedFraction(); @@ -3636,8 +3569,7 @@ public class Workspace extends PagedView @Override public void onAnimationStart(Animator animation) { - mTransitionProgress = 0; - onStartStateTransition(); + onStartStateTransition(mToState); } @Override diff --git a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java index af56fd77c6..d626b65818 100644 --- a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java +++ b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java @@ -18,8 +18,6 @@ package com.android.launcher3; import static com.android.launcher3.LauncherAnimUtils.DRAWABLE_ALPHA; import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY; -import static com.android.launcher3.LauncherState.OVERVIEW; -import static com.android.launcher3.LauncherState.SPRING_LOADED; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; @@ -145,8 +143,6 @@ public class WorkspaceStateTransitionAnimation { private final Launcher mLauncher; private final Workspace mWorkspace; - private final float mSpringLoadedShrinkFactor; - private final float mOverviewModeShrinkFactor; private final boolean mWorkspaceFadeInAdjacentScreens; private float mNewScale; @@ -157,9 +153,6 @@ public class WorkspaceStateTransitionAnimation { DeviceProfile grid = mLauncher.getDeviceProfile(); Resources res = launcher.getResources(); - mSpringLoadedShrinkFactor = mLauncher.getDeviceProfile().workspaceSpringLoadShrinkFactor; - mOverviewModeShrinkFactor = - res.getInteger(R.integer.config_workspaceOverviewShrinkPercentage) / 100f; mWorkspaceScrimAlpha = res.getInteger(R.integer.config_workspaceScrimAlpha); mWorkspaceFadeInAdjacentScreens = grid.shouldFadeAdjacentWorkspaceScreens(); } @@ -188,17 +181,9 @@ public class WorkspaceStateTransitionAnimation { // Update the workspace state int finalBackgroundAlpha = state.hasScrim ? 255 : 0; - final float finalWorkspaceTranslationY; - if (state == OVERVIEW) { - mNewScale = mOverviewModeShrinkFactor; - finalWorkspaceTranslationY = mWorkspace.getOverviewModeTranslationY(); - } else if (state == SPRING_LOADED) { - mNewScale = mSpringLoadedShrinkFactor; - finalWorkspaceTranslationY = mWorkspace.getSpringLoadedTranslationY(); - } else { - mNewScale = 1f; - finalWorkspaceTranslationY = 0; - } + float[] scaleAndTranslationY = state.getWorkspaceScaleAndTranslation(mLauncher); + final float mNewScale = scaleAndTranslationY[0]; + final float finalWorkspaceTranslationY = scaleAndTranslationY[1]; int toPage = mWorkspace.getPageNearestToCenterOfScreen(); final int childCount = mWorkspace.getChildCount(); diff --git a/src/com/android/launcher3/states/OverviewState.java b/src/com/android/launcher3/states/OverviewState.java new file mode 100644 index 0000000000..911cec62f5 --- /dev/null +++ b/src/com/android/launcher3/states/OverviewState.java @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2017 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.states; + +import static com.android.launcher3.LauncherAnimUtils.OVERVIEW_TRANSITION_MS; +import static com.android.launcher3.Utilities.isAccessibilityEnabled; + +import android.graphics.Rect; +import android.view.accessibility.AccessibilityNodeInfo; + +import com.android.launcher3.DeviceProfile; +import com.android.launcher3.Launcher; +import com.android.launcher3.LauncherState; +import com.android.launcher3.Workspace; +import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; + +/** + * Definition for overview state + */ +public class OverviewState extends LauncherState { + + // The percent to shrink the workspace during overview mode + public static final float SCALE_FACTOR = 0.7f; + + private static final int STATE_FLAGS = FLAG_SHOW_SCRIM | FLAG_MULTI_PAGE | FLAG_HIDE_HOTSEAT | + FLAG_DO_NOT_RESTORE; + + public OverviewState(int id) { + super(id, ContainerType.WORKSPACE, OVERVIEW_TRANSITION_MS, STATE_FLAGS); + } + + @Override + public float[] getWorkspaceScaleAndTranslation(Launcher launcher) { + DeviceProfile grid = launcher.getDeviceProfile(); + Workspace ws = launcher.getWorkspace(); + Rect insets = launcher.getDragLayer().getInsets(); + + int overviewButtonBarHeight = grid.getOverviewModeButtonBarHeight(); + int scaledHeight = (int) (SCALE_FACTOR * ws.getNormalChildHeight()); + Rect workspacePadding = grid.getWorkspacePadding(null); + int workspaceTop = insets.top + workspacePadding.top; + int workspaceBottom = ws.getViewportHeight() - insets.bottom - workspacePadding.bottom; + int overviewTop = insets.top; + int overviewBottom = ws.getViewportHeight() - insets.bottom - overviewButtonBarHeight; + int workspaceOffsetTopEdge = + workspaceTop + ((workspaceBottom - workspaceTop) - scaledHeight) / 2; + int overviewOffsetTopEdge = overviewTop + (overviewBottom - overviewTop - scaledHeight) / 2; + return new float[] {SCALE_FACTOR, -workspaceOffsetTopEdge + overviewOffsetTopEdge }; + } + + @Override + public void onStateEnabled(Launcher launcher) { + launcher.getWorkspace().setPageRearrangeEnabled(true); + + if (isAccessibilityEnabled(launcher)) { + launcher.getOverviewPanel().getChildAt(0).performAccessibilityAction( + AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null); + } + } + + @Override + public void onStateDisabled(Launcher launcher) { + launcher.getWorkspace().setPageRearrangeEnabled(false); + } +} diff --git a/src/com/android/launcher3/states/SpringLoadedState.java b/src/com/android/launcher3/states/SpringLoadedState.java new file mode 100644 index 0000000000..f60ef0ca1b --- /dev/null +++ b/src/com/android/launcher3/states/SpringLoadedState.java @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2017 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.states; + +import static com.android.launcher3.LauncherAnimUtils.SPRING_LOADED_TRANSITION_MS; + +import android.content.pm.ActivityInfo; +import android.graphics.Rect; +import android.os.Handler; + +import com.android.launcher3.DeviceProfile; +import com.android.launcher3.InstallShortcutReceiver; +import com.android.launcher3.Launcher; +import com.android.launcher3.LauncherState; +import com.android.launcher3.Workspace; +import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; + +/** + * Definition for spring loaded state used during drag and drop. + */ +public class SpringLoadedState extends LauncherState { + + private static final int STATE_FLAGS = FLAG_SHOW_SCRIM | FLAG_MULTI_PAGE | + FLAG_DISABLE_ACCESSIBILITY | FLAG_DO_NOT_RESTORE; + + // Determines how long to wait after a rotation before restoring the screen orientation to + // match the sensor state. + private static final int RESTORE_SCREEN_ORIENTATION_DELAY = 500; + + public SpringLoadedState(int id) { + super(id, ContainerType.OVERVIEW, SPRING_LOADED_TRANSITION_MS, STATE_FLAGS); + } + + @Override + public float[] getWorkspaceScaleAndTranslation(Launcher launcher) { + DeviceProfile grid = launcher.getDeviceProfile(); + Workspace ws = launcher.getWorkspace(); + if (grid.isVerticalBarLayout() || ws.getChildCount() == 0) { + return super.getWorkspaceScaleAndTranslation(launcher); + } + + float scale = grid.workspaceSpringLoadShrinkFactor; + Rect insets = launcher.getDragLayer().getInsets(); + + float scaledHeight = scale * ws.getNormalChildHeight(); + float shrunkTop = insets.top + grid.dropTargetBarSizePx; + float shrunkBottom = ws.getViewportHeight() - insets.bottom + - grid.getWorkspacePadding(null).bottom + - grid.workspaceSpringLoadedBottomSpace; + float totalShrunkSpace = shrunkBottom - shrunkTop; + + float desiredCellTop = shrunkTop + (totalShrunkSpace - scaledHeight) / 2; + + float halfHeight = ws.getHeight() / 2; + float myCenter = ws.getTop() + halfHeight; + float cellTopFromCenter = halfHeight - ws.getChildAt(0).getTop(); + float actualCellTop = myCenter - cellTopFromCenter * scale; + return new float[] { scale, (desiredCellTop - actualCellTop) / scale}; + } + + @Override + public void onStateEnabled(Launcher launcher) { + Workspace ws = launcher.getWorkspace(); + ws.showPageIndicatorAtCurrentScroll(); + ws.getPageIndicator().setShouldAutoHide(false); + + // Lock the orientation: + if (launcher.isRotationEnabled()) { + launcher.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED); + } + + // Prevent any Un/InstallShortcutReceivers from updating the db while we are + // in spring loaded mode + InstallShortcutReceiver.enableInstallQueue(InstallShortcutReceiver.FLAG_DRAG_AND_DROP); + } + + @Override + public void onStateDisabled(final Launcher launcher) { + launcher.getWorkspace().getPageIndicator().setShouldAutoHide(true); + + // Unlock rotation lock + if (launcher.isRotationEnabled()) { + new Handler().postDelayed(new Runnable() { + @Override + public void run() { + launcher.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); + } + }, RESTORE_SCREEN_ORIENTATION_DELAY); + } + + // Re-enable any Un/InstallShortcutReceiver and now process any queued items + InstallShortcutReceiver.disableAndFlushInstallQueue( + InstallShortcutReceiver.FLAG_DRAG_AND_DROP, launcher); + } +}