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));
+        });
+    }
+}