Merge "Fixing some robolectric tests" into ub-launcher3-master
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskMenuView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskMenuView.java
index 742d6a2..07d0796 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskMenuView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskMenuView.java
@@ -161,9 +161,6 @@
     }
 
     public static TaskMenuView showForTask(TaskView taskView) {
-        if (TestProtocol.sDebugTracing) {
-            Log.d(TestProtocol.WELLBEING_NO_TASK_MENU, "showForTask");
-        }
         BaseDraggingActivity activity = BaseDraggingActivity.fromContext(taskView.getContext());
         final TaskMenuView taskMenuView = (TaskMenuView) activity.getLayoutInflater().inflate(
                         R.layout.task_menu, activity.getDragLayer(), false);
@@ -171,15 +168,9 @@
     }
 
     private boolean populateAndShowForTask(TaskView taskView) {
-        if (TestProtocol.sDebugTracing) {
-            Log.d(TestProtocol.WELLBEING_NO_TASK_MENU, "populateAndShowForTask1");
-        }
         if (isAttachedToWindow()) {
             return false;
         }
-        if (TestProtocol.sDebugTracing) {
-            Log.d(TestProtocol.WELLBEING_NO_TASK_MENU, "populateAndShowForTask2");
-        }
         mActivity.getDragLayer().addView(this);
         mTaskView = taskView;
         addMenuOptions(mTaskView);
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java
index 2e6b662..5799c01 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java
@@ -39,23 +39,27 @@
 import android.util.FloatProperty;
 import android.util.Property;
 import android.view.View;
+import android.view.ViewGroup;
 
 import com.android.launcher3.BaseActivity;
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
+import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
 import com.android.launcher3.util.SystemUiController;
 import com.android.launcher3.util.Themes;
 import com.android.quickstep.TaskOverlayFactory;
 import com.android.quickstep.TaskOverlayFactory.TaskOverlay;
 import com.android.quickstep.util.TaskCornerRadius;
+import com.android.systemui.plugins.OverviewScreenshotActions;
+import com.android.systemui.plugins.PluginListener;
 import com.android.systemui.shared.recents.model.Task;
 import com.android.systemui.shared.recents.model.ThumbnailData;
 
 /**
  * A task in the Recents view.
  */
-public class TaskThumbnailView extends View {
+public class TaskThumbnailView extends View implements PluginListener<OverviewScreenshotActions> {
 
     private final static ColorMatrix COLOR_MATRIX = new ColorMatrix();
     private final static ColorMatrix SATURATION_COLOR_MATRIX = new ColorMatrix();
@@ -99,6 +103,7 @@
 
     private boolean mOverlayEnabled;
     private boolean mRotated;
+    private OverviewScreenshotActions mOverviewScreenshotActionsPlugin;
 
     public TaskThumbnailView(Context context) {
         this(context, null);
@@ -146,6 +151,10 @@
             mPaint.setShader(null);
             mOverlay.reset();
         }
+        if (mOverviewScreenshotActionsPlugin != null) {
+            mOverviewScreenshotActionsPlugin
+                .setupActions((ViewGroup) getTaskView(), getThumbnail(), mActivity);
+        }
         updateThumbnailPaintFilter();
     }
 
@@ -210,6 +219,33 @@
         canvas.restore();
     }
 
+    @Override
+    public void onPluginConnected(OverviewScreenshotActions overviewScreenshotActions,
+            Context context) {
+        mOverviewScreenshotActionsPlugin = overviewScreenshotActions;
+        mOverviewScreenshotActionsPlugin.setupActions(getTaskView(), getThumbnail(), mActivity);
+    }
+
+    @Override
+    public void onPluginDisconnected(OverviewScreenshotActions plugin) {
+        if (mOverviewScreenshotActionsPlugin != null) {
+            mOverviewScreenshotActionsPlugin = null;
+        }
+    }
+
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        PluginManagerWrapper.INSTANCE.get(getContext())
+            .addPluginListener(this, OverviewScreenshotActions.class);
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+        PluginManagerWrapper.INSTANCE.get(getContext()).removePluginListener(this);
+    }
+
     public RectF getInsetsToDrawInFullscreen(boolean isMultiWindowMode) {
         // Don't show insets in multi window mode.
         return isMultiWindowMode ? EMPTY_RECT_F : mClippedInsets;
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java
index 3eed281..51802df 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java
@@ -391,9 +391,6 @@
             mIconView.setDrawable(icon);
             mIconView.setOnClickListener(v -> showTaskMenu(Touch.TAP));
             mIconView.setOnLongClickListener(v -> {
-                if (TestProtocol.sDebugTracing) {
-                    Log.d(TestProtocol.WELLBEING_NO_TASK_MENU, "setOnLongClickListener");
-                }
                 requestDisallowInterceptTouchEvent(true);
                 return showTaskMenu(Touch.LONGPRESS);
             });
diff --git a/src/com/android/launcher3/InstallShortcutReceiver.java b/src/com/android/launcher3/InstallShortcutReceiver.java
index c9e7d91..aa975bd 100644
--- a/src/com/android/launcher3/InstallShortcutReceiver.java
+++ b/src/com/android/launcher3/InstallShortcutReceiver.java
@@ -620,6 +620,11 @@
     }
 
     private static WorkspaceItemInfo createWorkspaceItemInfo(Intent data, LauncherAppState app) {
+        if (data == null) {
+            Log.e(TAG, "Can't construct WorkspaceItemInfo with null data");
+            return null;
+        }
+
         Intent intent = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT);
         String name = data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME);
         Parcelable bitmap = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_ICON);
