diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java index d96855ecfe..d75006e893 100644 --- a/src/com/android/launcher3/BubbleTextView.java +++ b/src/com/android/launcher3/BubbleTextView.java @@ -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) { diff --git a/src/com/android/launcher3/ItemInfo.java b/src/com/android/launcher3/ItemInfo.java index a130604779..134e116063 100644 --- a/src/com/android/launcher3/ItemInfo.java +++ b/src/com/android/launcher3/ItemInfo.java @@ -114,8 +114,6 @@ public class ItemInfo { ItemInfo(ItemInfo info) { copyFrom(info); - // tempdebug: - LauncherModel.checkItemInfo(this); } public void copyFrom(ItemInfo info) { diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index 61cd2f10aa..99343aa2b3 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -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) { diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java index b1664f1103..c559f2ba1e 100644 --- a/src/com/android/launcher3/LauncherModel.java +++ b/src/com/android/launcher3/LauncherModel.java @@ -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. */ diff --git a/src/com/android/launcher3/model/BaseLoaderResults.java b/src/com/android/launcher3/model/BaseLoaderResults.java index 210f744492..97cf267d34 100644 --- a/src/com/android/launcher3/model/BaseLoaderResults.java +++ b/src/com/android/launcher3/model/BaseLoaderResults.java @@ -61,6 +61,8 @@ public abstract class BaseLoaderResults { protected final WeakReference mCallbacks; + private int mMyBindingId; + public BaseLoaderResults(LauncherAppState app, BgDataModel dataModel, AllAppsList allAppsList, int pageToBindFirst, WeakReference 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); diff --git a/src/com/android/launcher3/model/ModelWriter.java b/src/com/android/launcher3/model/ModelWriter.java index ac5076c11b..daf99e9cac 100644 --- a/src/com/android/launcher3/model/ModelWriter.java +++ b/src/com/android/launcher3/model/ModelWriter.java @@ -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) {