Use Quickstep ActivityOptions when launching activities from App Widgets

Set a Quickstep specific InteractionHandler on QuickstepLauncher's
AppWidgetHost, which provides QuickstepTransitionManager-generated
ActivityOptions when starting activities from app widget interactions.

Bug: 169042867
Test: manual
Topic: quickstep-widget-app-launch
Change-Id: I231122b09aede940c047f19a5b5d1e7c562f6d3f
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java
new file mode 100644
index 0000000..66e4f4c
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2021 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.uioverrides;
+
+import android.app.ActivityOptions;
+import android.app.PendingIntent;
+import android.content.Intent;
+import android.util.Log;
+import android.util.Pair;
+import android.view.View;
+import android.widget.RemoteViews;
+
+import com.android.launcher3.util.ActivityOptionsWrapper;
+import com.android.launcher3.widget.LauncherAppWidgetHostView;
+
+/** Provides a Quickstep specific animation when launching an activity from an app widget. */
+class QuickstepInteractionHandler implements RemoteViews.InteractionHandler {
+
+    private static final String TAG = "QuickstepInteractionHandler";
+
+    private final QuickstepLauncher mLauncher;
+
+    QuickstepInteractionHandler(QuickstepLauncher launcher) {
+        mLauncher = launcher;
+    }
+
+    @Override
+    public boolean onInteraction(View view, PendingIntent pendingIntent,
+            RemoteViews.RemoteResponse remoteResponse) {
+        LauncherAppWidgetHostView hostView = findHostViewAncestor(view);
+        if (hostView == null) {
+            Log.e(TAG, "View did not have a LauncherAppWidgetHostView ancestor.");
+            return RemoteViews.startPendingIntent(hostView, pendingIntent,
+                    remoteResponse.getLaunchOptions(view));
+        }
+        Pair<Intent, ActivityOptions> options = remoteResponse.getLaunchOptions(hostView);
+        ActivityOptionsWrapper activityOptions = mLauncher.getAppTransitionManager()
+                .getActivityLaunchOptions(mLauncher, hostView);
+        options = Pair.create(options.first, activityOptions.options);
+        return RemoteViews.startPendingIntent(hostView, pendingIntent, options);
+    }
+
+    private LauncherAppWidgetHostView findHostViewAncestor(View v) {
+        while (v != null) {
+            if (v instanceof LauncherAppWidgetHostView) return (LauncherAppWidgetHostView) v;
+            v = (View) v.getParent();
+        }
+        return null;
+    }
+}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index 0ceb8c7..f09d9e0 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -36,6 +36,7 @@
 import android.content.Intent;
 import android.content.SharedPreferences;
 import android.content.res.Configuration;
+import android.os.SystemProperties;
 import android.view.HapticFeedbackConstants;
 import android.view.View;
 
@@ -71,6 +72,7 @@
 import com.android.launcher3.util.TouchController;
 import com.android.launcher3.util.UiThreadHelper;
 import com.android.launcher3.util.UiThreadHelper.AsyncCommand;
+import com.android.launcher3.widget.LauncherAppWidgetHost;
 import com.android.quickstep.SysUINavigationMode;
 import com.android.quickstep.SysUINavigationMode.Mode;
 import com.android.quickstep.SystemUiProxy;
@@ -88,6 +90,9 @@
 
 public class QuickstepLauncher extends BaseQuickstepLauncher {
 
+    private static final boolean ENABLE_APP_WIDGET_LAUNCH_ANIMATION =
+            SystemProperties.getBoolean("persist.debug.quickstep_app_widget_launch", false);
+
     public static final boolean GO_LOW_RAM_RECENTS_ENABLED = false;
     /**
      * Reusable command for applying the shelf height on the background thread.
@@ -320,6 +325,14 @@
         return new QuickstepAtomicAnimationFactory(this);
     }
 
+    protected LauncherAppWidgetHost createAppWidgetHost() {
+        LauncherAppWidgetHost appWidgetHost = super.createAppWidgetHost();
+        if (ENABLE_APP_WIDGET_LAUNCH_ANIMATION) {
+            appWidgetHost.setInteractionHandler(new QuickstepInteractionHandler(this));
+        }
+        return appWidgetHost;
+    }
+
     private static final class LauncherTaskViewController extends
             TaskViewTouchController<Launcher> {
 
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 5091543..3236f5d 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -436,8 +436,7 @@
         mOnboardingPrefs = createOnboardingPrefs(mSharedPrefs);
 
         mAppWidgetManager = new WidgetManagerHelper(this);
-        mAppWidgetHost = new LauncherAppWidgetHost(this,
-                appWidgetId -> getWorkspace().removeWidget(appWidgetId));
+        mAppWidgetHost = createAppWidgetHost();
         mAppWidgetHost.startListening();
 
         inflateRootView(R.layout.launcher);
@@ -1428,6 +1427,11 @@
         return mAppWidgetHost;
     }
 
+    protected LauncherAppWidgetHost createAppWidgetHost() {
+        return new LauncherAppWidgetHost(this,
+                appWidgetId -> getWorkspace().removeWidget(appWidgetId));
+    }
+
     public LauncherModel getModel() {
         return mModel;
     }