diff --git a/src/com/android/launcher3/testing/TestProtocol.java b/src/com/android/launcher3/testing/TestProtocol.java
index 99af182..62dd3a9 100644
--- a/src/com/android/launcher3/testing/TestProtocol.java
+++ b/src/com/android/launcher3/testing/TestProtocol.java
@@ -84,5 +84,4 @@
     public static final String NO_BACKGROUND_TO_OVERVIEW_TAG = "b/138251824";
     public static final String NO_DRAG_TO_WORKSPACE = "b/138729456";
     public static final String APP_NOT_DISABLED = "b/139891609";
-    public static final String WELLBEING_NO_TASK_MENU = "b/141275518";
 }
diff --git a/src_plugins/com/android/systemui/plugins/OverviewScreenshotActions.java b/src_plugins/com/android/systemui/plugins/OverviewScreenshotActions.java
new file mode 100644
index 0000000..8d9c0f4
--- /dev/null
+++ b/src_plugins/com/android/systemui/plugins/OverviewScreenshotActions.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2019 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.systemui.plugins;
+
+import android.app.Activity;
+import android.graphics.Bitmap;
+import android.view.ViewGroup;
+
+import com.android.systemui.plugins.annotations.ProvidesInterface;
+
+/**
+ * Implement this interface to add action buttons for overview screenshots, e.g. share, edit etc.
+ */
+@ProvidesInterface(
+        action = OverviewScreenshotActions.ACTION, version = OverviewScreenshotActions.VERSION)
+public interface OverviewScreenshotActions extends Plugin {
+    String ACTION = "com.android.systemui.action.PLUGIN_OVERVIEW_SCREENSHOT_ACTIONS";
+    int VERSION = 1;
+
+    /**
+     * Setup the actions for the screenshot, including edit, save, etc.
+     * @param parent The parent view to add buttons on.
+     * @param screenshot The screenshot we will do actions on.
+     * @param activity THe host activity.
+     */
+    void setupActions(ViewGroup parent, Bitmap screenshot, Activity activity);
+}
diff --git a/tests/src/com/android/launcher3/util/rule/TestStabilityRule.java b/tests/src/com/android/launcher3/util/rule/TestStabilityRule.java
index 8feadbe..d7f41bf 100644
--- a/tests/src/com/android/launcher3/util/rule/TestStabilityRule.java
+++ b/tests/src/com/android/launcher3/util/rule/TestStabilityRule.java
@@ -40,8 +40,8 @@
                     + "(?<local>(BuildFromAndroidStudio|"
                     + "([0-9]+|[A-Z])-eng\\.[a-z]+\\.[0-9]+\\.[0-9]+))|"
                     + "(?<presubmit>([0-9]+|[A-Z])-P[0-9]+)|"
