Linking various settings that control icon cache to icon state
Also separating icon provider for recents from Launcher as it used a fixed size Bug: 183641907 Test: Verified on device Change-Id: I6ea3caa0066d1483bfb8a81f0e8aaa472c813afe
This commit is contained in:
@@ -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;
|
||||
@@ -252,11 +251,9 @@ public class QuickstepModelDelegate extends ModelDelegate implements OnIDPChange
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onIdpChanged(int changeFlags, InvariantDeviceProfile profile) {
|
||||
if ((changeFlags & CHANGE_FLAG_GRID) != 0) {
|
||||
// Reinitialize everything
|
||||
Executors.MODEL_EXECUTOR.execute(this::recreatePredictors);
|
||||
}
|
||||
public void onIdpChanged(InvariantDeviceProfile profile) {
|
||||
// Reinitialize everything
|
||||
Executors.MODEL_EXECUTOR.execute(this::recreatePredictors);
|
||||
}
|
||||
|
||||
private void onAppTargetEvent(AppTargetEvent event, int client) {
|
||||
|
||||
@@ -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;
|
||||
@@ -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 =
|
||||
@@ -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() {
|
||||
@@ -183,17 +185,23 @@ 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();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a listener for visuals changes
|
||||
*/
|
||||
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -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) {
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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 = "";
|
||||
|
||||
@@ -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;
|
||||
@@ -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") {
|
||||
@@ -705,16 +703,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);
|
||||
@@ -739,7 +727,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);
|
||||
@@ -758,7 +745,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);
|
||||
|
||||
Reference in New Issue
Block a user