Rearranging the code structure to allow replacing state logic.

Change-Id: I6f83d0f77045ba189f02dd465bf70ffc2a239aa1
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 1542703..ca75603 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -167,7 +167,6 @@
 public class Launcher extends BaseActivity
         implements LauncherExterns, View.OnClickListener, OnLongClickListener,
                    LauncherModel.Callbacks, View.OnTouchListener, LauncherProviderChangeListener,
-                   AccessibilityManager.AccessibilityStateChangeListener,
                    WallpaperColorInfo.OnThemeChangeListener {
     public static final String TAG = "Launcher";
     static final boolean LOGD = false;
@@ -361,9 +360,6 @@
 
         mPopupDataProvider = new PopupDataProvider(this);
 
-        ((AccessibilityManager) getSystemService(ACCESSIBILITY_SERVICE))
-                .addAccessibilityStateChangeListener(this);
-
         restoreState(savedInstanceState);
 
         // We only load the page synchronously if the user rotates (or triggers a
@@ -1552,10 +1548,6 @@
         mAppWidgetHost = null;
 
         TextKeyListener.getInstance().release();
-
-        ((AccessibilityManager) getSystemService(ACCESSIBILITY_SERVICE))
-                .removeAccessibilityStateChangeListener(this);
-
         WallpaperColorInfo.getInstance(this).setOnThemeChangeListener(null);
 
         LauncherAnimUtils.onDestroyActivity();
@@ -2190,11 +2182,6 @@
         startActivity(intent, getActivityLaunchOptions(v));
     }
 