-                    + "(?<postsubmit>([0-9]+|[A-Z])+-[0-9]+|"
-                    + "(?<platform>([0-9]+|[A-Z])+))"
+                    + "(?<postsubmit>([0-9]+|[A-Z])-[0-9]+)|"
+                    + "(?<platform>[0-9]+|[A-Z])"
                     + ")$");
     private static final Pattern PLATFORM_BUILD =
             Pattern.compile("^("
@@ -61,70 +61,7 @@
             return new Statement() {
                 @Override
                 public void evaluate() throws Throwable {
-                    final String launcherVersion =
-                            getInstrumentation().
-                                    getContext().
-                                    getPackageManager().
-                                    getPackageInfo(
-                                            UiDevice.getInstance(getInstrumentation()).
-                                                    getLauncherPackageName(),
-                                            0).
-                                    versionName;
-
-                    final Matcher launcherBuildMatcher = LAUNCHER_BUILD.matcher(launcherVersion);
-
-                    boolean launcherLocalBuild = false;
-                    boolean launcherUnbundledPresubmit = false;
-                    boolean launcherUnbundledPostsubmit = false;
-                    boolean launcherPlatform = false;
-
-                    if (!launcherBuildMatcher.find()) {
-                        Log.e(TAG, "Match not found");
-                    } else if (launcherBuildMatcher.group("local") != null) {
-                        launcherLocalBuild = true;
-                    } else if (launcherBuildMatcher.group("presubmit") != null) {
-                        launcherUnbundledPresubmit = true;
-                    } else if (launcherBuildMatcher.group("postsubmit") != null) {
-                        launcherUnbundledPostsubmit = true;
-                    } else if (launcherBuildMatcher.group("platform") != null) {
-                        launcherPlatform = true;
-                    } else {
-                        Log.e(TAG, "ERROR1");
-                    }
-
-                    boolean platformLocalBuild = false;
-                    boolean platformPresubmit = false;
-                    boolean platformPostsubmit = false;
-
-                    final String platformVersion = Build.VERSION.INCREMENTAL;
-                    final Matcher platformBuildMatcher = PLATFORM_BUILD.matcher(platformVersion);
-                    if (!platformBuildMatcher.find()) {
-                        Log.e(TAG, "Match not found");
-                    } else if (platformBuildMatcher.group("commandLine") != null) {
-                        platformLocalBuild = true;
-                    } else if (platformBuildMatcher.group("presubmit") != null) {
-                        platformPresubmit = true;
-                    } else if (platformBuildMatcher.group("postsubmit") != null) {
-                        platformPostsubmit = true;
-                    } else {
-                        Log.e(TAG, "ERROR2");
-                    }
-
-                    Log.d(TAG, "Launcher: " + launcherVersion + ", platform: " + platformVersion);
-
-                    if (launcherLocalBuild && (platformLocalBuild || platformPostsubmit)) {
-                        Log.d(TAG, "LOCAL RUN");
-                    } else if (launcherUnbundledPresubmit && platformPostsubmit) {
-                        Log.d(TAG, "UNBUNDLED PRESUBMIT");
-                    } else if (launcherUnbundledPostsubmit && platformPostsubmit) {
-                        Log.d(TAG, "UNBUNDLED POSTSUBMIT");
-                    } else if (launcherPlatform && platformPresubmit) {
-                        Log.d(TAG, "PLATFORM PRESUBMIT");
-                    } else if (launcherPlatform && platformPostsubmit) {
-                        Log.d(TAG, "PLATFORM POSTSUBMIT");
-                    } else {
-                        Log.e(TAG, "ERROR3");
-                    }
+                    getRunFlavor();
 
                     base.evaluate();
                 }
@@ -133,4 +70,50 @@
             return base;
         }
     }
