/* * Copyright (C) 2024 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.widget.picker.model import android.content.Context import com.android.launcher3.dagger.LauncherComponentProvider.appComponent import com.android.launcher3.model.WidgetItem import com.android.launcher3.model.WidgetsFilterDataProvider import com.android.launcher3.model.WidgetsFilterDataProvider.WidgetsFilterLoadedCallback import com.android.launcher3.model.data.ItemInfo import com.android.launcher3.widget.model.WidgetsListBaseEntry import com.android.launcher3.widget.picker.model.data.WidgetPickerData import com.android.launcher3.widget.picker.model.data.WidgetPickerDataUtils.withRecommendedWidgets import com.android.launcher3.widget.picker.model.data.WidgetPickerDataUtils.withWidgets import java.io.PrintWriter import java.util.function.Predicate /** * Provides [WidgetPickerData] to various views such as widget picker, app-specific widget picker, * widgets shortcut. */ class WidgetPickerDataProvider(private val filterProvider: WidgetsFilterDataProvider) : WidgetsFilterLoadedCallback { constructor(context: Context) : this(context.appComponent.widgetsFilterDataProvider) /** All the widgets data provided for the views */ private var mWidgetPickerData: WidgetPickerData = WidgetPickerData() private var changeListener: WidgetPickerDataChangeListener? = null var hostSpecifiedDefaultWidgetsFilter: Predicate? = null private var allWidgets: List = emptyList() /** Sets a listener to be called back when widget data is updated. */ fun setChangeListener(changeListener: WidgetPickerDataChangeListener?) { this.changeListener = changeListener } init { filterProvider.addFilterChangeCallback(this) } /** Returns the current snapshot of [WidgetPickerData]. */ fun get(): WidgetPickerData { return mWidgetPickerData } override fun onWidgetsFilterLoaded() { setWidgets(allWidgets) } /** * Updates the widgets available to the widget picker. * * Generally called when the widgets model has new data. */ fun setWidgets(allWidgets: List) { this.allWidgets = allWidgets val currentFilter = filterProvider.defaultWidgetsFilter val finalFilter = when { currentFilter != null && hostSpecifiedDefaultWidgetsFilter != null -> currentFilter.and(hostSpecifiedDefaultWidgetsFilter) hostSpecifiedDefaultWidgetsFilter != null -> hostSpecifiedDefaultWidgetsFilter else -> currentFilter } val defaultWidgets = if (finalFilter != null) allWidgets .map { it.copy().apply { mWidgets.removeIf(finalFilter) } } .filter { it.mWidgets.isNotEmpty() } else emptyList() mWidgetPickerData = mWidgetPickerData.withWidgets(allWidgets = allWidgets, defaultWidgets = defaultWidgets) changeListener?.onWidgetsBound() } /** * Makes the widget recommendations available to the widget picker * * Generally called when new widget predictions are available. */ fun setWidgetRecommendations(recommendations: List) { mWidgetPickerData = mWidgetPickerData.withRecommendedWidgets(recommendations) changeListener?.onRecommendedWidgetsBound() } /** Writes the current state to the provided writer. */ fun dump(prefix: String, writer: PrintWriter) { writer.println(prefix + "WidgetPickerDataProvider:") writer.println("$prefix\twidgetPickerData:$mWidgetPickerData") } fun destroy() { filterProvider.removeFilterChangeCallback(this) } interface WidgetPickerDataChangeListener { /** A callback to get notified when widgets are bound. */ fun onWidgetsBound() /** A callback to get notified when recommended widgets are bound. */ fun onRecommendedWidgetsBound() } }