Loading quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java +3 −6 Original line number Diff line number Diff line Loading @@ -18,7 +18,6 @@ package com.android.launcher3.model; import static android.text.format.DateUtils.DAY_IN_MILLIS; 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; Loading Loading @@ -252,12 +251,10 @@ public class QuickstepModelDelegate extends ModelDelegate implements OnIDPChange } @Override public void onIdpChanged(int changeFlags, InvariantDeviceProfile profile) { if ((changeFlags & CHANGE_FLAG_GRID) != 0) { 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; Loading quickstep/src/com/android/quickstep/RecentsModel.java +16 −8 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import android.os.UserHandle; import androidx.annotation.VisibleForTesting; import com.android.launcher3.icons.IconProvider; import com.android.launcher3.icons.IconProvider.IconChangeListener; import com.android.launcher3.util.Executors.SimpleThreadFactory; import com.android.launcher3.util.MainThreadInitializedObject; import com.android.systemui.shared.recents.model.Task; Loading @@ -49,7 +50,7 @@ import java.util.function.Consumer; * Singleton class to load and manage recents model. */ @TargetApi(Build.VERSION_CODES.O) public class RecentsModel extends TaskStackChangeListener { public class RecentsModel extends TaskStackChangeListener implements IconChangeListener { // We do not need any synchronization for this variable as its only written on UI thread. public static final MainThreadInitializedObject<RecentsModel> INSTANCE = Loading @@ -69,12 +70,13 @@ public class RecentsModel extends TaskStackChangeListener { mContext = context; mTaskList = new RecentTasksList(MAIN_EXECUTOR, new KeyguardManagerCompat(context), ActivityManagerWrapper.getInstance()); mIconCache = new TaskIconCache(context, RECENTS_MODEL_EXECUTOR); IconProvider iconProvider = new IconProvider(context); mIconCache = new TaskIconCache(context, RECENTS_MODEL_EXECUTOR, iconProvider); mThumbnailCache = new TaskThumbnailCache(context, RECENTS_MODEL_EXECUTOR); ActivityManagerWrapper.getInstance().registerTaskStackListener(this); IconProvider.registerIconChangeListener(context, this::onPackageIconChanged, MAIN_EXECUTOR.getHandler()); iconProvider.registerIconChangeListener(this, MAIN_EXECUTOR.getHandler()); } public TaskIconCache getIconCache() { Loading Loading @@ -183,15 +185,21 @@ public class RecentsModel extends TaskStackChangeListener { if (level == ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL) { // Clear everything once we reach a low-mem situation mThumbnailCache.clear(); mIconCache.clear(); mIconCache.clearCache(); } } private void onPackageIconChanged(String pkg, UserHandle user) { mIconCache.invalidateCacheEntries(pkg, user); @Override public void onAppIconChanged(String packageName, UserHandle user) { mIconCache.invalidateCacheEntries(packageName, user); for (int i = mThumbnailChangeListeners.size() - 1; i >= 0; i--) { mThumbnailChangeListeners.get(i).onTaskIconChanged(pkg, user); mThumbnailChangeListeners.get(i).onTaskIconChanged(packageName, user); } } @Override public void onSystemIconStateChanged(String iconState) { mIconCache.clearCache(); } /** Loading quickstep/src/com/android/quickstep/TaskIconCache.java +47 −12 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.quickstep; import static com.android.launcher3.uioverrides.QuickstepLauncher.GO_LOW_RAM_RECENTS_ENABLED; import static com.android.launcher3.util.DisplayController.CHANGE_DENSITY; import android.app.ActivityManager.TaskDescription; import android.content.Context; Loading @@ -35,9 +36,12 @@ import androidx.annotation.WorkerThread; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.icons.BaseIconFactory; import com.android.launcher3.icons.BitmapInfo; import com.android.launcher3.icons.IconProvider; import com.android.launcher3.icons.LauncherIcons; import com.android.launcher3.util.DisplayController; import com.android.launcher3.util.DisplayController.DisplayInfoChangeListener; import com.android.launcher3.util.DisplayController.Info; import com.android.launcher3.util.Preconditions; import com.android.quickstep.util.CancellableTask; import com.android.quickstep.util.TaskKeyLruCache; Loading @@ -52,7 +56,7 @@ import java.util.function.Consumer; /** * Manages the caching of task icons and related data. */ public class TaskIconCache { public class TaskIconCache implements DisplayInfoChangeListener { private final Executor mBgExecutor; private final AccessibilityManager mAccessibilityManager; Loading @@ -62,15 +66,27 @@ public class TaskIconCache { private final SparseArray<BitmapInfo> mDefaultIcons = new SparseArray<>(); private final IconProvider mIconProvider; public TaskIconCache(Context context, Executor bgExecutor) { private BaseIconFactory mIconFactory; public TaskIconCache(Context context, Executor bgExecutor, IconProvider iconProvider) { mContext = context; mBgExecutor = bgExecutor; mAccessibilityManager = context.getSystemService(AccessibilityManager.class); mIconProvider = iconProvider; Resources res = context.getResources(); int cacheSize = res.getInteger(R.integer.recentsIconCacheSize); mIconCache = new TaskKeyLruCache<>(cacheSize); mIconProvider = new IconProvider(context); DisplayController.INSTANCE.get(mContext).addChangeListener(this); } @Override public void onDisplayInfoChanged(Context context, Info info, int flags) { if ((flags & CHANGE_DENSITY) != 0) { clearCache(); } } /** Loading Loading @@ -104,8 +120,11 @@ public class TaskIconCache { return request; } public void clear() { mIconCache.evictAll(); /** * Clears the icon cache */ public void clearCache() { mBgExecutor.execute(this::resetFactory); } void onTaskRemoved(TaskKey taskKey) { Loading Loading @@ -193,8 +212,8 @@ public class TaskIconCache { synchronized (mDefaultIcons) { BitmapInfo info = mDefaultIcons.get(userId); if (info == null) { try (LauncherIcons la = LauncherIcons.obtain(mContext)) { info = la.makeDefaultIcon(UserHandle.of(userId)); try (BaseIconFactory bif = getIconFactory()) { info = bif.makeDefaultIcon(UserHandle.of(userId)); } mDefaultIcons.put(userId, info); } Loading @@ -205,16 +224,32 @@ public class TaskIconCache { @WorkerThread private BitmapInfo getBitmapInfo(Drawable drawable, int userId, int primaryColor, boolean isInstantApp) { try (LauncherIcons la = LauncherIcons.obtain(mContext)) { la.disableColorExtraction(); la.setWrapperBackgroundColor(primaryColor); try (BaseIconFactory bif = getIconFactory()) { bif.disableColorExtraction(); bif.setWrapperBackgroundColor(primaryColor); // User version code O, so that the icon is always wrapped in an adaptive icon container return la.createBadgedIconBitmap(drawable, UserHandle.of(userId), return bif.createBadgedIconBitmap(drawable, UserHandle.of(userId), Build.VERSION_CODES.O, isInstantApp); } } @WorkerThread private BaseIconFactory getIconFactory() { if (mIconFactory == null) { mIconFactory = new BaseIconFactory(mContext, DisplayController.INSTANCE.get(mContext).getInfo().densityDpi, mContext.getResources().getDimensionPixelSize(R.dimen.taskbar_icon_size)); } return mIconFactory; } @WorkerThread private void resetFactory() { mIconFactory = null; mIconCache.evictAll(); } private static class TaskCacheEntry { public Drawable icon; public String contentDescription = ""; Loading quickstep/src/com/android/quickstep/views/RecentsView.java +1 −15 Original line number Diff line number Diff line Loading @@ -23,7 +23,6 @@ import static android.view.View.MeasureSpec.makeMeasureSpec; import static com.android.launcher3.AbstractFloatingView.TYPE_TASK_MENU; import static com.android.launcher3.AbstractFloatingView.getTopOpenViewWithType; import static com.android.launcher3.BaseActivity.STATE_HANDLER_INVISIBILITY_FLAGS; import static com.android.launcher3.InvariantDeviceProfile.CHANGE_FLAG_ICON_PARAMS; import static com.android.launcher3.LauncherAnimUtils.SUCCESS_TRANSITION_PROGRESS; import static com.android.launcher3.LauncherAnimUtils.VIEW_ALPHA; import static com.android.launcher3.LauncherState.BACKGROUND_APP; Loading Loading @@ -171,8 +170,7 @@ import java.util.function.Consumer; public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_TYPE>, STATE_TYPE extends BaseState<STATE_TYPE>> extends PagedView implements Insettable, TaskThumbnailCache.HighResLoadingState.HighResLoadingStateChangedCallback, InvariantDeviceProfile.OnIDPChangeListener, TaskVisualsChangeListener, SplitScreenBounds.OnChangeListener { TaskVisualsChangeListener, SplitScreenBounds.OnChangeListener { public static final FloatProperty<RecentsView> CONTENT_ALPHA = new FloatProperty<RecentsView>("contentAlpha") { Loading Loading @@ -746,16 +744,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T updateTaskStackListenerState(); } @Override public void onIdpChanged(int changeFlags, InvariantDeviceProfile idp) { if ((changeFlags & CHANGE_FLAG_ICON_PARAMS) == 0) { return; } mModel.getIconCache().clear(); unloadVisibleTaskData(TaskView.FLAG_UPDATE_ICON); loadVisibleTaskData(TaskView.FLAG_UPDATE_ICON); } public void init(OverviewActionsView actionsView, SplitPlaceholderView splitPlaceholderView) { mActionsView = actionsView; mActionsView.updateHiddenFlags(HIDDEN_NO_TASKS, getTaskViewCount() == 0); Loading @@ -780,7 +768,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T mSyncTransactionApplier = new SurfaceTransactionApplier(this); mLiveTileParams.setSyncTransactionApplier(mSyncTransactionApplier); RecentsModel.INSTANCE.get(getContext()).addThumbnailChangeListener(this); mIdp.addOnChangeListener(this); mIPipAnimationListener.setActivity(mActivity); SystemUiProxy.INSTANCE.get(getContext()).setPinnedStackAnimationListener( mIPipAnimationListener); Loading @@ -799,7 +786,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T mSyncTransactionApplier = null; mLiveTileParams.setSyncTransactionApplier(null); RecentsModel.INSTANCE.get(getContext()).removeThumbnailChangeListener(this); mIdp.removeOnChangeListener(this); SystemUiProxy.INSTANCE.get(getContext()).setPinnedStackAnimationListener(null); SplitScreenBounds.INSTANCE.removeOnChangeListener(this); mIPipAnimationListener.setActivity(null); Loading src/com/android/launcher3/InvariantDeviceProfile.java +5 −81 Original line number Diff line number Diff line Loading @@ -17,20 +17,16 @@ package com.android.launcher3; import static com.android.launcher3.Utilities.dpiFromPx; import static com.android.launcher3.Utilities.getDevicePrefs; import static com.android.launcher3.Utilities.getPointString; import static com.android.launcher3.config.FeatureFlags.ENABLE_TWO_PANEL_HOME; import static com.android.launcher3.util.DisplayController.CHANGE_DENSITY; import static com.android.launcher3.util.DisplayController.CHANGE_SUPPORTED_BOUNDS; import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static com.android.launcher3.util.PackageManagerHelper.getPackageFilter; import android.annotation.TargetApi; import android.appwidget.AppWidgetHostView; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.res.Configuration; import android.content.res.Resources; import android.content.res.TypedArray; Loading @@ -49,7 +45,6 @@ import android.view.Display; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import com.android.launcher3.graphics.IconShape; import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.util.DisplayController; import com.android.launcher3.util.DisplayController.Info; Loading Loading @@ -83,11 +78,6 @@ public class InvariantDeviceProfile { private static final float ICON_SIZE_DEFINED_IN_APP_DP = 48; public static final int CHANGE_FLAG_GRID = 1 << 0; public static final int CHANGE_FLAG_ICON_PARAMS = 1 << 1; public static final String KEY_ICON_PATH_REF = "pref_icon_shape_path"; // Constants that affects the interpolation curve between statically defined device profile // buckets. private static final float KNEARESTNEIGHBOR = 3; Loading @@ -96,9 +86,6 @@ public class InvariantDeviceProfile { // used to offset float not being able to express extremely small weights in extreme cases. private static final float WEIGHT_EFFICIENT = 100000f; private static final int CONFIG_ICON_MASK_RES_ID = Resources.getSystem().getIdentifier( "config_icon_mask", "string", "android"); /** * Number of icons per row and column in the workspace. */ Loading @@ -111,7 +98,6 @@ public class InvariantDeviceProfile { public int numFolderRows; public int numFolderColumns; public float iconSize; public String iconShapePath; public float landscapeIconSize; public float landscapeIconTextSize; public int iconBitmapSize; Loading Loading @@ -162,7 +148,6 @@ public class InvariantDeviceProfile { public Rect defaultWidgetPadding; private final ArrayList<OnIDPChangeListener> mChangeListeners = new ArrayList<>(); private OverlayMonitor mOverlayMonitor; @VisibleForTesting public InvariantDeviceProfile() {} Loading @@ -173,7 +158,6 @@ public class InvariantDeviceProfile { numFolderRows = p.numFolderRows; numFolderColumns = p.numFolderColumns; iconSize = p.iconSize; iconShapePath = p.iconShapePath; landscapeIconSize = p.landscapeIconSize; iconBitmapSize = p.iconBitmapSize; iconTextSize = p.iconTextSize; Loading @@ -193,7 +177,6 @@ public class InvariantDeviceProfile { defaultLayoutId = p.defaultLayoutId; demoModeLayoutId = p.demoModeLayoutId; mExtraAttrs = p.mExtraAttrs; mOverlayMonitor = p.mOverlayMonitor; devicePaddings = p.devicePaddings; } Loading @@ -215,7 +198,6 @@ public class InvariantDeviceProfile { onConfigChanged(displayContext); } }); mOverlayMonitor = new OverlayMonitor(context); } /** Loading Loading @@ -266,17 +248,6 @@ public class InvariantDeviceProfile { ? Utilities.getPrefs(context).getString(KEY_IDP_GRID_NAME, null) : null; } /** * Retrieve system defined or RRO overriden icon shape. */ private static String getIconShapePath(Context context) { if (CONFIG_ICON_MASK_RES_ID == 0) { Log.e(TAG, "Icon mask res identifier failed to retrieve."); return ""; } return context.getResources().getString(CONFIG_ICON_MASK_RES_ID); } private String initGrid(Context context, String gridName) { Info displayInfo = DisplayController.INSTANCE.get(context).getInfo(); // Determine if we have split display Loading Loading @@ -317,7 +288,6 @@ public class InvariantDeviceProfile { mExtraAttrs = closestProfile.extraAttrs; iconSize = displayOption.iconSize; iconShapePath = getIconShapePath(context); landscapeIconSize = displayOption.landscapeIconSize; iconBitmapSize = ResourceUtils.pxFromDp(iconSize, metrics); iconTextSize = displayOption.iconTextSize; Loading Loading @@ -391,18 +361,6 @@ public class InvariantDeviceProfile { mChangeListeners.remove(listener); } public void verifyConfigChangedInBackground(final Context context) { String savedIconMaskPath = getDevicePrefs(context).getString(KEY_ICON_PATH_REF, ""); // Good place to check if grid size changed in themepicker when launcher was dead. if (savedIconMaskPath.isEmpty()) { getDevicePrefs(context).edit().putString(KEY_ICON_PATH_REF, getIconShapePath(context)) .apply(); } else if (!savedIconMaskPath.equals(getIconShapePath(context))) { getDevicePrefs(context).edit().putString(KEY_ICON_PATH_REF, getIconShapePath(context)) .apply(); apply(CHANGE_FLAG_ICON_PARAMS); } } public void setCurrentGrid(Context context, String gridName) { Context appContext = context.getApplicationContext(); Loading @@ -414,36 +372,13 @@ public class InvariantDeviceProfile { if (TestProtocol.sDebugTracing) { Log.d(TestProtocol.LAUNCHER_NOT_TRANSPOSED, "IDP.onConfigChanged"); } // Config changes, what shall we do? InvariantDeviceProfile oldProfile = new InvariantDeviceProfile(this); // Re-init grid String gridName = getCurrentGridName(context); initGrid(context, gridName); int changeFlags = 0; if (numRows != oldProfile.numRows || numColumns != oldProfile.numColumns || numFolderColumns != oldProfile.numFolderColumns || numFolderRows != oldProfile.numFolderRows || numDatabaseHotseatIcons != oldProfile.numDatabaseHotseatIcons) { changeFlags |= CHANGE_FLAG_GRID; } if (iconSize != oldProfile.iconSize || iconBitmapSize != oldProfile.iconBitmapSize || !iconShapePath.equals(oldProfile.iconShapePath)) { changeFlags |= CHANGE_FLAG_ICON_PARAMS; } if (!iconShapePath.equals(oldProfile.iconShapePath)) { IconShape.init(context); } apply(changeFlags); } private void apply(int changeFlags) { for (OnIDPChangeListener listener : mChangeListeners) { listener.onIdpChanged(changeFlags, this); listener.onIdpChanged(this); } } Loading Loading @@ -650,7 +585,10 @@ public class InvariantDeviceProfile { public interface OnIDPChangeListener { void onIdpChanged(int changeFlags, InvariantDeviceProfile profile); /** * Called when the device provide changes */ void onIdpChanged(InvariantDeviceProfile profile); } Loading Loading @@ -809,18 +747,4 @@ public class InvariantDeviceProfile { return this; } } private class OverlayMonitor extends BroadcastReceiver { private final String ACTION_OVERLAY_CHANGED = "android.intent.action.OVERLAY_CHANGED"; OverlayMonitor(Context context) { context.registerReceiver(this, getPackageFilter("android", ACTION_OVERLAY_CHANGED)); } @Override public void onReceive(Context context, Intent intent) { onConfigChanged(context); } } } Loading
quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java +3 −6 Original line number Diff line number Diff line Loading @@ -18,7 +18,6 @@ package com.android.launcher3.model; import static android.text.format.DateUtils.DAY_IN_MILLIS; 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; Loading Loading @@ -252,12 +251,10 @@ public class QuickstepModelDelegate extends ModelDelegate implements OnIDPChange } @Override public void onIdpChanged(int changeFlags, InvariantDeviceProfile profile) { if ((changeFlags & CHANGE_FLAG_GRID) != 0) { 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; Loading
quickstep/src/com/android/quickstep/RecentsModel.java +16 −8 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import android.os.UserHandle; import androidx.annotation.VisibleForTesting; import com.android.launcher3.icons.IconProvider; import com.android.launcher3.icons.IconProvider.IconChangeListener; import com.android.launcher3.util.Executors.SimpleThreadFactory; import com.android.launcher3.util.MainThreadInitializedObject; import com.android.systemui.shared.recents.model.Task; Loading @@ -49,7 +50,7 @@ import java.util.function.Consumer; * Singleton class to load and manage recents model. */ @TargetApi(Build.VERSION_CODES.O) public class RecentsModel extends TaskStackChangeListener { public class RecentsModel extends TaskStackChangeListener implements IconChangeListener { // We do not need any synchronization for this variable as its only written on UI thread. public static final MainThreadInitializedObject<RecentsModel> INSTANCE = Loading @@ -69,12 +70,13 @@ public class RecentsModel extends TaskStackChangeListener { mContext = context; mTaskList = new RecentTasksList(MAIN_EXECUTOR, new KeyguardManagerCompat(context), ActivityManagerWrapper.getInstance()); mIconCache = new TaskIconCache(context, RECENTS_MODEL_EXECUTOR); IconProvider iconProvider = new IconProvider(context); mIconCache = new TaskIconCache(context, RECENTS_MODEL_EXECUTOR, iconProvider); mThumbnailCache = new TaskThumbnailCache(context, RECENTS_MODEL_EXECUTOR); ActivityManagerWrapper.getInstance().registerTaskStackListener(this); IconProvider.registerIconChangeListener(context, this::onPackageIconChanged, MAIN_EXECUTOR.getHandler()); iconProvider.registerIconChangeListener(this, MAIN_EXECUTOR.getHandler()); } public TaskIconCache getIconCache() { Loading Loading @@ -183,15 +185,21 @@ public class RecentsModel extends TaskStackChangeListener { if (level == ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL) { // Clear everything once we reach a low-mem situation mThumbnailCache.clear(); mIconCache.clear(); mIconCache.clearCache(); } } private void onPackageIconChanged(String pkg, UserHandle user) { mIconCache.invalidateCacheEntries(pkg, user); @Override public void onAppIconChanged(String packageName, UserHandle user) { mIconCache.invalidateCacheEntries(packageName, user); for (int i = mThumbnailChangeListeners.size() - 1; i >= 0; i--) { mThumbnailChangeListeners.get(i).onTaskIconChanged(pkg, user); mThumbnailChangeListeners.get(i).onTaskIconChanged(packageName, user); } } @Override public void onSystemIconStateChanged(String iconState) { mIconCache.clearCache(); } /** Loading
quickstep/src/com/android/quickstep/TaskIconCache.java +47 −12 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.quickstep; import static com.android.launcher3.uioverrides.QuickstepLauncher.GO_LOW_RAM_RECENTS_ENABLED; import static com.android.launcher3.util.DisplayController.CHANGE_DENSITY; import android.app.ActivityManager.TaskDescription; import android.content.Context; Loading @@ -35,9 +36,12 @@ import androidx.annotation.WorkerThread; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.icons.BaseIconFactory; import com.android.launcher3.icons.BitmapInfo; import com.android.launcher3.icons.IconProvider; import com.android.launcher3.icons.LauncherIcons; import com.android.launcher3.util.DisplayController; import com.android.launcher3.util.DisplayController.DisplayInfoChangeListener; import com.android.launcher3.util.DisplayController.Info; import com.android.launcher3.util.Preconditions; import com.android.quickstep.util.CancellableTask; import com.android.quickstep.util.TaskKeyLruCache; Loading @@ -52,7 +56,7 @@ import java.util.function.Consumer; /** * Manages the caching of task icons and related data. */ public class TaskIconCache { public class TaskIconCache implements DisplayInfoChangeListener { private final Executor mBgExecutor; private final AccessibilityManager mAccessibilityManager; Loading @@ -62,15 +66,27 @@ public class TaskIconCache { private final SparseArray<BitmapInfo> mDefaultIcons = new SparseArray<>(); private final IconProvider mIconProvider; public TaskIconCache(Context context, Executor bgExecutor) { private BaseIconFactory mIconFactory; public TaskIconCache(Context context, Executor bgExecutor, IconProvider iconProvider) { mContext = context; mBgExecutor = bgExecutor; mAccessibilityManager = context.getSystemService(AccessibilityManager.class); mIconProvider = iconProvider; Resources res = context.getResources(); int cacheSize = res.getInteger(R.integer.recentsIconCacheSize); mIconCache = new TaskKeyLruCache<>(cacheSize); mIconProvider = new IconProvider(context); DisplayController.INSTANCE.get(mContext).addChangeListener(this); } @Override public void onDisplayInfoChanged(Context context, Info info, int flags) { if ((flags & CHANGE_DENSITY) != 0) { clearCache(); } } /** Loading Loading @@ -104,8 +120,11 @@ public class TaskIconCache { return request; } public void clear() { mIconCache.evictAll(); /** * Clears the icon cache */ public void clearCache() { mBgExecutor.execute(this::resetFactory); } void onTaskRemoved(TaskKey taskKey) { Loading Loading @@ -193,8 +212,8 @@ public class TaskIconCache { synchronized (mDefaultIcons) { BitmapInfo info = mDefaultIcons.get(userId); if (info == null) { try (LauncherIcons la = LauncherIcons.obtain(mContext)) { info = la.makeDefaultIcon(UserHandle.of(userId)); try (BaseIconFactory bif = getIconFactory()) { info = bif.makeDefaultIcon(UserHandle.of(userId)); } mDefaultIcons.put(userId, info); } Loading @@ -205,16 +224,32 @@ public class TaskIconCache { @WorkerThread private BitmapInfo getBitmapInfo(Drawable drawable, int userId, int primaryColor, boolean isInstantApp) { try (LauncherIcons la = LauncherIcons.obtain(mContext)) { la.disableColorExtraction(); la.setWrapperBackgroundColor(primaryColor); try (BaseIconFactory bif = getIconFactory()) { bif.disableColorExtraction(); bif.setWrapperBackgroundColor(primaryColor); // User version code O, so that the icon is always wrapped in an adaptive icon container return la.createBadgedIconBitmap(drawable, UserHandle.of(userId), return bif.createBadgedIconBitmap(drawable, UserHandle.of(userId), Build.VERSION_CODES.O, isInstantApp); } } @WorkerThread private BaseIconFactory getIconFactory() { if (mIconFactory == null) { mIconFactory = new BaseIconFactory(mContext, DisplayController.INSTANCE.get(mContext).getInfo().densityDpi, mContext.getResources().getDimensionPixelSize(R.dimen.taskbar_icon_size)); } return mIconFactory; } @WorkerThread private void resetFactory() { mIconFactory = null; mIconCache.evictAll(); } private static class TaskCacheEntry { public Drawable icon; public String contentDescription = ""; Loading
quickstep/src/com/android/quickstep/views/RecentsView.java +1 −15 Original line number Diff line number Diff line Loading @@ -23,7 +23,6 @@ import static android.view.View.MeasureSpec.makeMeasureSpec; import static com.android.launcher3.AbstractFloatingView.TYPE_TASK_MENU; import static com.android.launcher3.AbstractFloatingView.getTopOpenViewWithType; import static com.android.launcher3.BaseActivity.STATE_HANDLER_INVISIBILITY_FLAGS; import static com.android.launcher3.InvariantDeviceProfile.CHANGE_FLAG_ICON_PARAMS; import static com.android.launcher3.LauncherAnimUtils.SUCCESS_TRANSITION_PROGRESS; import static com.android.launcher3.LauncherAnimUtils.VIEW_ALPHA; import static com.android.launcher3.LauncherState.BACKGROUND_APP; Loading Loading @@ -171,8 +170,7 @@ import java.util.function.Consumer; public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_TYPE>, STATE_TYPE extends BaseState<STATE_TYPE>> extends PagedView implements Insettable, TaskThumbnailCache.HighResLoadingState.HighResLoadingStateChangedCallback, InvariantDeviceProfile.OnIDPChangeListener, TaskVisualsChangeListener, SplitScreenBounds.OnChangeListener { TaskVisualsChangeListener, SplitScreenBounds.OnChangeListener { public static final FloatProperty<RecentsView> CONTENT_ALPHA = new FloatProperty<RecentsView>("contentAlpha") { Loading Loading @@ -746,16 +744,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T updateTaskStackListenerState(); } @Override public void onIdpChanged(int changeFlags, InvariantDeviceProfile idp) { if ((changeFlags & CHANGE_FLAG_ICON_PARAMS) == 0) { return; } mModel.getIconCache().clear(); unloadVisibleTaskData(TaskView.FLAG_UPDATE_ICON); loadVisibleTaskData(TaskView.FLAG_UPDATE_ICON); } public void init(OverviewActionsView actionsView, SplitPlaceholderView splitPlaceholderView) { mActionsView = actionsView; mActionsView.updateHiddenFlags(HIDDEN_NO_TASKS, getTaskViewCount() == 0); Loading @@ -780,7 +768,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T mSyncTransactionApplier = new SurfaceTransactionApplier(this); mLiveTileParams.setSyncTransactionApplier(mSyncTransactionApplier); RecentsModel.INSTANCE.get(getContext()).addThumbnailChangeListener(this); mIdp.addOnChangeListener(this); mIPipAnimationListener.setActivity(mActivity); SystemUiProxy.INSTANCE.get(getContext()).setPinnedStackAnimationListener( mIPipAnimationListener); Loading @@ -799,7 +786,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T mSyncTransactionApplier = null; mLiveTileParams.setSyncTransactionApplier(null); RecentsModel.INSTANCE.get(getContext()).removeThumbnailChangeListener(this); mIdp.removeOnChangeListener(this); SystemUiProxy.INSTANCE.get(getContext()).setPinnedStackAnimationListener(null); SplitScreenBounds.INSTANCE.removeOnChangeListener(this); mIPipAnimationListener.setActivity(null); Loading
src/com/android/launcher3/InvariantDeviceProfile.java +5 −81 Original line number Diff line number Diff line Loading @@ -17,20 +17,16 @@ package com.android.launcher3; import static com.android.launcher3.Utilities.dpiFromPx; import static com.android.launcher3.Utilities.getDevicePrefs; import static com.android.launcher3.Utilities.getPointString; import static com.android.launcher3.config.FeatureFlags.ENABLE_TWO_PANEL_HOME; import static com.android.launcher3.util.DisplayController.CHANGE_DENSITY; import static com.android.launcher3.util.DisplayController.CHANGE_SUPPORTED_BOUNDS; import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static com.android.launcher3.util.PackageManagerHelper.getPackageFilter; import android.annotation.TargetApi; import android.appwidget.AppWidgetHostView; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.res.Configuration; import android.content.res.Resources; import android.content.res.TypedArray; Loading @@ -49,7 +45,6 @@ import android.view.Display; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import com.android.launcher3.graphics.IconShape; import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.util.DisplayController; import com.android.launcher3.util.DisplayController.Info; Loading Loading @@ -83,11 +78,6 @@ public class InvariantDeviceProfile { private static final float ICON_SIZE_DEFINED_IN_APP_DP = 48; public static final int CHANGE_FLAG_GRID = 1 << 0; public static final int CHANGE_FLAG_ICON_PARAMS = 1 << 1; public static final String KEY_ICON_PATH_REF = "pref_icon_shape_path"; // Constants that affects the interpolation curve between statically defined device profile // buckets. private static final float KNEARESTNEIGHBOR = 3; Loading @@ -96,9 +86,6 @@ public class InvariantDeviceProfile { // used to offset float not being able to express extremely small weights in extreme cases. private static final float WEIGHT_EFFICIENT = 100000f; private static final int CONFIG_ICON_MASK_RES_ID = Resources.getSystem().getIdentifier( "config_icon_mask", "string", "android"); /** * Number of icons per row and column in the workspace. */ Loading @@ -111,7 +98,6 @@ public class InvariantDeviceProfile { public int numFolderRows; public int numFolderColumns; public float iconSize; public String iconShapePath; public float landscapeIconSize; public float landscapeIconTextSize; public int iconBitmapSize; Loading Loading @@ -162,7 +148,6 @@ public class InvariantDeviceProfile { public Rect defaultWidgetPadding; private final ArrayList<OnIDPChangeListener> mChangeListeners = new ArrayList<>(); private OverlayMonitor mOverlayMonitor; @VisibleForTesting public InvariantDeviceProfile() {} Loading @@ -173,7 +158,6 @@ public class InvariantDeviceProfile { numFolderRows = p.numFolderRows; numFolderColumns = p.numFolderColumns; iconSize = p.iconSize; iconShapePath = p.iconShapePath; landscapeIconSize = p.landscapeIconSize; iconBitmapSize = p.iconBitmapSize; iconTextSize = p.iconTextSize; Loading @@ -193,7 +177,6 @@ public class InvariantDeviceProfile { defaultLayoutId = p.defaultLayoutId; demoModeLayoutId = p.demoModeLayoutId; mExtraAttrs = p.mExtraAttrs; mOverlayMonitor = p.mOverlayMonitor; devicePaddings = p.devicePaddings; } Loading @@ -215,7 +198,6 @@ public class InvariantDeviceProfile { onConfigChanged(displayContext); } }); mOverlayMonitor = new OverlayMonitor(context); } /** Loading Loading @@ -266,17 +248,6 @@ public class InvariantDeviceProfile { ? Utilities.getPrefs(context).getString(KEY_IDP_GRID_NAME, null) : null; } /** * Retrieve system defined or RRO overriden icon shape. */ private static String getIconShapePath(Context context) { if (CONFIG_ICON_MASK_RES_ID == 0) { Log.e(TAG, "Icon mask res identifier failed to retrieve."); return ""; } return context.getResources().getString(CONFIG_ICON_MASK_RES_ID); } private String initGrid(Context context, String gridName) { Info displayInfo = DisplayController.INSTANCE.get(context).getInfo(); // Determine if we have split display Loading Loading @@ -317,7 +288,6 @@ public class InvariantDeviceProfile { mExtraAttrs = closestProfile.extraAttrs; iconSize = displayOption.iconSize; iconShapePath = getIconShapePath(context); landscapeIconSize = displayOption.landscapeIconSize; iconBitmapSize = ResourceUtils.pxFromDp(iconSize, metrics); iconTextSize = displayOption.iconTextSize; Loading Loading @@ -391,18 +361,6 @@ public class InvariantDeviceProfile { mChangeListeners.remove(listener); } public void verifyConfigChangedInBackground(final Context context) { String savedIconMaskPath = getDevicePrefs(context).getString(KEY_ICON_PATH_REF, ""); // Good place to check if grid size changed in themepicker when launcher was dead. if (savedIconMaskPath.isEmpty()) { getDevicePrefs(context).edit().putString(KEY_ICON_PATH_REF, getIconShapePath(context)) .apply(); } else if (!savedIconMaskPath.equals(getIconShapePath(context))) { getDevicePrefs(context).edit().putString(KEY_ICON_PATH_REF, getIconShapePath(context)) .apply(); apply(CHANGE_FLAG_ICON_PARAMS); } } public void setCurrentGrid(Context context, String gridName) { Context appContext = context.getApplicationContext(); Loading @@ -414,36 +372,13 @@ public class InvariantDeviceProfile { if (TestProtocol.sDebugTracing) { Log.d(TestProtocol.LAUNCHER_NOT_TRANSPOSED, "IDP.onConfigChanged"); } // Config changes, what shall we do? InvariantDeviceProfile oldProfile = new InvariantDeviceProfile(this); // Re-init grid String gridName = getCurrentGridName(context); initGrid(context, gridName); int changeFlags = 0; if (numRows != oldProfile.numRows || numColumns != oldProfile.numColumns || numFolderColumns != oldProfile.numFolderColumns || numFolderRows != oldProfile.numFolderRows || numDatabaseHotseatIcons != oldProfile.numDatabaseHotseatIcons) { changeFlags |= CHANGE_FLAG_GRID; } if (iconSize != oldProfile.iconSize || iconBitmapSize != oldProfile.iconBitmapSize || !iconShapePath.equals(oldProfile.iconShapePath)) { changeFlags |= CHANGE_FLAG_ICON_PARAMS; } if (!iconShapePath.equals(oldProfile.iconShapePath)) { IconShape.init(context); } apply(changeFlags); } private void apply(int changeFlags) { for (OnIDPChangeListener listener : mChangeListeners) { listener.onIdpChanged(changeFlags, this); listener.onIdpChanged(this); } } Loading Loading @@ -650,7 +585,10 @@ public class InvariantDeviceProfile { public interface OnIDPChangeListener { void onIdpChanged(int changeFlags, InvariantDeviceProfile profile); /** * Called when the device provide changes */ void onIdpChanged(InvariantDeviceProfile profile); } Loading Loading @@ -809,18 +747,4 @@ public class InvariantDeviceProfile { return this; } } private class OverlayMonitor extends BroadcastReceiver { private final String ACTION_OVERLAY_CHANGED = "android.intent.action.OVERLAY_CHANGED"; OverlayMonitor(Context context) { context.registerReceiver(this, getPackageFilter("android", ACTION_OVERLAY_CHANGED)); } @Override public void onReceive(Context context, Intent intent) { onConfigChanged(context); } } }