mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-02-17 01:28:21 +00:00
Merge remote-tracking branch 'aosp/android12L-release' into 12.1-dev
This commit is contained in:
@@ -25,8 +25,14 @@ import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPLICA
|
||||
import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT;
|
||||
import static com.android.launcher3.Utilities.getDevicePrefs;
|
||||
import static com.android.launcher3.hybridhotseat.HotseatPredictionModel.convertDataModelToAppTargetBundle;
|
||||
import static com.android.launcher3.model.PredictionHelper.getAppTargetFromItemInfo;
|
||||
import static com.android.launcher3.model.PredictionHelper.wrapAppTargetWithItemLocation;
|
||||
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
|
||||
|
||||
import android.Manifest;
|
||||
import static java.util.stream.Collectors.toCollection;
|
||||
|
||||
import android.app.StatsManager;
|
||||
import android.app.prediction.AppPredictionContext;
|
||||
import android.app.prediction.AppPredictionManager;
|
||||
import android.app.prediction.AppPredictor;
|
||||
@@ -39,8 +45,10 @@ import android.content.pm.LauncherActivityInfo;
|
||||
import android.content.pm.LauncherApps;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
import android.util.Log;
|
||||
import android.util.StatsEvent;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
import androidx.annotation.NonNull;
|
||||
@@ -48,9 +56,9 @@ import androidx.annotation.Nullable;
|
||||
import androidx.annotation.WorkerThread;
|
||||
|
||||
import com.android.launcher3.InvariantDeviceProfile;
|
||||
import com.android.launcher3.InvariantDeviceProfile.OnIDPChangeListener;
|
||||
import com.android.launcher3.LauncherAppState;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.logger.LauncherAtom;
|
||||
import com.android.launcher3.logging.InstanceId;
|
||||
import com.android.launcher3.logging.InstanceIdSequence;
|
||||
import com.android.launcher3.model.BgDataModel.FixedContainerItems;
|
||||
@@ -59,11 +67,13 @@ import com.android.launcher3.model.data.FolderInfo;
|
||||
import com.android.launcher3.model.data.ItemInfo;
|
||||
import com.android.launcher3.model.data.WorkspaceItemInfo;
|
||||
import com.android.launcher3.shortcuts.ShortcutKey;
|
||||
import com.android.launcher3.util.Executors;
|
||||
import com.android.launcher3.util.IntSparseArrayMap;
|
||||
import com.android.launcher3.util.PersistedItemArray;
|
||||
import com.android.quickstep.logging.SettingsChangeLogger;
|
||||
import com.android.quickstep.logging.StatsLogCompatManager;
|
||||
import com.android.systemui.shared.system.SysUiStatsLog;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -73,10 +83,11 @@ import java.util.stream.IntStream;
|
||||
/**
|
||||
* Model delegate which loads prediction items
|
||||
*/
|
||||
public class QuickstepModelDelegate extends ModelDelegate implements OnIDPChangeListener {
|
||||
public class QuickstepModelDelegate extends ModelDelegate {
|
||||
|
||||
public static final String LAST_PREDICTION_ENABLED_STATE = "last_prediction_enabled_state";
|
||||
private static final String LAST_SNAPSHOT_TIME_MILLIS = "LAST_SNAPSHOT_TIME_MILLIS";
|
||||
private static final String BUNDLE_KEY_ADDED_APP_WIDGETS = "added_app_widgets";
|
||||
private static final int NUM_OF_RECOMMENDED_WIDGETS_PREDICATION = 20;
|
||||
|
||||
private static final boolean IS_DEBUG = false;
|
||||
@@ -91,15 +102,18 @@ public class QuickstepModelDelegate extends ModelDelegate implements OnIDPChange
|
||||
|
||||
private final InvariantDeviceProfile mIDP;
|
||||
private final AppEventProducer mAppEventProducer;
|
||||
private final StatsManager mStatsManager;
|
||||
private final Context mContext;
|
||||
|
||||
protected boolean mActive = false;
|
||||
|
||||
public QuickstepModelDelegate(Context context) {
|
||||
mContext = context;
|
||||
mAppEventProducer = new AppEventProducer(context, this::onAppTargetEvent);
|
||||
|
||||
mIDP = InvariantDeviceProfile.INSTANCE.get(context);
|
||||
mIDP.addOnChangeListener(this);
|
||||
StatsLogCompatManager.LOGS_CONSUMER.add(mAppEventProducer);
|
||||
mStatsManager = context.getSystemService(StatsManager.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -155,17 +169,82 @@ public class QuickstepModelDelegate extends ModelDelegate implements OnIDPChange
|
||||
}
|
||||
InstanceId instanceId = new InstanceIdSequence().newInstanceId();
|
||||
for (ItemInfo info : itemsIdMap) {
|
||||
FolderInfo parent = info.container > 0
|
||||
? (FolderInfo) itemsIdMap.get(info.container) : null;
|
||||
FolderInfo parent = getContainer(info, itemsIdMap);
|
||||
StatsLogCompatManager.writeSnapshot(info.buildProto(parent), instanceId);
|
||||
}
|
||||
additionalSnapshotEvents(instanceId);
|
||||
prefs.edit().putLong(LAST_SNAPSHOT_TIME_MILLIS, now).apply();
|
||||
}
|
||||
|
||||
// Only register for launcher snapshot logging if this is the primary ModelDelegate
|
||||
// instance, as there will be additional instances that may be destroyed at any time.
|
||||
if (mIsPrimaryInstance) {
|
||||
registerSnapshotLoggingCallback();
|
||||
}
|
||||
}
|
||||
|
||||
protected void additionalSnapshotEvents(InstanceId snapshotInstanceId){}
|
||||
|
||||
/**
|
||||
* Registers a callback to log launcher workspace layout using Statsd pulled atom.
|
||||
*/
|
||||
protected void registerSnapshotLoggingCallback() {
|
||||
if (mStatsManager == null) {
|
||||
Log.d(TAG, "Failed to get StatsManager");
|
||||
}
|
||||
|
||||
try {
|
||||
mStatsManager.setPullAtomCallback(
|
||||
SysUiStatsLog.LAUNCHER_LAYOUT_SNAPSHOT,
|
||||
null /* PullAtomMetadata */,
|
||||
MODEL_EXECUTOR,
|
||||
(i, eventList) -> {
|
||||
InstanceId instanceId = new InstanceIdSequence().newInstanceId();
|
||||
IntSparseArrayMap<ItemInfo> itemsIdMap;
|
||||
synchronized (mDataModel) {
|
||||
itemsIdMap = mDataModel.itemsIdMap.clone();
|
||||
}
|
||||
|
||||
for (ItemInfo info : itemsIdMap) {
|
||||
FolderInfo parent = getContainer(info, itemsIdMap);
|
||||
LauncherAtom.ItemInfo itemInfo = info.buildProto(parent);
|
||||
Log.d(TAG, itemInfo.toString());
|
||||
StatsEvent statsEvent = StatsLogCompatManager.buildStatsEvent(itemInfo,
|
||||
instanceId);
|
||||
eventList.add(statsEvent);
|
||||
}
|
||||
Log.d(TAG,
|
||||
String.format(
|
||||
"Successfully logged %d workspace items with instanceId=%d",
|
||||
itemsIdMap.size(), instanceId.getId()));
|
||||
additionalSnapshotEvents(instanceId);
|
||||
SettingsChangeLogger.INSTANCE.get(mContext).logSnapshot(instanceId);
|
||||
return StatsManager.PULL_SUCCESS;
|
||||
}
|
||||
);
|
||||
Log.d(TAG, "Successfully registered for launcher snapshot logging!");
|
||||
} catch (RuntimeException e) {
|
||||
Log.e(TAG, "Failed to register launcher snapshot logging callback with StatsManager",
|
||||
e);
|
||||
}
|
||||
}
|
||||
|
||||
private static FolderInfo getContainer(ItemInfo info, IntSparseArrayMap<ItemInfo> itemsIdMap) {
|
||||
if (info.container > 0) {
|
||||
ItemInfo containerInfo = itemsIdMap.get(info.container);
|
||||
|
||||
if (!(containerInfo instanceof FolderInfo)) {
|
||||
Log.e(TAG, String.format(
|
||||
"Item info: %s found with invalid container: %s",
|
||||
info,
|
||||
containerInfo));
|
||||
} else {
|
||||
return (FolderInfo) containerInfo;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validateData() {
|
||||
super.validateData();
|
||||
@@ -182,9 +261,10 @@ public class QuickstepModelDelegate extends ModelDelegate implements OnIDPChange
|
||||
super.destroy();
|
||||
mActive = false;
|
||||
StatsLogCompatManager.LOGS_CONSUMER.remove(mAppEventProducer);
|
||||
|
||||
if (mIsPrimaryInstance) {
|
||||
mStatsManager.clearPullAtomCallback(SysUiStatsLog.LAUNCHER_LAYOUT_SNAPSHOT);
|
||||
}
|
||||
destroyPredictors();
|
||||
mIDP.removeOnChangeListener(this);
|
||||
}
|
||||
|
||||
private void destroyPredictors() {
|
||||
@@ -225,6 +305,7 @@ public class QuickstepModelDelegate extends ModelDelegate implements OnIDPChange
|
||||
registerWidgetsPredictor(apm.createAppPredictionSession(
|
||||
new AppPredictionContext.Builder(context)
|
||||
.setUiSurface("widgets")
|
||||
.setExtras(getBundleForWidgetsOnWorkspace(context, mDataModel))
|
||||
.setPredictedTargetCount(NUM_OF_RECOMMENDED_WIDGETS_PREDICATION)
|
||||
.build()));
|
||||
}
|
||||
@@ -232,7 +313,7 @@ public class QuickstepModelDelegate extends ModelDelegate implements OnIDPChange
|
||||
private void registerPredictor(PredictorState state, AppPredictor predictor) {
|
||||
state.predictor = predictor;
|
||||
state.predictor.registerPredictionUpdates(
|
||||
Executors.MODEL_EXECUTOR, new AppPredictor.Callback() {
|
||||
MODEL_EXECUTOR, new AppPredictor.Callback() {
|
||||
@Keep
|
||||
@Override
|
||||
public void onTargetsAvailable(@NonNull List<AppTarget> targets) {
|
||||
@@ -253,7 +334,7 @@ public class QuickstepModelDelegate extends ModelDelegate implements OnIDPChange
|
||||
private void registerWidgetsPredictor(AppPredictor predictor) {
|
||||
mWidgetsRecommendationState.predictor = predictor;
|
||||
mWidgetsRecommendationState.predictor.registerPredictionUpdates(
|
||||
Executors.MODEL_EXECUTOR, new AppPredictor.Callback() {
|
||||
MODEL_EXECUTOR, new AppPredictor.Callback() {
|
||||
@Keep
|
||||
@Override
|
||||
public void onTargetsAvailable(@NonNull List<AppTarget> targets) {
|
||||
@@ -268,19 +349,44 @@ public class QuickstepModelDelegate extends ModelDelegate implements OnIDPChange
|
||||
mWidgetsRecommendationState.predictor.requestPredictionUpdate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onIdpChanged(InvariantDeviceProfile profile) {
|
||||
// Reinitialize everything
|
||||
Executors.MODEL_EXECUTOR.execute(this::recreatePredictors);
|
||||
}
|
||||
|
||||
private void onAppTargetEvent(AppTargetEvent event, int client) {
|
||||
PredictorState state = client == CONTAINER_PREDICTION ? mAllAppsState : mHotseatState;
|
||||
PredictorState state;
|
||||
switch(client) {
|
||||
case CONTAINER_PREDICTION:
|
||||
state = mAllAppsState;
|
||||
break;
|
||||
case CONTAINER_WIDGETS_PREDICTION:
|
||||
state = mWidgetsRecommendationState;
|
||||
break;
|
||||
case CONTAINER_HOTSEAT_PREDICTION:
|
||||
default:
|
||||
state = mHotseatState;
|
||||
break;
|
||||
}
|
||||
if (state.predictor != null) {
|
||||
state.predictor.notifyAppTargetEvent(event);
|
||||
Log.d(TAG, "notifyAppTargetEvent action=" + event.getAction()
|
||||
+ " launchLocation=" + event.getLaunchLocation());
|
||||
}
|
||||
}
|
||||
|
||||
private Bundle getBundleForWidgetsOnWorkspace(Context context, BgDataModel dataModel) {
|
||||
Bundle bundle = new Bundle();
|
||||
ArrayList<AppTargetEvent> widgetEvents =
|
||||
dataModel.getAllWorkspaceItems().stream()
|
||||
.filter(PredictionHelper::isTrackedForWidgetPrediction)
|
||||
.map(item -> {
|
||||
AppTarget target = getAppTargetFromItemInfo(context, item);
|
||||
if (target == null) return null;
|
||||
return wrapAppTargetWithItemLocation(
|
||||
target, AppTargetEvent.ACTION_PIN, item);
|
||||
})
|
||||
.filter(Objects::nonNull)
|
||||
.collect(toCollection(ArrayList::new));
|
||||
bundle.putParcelableArrayList(BUNDLE_KEY_ADDED_APP_WIDGETS, widgetEvents);
|
||||
return bundle;
|
||||
}
|
||||
|
||||
static class PredictorState {
|
||||
|
||||
public final FixedContainerItems items;
|
||||
|
||||
Reference in New Issue
Block a user