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:
parent
e41034034f
commit
b47172bc4e
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue