Merge "Implement LauncherLayoutSnapshot pulled atom callback." into sc-v2-dev am: 8c8dc56495

Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Launcher3/+/15685719

Change-Id: I031cd264a3631248e0c8e0a1a2d524e1720ba0e1
This commit is contained in:
Thiru Ramasamy
2021-09-10 23:15:43 +00:00
committed by Automerger Merge Worker
6 changed files with 114 additions and 10 deletions
+9
View File
@@ -33,6 +33,9 @@ license {
android_library {
name: "launcher-aosp-tapl",
libs: [
"framework-statsd",
],
static_libs: [
"androidx.annotation_annotation",
"androidx.test.runner",
@@ -192,6 +195,9 @@ android_library {
resource_dirs: [
"quickstep/res",
],
libs: [
"framework-statsd",
],
static_libs: [
"Launcher3ResLib",
"SystemUISharedLib",
@@ -261,6 +267,9 @@ android_library {
resource_dirs: [
"quickstep/res",
],
libs: [
"framework-statsd",
],
static_libs: [
"SystemUI-statsd",
"SystemUISharedLib",
@@ -25,7 +25,9 @@ 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.util.Executors.MODEL_EXECUTOR;
import android.app.StatsManager;
import android.app.prediction.AppPredictionContext;
import android.app.prediction.AppPredictionManager;
import android.app.prediction.AppPredictor;
@@ -39,12 +41,14 @@ import android.content.pm.LauncherApps;
import android.content.pm.ShortcutInfo;
import android.os.UserHandle;
import android.util.Log;
import android.util.StatsEvent;
import androidx.annotation.Nullable;
import androidx.annotation.WorkerThread;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.LauncherAppState;
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;
@@ -53,10 +57,10 @@ 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.StatsLogCompatManager;
import com.android.systemui.shared.system.SysUiStatsLog;
import java.util.Collections;
import java.util.List;
@@ -85,6 +89,7 @@ public class QuickstepModelDelegate extends ModelDelegate {
private final InvariantDeviceProfile mIDP;
private final AppEventProducer mAppEventProducer;
private final StatsManager mStatsManager;
protected boolean mActive = false;
@@ -93,6 +98,7 @@ public class QuickstepModelDelegate extends ModelDelegate {
mIDP = InvariantDeviceProfile.INSTANCE.get(context);
StatsLogCompatManager.LOGS_CONSUMER.add(mAppEventProducer);
mStatsManager = context.getSystemService(StatsManager.class);
}
@Override
@@ -155,10 +161,60 @@ public class QuickstepModelDelegate extends ModelDelegate {
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 = info.container > 0
? (FolderInfo) itemsIdMap.get(info.container) : null;
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);
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);
}
}
@Override
public void validateData() {
super.validateData();
@@ -175,7 +231,9 @@ public class QuickstepModelDelegate extends ModelDelegate {
super.destroy();
mActive = false;
StatsLogCompatManager.LOGS_CONSUMER.remove(mAppEventProducer);
if (mIsPrimaryInstance) {
mStatsManager.clearPullAtomCallback(SysUiStatsLog.LAUNCHER_LAYOUT_SNAPSHOT);
}
destroyPredictors();
}
@@ -221,7 +279,7 @@ public class QuickstepModelDelegate extends ModelDelegate {
private void registerPredictor(PredictorState state, AppPredictor predictor) {
state.predictor = predictor;
state.predictor.registerPredictionUpdates(
Executors.MODEL_EXECUTOR, t -> handleUpdate(state, t));
MODEL_EXECUTOR, t -> handleUpdate(state, t));
state.predictor.requestPredictionUpdate();
}
@@ -236,7 +294,7 @@ public class QuickstepModelDelegate extends ModelDelegate {
private void registerWidgetsPredictor(AppPredictor predictor) {
mWidgetsRecommendationState.predictor = predictor;
mWidgetsRecommendationState.predictor.registerPredictionUpdates(
Executors.MODEL_EXECUTOR, targets -> {
MODEL_EXECUTOR, targets -> {
if (mWidgetsRecommendationState.setTargets(targets)) {
// No diff, skip
return;
@@ -31,9 +31,11 @@ import static com.android.systemui.shared.system.SysUiStatsLog.LAUNCHER_UICHANGE
import android.content.Context;
import android.util.Log;
import android.util.StatsEvent;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.WorkerThread;
import androidx.slice.SliceItem;
@@ -134,6 +136,36 @@ public class StatsLogCompatManager extends StatsLogManager {
getFeatures(info));
}
/**
* Builds {@link StatsEvent} from {@link LauncherAtom.ItemInfo}. Used for pulled atom callback
* implementation.
*/
public static StatsEvent buildStatsEvent(LauncherAtom.ItemInfo info,
@Nullable InstanceId instanceId) {
return SysUiStatsLog.buildStatsEvent(
SysUiStatsLog.LAUNCHER_LAYOUT_SNAPSHOT, // atom ID,
LAUNCHER_WORKSPACE_SNAPSHOT.getId(), // event_id = 1;
info.getAttribute().getNumber() * ATTRIBUTE_MULTIPLIER
+ info.getItemCase().getNumber(), // item_id = 2;
instanceId == null ? 0 : instanceId.getId(), //instance_id = 3;
0, //uid = 4 [(is_uid) = true];
getPackageName(info), // package_name = 5;
getComponentName(info), // component_name = 6;
getGridX(info, false), //grid_x = 7 [default = -1];
getGridY(info, false), //grid_y = 8 [default = -1];
getPageId(info), // page_id = 9 [default = -2];
getGridX(info, true), //grid_x_parent = 10 [default = -1];
getGridY(info, true), //grid_y_parent = 11 [default = -1];
getParentPageId(info), //page_id_parent = 12 [default = -2];
getHierarchy(info), // container_id = 13;
info.getIsWork(), // is_work_profile = 14;
info.getAttribute().getNumber(), // attribute_id = 15;
getCardinality(info), // cardinality = 16;
info.getWidget().getSpanX(), // span_x = 17 [default = 1];
info.getWidget().getSpanY() // span_y = 18 [default = 1];
);
}
/**
* Helps to construct and write statsd compatible log message.
*/
@@ -138,10 +138,11 @@ public class LauncherAppState implements SafeCloseable {
mContext = context;
mInvariantDeviceProfile = InvariantDeviceProfile.INSTANCE.get(context);
mIconProvider = new IconProvider(context, Themes.isThemedIconEnabled(context));
mIconProvider = new IconProvider(context, Themes.isThemedIconEnabled(context));
mIconCache = new IconCache(mContext, mInvariantDeviceProfile,
iconCacheFileName, mIconProvider);
mModel = new LauncherModel(context, this, mIconCache, new AppFilter(mContext));
mModel = new LauncherModel(context, this, mIconCache, new AppFilter(mContext),
iconCacheFileName != null);
mOnTerminateCallback.add(mIconCache::close);
}
+4 -2
View File
@@ -126,10 +126,12 @@ public class LauncherModel extends LauncherApps.Callback implements InstallSessi
}
};
LauncherModel(Context context, LauncherAppState app, IconCache iconCache, AppFilter appFilter) {
LauncherModel(Context context, LauncherAppState app, IconCache iconCache, AppFilter appFilter,
boolean isPrimaryInstance) {
mApp = app;
mBgAllAppsList = new AllAppsList(iconCache, appFilter);
mModelDelegate = ModelDelegate.newInstance(context, app, mBgAllAppsList, mBgDataModel);
mModelDelegate = ModelDelegate.newInstance(context, app, mBgAllAppsList, mBgDataModel,
isPrimaryInstance);
}
public ModelDelegate getModelDelegate() {
@@ -40,19 +40,21 @@ public class ModelDelegate implements ResourceBasedOverride {
* Creates and initializes a new instance of the delegate
*/
public static ModelDelegate newInstance(
Context context, LauncherAppState app, AllAppsList appsList, BgDataModel dataModel) {
Context context, LauncherAppState app, AllAppsList appsList, BgDataModel dataModel,
boolean isPrimaryInstance) {
ModelDelegate delegate = Overrides.getObject(
ModelDelegate.class, context, R.string.model_delegate_class);
delegate.mApp = app;
delegate.mAppsList = appsList;
delegate.mDataModel = dataModel;
delegate.mIsPrimaryInstance = isPrimaryInstance;
return delegate;
}
protected LauncherAppState mApp;
protected AllAppsList mAppsList;
protected BgDataModel mDataModel;
protected boolean mIsPrimaryInstance;
public ModelDelegate() { }