Updates to repository interfaces & data types for widget picker

- I think the previews / featured / search all could be part of widgets
 repository. Internally, it will use separate datasource to prepare the
  respective data - but as a repository, they all are probably just
  a widgets repo.
- Includes minor changes to data types as well to prepare for upcoming
changes.

Bug: 408283627
Flag: EXEMPT independent module
Test: Not applicable - interface changes
Change-Id: I765c11318a655603becdf2cab081f0fcf777da1a
This commit is contained in:
Shamali Patwa
2025-05-22 16:03:16 -07:00
parent 10b72a252d
commit a4ffc73d92
10 changed files with 141 additions and 46 deletions

View File

@@ -22,7 +22,7 @@ android_library {
sdk_version: "current",
min_sdk_version: min_launcher3_sdk_version,
srcs: [
"src/com/android/launcher3/widgetpicker/WidgetPickerSingleton.kt",
"src/com/android/launcher3/widgetpicker/Annotations.kt",
],
static_libs: [
@@ -52,11 +52,13 @@ android_library {
min_sdk_version: min_launcher3_sdk_version,
srcs: [
"src/com/android/launcher3/widgetpicker/shared/model/PickableWidget.kt",
"src/com/android/launcher3/widgetpicker/shared/model/WidgetApp.kt",
"src/com/android/launcher3/widgetpicker/shared/model/WidgetAppIcon.kt",
"src/com/android/launcher3/widgetpicker/shared/model/WidgetAppId.kt",
"src/com/android/launcher3/widgetpicker/shared/model/WidgetId.kt",
"src/com/android/launcher3/widgetpicker/shared/model/WidgetPreview.kt",
"src/com/android/launcher3/widgetpicker/shared/model/WidgetUserProfiles.kt",
"src/com/android/launcher3/widgetpicker/shared/model/WidgetHostInfo.kt",
],
static_libs: [
"androidx.core_core-ktx",
@@ -70,8 +72,6 @@ android_library {
min_sdk_version: min_launcher3_sdk_version,
srcs: [
"src/com/android/launcher3/widgetpicker/data/repository/WidgetAppIconsRepository.kt",
"src/com/android/launcher3/widgetpicker/data/repository/WidgetPreviewRepository.kt",
"src/com/android/launcher3/widgetpicker/data/repository/WidgetRecommendationsRepository.kt",
"src/com/android/launcher3/widgetpicker/data/repository/WidgetsRepository.kt",
"src/com/android/launcher3/widgetpicker/data/repository/WidgetUsersRepository.kt",
],

View File

@@ -16,6 +16,7 @@
package com.android.launcher3.widgetpicker
import javax.inject.Qualifier
import javax.inject.Scope
/** Scope annotation for singleton items within the widget picker. */
@@ -23,3 +24,9 @@ import javax.inject.Scope
@Retention(AnnotationRetention.RUNTIME)
@Scope
annotation class WidgetPickerSingleton
/** Qualifier annotation for information about the widget host. */
@Qualifier
@MustBeDocumented
@Retention(AnnotationRetention.RUNTIME)
annotation class WidgetPickerHostInfo

View File

@@ -22,9 +22,18 @@ import kotlinx.coroutines.flow.Flow
/** A repository that provides app icons for the widget picker. */
interface WidgetAppIconsRepository {
/**
* A hook to setup the repository so clients can observe the widgets available on device.
* This serves as a place to start listening to the backing caches / data sources.
*/
fun initialize()
/**
* Loads and returns app icon (may initially return a low res icon, followed by a high res once
* available).
*/
fun getAppIcon(widgetAppId: WidgetAppId): Flow<WidgetAppIcon>
/** Clean up any external listeners or state (if necessary). */
fun cleanUp()
}

View File

@@ -1,25 +0,0 @@
/*
* 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.data.repository
import com.android.launcher3.widgetpicker.shared.model.WidgetId
/** A repository of widgets that can be recommended to the users in widget picker. */
interface WidgetRecommendationsRepository {
/** Returns a list of widgets that can be recommended to the users in the widget picker. */
suspend fun getRecommendations(): List<WidgetId>
}

View File

@@ -16,7 +16,7 @@
package com.android.launcher3.widgetpicker.data.repository
import com.android.launcher3.widgetpicker.shared.model.WidgetUserProfileType
import android.os.UserHandle
import com.android.launcher3.widgetpicker.shared.model.WidgetUserProfiles
import kotlinx.coroutines.flow.Flow
@@ -25,6 +25,18 @@ import kotlinx.coroutines.flow.Flow
* the widget picker.
*/
interface WidgetUsersRepository {
/**
* A hook to setup the repository so clients can observe the widgets available on device.
* This serves as a place to start listening to the backing caches / data sources.
*/
fun initialize()
/** Get and listen to the changes in available user profiles. */
fun observeUsers(types: List<WidgetUserProfileType>): Flow<WidgetUserProfiles>
fun observeUserProfiles(): Flow<WidgetUserProfiles?>
/** Indicates if a user is a work profile user. */
fun getWorkProfileUser(): UserHandle?
/** Clean up any external listeners or state (if necessary). */
fun cleanUp()
}

View File

@@ -17,11 +17,34 @@
package com.android.launcher3.widgetpicker.data.repository
import com.android.launcher3.widgetpicker.shared.model.PickableWidget
import com.android.launcher3.widgetpicker.shared.model.WidgetApp
import com.android.launcher3.widgetpicker.shared.model.WidgetId
import com.android.launcher3.widgetpicker.shared.model.WidgetPreview
import kotlinx.coroutines.flow.Flow
/** A repository of widgets available on the device from various apps */
interface WidgetsRepository {
/**
* A hook to setup the repository so clients can observe the widgets available on device.
* This serves as a place to start listening to the backing caches / data sources.
*/
fun initialize()
/** Observe widgets available on the device. */
fun observeWidgets(): Flow<List<PickableWidget>>
/** Observe widgets available on the device from different apps. */
fun observeWidgets(): Flow<List<WidgetApp>>
/** Loads a preview for an app widget. Returns a placeholder preview if the widget is not found. */
suspend fun getWidgetPreview(id: WidgetId): WidgetPreview
/** Get widgets that can be featured in widget picker. */
fun getFeaturedWidgets(): Flow<List<PickableWidget>>
/**
* Search widgets and their apps that match the given plain text [query] string typed by the
* user. Matches the widget's label, description and app's title (case-insensitive).
*/
suspend fun searchWidgets(query: String): List<WidgetApp>
/** Clean up any external listeners or state (if necessary). */
fun cleanUp()
}

View File

@@ -39,7 +39,12 @@ data class PickableWidget(
val description: CharSequence?,
val appWidgetProviderInfo: AppWidgetProviderInfo,
val sizeInfo: WidgetSizeInfo,
)
) {
// Custom toString to account for the appWidgetProviderInfo.
override fun toString(): String =
"PickableWidget(id=$id,appId=$appId,label=$label,description=$description," +
"sizeInfo=$sizeInfo,provider=${appWidgetProviderInfo.provider})"
}
/**
* Sizing information for a specific widget shown in a grid.

View File

@@ -1,3 +1,5 @@
package com.android.launcher3.widgetpicker.shared.model
/*
* Copyright (C) 2025 The Android Open Source Project
*
@@ -14,13 +16,16 @@
* limitations under the License.
*/
package com.android.launcher3.widgetpicker.data.repository
import com.android.launcher3.widgetpicker.shared.model.WidgetId
import com.android.launcher3.widgetpicker.shared.model.WidgetPreview
/** A repository that provides previews for the widgets to be displayed in the widget picker. */
interface WidgetPreviewRepository {
/** Returns the preview for a widget represented by given [WidgetId]. */
suspend fun getPreview(widgetId: WidgetId): WidgetPreview
}
/**
* Represents an app hosting widgets that is shown in widget picker.
*
* @param id a unique identifier for the app
* @param title a user readable title for the app; if null a placeholder text (e.g. "pending..")
* is shown until the title is loaded.
* @param widgets list of widgets available to picker from the app.
*/
data class WidgetApp(
val id: WidgetAppId,
val title: CharSequence?,
val widgets: List<PickableWidget>,
)

View File

@@ -0,0 +1,59 @@
/*
* 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.shared.model
import android.os.UserHandle
/**
* Data class that holds information about the host needs to display the widget picker.
*
* @param title an optional title that should be shown in place of default "Widgets" title.
* @param description an optional 1-2 line description to be shown below the title. If not set, no
* description is shown.
* @param constraints constraints around which widgets can be shown in the picker.
*/
data class WidgetHostInfo(
val title: String? = null,
val description: String? = null,
val constraints: List<HostConstraint> = emptyList(),
)
/** Various constraints for the widget host. */
sealed class HostConstraint {
/**
* A constraint to apply on `widgetCategory` when deciding whether to show a widget in the
* widget picker.
*
* @param categoryInclusionMask mask that includes widgets matching the given widget category
* mask e.g. HOME_SCREEN or KEYGUARD; 0 implies no mask
* @param categoryExclusionMask mask that excludes widgets matching the mask e.g.
* NOT_KEYGUARD.inv(); 0 implies no mask
*/
data class HostCategoryConstraint(
val categoryInclusionMask: Int,
val categoryExclusionMask: Int,
) : HostConstraint()
/**
* A constraint to apply on `user` associated with widgets shown in widget picker.
*
* @param userFilters user profiles for which widgets list should be shown as empty. e.g. for
* lockscreen widgets, based on an admin setting, the host may filter out work widgets. In
* such case, the profile tab shows a generic no widgets available message.
*/
data class HostUserConstraint(val userFilters: List<UserHandle>) : HostConstraint()
}

View File

@@ -20,7 +20,7 @@ package com.android.launcher3.widgetpicker.shared.model
* Holds data about all the available user profiles on device that are supported in the widget
* picker.
*/
data class WidgetUserProfiles(val users: List<WidgetUserProfile>)
data class WidgetUserProfiles(val personal: WidgetUserProfile, val work: WidgetUserProfile?)
/**
* Data about a specific user profile that is supported in the widget picker.
@@ -36,8 +36,8 @@ data class WidgetUserProfiles(val users: List<WidgetUserProfile>)
data class WidgetUserProfile(
val type: WidgetUserProfileType,
val label: String,
val paused: Boolean,
val pausedProfileMessage: String,
val paused: Boolean = false,
val pausedProfileMessage: String? = null,
)
/** Represents types of user profiles that are supported in the widget picker. */