Show Launcher's widget picker in an activity.

Bug: 307306823
Test: atest Launcher3Tests
Flag: NA

Change-Id: I28ef731abcdf1bd44c66366d42a135912dbcc5be
diff --git a/quickstep/AndroidManifest.xml b/quickstep/AndroidManifest.xml
index 82f8ebe..db46508 100644
--- a/quickstep/AndroidManifest.xml
+++ b/quickstep/AndroidManifest.xml
@@ -43,6 +43,10 @@
 
     <uses-permission android:name="android.permission.SYSTEM_APPLICATION_OVERLAY" />
 
+    <!-- Permission required to start a WidgetPickerActivity. -->
+    <permission android:name="${packageName}.permission.START_WIDGET_PICKER_ACTIVITY"
+        android:protectionLevel="signature|privileged" />
+
     <application android:backupAgent="com.android.launcher3.LauncherBackupAgent"
          android:fullBackupOnly="true"
          android:fullBackupContent="@xml/backupscheme"
@@ -133,6 +137,20 @@
             </intent-filter>
         </activity>
 
+        <activity android:name="com.android.launcher3.WidgetPickerActivity"
+            android:theme="@style/WidgetPickerActivityTheme"
+            android:excludeFromRecents="true"
+            android:autoRemoveFromRecents="true"
+            android:showOnLockScreen="true"
+            android:launchMode="singleTop"
+            android:exported="true"
+            android:permission="android.permission.START_WIDGET_PICKER_ACTIVITY">
+            <intent-filter>
+                <action android:name="android.intent.action.PICK" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+
     </application>
 
 </manifest>
diff --git a/quickstep/res/layout/widget_picker_activity.xml b/quickstep/res/layout/widget_picker_activity.xml
new file mode 100644
index 0000000..3388e40
--- /dev/null
+++ b/quickstep/res/layout/widget_picker_activity.xml
@@ -0,0 +1,24 @@
+<!--
+  ~ Copyright (C) 2023 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.
+  -->
+
+<com.android.launcher3.dragndrop.SimpleDragLayer
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/drag_layer"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:clipChildren="false"
+    android:clipToPadding="false"
+    android:importantForAccessibility="no" />
diff --git a/quickstep/res/values/styles.xml b/quickstep/res/values/styles.xml
index ae62c26..bdc86b2 100644
--- a/quickstep/res/values/styles.xml
+++ b/quickstep/res/values/styles.xml
@@ -311,4 +311,9 @@
         <item name="android:letterSpacing">0.025</item>
         <item name="android:lineHeight">20sp</item>
     </style>
+
+    <style name="WidgetPickerActivityTheme" parent="@android:style/Theme.Translucent.NoTitleBar">
+        <item name="widgetsTheme">@style/WidgetContainerTheme</item>
+        <item name="android:windowBackground">@android:color/transparent</item>
+    </style>
 </resources>
diff --git a/quickstep/src/com/android/launcher3/WidgetPickerActivity.java b/quickstep/src/com/android/launcher3/WidgetPickerActivity.java
new file mode 100644
index 0000000..43716ab
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/WidgetPickerActivity.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2023 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 android.view.WindowInsets.Type.navigationBars;
+import static android.view.WindowInsets.Type.statusBars;
+
+import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
+import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
+
+import android.os.Bundle;
+import android.view.WindowInsetsController;
+import android.view.WindowManager;
+
+import androidx.annotation.NonNull;
+
+import com.android.launcher3.dragndrop.SimpleDragLayer;
+import com.android.launcher3.model.WidgetsModel;
+import com.android.launcher3.popup.PopupDataProvider;
+import com.android.launcher3.widget.BaseWidgetSheet;
+import com.android.launcher3.widget.model.WidgetsListBaseEntry;
+import com.android.launcher3.widget.picker.WidgetsFullSheet;
+
+import java.util.ArrayList;
+
+/** An Activity that can host Launcher's widget picker. */
+public class WidgetPickerActivity extends BaseActivity {
+    private SimpleDragLayer<WidgetPickerActivity> mDragLayer;
+    private WidgetsModel mModel;
+    private final PopupDataProvider mPopupDataProvider = new PopupDataProvider(i -> {});
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
+        getWindow().clearFlags(WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER);
+
+        LauncherAppState app = LauncherAppState.getInstance(this);
+        InvariantDeviceProfile idp = app.getInvariantDeviceProfile();
+
+        mDeviceProfile = idp.getDeviceProfile(this);
+        mModel = new WidgetsModel();
+
+        setContentView(R.layout.widget_picker_activity);
+        mDragLayer = findViewById(R.id.drag_layer);
+        mDragLayer.recreateControllers();
+
+        WindowInsetsController wc = mDragLayer.getWindowInsetsController();
+        wc.hide(navigationBars() + statusBars());
+
+        BaseWidgetSheet widgetSheet = WidgetsFullSheet.show(this, true);
+        widgetSheet.disableNavBarScrim(true);
+        widgetSheet.addOnCloseListener(this::finish);
+
+        refreshAndBindWidgets();
+    }
+
+    @NonNull
+    @Override
+    public PopupDataProvider getPopupDataProvider() {
+        return mPopupDataProvider;
+    }
+
+    @Override
+    public SimpleDragLayer<WidgetPickerActivity> getDragLayer() {
+        return mDragLayer;
+    }
+
+    private void refreshAndBindWidgets() {
+        MODEL_EXECUTOR.execute(() -> {
+            LauncherAppState app = LauncherAppState.getInstance(this);
+            mModel.update(app, null);
+            final ArrayList<WidgetsListBaseEntry> widgets =
+                    mModel.getWidgetsListForPicker(app.getContext());
+            MAIN_EXECUTOR.execute(() -> mPopupDataProvider.setAllWidgets(widgets));
+        });
+    }
+}
diff --git a/res/layout/add_item_confirmation_activity.xml b/res/layout/add_item_confirmation_activity.xml
index e29e1b1..d113a38 100644
--- a/res/layout/add_item_confirmation_activity.xml
+++ b/res/layout/add_item_confirmation_activity.xml
@@ -16,7 +16,7 @@
 ** limitations under the License.
 */
 -->
