diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 1bce9b3757..43fa274e7e 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -26,6 +26,10 @@
Refer comments around specific entries on how to extend individual components.
-->
+
+
+
+
+
+
+
+
+
diff --git a/quickstep/AndroidManifest.xml b/quickstep/AndroidManifest.xml
index dfcdc22e3c..a94873bda9 100644
--- a/quickstep/AndroidManifest.xml
+++ b/quickstep/AndroidManifest.xml
@@ -150,11 +150,10 @@
-
diff --git a/quickstep/res/values/styles.xml b/quickstep/res/values/styles.xml
index 727b21bcdb..0ffd93b8e4 100644
--- a/quickstep/res/values/styles.xml
+++ b/quickstep/res/values/styles.xml
@@ -342,18 +342,6 @@
- 20sp
-
-
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 73e8a43176..a5b3c17884 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -545,4 +545,25 @@
variable-title-small
+
+
diff --git a/src/com/android/launcher3/widgetpicker/WidgetPickerActivity.kt b/src/com/android/launcher3/widgetpicker/WidgetPickerActivity.kt
new file mode 100644
index 0000000000..36c6d10b86
--- /dev/null
+++ b/src/com/android/launcher3/widgetpicker/WidgetPickerActivity.kt
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2025 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.widgetpicker
+
+import android.os.Bundle
+import com.android.launcher3.BaseActivity
+import com.android.launcher3.Flags
+import com.android.launcher3.R
+import com.android.launcher3.compose.ComposeFacade.isComposeAvailable
+import com.android.launcher3.dagger.LauncherComponentProvider
+import com.android.launcher3.dragndrop.SimpleDragLayer
+import com.android.launcher3.util.ScreenOnTracker
+
+/**
+ * Activity that shows widget picker UI; shows content only if `enableWidgetPickerRefactor` flag is
+ * on and compose is available.
+ */
+open class WidgetPickerActivity : BaseActivity() {
+ private var _dragLayer: SimpleDragLayer? = null
+ protected var widgetPickerConfig: WidgetPickerConfig = WidgetPickerConfig()
+
+ private val screenOnListener =
+ ScreenOnTracker.ScreenOnListener { on: Boolean -> this.onScreenOnChange(on) }
+
+ override fun getDragLayer(): SimpleDragLayer? = _dragLayer
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ val component = LauncherComponentProvider.get(this)
+ component.screenOnTracker.addListener(screenOnListener)
+ mDeviceProfile = component.idp.getDeviceProfile(this)
+
+ setContentView(R.layout.widget_picker_activity)
+ _dragLayer = findViewById(R.id.drag_layer)
+ checkNotNull(_dragLayer).recreateControllers()
+
+ if (Flags.enableWidgetPickerRefactor() && isComposeAvailable()) {
+ // TODO(b/408283627): add compose picker here.
+ }
+ }
+
+ private fun onScreenOnChange(on: Boolean) {
+ if (!on) {
+ finish() // auto close when user locks device.
+ }
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ ScreenOnTracker.INSTANCE[this].removeListener(screenOnListener)
+ }
+}
\ No newline at end of file
diff --git a/src/com/android/launcher3/widgetpicker/WidgetPickerConfig.kt b/src/com/android/launcher3/widgetpicker/WidgetPickerConfig.kt
new file mode 100644
index 0000000000..2eeac52506
--- /dev/null
+++ b/src/com/android/launcher3/widgetpicker/WidgetPickerConfig.kt
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2025 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.widgetpicker
+
+import android.os.UserHandle
+
+/**
+ * Possible parameters sent over by the widget host when launching the widget picker activity.
+ * @param uiSurface surface string representing the host. "widgets" for home screen
+ * @param title an optional title that some surfaces like lockscreen may provide to change the
+ * title appearing in widget picker.
+ * @param description an optional description that some surfaces like lockscreen may provide to
+ * display it below the title in widget picker; by default no description is
+ * shown.
+ * @param categoryInclusionFilter mask applied to identify if a widget's category matches the
+ * host's category requirements and if widget can be included.
+ * @param categoryExclusionFilter mask applied to identify if per host requirements the widget
+ * should be excluded from the picker.
+ * @param filteredUsers users for which widgets list should be shown empty (potentially due to
+ * admin / enterprise restrictions); no widgets message is shown instead.
+ */
+data class WidgetPickerConfig(
+ val uiSurface: String = HOMESCREEN_WIDGETS_UI_SURFACE,
+ val title: String? = null,
+ val description: String? = null,
+ val categoryInclusionFilter: Int = 0,
+ val categoryExclusionFilter: Int = 0,
+ val filteredUsers: List = listOf()
+) {
+ /**
+ * Indicates if the intent request is for picking home screen widgets.
+ * If false, implies its for another surface external to launcher.
+ */
+ val isForHomeScreen: Boolean
+ get() = uiSurface == HOMESCREEN_WIDGETS_UI_SURFACE
+
+ companion object {
+ /**
+ * Name of the extra (set by widget picker) in the result when the activity is launched by
+ * lockscreen with `startActivityForResult`; indicates that activity finished since a widget
+ * was being dragged.
+ */
+ const val EXTRA_IS_PENDING_WIDGET_DRAG = "is_pending_widget_drag"
+
+ const val HOMESCREEN_WIDGETS_UI_SURFACE = "widgets"
+ }
+}