Merge "Fixing crash when window is not attached" into ub-launcher3-master
diff --git a/quickstep/src/com/android/quickstep/BaseSwipeInteractionHandler.java b/quickstep/src/com/android/quickstep/BaseSwipeInteractionHandler.java
index b3ebd77..5bf7e4e 100644
--- a/quickstep/src/com/android/quickstep/BaseSwipeInteractionHandler.java
+++ b/quickstep/src/com/android/quickstep/BaseSwipeInteractionHandler.java
@@ -20,11 +20,13 @@
 import com.android.launcher3.states.InternalStateHandler;
 import com.android.quickstep.TouchConsumer.InteractionType;
 
+import java.util.function.Consumer;
+
 public abstract class BaseSwipeInteractionHandler extends InternalStateHandler {
 
-    protected Runnable mGestureEndCallback;
+    protected Consumer<BaseSwipeInteractionHandler> mGestureEndCallback;
 
-    public void setGestureEndCallback(Runnable gestureEndCallback) {
+    public void setGestureEndCallback(Consumer<BaseSwipeInteractionHandler> gestureEndCallback) {
         mGestureEndCallback = gestureEndCallback;
     }
 
diff --git a/quickstep/src/com/android/quickstep/NavBarSwipeInteractionHandler.java b/quickstep/src/com/android/quickstep/NavBarSwipeInteractionHandler.java
index f333b93..0be13ea 100644
--- a/quickstep/src/com/android/quickstep/NavBarSwipeInteractionHandler.java
+++ b/quickstep/src/com/android/quickstep/NavBarSwipeInteractionHandler.java
@@ -347,7 +347,7 @@
     public void reset() {
         mCurrentShift.cancelAnimation();
         if (mGestureEndCallback != null) {
-            mGestureEndCallback.run();
+            mGestureEndCallback.accept(this);
         }
     }
 
diff --git a/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java b/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java
index 53eb910..b3354a4 100644
--- a/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java
+++ b/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java
@@ -38,8 +38,10 @@
 import android.graphics.Point;
 import android.graphics.PointF;
 import android.graphics.Rect;
+import android.metrics.LogMaker;
 import android.os.Bundle;
 import android.os.Looper;
+import android.os.SystemClock;
 import android.util.Log;
 import android.view.Display;
 import android.view.MotionEvent;
@@ -64,6 +66,40 @@
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
+class EventLogTags {
+    private EventLogTags() {
+    }  // don't instantiate
+
+    /** 524292 sysui_multi_action (content|4) */
+    public static final int SYSUI_MULTI_ACTION = 524292;
+
+    public static void writeSysuiMultiAction(Object[] content) {
+        android.util.EventLog.writeEvent(SYSUI_MULTI_ACTION, content);
+    }
+}
+
+class MetricsLogger {
+    private static MetricsLogger sMetricsLogger;
+
+    private static MetricsLogger getLogger() {
+        if (sMetricsLogger == null) {
+            sMetricsLogger = new MetricsLogger();
+        }
+        return sMetricsLogger;
+    }
+
+    protected void saveLog(Object[] rep) {
+        EventLogTags.writeSysuiMultiAction(rep);
+    }
+
+    public void write(LogMaker content) {
+        if (content.getType() == 0/*MetricsEvent.TYPE_UNKNOWN*/) {
+            content.setType(4/*MetricsEvent.TYPE_ACTION*/);
+        }
+        saveLog(content.serialize());
+    }
+}
+
 /**
  * Touch consumer for handling events originating from an activity other than Launcher
  */
@@ -91,6 +127,8 @@
 
     private VelocityTracker mVelocityTracker;
 
+    private final MetricsLogger mMetricsLogger = new MetricsLogger();
+
     public OtherActivityTouchConsumer(Context base, RunningTaskInfo runningTaskInfo,
             RecentsModel recentsModel, Intent homeIntent, ISystemUiProxy systemUiProxy,
             MainThreadExecutor mainThreadExecutor) {
@@ -124,8 +162,8 @@
 
                 // Start the window animation on down to give more time for launcher to draw if the
                 // user didn't start the gesture over the back button
-                if (mDownHitTarget != HIT_TARGET_BACK && !isUsingScreenShot()) {
-                    startTouchTrackingForWindowAnimation();
+                if (!isUsingScreenShot()) {
+                    startTouchTrackingForWindowAnimation(ev.getEventTime());
                 }
 
                 Display display = getSystemService(WindowManager.class).getDefaultDisplay();
@@ -166,10 +204,6 @@
 
                         if (isUsingScreenShot()) {
                             startTouchTrackingForScreenshotAnimation();
-                        } else if (mDownHitTarget == HIT_TARGET_BACK) {
-                            // If the window animation was deferred on DOWN due to it starting over
-                            // the back button, then start it now
-                            startTouchTrackingForWindowAnimation();
                         }
 
                         notifyGestureStarted();
@@ -268,7 +302,7 @@
         }
     }
 
-    private void startTouchTrackingForWindowAnimation() {
+    private void startTouchTrackingForWindowAnimation(long touchTimeMs) {
         // Create the shared handler
         final WindowTransformSwipeHandler handler =
                 new WindowTransformSwipeHandler(mRunningTask, this);
@@ -306,6 +340,16 @@
                         } else {
                             controller.finish(false /* toHome */);
                         }
+
+                        // Mimic ActivityMetricsLogger.logAppTransitionMultiEvents() logging for
+                        // "Recents" activity for app transition tests.
+                        final LogMaker builder = new LogMaker(761/*APP_TRANSITION*/);
+                        builder.setPackageName("com.android.systemui");
+                        builder.addTaggedData(871/*FIELD_CLASS_NAME*/,
+                                "com.android.systemui.recents.RecentsActivity");
+                        builder.addTaggedData(319/*APP_TRANSITION_DELAY_MS*/,
+                                SystemClock.uptimeMillis() - touchTimeMs);
+                        mMetricsLogger.write(builder);
                     }
 
                     public void onAnimationCanceled() {
@@ -397,8 +441,10 @@
         }
     }
 
-    private void onFinish() {
-        mInteractionHandler = null;
+    private void onFinish(BaseSwipeInteractionHandler handler) {
+        if (mInteractionHandler == handler) {
+            mInteractionHandler = null;
+        }
     }
 
     public void onTouchTrackingComplete() { }
diff --git a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
index 91f4453..d09daed 100644
--- a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
+++ b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
@@ -605,7 +605,7 @@
         mCurrentShift.cancelAnimation();
 
         if (mGestureEndCallback != null) {
-            mGestureEndCallback.run();
+            mGestureEndCallback.accept(this);
         }
 
         clearReference();
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index f6abae8..7905ed0 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -1848,6 +1848,18 @@
         if (intent == null) {
             throw new IllegalArgumentException("Input must have a valid intent");
         }
+        if (item instanceof ShortcutInfo) {
+            ShortcutInfo si = (ShortcutInfo) item;
+            if (si.hasStatusFlag(ShortcutInfo.FLAG_SUPPORTS_WEB_UI)
+                    && intent.getAction() == Intent.ACTION_VIEW) {
+                // make a copy of the intent that has the package set to null
+                // we do this because the platform sometimes disables instant
+                // apps temporarily (triggered by the user) and fallbacks to the
+                // web ui. This only works though if the package isn't set
+                intent = new Intent(intent);
+                intent.setPackage(null);
+            }
+        }
         startActivitySafely(v, intent, item);
     }