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:
Sunny Goyal 2021-05-03 19:59:51 -07:00
parent e41034034f
commit b47172bc4e
11 changed files with 146 additions and 194 deletions

View File

@ -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) {

View File

@ -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
*/

View File

@ -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 = "";

View File

@ -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);

View File

@ -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;
@ -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;
@ -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;
@ -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.
*/
@ -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;
@ -162,7 +148,6 @@ public class InvariantDeviceProfile {
public Rect defaultWidgetPadding;
private final ArrayList<OnIDPChangeListener> mChangeListeners = new ArrayList<>();
private OverlayMonitor mOverlayMonitor;
@VisibleForTesting
public InvariantDeviceProfile() {}
@ -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;
@ -193,7 +177,6 @@ public class InvariantDeviceProfile {
defaultLayoutId = p.defaultLayoutId;
demoModeLayoutId = p.demoModeLayoutId;
mExtraAttrs = p.mExtraAttrs;
mOverlayMonitor = p.mOverlayMonitor;
devicePaddings = p.devicePaddings;
}
@ -215,7 +198,6 @@ public class InvariantDeviceProfile {
onConfigChanged(displayContext);
}
});
mOverlayMonitor = new OverlayMonitor(context);
}
/**
@ -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
@ -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;
@ -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();
@ -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);
}
}
@ -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);
}
@ -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);
}
}
}

View File

@ -565,11 +565,7 @@ public class Launcher extends StatefulActivity<LauncherState> implements Launche
}
@Override
public void onIdpChanged(int changeFlags, InvariantDeviceProfile idp) {
onIdpChanged(idp);
}
private void onIdpChanged(InvariantDeviceProfile idp) {
public void onIdpChanged(InvariantDeviceProfile idp) {
if (TestProtocol.sDebugTracing) {
Log.d(TestProtocol.LAUNCHER_NOT_TRANSPOSED, "onIdpChanged");
}

View File

@ -16,7 +16,8 @@
package com.android.launcher3;
import static com.android.launcher3.InvariantDeviceProfile.CHANGE_FLAG_ICON_PARAMS;
import static com.android.launcher3.Utilities.getDevicePrefs;
import static com.android.launcher3.config.FeatureFlags.ENABLE_THEMED_ICONS;
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
import static com.android.launcher3.util.SettingsCache.NOTIFICATION_BADGING_URI;
@ -24,12 +25,13 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.LauncherApps;
import android.os.Handler;
import android.os.UserHandle;
import android.util.Log;
import androidx.annotation.Nullable;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.graphics.IconShape;
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.icons.IconProvider;
import com.android.launcher3.icons.LauncherIcons;
@ -39,6 +41,7 @@ import com.android.launcher3.pm.InstallSessionTracker;
import com.android.launcher3.pm.UserCache;
import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.launcher3.util.Preconditions;
import com.android.launcher3.util.RunnableList;
import com.android.launcher3.util.SafeCloseable;
import com.android.launcher3.util.SettingsCache;
import com.android.launcher3.util.SimpleBroadcastReceiver;
@ -47,6 +50,7 @@ import com.android.launcher3.widget.custom.CustomWidgetManager;
public class LauncherAppState {
public static final String ACTION_FORCE_ROLOAD = "force-reload-launcher";
private static final String KEY_ICON_STATE = "pref_icon_shape_path";
// We do not need any synchronization for this variable as its only written on UI thread.
public static final MainThreadInitializedObject<LauncherAppState> INSTANCE =
@ -54,16 +58,11 @@ public class LauncherAppState {
private final Context mContext;
private final LauncherModel mModel;
private final IconProvider mIconProvider;
private final IconCache mIconCache;
private final WidgetPreviewLoader mWidgetCache;
private final InvariantDeviceProfile mInvariantDeviceProfile;
private SettingsCache.OnChangeListener mNotificationSettingsChangedListener;
private SettingsCache mSettingsCache;
private InstallSessionTracker mInstallSessionTracker;
private SimpleBroadcastReceiver mModelChangeReceiver;
private SafeCloseable mCalendarChangeTracker;
private SafeCloseable mUserChangeListener;
private final RunnableList mOnTerminateCallback = new RunnableList();
public static LauncherAppState getInstance(final Context context) {
return INSTANCE.get(context);
@ -80,40 +79,47 @@ public class LauncherAppState {
public LauncherAppState(Context context) {
this(context, LauncherFiles.APP_ICONS_DB);
mModelChangeReceiver = new SimpleBroadcastReceiver(mModel::onBroadcastIntent);
mInvariantDeviceProfile.addOnChangeListener(idp -> refreshAndReloadLauncher());
mContext.getSystemService(LauncherApps.class).registerCallback(mModel);
mModelChangeReceiver.register(mContext, Intent.ACTION_LOCALE_CHANGED,
SimpleBroadcastReceiver modelChangeReceiver =
new SimpleBroadcastReceiver(mModel::onBroadcastIntent);
modelChangeReceiver.register(mContext, Intent.ACTION_LOCALE_CHANGED,
Intent.ACTION_MANAGED_PROFILE_AVAILABLE,
Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE,
Intent.ACTION_MANAGED_PROFILE_UNLOCKED);
if (FeatureFlags.IS_STUDIO_BUILD) {
mModelChangeReceiver.register(mContext, ACTION_FORCE_ROLOAD);
modelChangeReceiver.register(mContext, ACTION_FORCE_ROLOAD);
}
mCalendarChangeTracker = IconProvider.registerIconChangeListener(mContext,
mModel::onAppIconChanged, MODEL_EXECUTOR.getHandler());
mOnTerminateCallback.add(() -> mContext.unregisterReceiver(modelChangeReceiver));
// TODO: remove listener on terminate
FeatureFlags.APP_SEARCH_IMPROVEMENTS.addChangeListener(context, mModel::forceReload);
CustomWidgetManager.INSTANCE.get(mContext)
.setWidgetRefreshCallback(mModel::refreshAndBindWidgetsAndShortcuts);
mUserChangeListener = UserCache.INSTANCE.get(mContext)
SafeCloseable userChangeListener = UserCache.INSTANCE.get(mContext)
.addUserChangeListener(mModel::forceReload);
mOnTerminateCallback.add(userChangeListener::close);
mInvariantDeviceProfile.addOnChangeListener(this::onIdpChanged);
new Handler().post( () -> mInvariantDeviceProfile.verifyConfigChangedInBackground(context));
IconObserver observer = new IconObserver();
SafeCloseable iconChangeTracker = mIconProvider.registerIconChangeListener(
observer, MODEL_EXECUTOR.getHandler());
mOnTerminateCallback.add(iconChangeTracker::close);
MODEL_EXECUTOR.execute(observer::verifyIconChanged);
mInstallSessionTracker = InstallSessionHelper.INSTANCE.get(context)
.registerInstallTracker(mModel);
InstallSessionTracker installSessionTracker =
InstallSessionHelper.INSTANCE.get(context).registerInstallTracker(mModel);
mOnTerminateCallback.add(installSessionTracker::unregister);
// Register an observer to rebind the notification listener when dots are re-enabled.
mSettingsCache = SettingsCache.INSTANCE.get(mContext);
mNotificationSettingsChangedListener = this::onNotificationSettingsChanged;
mSettingsCache.register(NOTIFICATION_BADGING_URI,
mNotificationSettingsChangedListener);
onNotificationSettingsChanged(mSettingsCache.getValue(NOTIFICATION_BADGING_URI));
SettingsCache settingsCache = SettingsCache.INSTANCE.get(mContext);
SettingsCache.OnChangeListener notificationLister = this::onNotificationSettingsChanged;
settingsCache.register(NOTIFICATION_BADGING_URI, notificationLister);
onNotificationSettingsChanged(settingsCache.getValue(NOTIFICATION_BADGING_URI));
mOnTerminateCallback.add(() ->
settingsCache.unregister(NOTIFICATION_BADGING_URI, notificationLister));
}
public LauncherAppState(Context context, @Nullable String iconCacheFileName) {
@ -122,30 +128,25 @@ public class LauncherAppState {
mContext = context;
mInvariantDeviceProfile = InvariantDeviceProfile.INSTANCE.get(context);
mIconCache = new IconCache(mContext, mInvariantDeviceProfile, iconCacheFileName);
mIconProvider = new IconProvider(context, ENABLE_THEMED_ICONS.get());
mIconCache = new IconCache(mContext, mInvariantDeviceProfile,
iconCacheFileName, mIconProvider);
mWidgetCache = new WidgetPreviewLoader(mContext, mIconCache);
mModel = new LauncherModel(context, this, mIconCache, new AppFilter(mContext));
}
protected void onNotificationSettingsChanged(boolean areNotificationDotsEnabled) {
private void onNotificationSettingsChanged(boolean areNotificationDotsEnabled) {
if (areNotificationDotsEnabled) {
NotificationListener.requestRebind(new ComponentName(
mContext, NotificationListener.class));
}
}
private void onIdpChanged(int changeFlags, InvariantDeviceProfile idp) {
if (changeFlags == 0) {
return;
}
if ((changeFlags & CHANGE_FLAG_ICON_PARAMS) != 0) {
LauncherIcons.clearPool();
mIconCache.updateIconParams(idp.fillResIconDpi, idp.iconBitmapSize);
mWidgetCache.refresh();
}
private void refreshAndReloadLauncher() {
LauncherIcons.clearPool();
mIconCache.updateIconParams(
mInvariantDeviceProfile.fillResIconDpi, mInvariantDeviceProfile.iconBitmapSize);
mWidgetCache.refresh();
mModel.forceReload();
}
@ -154,25 +155,13 @@ public class LauncherAppState {
*/
public void onTerminate() {
mModel.destroy();
if (mModelChangeReceiver != null) {
mContext.unregisterReceiver(mModelChangeReceiver);
}
mContext.getSystemService(LauncherApps.class).unregisterCallback(mModel);
if (mInstallSessionTracker != null) {
mInstallSessionTracker.unregister();
}
if (mCalendarChangeTracker != null) {
mCalendarChangeTracker.close();
}
if (mUserChangeListener != null) {
mUserChangeListener.close();
}
CustomWidgetManager.INSTANCE.get(mContext).setWidgetRefreshCallback(null);
mOnTerminateCallback.executeAllAndDestroy();
}
if (mSettingsCache != null) {
mSettingsCache.unregister(NOTIFICATION_BADGING_URI,
mNotificationSettingsChangedListener);
}
public IconProvider getIconProvider() {
return mIconProvider;
}
public IconCache getIconCache() {
@ -197,4 +186,26 @@ public class LauncherAppState {
public static InvariantDeviceProfile getIDP(Context context) {
return InvariantDeviceProfile.INSTANCE.get(context);
}
private class IconObserver implements IconProvider.IconChangeListener {
@Override
public void onAppIconChanged(String packageName, UserHandle user) {
mModel.onAppIconChanged(packageName, user);
}
@Override
public void onSystemIconStateChanged(String iconState) {
IconShape.init(mContext);
refreshAndReloadLauncher();
getDevicePrefs(mContext).edit().putString(KEY_ICON_STATE, iconState).apply();
}
void verifyIconChanged() {
String iconState = mIconProvider.getSystemIconState();
if (!iconState.equals(getDevicePrefs(mContext).getString(KEY_ICON_STATE, ""))) {
onSystemIconStateChanged(iconState);
}
}
}
}

View File

@ -661,7 +661,7 @@ public final class Utilities {
.resolveActivity(info.getIntent(), info.user);
outObj[0] = activityInfo;
return activityInfo == null ? null : LauncherAppState.getInstance(launcher)
.getIconCache().getIconProvider().getIcon(
.getIconProvider().getIcon(
activityInfo, launcher.getDeviceProfile().inv.fillResIconDpi);
} else if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
if (info instanceof PendingAddShortcutInfo) {

View File

@ -81,10 +81,11 @@ public class IconCache extends BaseIconCache {
private int mPendingIconRequestCount = 0;
public IconCache(Context context, InvariantDeviceProfile idp) {
this(context, idp, LauncherFiles.APP_ICONS_DB);
this(context, idp, LauncherFiles.APP_ICONS_DB, new IconProvider(context));
}
public IconCache(Context context, InvariantDeviceProfile idp, String dbFileName) {
public IconCache(Context context, InvariantDeviceProfile idp, String dbFileName,
IconProvider iconProvider) {
super(context, dbFileName, MODEL_EXECUTOR.getLooper(),
idp.fillResIconDpi, idp.iconBitmapSize, true /* inMemoryCache */);
mComponentWithLabelCachingLogic = new ComponentCachingLogic(context, false);
@ -93,7 +94,7 @@ public class IconCache extends BaseIconCache {
mLauncherApps = mContext.getSystemService(LauncherApps.class);
mUserManager = UserCache.INSTANCE.get(mContext);
mInstantAppResolver = InstantAppResolver.newInstance(mContext);
mIconProvider = new IconProvider(context, true /* supportsIconTheme */);
mIconProvider = iconProvider;
}
@Override
@ -106,10 +107,6 @@ public class IconCache extends BaseIconCache {
return mInstantAppResolver.isInstantApp(info);
}
public IconProvider getIconProvider() {
return mIconProvider;
}
@Override
public BaseIconFactory getIconFactory() {
return LauncherIcons.obtain(mContext);

View File

@ -58,7 +58,7 @@ public class LauncherActivityCachingLogic
public BitmapInfo loadIcon(Context context, LauncherActivityInfo object) {
try (LauncherIcons li = LauncherIcons.obtain(context)) {
return li.createBadgedIconBitmap(LauncherAppState.getInstance(context)
.getIconCache().getIconProvider().getIcon(object, li.mFillResIconDpi),
.getIconProvider().getIcon(object, li.mFillResIconDpi),
object.getUser(), object.getApplicationInfo().targetSdkVersion);
}
}

View File

@ -16,8 +16,6 @@
package com.android.launcher3.model.data;
import static com.android.launcher3.config.FeatureFlags.ENABLE_THEMED_ICONS;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@ -232,7 +230,7 @@ public abstract class ItemInfoWithIcon extends ItemInfo {
* Returns a FastBitmapDrawable with the icon and context theme applied
*/
public FastBitmapDrawable newIcon(Context context, boolean applyTheme) {
FastBitmapDrawable drawable = applyTheme && ENABLE_THEMED_ICONS.get()
FastBitmapDrawable drawable = applyTheme
? bitmap.newThemedIcon(context) : bitmap.newIcon(context);
drawable.setIsDisabled(isDisabled());
return drawable;