diff --git a/quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java b/quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java index b0c13f99c0..a9c2a5e51d 100644 --- a/quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java +++ b/quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java @@ -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) { diff --git a/quickstep/src/com/android/quickstep/RecentsModel.java b/quickstep/src/com/android/quickstep/RecentsModel.java index c786167241..2eb9dd84eb 100644 --- a/quickstep/src/com/android/quickstep/RecentsModel.java +++ b/quickstep/src/com/android/quickstep/RecentsModel.java @@ -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 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 */ diff --git a/quickstep/src/com/android/quickstep/TaskIconCache.java b/quickstep/src/com/android/quickstep/TaskIconCache.java index ba1c413909..fa61fffbc6 100644 --- a/quickstep/src/com/android/quickstep/TaskIconCache.java +++ b/quickstep/src/com/android/quickstep/TaskIconCache.java @@ -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 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 = ""; diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index 3c59441c66..841f63b3c1 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -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, STATE_TYPE extends BaseState> extends PagedView implements Insettable, TaskThumbnailCache.HighResLoadingState.HighResLoadingStateChangedCallback, - InvariantDeviceProfile.OnIDPChangeListener, TaskVisualsChangeListener, - SplitScreenBounds.OnChangeListener { + TaskVisualsChangeListener, SplitScreenBounds.OnChangeListener { public static final FloatProperty CONTENT_ALPHA = new FloatProperty("contentAlpha") { @@ -705,16 +703,6 @@ public abstract class RecentsView 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); - } - } } diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index 09c7b7aff0..067e58a96e 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -565,11 +565,7 @@ public class Launcher extends StatefulActivity 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"); } diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java index 11585f9f23..834b5a7e8c 100644 --- a/src/com/android/launcher3/LauncherAppState.java +++ b/src/com/android/launcher3/LauncherAppState.java @@ -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 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); + } + } + } } diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java index 972a6e84f5..7c0036250b 100644 --- a/src/com/android/launcher3/Utilities.java +++ b/src/com/android/launcher3/Utilities.java @@ -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) { diff --git a/src/com/android/launcher3/icons/IconCache.java b/src/com/android/launcher3/icons/IconCache.java index bc93a1e3d9..297325a0ee 100644 --- a/src/com/android/launcher3/icons/IconCache.java +++ b/src/com/android/launcher3/icons/IconCache.java @@ -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); diff --git a/src/com/android/launcher3/icons/LauncherActivityCachingLogic.java b/src/com/android/launcher3/icons/LauncherActivityCachingLogic.java index 8fc397738e..e820ac474a 100644 --- a/src/com/android/launcher3/icons/LauncherActivityCachingLogic.java +++ b/src/com/android/launcher3/icons/LauncherActivityCachingLogic.java @@ -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); } } diff --git a/src/com/android/launcher3/model/data/ItemInfoWithIcon.java b/src/com/android/launcher3/model/data/ItemInfoWithIcon.java index 0754c293b6..6813b972ab 100644 --- a/src/com/android/launcher3/model/data/ItemInfoWithIcon.java +++ b/src/com/android/launcher3/model/data/ItemInfoWithIcon.java @@ -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;