Widgets recommendation backend

Add a widgets recommendation mechanism based on AiAI app predication
ranking with the following changes:

1. Only one widget is picked from one app.
2. Widgets that are already added to the workspace are excluded from
   the recommendation.

Test: run PredicationUpdateTaskTest

Bug: 179797520
Change-Id: Ia697bc6df0bae75969e68b7b3de32d57901f7461
This commit is contained in:
Steven Ng
2021-03-02 21:26:00 +00:00
parent 1f4a3414f1
commit 3a8353256a
11 changed files with 461 additions and 5 deletions

View File

@@ -21,6 +21,7 @@ import static android.text.format.DateUtils.formatElapsedTime;
import static com.android.launcher3.InvariantDeviceProfile.CHANGE_FLAG_GRID;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT_PREDICTION;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_PREDICTION;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_WIDGETS_PREDICTION;
import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT;
import static com.android.launcher3.Utilities.getDevicePrefs;
@@ -80,6 +81,8 @@ public class QuickstepModelDelegate extends ModelDelegate implements OnIDPChange
new PredictorState(CONTAINER_PREDICTION, "all_apps_predictions");
private final PredictorState mHotseatState =
new PredictorState(CONTAINER_HOTSEAT_PREDICTION, "hotseat_predictions");
private final PredictorState mWidgetsRecommendationState =
new PredictorState(CONTAINER_WIDGETS_PREDICTION, "widgets_prediction");
private final InvariantDeviceProfile mIDP;
private final AppEventProducer mAppEventProducer;
@@ -111,6 +114,9 @@ public class QuickstepModelDelegate extends ModelDelegate implements OnIDPChange
mHotseatState.items.setItems(
mHotseatState.storage.read(mApp.getContext(), hotseatFactory, ums.allUsers::get));
mDataModel.extraItems.put(CONTAINER_HOTSEAT_PREDICTION, mHotseatState.items);
// Widgets prediction isn't used frequently. And thus, it is not persisted on disk.
mDataModel.extraItems.put(CONTAINER_WIDGETS_PREDICTION, mWidgetsRecommendationState.items);
mActive = true;
}
@@ -161,6 +167,9 @@ public class QuickstepModelDelegate extends ModelDelegate implements OnIDPChange
if (mAllAppsState.predictor != null) {
mAllAppsState.predictor.requestPredictionUpdate();
}
if (mWidgetsRecommendationState.predictor != null) {
mWidgetsRecommendationState.predictor.requestPredictionUpdate();
}
}
@Override
@@ -176,6 +185,7 @@ public class QuickstepModelDelegate extends ModelDelegate implements OnIDPChange
private void destroyPredictors() {
mAllAppsState.destroyPredictor();
mHotseatState.destroyPredictor();
mWidgetsRecommendationState.destroyPredictor();
}
@WorkerThread
@@ -203,6 +213,12 @@ public class QuickstepModelDelegate extends ModelDelegate implements OnIDPChange
.setPredictedTargetCount(mIDP.numHotseatIcons)
.setExtras(convertDataModelToAppTargetBundle(context, mDataModel))
.build()));
registerWidgetsPredictor(apm.createAppPredictionSession(
new AppPredictionContext.Builder(context)
.setUiSurface("widgets")
.setPredictedTargetCount(mIDP.numColumns)
.build()));
}
private void registerPredictor(PredictorState state, AppPredictor predictor) {
@@ -220,6 +236,20 @@ public class QuickstepModelDelegate extends ModelDelegate implements OnIDPChange
mApp.getModel().enqueueModelUpdateTask(new PredictionUpdateTask(state, targets));
}
private void registerWidgetsPredictor(AppPredictor predictor) {
mWidgetsRecommendationState.predictor = predictor;
mWidgetsRecommendationState.predictor.registerPredictionUpdates(
Executors.MODEL_EXECUTOR, targets -> {
if (mWidgetsRecommendationState.setTargets(targets)) {
// No diff, skip
return;
}
mApp.getModel().enqueueModelUpdateTask(
new WidgetsPredictionUpdateTask(mWidgetsRecommendationState, targets));
});
mWidgetsRecommendationState.predictor.requestPredictionUpdate();
}
@Override
public void onIdpChanged(int changeFlags, InvariantDeviceProfile profile) {
if ((changeFlags & CHANGE_FLAG_GRID) != 0) {