-    @Override
-    public void onAccessibilityStateChanged(boolean enabled) {
-        mDragLayer.onAccessibilityStateChanged(enabled);
-    }
-
     private void startShortcutIntentSafely(Intent intent, Bundle optsBundle, ItemInfo info) {
         try {
             StrictMode.VmPolicy oldPolicy = StrictMode.getVmPolicy();
diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java
index 25a698b..98568e4 100644
--- a/src/com/android/launcher3/LauncherProvider.java
+++ b/src/com/android/launcher3/LauncherProvider.java
@@ -44,7 +44,6 @@
 import android.os.Handler;
 import android.os.Message;
 import android.os.Process;
-import android.os.Trace;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.text.TextUtils;
@@ -86,7 +85,7 @@
      */
     public static final int SCHEMA_VERSION = 27;
 
-    public static final String AUTHORITY = (BuildConfig.APPLICATION_ID + ".settings").intern();
+    public static final String AUTHORITY = FeatureFlags.AUTHORITY;
 
     static final String EMPTY_DATABASE_CREATED = "EMPTY_DATABASE_CREATED";
 
diff --git a/src/com/android/launcher3/LauncherState.java b/src/com/android/launcher3/LauncherState.java
index 63c232d..bb09a9f 100644
--- a/src/com/android/launcher3/LauncherState.java
+++ b/src/com/android/launcher3/LauncherState.java
@@ -21,9 +21,9 @@
 
 import android.view.View;
 
-import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.states.AllAppsState;
 import com.android.launcher3.states.SpringLoadedState;
+import com.android.launcher3.uioverrides.OverviewState;
 import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
 
 import java.util.Arrays;
@@ -49,7 +49,7 @@
 
     public static final LauncherState SPRING_LOADED = new SpringLoadedState(2);
 
-    public static final LauncherState OVERVIEW = FeatureFlags.createOverviewState(3);
+    public static final LauncherState OVERVIEW = new OverviewState(3);
 
     public final int ordinal;
 
diff --git a/src/com/android/launcher3/LauncherStateManager.java b/src/com/android/launcher3/LauncherStateManager.java
index fd94067..b99df71 100644
--- a/src/com/android/launcher3/LauncherStateManager.java
+++ b/src/com/android/launcher3/LauncherStateManager.java
@@ -179,7 +179,7 @@
      * @param duration intended duration for normal playback. Use higher duration for better
      *                accuracy.
      */
-    protected AnimatorPlaybackController createAnimationToNewWorkspace(
+    public AnimatorPlaybackController createAnimationToNewWorkspace(
             LauncherState state, long duration) {
         mConfig.reset();
         mConfig.userControlled = true;
diff --git a/src/com/android/launcher3/PinchToOverviewListener.java b/src/com/android/launcher3/PinchToOverviewListener.java
deleted file mode 100644
index 27edaf6..0000000
--- a/src/com/android/launcher3/PinchToOverviewListener.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (C) 2016 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;
-
-import static com.android.launcher3.LauncherAnimUtils.OVERVIEW_TRANSITION_MS;
-import static com.android.launcher3.LauncherState.NORMAL;
-import static com.android.launcher3.LauncherState.OVERVIEW;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.AnimatorSet;
-import android.view.MotionEvent;
-import android.view.ScaleGestureDetector;
-import android.view.ScaleGestureDetector.OnScaleGestureListener;
-
-import com.android.launcher3.anim.AnimatorPlaybackController;
-import com.android.launcher3.util.TouchController;
-
-/**
- * Detects pinches and animates the Workspace to/from overview mode.
- */
-public class PinchToOverviewListener extends AnimatorListenerAdapter
-        implements TouchController, OnScaleGestureListener {
-
-    private static final float ACCEPT_THRESHOLD = 0.65f;
-    /**
-     * The velocity threshold at which a pinch will be completed instead of canceled,
-     * even if the first threshold has not been passed. Measured in scale / millisecond
-     */
-    private static final float FLING_VELOCITY = 0.001f;
-
-    private final ScaleGestureDetector mPinchDetector;
-    private Launcher mLauncher;
-    private Workspace mWorkspace = null;
-    private boolean mPinchStarted = false;
-
-    private AnimatorPlaybackController mCurrentAnimation;
-    private float mCurrentScale;
-    private boolean mShouldGoToFinalState;
-
-    private LauncherState mToState;
-
-    public PinchToOverviewListener(Launcher launcher) {
-        mLauncher = launcher;
-        mPinchDetector = new ScaleGestureDetector(mLauncher, this);
-    }
-
-    public boolean onControllerInterceptTouchEvent(MotionEvent ev) {
-        mPinchDetector.onTouchEvent(ev);
-        return mPinchStarted;
-    }
-
-    public boolean onControllerTouchEvent(MotionEvent ev) {
-        return mPinchDetector.onTouchEvent(ev);
-    }
-
-    @Override
-    public boolean onScaleBegin(ScaleGestureDetector detector) {
-        if (!mLauncher.isInState(NORMAL)
-                && !mLauncher.isInState(OVERVIEW)) {
-            // Don't listen for the pinch gesture if on all apps, widget picker, -1, etc.
-            return false;
-        }
-        if (mCurrentAnimation != null) {
-            // Don't listen for the pinch gesture if we are already animating from a previous one.
-            return false;
-        }
-        if (mLauncher.isWorkspaceLocked()) {
-            // Don't listen for the pinch gesture if the workspace isn't ready.
-            return false;
-        }
-        if (mWorkspace == null) {
-            mWorkspace = mLauncher.getWorkspace();
-        }
-        if (mWorkspace.isSwitchingState() || mWorkspace.mScrollInteractionBegan) {
-            // Don't listen for the pinch gesture while switching state, as it will cause a jump
-            // once the state switching animation is complete.
-            return false;
-        }
-        if (AbstractFloatingView.getTopOpenView(mLauncher) != null) {
-            // Don't listen for the pinch gesture if a floating view is open.
-            return false;
-        }
-
-        if (mLauncher.getDragController().isDragging()) {
-            mLauncher.getDragController().cancelDrag();
-        }
-
-        mToState = mLauncher.isInState(OVERVIEW) ? NORMAL : OVERVIEW;
-        mCurrentAnimation = mLauncher.getStateManager()
-                .createAnimationToNewWorkspace(mToState, OVERVIEW_TRANSITION_MS);
-        mCurrentAnimation.getTarget().addListener(this);
-        mPinchStarted = true;
-        mCurrentScale = 1;
-        mShouldGoToFinalState = false;
-
-        mCurrentAnimation.dispatchOnStart();
-        return true;
-    }
-
-    @Override
-    public void onAnimationEnd(Animator animation) {
-        mCurrentAnimation = null;
-        mPinchStarted = false;
-    }
-
-    @Override
-    public void onScaleEnd(ScaleGestureDetector detector) {
-        if (mShouldGoToFinalState) {
-            mCurrentAnimation.start();
-        } else {
-            mCurrentAnimation.setEndAction(new Runnable() {
-                @Override
-                public void run() {
-                    mLauncher.getStateManager().goToState(
-                            mToState == OVERVIEW ? NORMAL : OVERVIEW, false);
-                }
-            });
-            mCurrentAnimation.reverse();
-        }
-    }
-
-    @Override
-    public boolean onScale(ScaleGestureDetector detector) {
-        mCurrentScale = detector.getScaleFactor() * mCurrentScale;
-
-        // If we are zooming out, inverse the mCurrentScale so that animationFraction = [0, 1]
-        // 0 => Animation complete
-        // 1=> Animation started
-        float animationFraction = mToState == OVERVIEW ? mCurrentScale : (1 / mCurrentScale);
-
-        float velocity = (1 - detector.getScaleFactor()) / detector.getTimeDelta();
-        if (Math.abs(velocity) >= FLING_VELOCITY) {
-            LauncherState toState = velocity > 0 ? OVERVIEW : NORMAL;
-            mShouldGoToFinalState = toState == mToState;
-        } else {
-            mShouldGoToFinalState = animationFraction <= ACCEPT_THRESHOLD;
-        }
-
-        // Move the transition animation to that duration.
-        mCurrentAnimation.setPlayFraction(1 - animationFraction);
-        return true;
-    }
-}
\ No newline at end of file
diff --git a/src/com/android/launcher3/VerticalSwipeController.java b/src/com/android/launcher3/VerticalSwipeController.java
index 12c6916..b3dc176 100644
--- a/src/com/android/launcher3/VerticalSwipeController.java
+++ b/src/com/android/launcher3/VerticalSwipeController.java
@@ -75,7 +75,7 @@
 
     private boolean canInterceptTouch(MotionEvent ev) {
         if (!mLauncher.isInState(NORMAL) && !mLauncher.isInState(ALL_APPS)) {
-            // Don't listen for the pinch gesture if on all apps, widget picker, -1, etc.
+            // Don't listen for the swipe gesture if we are already in some other state.
             return false;
         }
         if (mCurrentAnimation != null) {
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 24c4704..32f96df 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -54,7 +54,6 @@
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
-import android.view.ViewDebug;
 import android.view.ViewGroup;
 import android.widget.Toast;
 
@@ -82,7 +81,7 @@
 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.uioverrides.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;
diff --git a/src/com/android/launcher3/config/BaseFlags.java b/src/com/android/launcher3/config/BaseFlags.java
index 4fbab39..a03dabb 100644
--- a/src/com/android/launcher3/config/BaseFlags.java
+++ b/src/com/android/launcher3/config/BaseFlags.java
@@ -16,9 +16,6 @@
 
 package com.android.launcher3.config;
 
-import com.android.launcher3.LauncherState;
-import com.android.launcher3.states.OverviewState;
-
 /**
  * Defines a set of flags used to control various launcher behaviors.
  *
@@ -32,10 +29,10 @@
     BaseFlags() {}
 
     public static final boolean IS_DOGFOOD_BUILD = false;
+    public static final String AUTHORITY = "com.android.launcher3.settings".intern();
 
     // Custom flags go below this
     public static boolean LAUNCHER3_DISABLE_ICON_NORMALIZATION = false;
-    public static boolean LAUNCHER3_DISABLE_PINCH_TO_OVERVIEW = false;
     // When enabled allows to use any point on the fast scrollbar to start dragging.
     public static final boolean LAUNCHER3_DIRECT_SCROLL = true;
     // When enabled the promise icon is visible in all apps while installation an app.
@@ -62,7 +59,4 @@
     // Features to control Launcher3Go behavior
     public static final boolean GO_DISABLE_WIDGETS = false;
 
-    public static LauncherState createOverviewState(int id) {
-        return new OverviewState(id);
-    }
 }
diff --git a/src/com/android/launcher3/dragndrop/DragLayer.java b/src/com/android/launcher3/dragndrop/DragLayer.java
index 0f0b20d..8189b23 100644
--- a/src/com/android/launcher3/dragndrop/DragLayer.java
+++ b/src/com/android/launcher3/dragndrop/DragLayer.java
@@ -42,17 +42,15 @@
 import com.android.launcher3.DropTargetBar;
 import com.android.launcher3.InsettableFrameLayout;
 import com.android.launcher3.Launcher;
-import com.android.launcher3.PinchToOverviewListener;
 import com.android.launcher3.R;
 import com.android.launcher3.ShortcutAndWidgetContainer;
 import com.android.launcher3.Utilities;
-import com.android.launcher3.VerticalSwipeController;
 import com.android.launcher3.allapps.AllAppsTransitionController;
 import com.android.launcher3.anim.Interpolators;
-import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.folder.Folder;
 import com.android.launcher3.folder.FolderIcon;
 import com.android.launcher3.keyboard.ViewGroupFocusHelper;
+import com.android.launcher3.uioverrides.UiFactory;
 import com.android.launcher3.util.Themes;
 import com.android.launcher3.util.Thunk;
 import com.android.launcher3.util.TouchController;
@@ -92,13 +90,10 @@
     private final ViewGroupFocusHelper mFocusIndicatorHelper;
     private final PageCutOutScrimDrawable mPageCutOutScrim;
 
-    // Related to pinch-to-go-to-overview gesture.
-    private PinchToOverviewListener mPinchListener = null;
-
     // Handles all apps pull up interaction
     private AllAppsTransitionController mAllAppsController;
-    private VerticalSwipeController mVerticalSwipeController;
 
+    protected TouchController[] mControllers;
     private TouchController mActiveController;
     /**
      * Used to create a new DragLayer from XML.
@@ -123,11 +118,7 @@
         mLauncher = launcher;
         mDragController = dragController;
         mAllAppsController = allAppsTransitionController;
-        mVerticalSwipeController = new VerticalSwipeController(mLauncher);
-
-        boolean isAccessibilityEnabled = ((AccessibilityManager) mLauncher.getSystemService(
-                Context.ACCESSIBILITY_SERVICE)).isEnabled();
-        onAccessibilityStateChanged(isAccessibilityEnabled);
+        mControllers = UiFactory.createTouchControllers(mLauncher);
     }
 
     public ViewGroupFocusHelper getFocusIndicatorHelper() {
@@ -144,11 +135,6 @@
         return super.verifyDrawable(who) || who == mPageCutOutScrim;
     }
 
-    public void onAccessibilityStateChanged(boolean isAccessibilityEnabled) {
-        mPinchListener = FeatureFlags.LAUNCHER3_DISABLE_PINCH_TO_OVERVIEW || isAccessibilityEnabled
-                ? null : new PinchToOverviewListener(mLauncher);
-    }
-
     public boolean isEventOverHotseat(MotionEvent ev) {
         return isEventOverView(mLauncher.getHotseat(), ev);
     }
@@ -194,15 +180,11 @@
             return true;
         }
 
-        if (mVerticalSwipeController.onControllerInterceptTouchEvent(ev)) {
-            mActiveController = mVerticalSwipeController;
-            return true;
-        }
-
-        if (mPinchListener != null && mPinchListener.onControllerInterceptTouchEvent(ev)) {
-            // Stop listening for scrolling etc. (onTouchEvent() handles the rest of the pinch.)
-            mActiveController = mPinchListener;
-            return true;
+        for (TouchController controller : mControllers) {
+            if (controller.onControllerInterceptTouchEvent(ev)) {
+                mActiveController = controller;
+                return true;
+            }
         }
         return false;
     }
diff --git a/src/com/android/launcher3/states/OverviewState.java b/src/com/android/launcher3/states/OverviewState.java
deleted file mode 100644
index 344a4f9..0000000
--- a/src/com/android/launcher3/states/OverviewState.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * 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.View;
-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;
-
-    public OverviewState(int id) {
-        super(id, ContainerType.WORKSPACE, OVERVIEW_TRANSITION_MS, 1f, 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);
-    }
-
-    @Override
-    public View getFinalFocus(Launcher launcher) {
-        return launcher.getOverviewPanel();
-    }
-}