From 9cbbc3a4b60c7fc9044650e2bcca38793d8e50c8 Mon Sep 17 00:00:00 2001 From: Becky Qiu Date: Tue, 7 Sep 2021 09:35:26 -0700 Subject: [PATCH 1/3] [OneSearch] Update the plugin interface to include more answer data. Bug: 196586652 Test: tested with OneSearchPlugin. Change-Id: I5c645828b83f1fe5b3bd2f71911b30e22909d56f --- .../android/systemui/plugins/OneSearch.java | 24 ++++--------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/src_plugins/com/android/systemui/plugins/OneSearch.java b/src_plugins/com/android/systemui/plugins/OneSearch.java index 6d57c19e66..8bd0b75a31 100644 --- a/src_plugins/com/android/systemui/plugins/OneSearch.java +++ b/src_plugins/com/android/systemui/plugins/OneSearch.java @@ -16,8 +16,7 @@ package com.android.systemui.plugins; -import android.graphics.Bitmap; -import android.text.Spanned; +import android.os.Parcelable; import com.android.systemui.plugins.annotations.ProvidesInterface; @@ -29,7 +28,7 @@ import java.util.ArrayList; @ProvidesInterface(action = OneSearch.ACTION, version = OneSearch.VERSION) public interface OneSearch extends Plugin { String ACTION = "com.android.systemui.action.PLUGIN_ONE_SEARCH"; - int VERSION = 2; + int VERSION = 3; /** * Get the content provider warmed up. @@ -37,23 +36,8 @@ public interface OneSearch extends Plugin { void warmUp(); /** - * Get the suggests for the query. + * Get the suggest search target list for the query. * @param query The query to get the search suggests for. */ - ArrayList getSuggests(String query); - - /** - * Get the image bitmap for the suggest. - * @param suggest The suggest to get the image bitmap for. - */ - Bitmap getImageBitmap(Spanned suggest); - - /** - * Get the subtitle for the suggest. - * @param suggest The suggest to get the subtitle for. - */ - String getSubtitle(Spanned suggest); - - /** Clear any cached data or storage used in search. */ - void clear(); + ArrayList getSuggests(Parcelable query); } From d495e8c8b47ec83a89826d653174164374226219 Mon Sep 17 00:00:00 2001 From: Thiru Ramasamy Date: Thu, 26 Aug 2021 10:37:17 -0700 Subject: [PATCH 2/3] Implement LauncherLayoutSnapshot pulled atom callback. This change will pull only the workspace items but not the launcher settings such as grid layout etc. Future CLs will address it. Bug: 181703659 Test: Manual-`statsd_testdrive 10108` http://gpaste/4894958784872448 Change-Id: I0e7d7da62034c411edb26ff9205a81b0e2e891a0 --- Android.bp | 9 +++ .../model/QuickstepModelDelegate.java | 66 +++++++++++++++++-- .../logging/StatsLogCompatManager.java | 32 +++++++++ .../android/launcher3/LauncherAppState.java | 5 +- src/com/android/launcher3/LauncherModel.java | 6 +- .../launcher3/model/ModelDelegate.java | 6 +- 6 files changed, 114 insertions(+), 10 deletions(-) diff --git a/Android.bp b/Android.bp index 43d28c9ad2..c8d9186010 100644 --- a/Android.bp +++ b/Android.bp @@ -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", diff --git a/quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java b/quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java index 5769f0bf65..55a140dffb 100644 --- a/quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java +++ b/quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java @@ -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 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; diff --git a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java index 6575996d69..7893f8d5a1 100644 --- a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java +++ b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java @@ -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. */ diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java index 86217d743e..10023b43d9 100644 --- a/src/com/android/launcher3/LauncherAppState.java +++ b/src/com/android/launcher3/LauncherAppState.java @@ -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); } diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java index 9ebec0a2ea..f38f66282a 100644 --- a/src/com/android/launcher3/LauncherModel.java +++ b/src/com/android/launcher3/LauncherModel.java @@ -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() { diff --git a/src/com/android/launcher3/model/ModelDelegate.java b/src/com/android/launcher3/model/ModelDelegate.java index 13ec1ecefb..765141a0e2 100644 --- a/src/com/android/launcher3/model/ModelDelegate.java +++ b/src/com/android/launcher3/model/ModelDelegate.java @@ -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() { } From 01c362bb6ced9a79fe6ca75a9fb7942cc991aee1 Mon Sep 17 00:00:00 2001 From: Lucas Dupin Date: Fri, 10 Sep 2021 22:57:24 +0000 Subject: [PATCH 3/3] Dump DepthController internals Add DepthController to dumpsys, so it's easier to debug any future issues. Bug: 198732728 Test: adb shell dumpsys activity com.google.android.apps.nexuslauncher Change-Id: Ifa7fe1d7fcb375cacc907d0da9524a2ee2a2677d --- .../launcher3/BaseQuickstepLauncher.java | 10 ++++++++ .../statehandlers/DepthController.java | 25 +++++++++++++++++-- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java index 2534699624..1f4be5b65a 100644 --- a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java +++ b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java @@ -90,6 +90,8 @@ import com.android.systemui.unfold.UnfoldTransitionFactory; import com.android.systemui.unfold.UnfoldTransitionProgressProvider; import com.android.systemui.unfold.config.UnfoldTransitionConfig; +import java.io.FileDescriptor; +import java.io.PrintWriter; import java.util.List; import java.util.stream.Stream; @@ -619,4 +621,12 @@ public abstract class BaseQuickstepLauncher extends Launcher recentsView.finishRecentsAnimation(/* toRecents= */ true, null); } } + + @Override + public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) { + super.dump(prefix, fd, writer, args); + if (mDepthController != null) { + mDepthController.dump(prefix, writer); + } + } } diff --git a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java index 3e2fb639e3..9d70cfaee6 100644 --- a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java +++ b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java @@ -44,6 +44,8 @@ import com.android.launcher3.states.StateAnimationConfig; import com.android.systemui.shared.system.BlurUtils; import com.android.systemui.shared.system.WallpaperManagerCompat; +import java.io.FileDescriptor; +import java.io.PrintWriter; import java.util.function.Consumer; /** @@ -137,6 +139,11 @@ public class DepthController implements StateHandler, * @see android.service.wallpaper.WallpaperService.Engine#onZoomChanged(float) */ private float mDepth; + /** + * Last blur value, in pixels, that was applied. + * For debugging purposes. + */ + private int mCurrentBlur; /** * If we're launching and app and should not be blurring the screen for performance reasons. */ @@ -306,10 +313,10 @@ public class DepthController implements StateHandler, if (supportsBlur) { boolean opaque = mLauncher.getScrimView().isFullyOpaque(); - int blur = !mCrossWindowBlursEnabled || mBlurDisabledForAppLaunch + mCurrentBlur = !mCrossWindowBlursEnabled || mBlurDisabledForAppLaunch ? 0 : (int) (depth * mMaxBlurRadius); SurfaceControl.Transaction transaction = new SurfaceControl.Transaction() - .setBackgroundBlurRadius(mSurface, blur) + .setBackgroundBlurRadius(mSurface, mCurrentBlur) .setOpaque(mSurface, opaque); // Set early wake-up flags when we know we're executing an expensive operation, this way @@ -348,4 +355,18 @@ public class DepthController implements StateHandler, mwAnimation.setAutoCancel(true); mwAnimation.start(); } + + public void dump(String prefix, PrintWriter writer) { + writer.println(prefix + this.getClass().getSimpleName()); + writer.println(prefix + "\tmMaxBlurRadius=" + mMaxBlurRadius); + writer.println(prefix + "\tmCrossWindowBlursEnabled=" + mCrossWindowBlursEnabled); + writer.println(prefix + "\tmSurface=" + mSurface); + writer.println(prefix + "\tmOverlayScrollProgress=" + mOverlayScrollProgress); + writer.println(prefix + "\tmDepth=" + mDepth); + writer.println(prefix + "\tmCurrentBlur=" + mCurrentBlur); + writer.println(prefix + "\tmBlurDisabledForAppLaunch=" + mBlurDisabledForAppLaunch); + writer.println(prefix + "\tmInEarlyWakeUp=" + mInEarlyWakeUp); + writer.println(prefix + "\tmIgnoreStateChangesDuringMultiWindowAnimation=" + + mIgnoreStateChangesDuringMultiWindowAnimation); + } }