-<com.android.launcher3.dragndrop.AddItemDragLayer
+<com.android.launcher3.dragndrop.SimpleDragLayer
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/add_item_drag_layer"
     android:layout_width="match_parent"
@@ -121,6 +121,6 @@
         </LinearLayout>
     </com.android.launcher3.widget.AddItemWidgetsBottomSheet>
 
-</com.android.launcher3.dragndrop.AddItemDragLayer>
+</com.android.launcher3.dragndrop.SimpleDragLayer>
 
 
diff --git a/src/com/android/launcher3/dragndrop/AddItemDragLayer.java b/src/com/android/launcher3/dragndrop/SimpleDragLayer.java
similarity index 70%
rename from src/com/android/launcher3/dragndrop/AddItemDragLayer.java
rename to src/com/android/launcher3/dragndrop/SimpleDragLayer.java
index 5b52c3d..e42ba72 100644
--- a/src/com/android/launcher3/dragndrop/AddItemDragLayer.java
+++ b/src/com/android/launcher3/dragndrop/SimpleDragLayer.java
@@ -20,18 +20,20 @@
 import android.util.AttributeSet;
 
 import com.android.launcher3.util.TouchController;
+import com.android.launcher3.views.ActivityContext;
 import com.android.launcher3.views.BaseDragLayer;
 
 /**
- * Drag layer for {@link AddItemActivity}.
+ * A concrete {@link BaseDragLayer} that creates an empty list of {@link TouchController}s.
+ * @param <T> The {@link ActivityContext} hosting the drag layer.
  */
