Merge "Accessibility sugar for Recents" into ub-launcher3-edmonton
diff --git a/src/com/android/launcher3/BaseActivity.java b/src/com/android/launcher3/BaseActivity.java
index 4219667..e117deb 100644
--- a/src/com/android/launcher3/BaseActivity.java
+++ b/src/com/android/launcher3/BaseActivity.java
@@ -30,7 +30,9 @@
 
 import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
 import com.android.launcher3.logging.UserEventDispatcher;
+import com.android.launcher3.logging.UserEventDispatcher.UserEventDelegate;
 import com.android.launcher3.uioverrides.UiFactory;
+import com.android.launcher3.userevent.nano.LauncherLogProto;
 import com.android.launcher3.util.SystemUiController;
 
 import java.io.FileDescriptor;
@@ -38,7 +40,7 @@
 import java.lang.annotation.Retention;
 import java.util.ArrayList;
 
-public abstract class BaseActivity extends Activity {
+public abstract class BaseActivity extends Activity implements UserEventDelegate{
 
     public static final int INVISIBLE_BY_STATE_HANDLER = 1 << 0;
     public static final int INVISIBLE_BY_APP_TRANSITIONS = 1 << 1;
@@ -89,9 +91,11 @@
         return null;
     }
 
+    public void modifyUserEvent(LauncherLogProto.LauncherEvent event) {}
+
     public final UserEventDispatcher getUserEventDispatcher() {
         if (mUserEventDispatcher == null) {
-            mUserEventDispatcher = UserEventDispatcher.newInstance(this, mDeviceProfile);
+            mUserEventDispatcher = UserEventDispatcher.newInstance(this, mDeviceProfile, this);
         }
         return mUserEventDispatcher;
     }
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index bddcde3..3eaead1 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -24,6 +24,7 @@
 import static com.android.launcher3.LauncherState.NORMAL;
 import static com.android.launcher3.dragndrop.DragLayer.ALPHA_INDEX_LAUNCHER_LOAD;
 import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
+import static com.android.launcher3.logging.LoggerUtils.newTarget;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
@@ -91,6 +92,7 @@
 import com.android.launcher3.keyboard.ViewGroupFocusHelper;
 import com.android.launcher3.logging.FileLog;
 import com.android.launcher3.logging.UserEventDispatcher;
+import com.android.launcher3.logging.UserEventDispatcher.UserEventDelegate;
 import com.android.launcher3.model.ModelWriter;
 import com.android.launcher3.notification.NotificationListener;
 import com.android.launcher3.popup.PopupContainerWithArrow;
@@ -100,6 +102,7 @@
 import com.android.launcher3.states.RotationHelper;
 import com.android.launcher3.touch.ItemClickHandler;
 import com.android.launcher3.uioverrides.UiFactory;
+import com.android.launcher3.userevent.nano.LauncherLogProto;
 import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
 import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
 import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
@@ -140,8 +143,8 @@
 /**
  * Default launcher application.
  */
-public class Launcher extends BaseDraggingActivity
-        implements LauncherExterns, LauncherModel.Callbacks, LauncherProviderChangeListener {
+public class Launcher extends BaseDraggingActivity implements LauncherExterns,
+        LauncherModel.Callbacks, LauncherProviderChangeListener, UserEventDelegate{
     public static final String TAG = "Launcher";
     static final boolean LOGD = false;
 
@@ -1643,6 +1646,24 @@
         }
     }
 
+    @Override
+    public void modifyUserEvent(LauncherLogProto.LauncherEvent event) {
+        if (event.srcTarget != null && event.srcTarget.length > 0 &&
+                event.srcTarget[1].containerType == ContainerType.PREDICTION) {
+            Target[] targets = new Target[3];
+            targets[0] = event.srcTarget[0];
+            targets[1] = event.srcTarget[1];
+            targets[2] = newTarget(Target.Type.CONTAINER);
+            event.srcTarget = targets;
+            LauncherState state = mStateManager.getState();
+            if (state == LauncherState.ALL_APPS) {
+                event.srcTarget[2].containerType = ContainerType.ALLAPPS;
+            } else if (state == LauncherState.OVERVIEW) {
+                event.srcTarget[2].containerType = ContainerType.TASKSWITCHER;
+            }
+        }
+    }
+
     public boolean startActivitySafely(View v, Intent intent, ItemInfo item) {
         boolean success = super.startActivitySafely(v, intent, item);
         if (success && v instanceof BubbleTextView) {
diff --git a/src/com/android/launcher3/logging/UserEventDispatcher.java b/src/com/android/launcher3/logging/UserEventDispatcher.java
index 1842e19..d1e1051 100644
--- a/src/com/android/launcher3/logging/UserEventDispatcher.java
+++ b/src/com/android/launcher3/logging/UserEventDispatcher.java
@@ -70,7 +70,8 @@
             FeatureFlags.IS_DOGFOOD_BUILD && Utilities.isPropertyEnabled(LogConfig.USEREVENT);
     private static final String UUID_STORAGE = "uuid";
 
-    public static UserEventDispatcher newInstance(Context context, DeviceProfile dp) {
+    public static UserEventDispatcher newInstance(Context context, DeviceProfile dp,
+            UserEventDelegate delegate) {
         SharedPreferences sharedPrefs = Utilities.getDevicePrefs(context);
         String uuidStr = sharedPrefs.getString(UUID_STORAGE, null);
         if (uuidStr == null) {
@@ -79,6 +80,7 @@
         }
         UserEventDispatcher ued = Utilities.getOverrideObject(UserEventDispatcher.class,
                 context.getApplicationContext(), R.string.user_event_dispatcher_class);
+        ued.mDelegate = delegate;
         ued.mIsInLandscapeMode = dp.isVerticalBarLayout();
         ued.mIsInMultiWindowMode = dp.isMultiWindowMode;
         ued.mUuidStr = uuidStr;
@@ -86,6 +88,14 @@
         return ued;
     }
 
+    public static UserEventDispatcher newInstance(Context context, DeviceProfile dp) {
+        return newInstance(context, dp, null);
+    }
+
+    public interface UserEventDelegate {
+        void modifyUserEvent(LauncherEvent event);
+    }
+
     /**
      * Implemented by containers to provide a container source for a given child.
      */
@@ -134,6 +144,7 @@
     private String mUuidStr;
     protected InstantAppResolver mInstantAppResolver;
     private boolean mAppOrTaskLaunch;
+    private UserEventDelegate mDelegate;
 
     //                      APP_ICON    SHORTCUT    WIDGET
     // --------------------------------------------------------------
@@ -162,6 +173,9 @@
                 newItemTarget(v, mInstantAppResolver), newTarget(Target.Type.CONTAINER));
 
         if (fillInLogContainerData(event, v)) {
+            if (mDelegate != null) {
+                mDelegate.modifyUserEvent(event);
+            }
             fillIntentInfo(event.srcTarget[0], intent);
         }
         dispatchUserEvent(event, intent);
diff --git a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
index a9006e3..453810c 100644
--- a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
+++ b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
@@ -42,9 +42,9 @@
 import com.android.launcher3.anim.AnimationSuccessListener;
 import com.android.launcher3.anim.AnimatorPlaybackController;
 import com.android.launcher3.anim.AnimatorSetBuilder;
+import com.android.launcher3.userevent.nano.LauncherLogProto;
 import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
 import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
-import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
 import com.android.launcher3.util.FlingBlockCheck;
 import com.android.launcher3.util.PendingAnimation;
 import com.android.launcher3.util.TouchController;
@@ -181,17 +181,6 @@
             return false;
         }
 
-        if (reachedToState) {
-            logReachedState(Touch.SWIPE);
-        }
-        if (newFromState == ALL_APPS) {
-            mStartContainerType = ContainerType.ALLAPPS;
-        } else if (newFromState == NORMAL) {
-            mStartContainerType = getLogContainerTypeForNormalState();
-        } else if (newFromState == OVERVIEW){
-            mStartContainerType = ContainerType.TASKSWITCHER;
-        }
-
         mFromState = newFromState;
         mToState = newToState;
 
@@ -237,6 +226,13 @@
     @Override
     public void onDragStart(boolean start) {
         mStartState = mLauncher.getStateManager().getState();
+        if (mStartState == ALL_APPS) {
+            mStartContainerType = LauncherLogProto.ContainerType.ALLAPPS;
+        } else if (mStartState == NORMAL) {
+            mStartContainerType = getLogContainerTypeForNormalState();
+        } else if (mStartState   == OVERVIEW){
+            mStartContainerType = LauncherLogProto.ContainerType.TASKSWITCHER;
+        }
         if (mCurrentAnimation == null) {
             mFromState = mStartState;
             mToState = null;
@@ -332,23 +328,21 @@
 
     @Override
     public void onDragEnd(float velocity, boolean fling) {
-        final int logAction;
-        final LauncherState targetState;
-        final float progress = mCurrentAnimation.getProgressFraction();
+        final int logAction = fling ? Touch.FLING : Touch.SWIPE;
 
         boolean blockedFling = fling && mFlingBlockCheck.isBlocked();
         if (blockedFling) {
             fling = false;
         }
 
+        final LauncherState targetState;
+        final float progress = mCurrentAnimation.getProgressFraction();
         if (fling) {
-            logAction = Touch.FLING;
             targetState =
                     Float.compare(Math.signum(velocity), Math.signum(mProgressMultiplier)) == 0
                             ? mToState : mFromState;
             // snap to top or bottom using the release velocity
         } else {
-            logAction = Touch.SWIPE;
             float successProgress = mToState == ALL_APPS
                     ? MIN_PROGRESS_TO_ALL_APPS : SUCCESS_TRANSITION_PROGRESS;
             targetState = (progress > successProgress) ? mToState : mFromState;
@@ -472,20 +466,20 @@
             shouldGoToTargetState = !reachedTarget;
         }
         if (shouldGoToTargetState) {
-            if (targetState != mFromState) {
-                logReachedState(logAction);
+            if (targetState != mStartState) {
+                logReachedState(logAction, targetState);
             }
             mLauncher.getStateManager().goToState(targetState, false /* animated */);
         }
     }
 
-    private void logReachedState(int logAction) {
+    private void logReachedState(int logAction, LauncherState targetState) {
         // Transition complete. log the action
         mLauncher.getUserEventDispatcher().logStateChangeAction(logAction,
                 getDirectionForLog(),
                 mStartContainerType,
-                mFromState.containerType,
-                mToState.containerType,
+                mStartState.containerType,
+                targetState.containerType,
                 mLauncher.getWorkspace().getCurrentPage());
     }