Fixing launcher UI not reapplied properly when IDP changed as a result of display changes
> Removing unnecessary check when binding model data as its safe to bind old data, we should just not persist it (that check is already there in model writer) > Adding additional check in model bind to skip old bind if there are multiple binds Bug: 126259547 Bug: 118441555 Change-Id: Ic250d2af13797d3e70c6e1fc70da65ebe6ab8d70
This commit is contained in:
parent
826405d095
commit
371ea051d1
|
@ -275,14 +275,6 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
|
|||
mLongPressHelper.setLongPressTimeoutFactor(longPressTimeoutFactor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTag(Object tag) {
|
||||
if (tag != null) {
|
||||
LauncherModel.checkItemInfo((ItemInfo) tag);
|
||||
}
|
||||
super.setTag(tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshDrawableState() {
|
||||
if (!mIgnorePressedStateChange) {
|
||||
|
|
|
@ -114,8 +114,6 @@ public class ItemInfo {
|
|||
|
||||
ItemInfo(ItemInfo info) {
|
||||
copyFrom(info);
|
||||
// tempdebug:
|
||||
LauncherModel.checkItemInfo(this);
|
||||
}
|
||||
|
||||
public void copyFrom(ItemInfo info) {
|
||||
|
|
|
@ -378,14 +378,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
|
|||
}
|
||||
|
||||
if ((diff & (CONFIG_ORIENTATION | CONFIG_SCREEN_SIZE)) != 0) {
|
||||
mUserEventDispatcher = null;
|
||||
initDeviceProfile(mDeviceProfile.inv);
|
||||
dispatchDeviceProfileChanged();
|
||||
reapplyUi();
|
||||
mDragLayer.recreateControllers();
|
||||
|
||||
// TODO: We can probably avoid rebind when only screen size changed.
|
||||
rebindModel();
|
||||
onIdpChanged(mDeviceProfile.inv);
|
||||
}
|
||||
|
||||
mOldConfig.setTo(newConfig);
|
||||
|
@ -410,8 +403,19 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
|
|||
|
||||
@Override
|
||||
public void onIdpChanged(int changeFlags, InvariantDeviceProfile idp) {
|
||||
onIdpChanged(idp);
|
||||
}
|
||||
|
||||
private void onIdpChanged(InvariantDeviceProfile idp) {
|
||||
mUserEventDispatcher = null;
|
||||
|
||||
initDeviceProfile(idp);
|
||||
getRootView().dispatchInsets();
|
||||
dispatchDeviceProfileChanged();
|
||||
reapplyUi();
|
||||
mDragLayer.recreateControllers();
|
||||
|
||||
// TODO: We can probably avoid rebind when only screen size changed.
|
||||
rebindModel();
|
||||
}
|
||||
|
||||
private void initDeviceProfile(InvariantDeviceProfile idp) {
|
||||
|
|
|
@ -34,7 +34,6 @@ import android.util.Pair;
|
|||
import com.android.launcher3.compat.LauncherAppsCompat;
|
||||
import com.android.launcher3.compat.PackageInstallerCompat.PackageInstallInfo;
|
||||
import com.android.launcher3.compat.UserManagerCompat;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.icons.IconCache;
|
||||
import com.android.launcher3.icons.LauncherIcons;
|
||||
import com.android.launcher3.model.AddWorkspaceItemsTask;
|
||||
|
@ -207,57 +206,6 @@ public class LauncherModel extends BroadcastReceiver
|
|||
hasVerticalHotseat, verifyChanges);
|
||||
}
|
||||
|
||||
static void checkItemInfoLocked(
|
||||
final int itemId, final ItemInfo item, StackTraceElement[] stackTrace) {
|
||||
ItemInfo modelItem = sBgDataModel.itemsIdMap.get(itemId);
|
||||
if (modelItem != null && item != modelItem) {
|
||||
// If it is a release build on a release device, check all the data is consistent as
|
||||
// we don't want to crash non-dev users.
|
||||
if (!Utilities.IS_DEBUG_DEVICE && !FeatureFlags.IS_DOGFOOD_BUILD &&
|
||||
modelItem instanceof ShortcutInfo && item instanceof ShortcutInfo) {
|
||||
if (modelItem.title.toString().equals(item.title.toString()) &&
|
||||
modelItem.getIntent().filterEquals(item.getIntent()) &&
|
||||
modelItem.id == item.id &&
|
||||
modelItem.itemType == item.itemType &&
|
||||
modelItem.container == item.container &&
|
||||
modelItem.screenId == item.screenId &&
|
||||
modelItem.cellX == item.cellX &&
|
||||
modelItem.cellY == item.cellY &&
|
||||
modelItem.spanX == item.spanX &&
|
||||
modelItem.spanY == item.spanY) {
|
||||
// For all intents and purposes, this is the same object
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// the modelItem needs to match up perfectly with item if our model is
|
||||
// to be consistent with the database-- for now, just require
|
||||
// modelItem == item or the equality check above
|
||||
String msg = "item: " + ((item != null) ? item.toString() : "null") +
|
||||
"modelItem: " +
|
||||
((modelItem != null) ? modelItem.toString() : "null") +
|
||||
"Error: ItemInfo passed to checkItemInfo doesn't match original";
|
||||
RuntimeException e = new RuntimeException(msg);
|
||||
if (stackTrace != null) {
|
||||
e.setStackTrace(stackTrace);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
static void checkItemInfo(final ItemInfo item) {
|
||||
final StackTraceElement[] stackTrace = new Throwable().getStackTrace();
|
||||
final int itemId = item.id;
|
||||
Runnable r = new Runnable() {
|
||||
public void run() {
|
||||
synchronized (sBgDataModel) {
|
||||
checkItemInfoLocked(itemId, item, stackTrace);
|
||||
}
|
||||
}
|
||||
};
|
||||
runOnWorkerThread(r);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this as the current Launcher activity object for the loader.
|
||||
*/
|
||||
|
|
|
@ -61,6 +61,8 @@ public abstract class BaseLoaderResults {
|
|||
|
||||
protected final WeakReference<Callbacks> mCallbacks;
|
||||
|
||||
private int mMyBindingId;
|
||||
|
||||
public BaseLoaderResults(LauncherAppState app, BgDataModel dataModel,
|
||||
AllAppsList allAppsList, int pageToBindFirst, WeakReference<Callbacks> callbacks) {
|
||||
mUiExecutor = new MainThreadExecutor();
|
||||
|
@ -94,6 +96,7 @@ public abstract class BaseLoaderResults {
|
|||
appWidgets.addAll(mBgDataModel.appWidgets);
|
||||
orderedScreenIds.addAll(mBgDataModel.collectWorkspaceScreens());
|
||||
mBgDataModel.lastBindId++;
|
||||
mMyBindingId = mBgDataModel.lastBindId;
|
||||
}
|
||||
|
||||
final int currentScreen;
|
||||
|
@ -285,6 +288,10 @@ public abstract class BaseLoaderResults {
|
|||
|
||||
protected void executeCallbacksTask(CallbackTask task, Executor executor) {
|
||||
executor.execute(() -> {
|
||||
if (mMyBindingId != mBgDataModel.lastBindId) {
|
||||
Log.d(TAG, "Too many consecutive reloads, skipping obsolete data-bind");
|
||||
return;
|
||||
}
|
||||
Callbacks callbacks = mCallbacks.get();
|
||||
if (callbacks != null) {
|
||||
task.execute(callbacks);
|
||||
|
|
|
@ -37,6 +37,7 @@ import com.android.launcher3.LauncherSettings;
|
|||
import com.android.launcher3.LauncherSettings.Favorites;
|
||||
import com.android.launcher3.LauncherSettings.Settings;
|
||||
import com.android.launcher3.ShortcutInfo;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.util.ContentWriter;
|
||||
import com.android.launcher3.util.ItemInfoMatcher;
|
||||
|
@ -112,19 +113,18 @@ public class ModelWriter {
|
|||
ItemInfo modelItem = mBgDataModel.itemsIdMap.get(itemId);
|
||||
if (modelItem != null && item != modelItem) {
|
||||
// check all the data is consistent
|
||||
if (modelItem instanceof ShortcutInfo && item instanceof ShortcutInfo) {
|
||||
ShortcutInfo modelShortcut = (ShortcutInfo) modelItem;
|
||||
ShortcutInfo shortcut = (ShortcutInfo) item;
|
||||
if (modelShortcut.title.toString().equals(shortcut.title.toString()) &&
|
||||
modelShortcut.intent.filterEquals(shortcut.intent) &&
|
||||
modelShortcut.id == shortcut.id &&
|
||||
modelShortcut.itemType == shortcut.itemType &&
|
||||
modelShortcut.container == shortcut.container &&
|
||||
modelShortcut.screenId == shortcut.screenId &&
|
||||
modelShortcut.cellX == shortcut.cellX &&
|
||||
modelShortcut.cellY == shortcut.cellY &&
|
||||
modelShortcut.spanX == shortcut.spanX &&
|
||||
modelShortcut.spanY == shortcut.spanY) {
|
||||
if (!Utilities.IS_DEBUG_DEVICE && !FeatureFlags.IS_DOGFOOD_BUILD &&
|
||||
modelItem instanceof ShortcutInfo && item instanceof ShortcutInfo) {
|
||||
if (modelItem.title.toString().equals(item.title.toString()) &&
|
||||
modelItem.getIntent().filterEquals(item.getIntent()) &&
|
||||
modelItem.id == item.id &&
|
||||
modelItem.itemType == item.itemType &&
|
||||
modelItem.container == item.container &&
|
||||
modelItem.screenId == item.screenId &&
|
||||
modelItem.cellX == item.cellX &&
|
||||
modelItem.cellY == item.cellY &&
|
||||
modelItem.spanX == item.spanX &&
|
||||
modelItem.spanY == item.spanY) {
|
||||
// For all intents and purposes, this is the same object
|
||||
return;
|
||||
}
|
||||
|
@ -310,7 +310,7 @@ public class ModelWriter {
|
|||
/**
|
||||
* Delete operations tracked using {@link #enqueueDeleteRunnable} will only be called
|
||||
* if {@link #commitDelete} is called. Note that one of {@link #commitDelete()} or
|
||||
* {@link #abortDelete()} MUST be called after this method, or else all delete
|
||||
* {@link #abortDelete} MUST be called after this method, or else all delete
|
||||
* operations will remain uncommitted indefinitely.
|
||||
*/
|
||||
public void prepareToUndoDelete() {
|
||||
|
@ -325,7 +325,7 @@ public class ModelWriter {
|
|||
|
||||
/**
|
||||
* If {@link #prepareToUndoDelete} has been called, we store the Runnable to be run when
|
||||
* {@link #commitDelete()} is called (or abandoned if {@link #abortDelete()} is called).
|
||||
* {@link #commitDelete()} is called (or abandoned if {@link #abortDelete} is called).
|
||||
* Otherwise, we run the Runnable immediately.
|
||||
*/
|
||||
private void enqueueDeleteRunnable(Runnable r) {
|
||||
|
|
Loading…
Reference in New Issue