-public class AddItemDragLayer extends BaseDragLayer<AddItemActivity> {
+public class SimpleDragLayer<T extends Context & ActivityContext> extends BaseDragLayer<T> {
 
-    public AddItemDragLayer(Context context, AttributeSet attrs) {
+    public SimpleDragLayer(Context context, AttributeSet attrs) {
         this(context, attrs, /*alphaChannelCount= */ 1);
     }
 
-    public AddItemDragLayer(Context context, AttributeSet attrs, int alphaChannelCount) {
+    public SimpleDragLayer(Context context, AttributeSet attrs, int alphaChannelCount) {
         super(context, attrs, alphaChannelCount);
     }
 
diff --git a/src/com/android/launcher3/widget/BaseWidgetSheet.java b/src/com/android/launcher3/widget/BaseWidgetSheet.java
index 5ec1022..5a3dd65 100644
--- a/src/com/android/launcher3/widget/BaseWidgetSheet.java
+++ b/src/com/android/launcher3/widget/BaseWidgetSheet.java
@@ -67,6 +67,8 @@
     protected int mNavBarScrimHeight;
     private final Paint mNavBarScrimPaint;
 
+    private boolean mDisableNavBarScrim = false;
+
     public BaseWidgetSheet(Context context, AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr);
         mContentHorizontalMargin = getResources().getDimensionPixelSize(
@@ -146,8 +148,15 @@
         }
     }
 
+    /** Enables or disables the sheet's nav bar scrim. */
+    public void disableNavBarScrim(boolean disable) {
+        mDisableNavBarScrim = disable;
+    }
+
     private int getNavBarScrimHeight(WindowInsets insets) {
-        if (Utilities.ATLEAST_Q) {
+        if (mDisableNavBarScrim) {
+            return 0;
+        } else if (Utilities.ATLEAST_Q) {
             return insets.getTappableElementInsets().bottom;
         } else {
             return insets.getStableInsetBottom();
diff --git a/tests/src/com/android/launcher3/util/viewcapture_analysis/AlphaJumpDetector.java b/tests/src/com/android/launcher3/util/viewcapture_analysis/AlphaJumpDetector.java
index 51b7b18..dfccffc1 100644
--- a/tests/src/com/android/launcher3/util/viewcapture_analysis/AlphaJumpDetector.java
+++ b/tests/src/com/android/launcher3/util/viewcapture_analysis/AlphaJumpDetector.java
@@ -33,17 +33,17 @@
 
     private static final IgnoreNode IGNORED_NODES_ROOT = buildIgnoreNodesTree(List.of(
             CONTENT
-                    + "AddItemDragLayer:id/add_item_drag_layer|AddItemWidgetsBottomSheet:id"
+                    + "SimpleDragLayer:id/add_item_drag_layer|AddItemWidgetsBottomSheet:id"
                     + "/add_item_bottom_sheet|LinearLayout:id/add_item_bottom_sheet_content"
                     + "|ScrollView:id/widget_preview_scroll_view|WidgetCell:id/widget_cell"
                     + "|WidgetCellPreview:id/widget_preview_container|ImageView:id/widget_badge",
             CONTENT
-                    + "AddItemDragLayer:id/add_item_drag_layer|AddItemWidgetsBottomSheet:id"
+                    + "SimpleDragLayer:id/add_item_drag_layer|AddItemWidgetsBottomSheet:id"
                     + "/add_item_bottom_sheet|LinearLayout:id/add_item_bottom_sheet_content"
                     + "|ScrollView:id/widget_preview_scroll_view|WidgetCell:id/widget_cell"
                     + "|WidgetCellPreview:id/widget_preview_container|WidgetCell$1|FrameLayout"
                     + "|ImageView:id/icon",
-            CONTENT + "AddItemDragLayer:id/add_item_drag_layer|View",
+            CONTENT + "SimpleDragLayer:id/add_item_drag_layer|View",
             DRAG_LAYER
                     + "AppWidgetResizeFrame|FrameLayout|ImageButton:id/widget_reconfigure_button",
             DRAG_LAYER
diff --git a/tests/src/com/android/launcher3/util/viewcapture_analysis/FlashDetector.java b/tests/src/com/android/launcher3/util/viewcapture_analysis/FlashDetector.java
index e333074..fc8f818 100644
--- a/tests/src/com/android/launcher3/util/viewcapture_analysis/FlashDetector.java
+++ b/tests/src/com/android/launcher3/util/viewcapture_analysis/FlashDetector.java
@@ -44,13 +44,13 @@
                     + "LauncherAllAppsContainerView:id/apps_view|AllAppsRecyclerView:id"
                     + "/apps_list_view|BubbleTextView:id/icon",
             CONTENT
-                    + "AddItemDragLayer:id/add_item_drag_layer|AddItemWidgetsBottomSheet:id"
+                    + "SimpleDragLayer:id/add_item_drag_layer|AddItemWidgetsBottomSheet:id"
                     + "/add_item_bottom_sheet|LinearLayout:id/add_item_bottom_sheet_content"
                     + "|ScrollView:id/widget_preview_scroll_view|WidgetCell:id/widget_cell"
                     + "|WidgetCellPreview:id/widget_preview_container|WidgetImageView:id"
                     + "/widget_preview",
             CONTENT
-                    + "AddItemDragLayer:id/add_item_drag_layer|AddItemWidgetsBottomSheet:id"
+                    + "SimpleDragLayer:id/add_item_drag_layer|AddItemWidgetsBottomSheet:id"
                     + "/add_item_bottom_sheet|LinearLayout:id/add_item_bottom_sheet_content"
                     + "|ScrollView:id/widget_preview_scroll_view|WidgetCell:id/widget_cell"
                     + "|WidgetCellPreview:id/widget_preview_container|ImageView:id/widget_badge",
diff --git a/tests/src/com/android/launcher3/util/viewcapture_analysis/PositionJumpDetector.java b/tests/src/com/android/launcher3/util/viewcapture_analysis/PositionJumpDetector.java
index 5f2c68c..88ace68 100644
--- a/tests/src/com/android/launcher3/util/viewcapture_analysis/PositionJumpDetector.java
+++ b/tests/src/com/android/launcher3/util/viewcapture_analysis/PositionJumpDetector.java
@@ -41,7 +41,7 @@
             DRAG_LAYER + "AppWidgetResizeFrame",
             DRAG_LAYER + "LauncherAllAppsContainerView:id/apps_view",
             CONTENT
-                    + "AddItemDragLayer:id/add_item_drag_layer|AddItemWidgetsBottomSheet:id"
+                    + "SimpleDragLayer:id/add_item_drag_layer|AddItemWidgetsBottomSheet:id"
                     + "/add_item_bottom_sheet|LinearLayout:id/add_item_bottom_sheet_content",
             DRAG_LAYER + "WidgetsTwoPaneSheet|SpringRelativeLayout:id/container",
             DRAG_LAYER + "WidgetsFullSheet|SpringRelativeLayout:id/container",