+
+    private static void getRunFlavor() throws Exception {
+        final String launcherVersion = getInstrumentation().
+                getContext().
+                getPackageManager().
+                getPackageInfo(
+                        UiDevice.getInstance(getInstrumentation()).
+                                getLauncherPackageName(),
+                        0).
+                versionName;
+
+        final Matcher launcherBuildMatcher = LAUNCHER_BUILD.matcher(launcherVersion);
+
+        if (!launcherBuildMatcher.find()) {
+            Log.e(TAG, "Match not found");
+        }
+
+        final String platformVersion = Build.VERSION.INCREMENTAL;
+        final Matcher platformBuildMatcher = PLATFORM_BUILD.matcher(platformVersion);
+
+        if (!platformBuildMatcher.find()) {
+            Log.e(TAG, "Match not found");
+        }
+
+        Log.d(TAG, "Launcher: " + launcherVersion + ", platform: " + platformVersion);
+
+        if (launcherBuildMatcher.group("local") != null && (
+                platformBuildMatcher.group("commandLine") != null ||
+                        platformBuildMatcher.group("postsubmit") != null)) {
+            Log.d(TAG, "LOCAL RUN");
+        } else if (launcherBuildMatcher.group("presubmit") != null
+                && platformBuildMatcher.group("postsubmit") != null) {
+            Log.d(TAG, "UNBUNDLED PRESUBMIT");
+        } else if (launcherBuildMatcher.group("postsubmit") != null
+                && platformBuildMatcher.group("postsubmit") != null) {
+            Log.d(TAG, "UNBUNDLED POSTSUBMIT");
+        } else if (launcherBuildMatcher.group("platform") != null
+                && platformBuildMatcher.group("presubmit") != null) {
+            Log.d(TAG, "PLATFORM PRESUBMIT");
+        } else if (launcherBuildMatcher.group("platform") != null
+                && platformBuildMatcher.group("postsubmit") != null) {
+            Log.d(TAG, "PLATFORM POSTSUBMIT");
+        } else {
+            Log.e(TAG, "ERROR3");
+        }
+    }
 }
diff --git a/tests/tapl/com/android/launcher3/tapl/Widgets.java b/tests/tapl/com/android/launcher3/tapl/Widgets.java
index 7d308af..2a04d46 100644
--- a/tests/tapl/com/android/launcher3/tapl/Widgets.java
+++ b/tests/tapl/com/android/launcher3/tapl/Widgets.java
@@ -48,7 +48,12 @@
                 "want to fling forward in widgets")) {
             LauncherInstrumentation.log("Widgets.flingForward enter");
             final UiObject2 widgetsContainer = verifyActiveContainer();
-            mLauncher.scroll(widgetsContainer, Direction.DOWN, 1f, MARGINS, FLING_STEPS);
+            final int margin = widgetsContainer.getVisibleBounds().bottom -
+                    mLauncher.getRealDisplaySize().y +
+                    ResourceUtils.getNavbarSize(
+                            ResourceUtils.NAVBAR_BOTTOM_GESTURE_SIZE, mLauncher.getResources());
+            mLauncher.scroll(
+                    widgetsContainer, Direction.DOWN, 1f, new Rect(0, 0, 0, margin), FLING_STEPS);
             try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer("flung forward")) {
                 verifyActiveContainer();
             }
@@ -64,7 +69,7 @@
                 "want to fling backwards in widgets")) {
             LauncherInstrumentation.log("Widgets.flingBackward enter");
             final UiObject2 widgetsContainer = verifyActiveContainer();
-            mLauncher.scroll(widgetsContainer, Direction.UP, 1f, MARGINS, FLING_STEPS);
+            mLauncher.scroll(widgetsContainer, Direction.UP, 1f, null, FLING_STEPS);
             try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer("flung back")) {
                 verifyActiveContainer();
             }