diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index 5a1143fc08..4d820bc0bc 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -150,7 +150,6 @@ import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set; -import java.util.concurrent.Executor; /** * Default launcher application. @@ -1166,7 +1165,7 @@ public class Launcher extends BaseActivity public void updateIconBadges(final Set updatedBadges) { mWorkspace.updateIconBadges(updatedBadges); - mAppsView.updateIconBadges(updatedBadges); + mAppsView.getAppsStore().updateIconBadges(updatedBadges); PopupContainerWithArrow popup = PopupContainerWithArrow.getOpen(Launcher.this); if (popup != null) { @@ -2527,6 +2526,11 @@ public class Launcher extends BaseActivity mPendingExecutor.markCompleted(); } mPendingExecutor = executor; + if (!isInState(ALL_APPS)) { + mAppsView.getAppsStore().setDeferUpdates(true); + mPendingExecutor.execute(() -> mAppsView.getAppsStore().setDeferUpdates(false)); + } + executor.attachTo(this); } @@ -2588,29 +2592,13 @@ public class Launcher extends BaseActivity * Implementation of the method from LauncherModel.Callbacks. */ public void bindAllApplications(ArrayList apps) { - if (mAppsView != null) { - Executor pendingExecutor = getPendingExecutor(); - if (pendingExecutor != null && !isInState(ALL_APPS)) { - // Wait until the fade in animation has finished before setting all apps list. - pendingExecutor.execute(() -> bindAllApplications(apps)); - return; - } + mAppsView.getAppsStore().setApps(apps); - mAppsView.setApps(apps); - } if (mLauncherCallbacks != null) { mLauncherCallbacks.bindAllApplications(apps); } } - /** - * Returns an Executor that will run after the launcher is first drawn (including after the - * initial fade in animation). Returns null if the first draw has already occurred. - */ - public @Nullable Executor getPendingExecutor() { - return mPendingExecutor != null && mPendingExecutor.canQueue() ? mPendingExecutor : null; - } - /** * Copies LauncherModel's map of activities to shortcut ids to Launcher's. This is necessary * because LauncherModel's map is updated in the background, while Launcher runs on the UI. @@ -2627,16 +2615,12 @@ public class Launcher extends BaseActivity */ @Override public void bindAppsAddedOrUpdated(ArrayList apps) { - if (mAppsView != null) { - mAppsView.addOrUpdateApps(apps); - } + mAppsView.getAppsStore().addOrUpdateApps(apps); } @Override public void bindPromiseAppProgressUpdated(PromiseAppInfo app) { - if (mAppsView != null) { - mAppsView.updatePromiseAppProgress(app); - } + mAppsView.getAppsStore().updatePromiseAppProgress(app); } @Override @@ -2682,10 +2666,7 @@ public class Launcher extends BaseActivity @Override public void bindAppInfosRemoved(final ArrayList appInfos) { - // Update AllApps - if (mAppsView != null) { - mAppsView.removeApps(appInfos); - } + mAppsView.getAppsStore().removeApps(appInfos); } @Override diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java index de08eb667c..d4277dbde2 100644 --- a/src/com/android/launcher3/allapps/AllAppsContainerView.java +++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java @@ -116,6 +116,8 @@ public class AllAppsContainerView extends RelativeLayout implements DragSource, mAH = new AdapterHolder[2]; mAH[AdapterHolder.MAIN] = new AdapterHolder(false /* isWork */); mAH[AdapterHolder.WORK] = new AdapterHolder(true /* isWork */); + + mAllAppsStore.addUpdateListener(this::onAppsUpdated); } @Override @@ -150,42 +152,24 @@ public class AllAppsContainerView extends RelativeLayout implements DragSource, } } + private void onAppsUpdated() { + if (FeatureFlags.ALL_APPS_TABS_ENABLED) { + boolean hasWorkApps = false; + for (AppInfo app : mAllAppsStore.getApps()) { + if (mWorkMatcher.matches(app, null)) { + hasWorkApps = true; + break; + } + } + rebindAdapters(hasWorkApps); + } + } + @Override public void setPressedIcon(BubbleTextView icon, Bitmap background) { mTouchFeedbackView.setPressedIcon(icon, background); } - /** - * Sets the current set of apps. - */ - public void setApps(List apps) { - boolean hasWorkProfileApp = hasWorkProfileApp(apps); - rebindAdapters(hasWorkProfileApp); - mAllAppsStore.setApps(apps); - } - - /** - * Adds or updates existing apps in the list - */ - public void addOrUpdateApps(List apps) { - mAllAppsStore.addOrUpdateApps(apps); - } - - /** - * Removes some apps from the list. - */ - public void removeApps(List apps) { - mAllAppsStore.removeApps(apps); - } - - public void updatePromiseAppProgress(PromiseAppInfo app) { - mAllAppsStore.updateAllIcons((child) -> { - if (child.getTag() == app) { - child.applyProgressLevel(app.level); - } - }); - } - /** * Returns whether the view itself will handle the touch event or not. */ @@ -324,18 +308,6 @@ public class AllAppsContainerView extends RelativeLayout implements DragSource, InsettableFrameLayout.dispatchInsets(this, insets); } - public void updateIconBadges(Set updatedBadges) { - PackageUserKey tempKey = new PackageUserKey(null, null); - mAllAppsStore.updateAllIcons((child) -> { - if (child.getTag() instanceof ItemInfo) { - ItemInfo info = (ItemInfo) child.getTag(); - if (tempKey.updateFromItemInfo(info) && updatedBadges.contains(tempKey)) { - child.applyBadgeState(info, true /* animate */); - } - } - }); - } - public SpringAnimationHandler getSpringAnimationHandler() { return mUsingTabs ? null : mAH[AdapterHolder.MAIN].animationHandler; } @@ -371,17 +343,6 @@ public class AllAppsContainerView extends RelativeLayout implements DragSource, applyTouchDelegate(); } - private boolean hasWorkProfileApp(List apps) { - if (FeatureFlags.ALL_APPS_TABS_ENABLED) { - for (AppInfo app : apps) { - if (mWorkMatcher.matches(app, null)) { - return true; - } - } - } - return false; - } - private void replaceRVContainer(boolean showTabs) { for (int i = 0; i < mAH.length; i++) { if (mAH[i].recyclerView != null) { diff --git a/src/com/android/launcher3/allapps/AllAppsStore.java b/src/com/android/launcher3/allapps/AllAppsStore.java index 846b6a99c8..dc3489290d 100644 --- a/src/com/android/launcher3/allapps/AllAppsStore.java +++ b/src/com/android/launcher3/allapps/AllAppsStore.java @@ -20,22 +20,30 @@ import android.view.ViewGroup; import com.android.launcher3.AppInfo; import com.android.launcher3.BubbleTextView; +import com.android.launcher3.ItemInfo; +import com.android.launcher3.PromiseAppInfo; import com.android.launcher3.util.ComponentKey; +import com.android.launcher3.util.PackageUserKey; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; +import java.util.Set; /** * A utility class to maintain the collection of all apps. */ public class AllAppsStore { + private PackageUserKey mTempKey = new PackageUserKey(null, null); private final HashMap mComponentToAppMap = new HashMap<>(); private final List mUpdateListeners = new ArrayList<>(); private final ArrayList mIconContainers = new ArrayList<>(); + private boolean mDeferUpdates = false; + private boolean mUpdatePending = false; + public Collection getApps() { return mComponentToAppMap.values(); } @@ -52,6 +60,17 @@ public class AllAppsStore { return mComponentToAppMap.get(key); } + public void setDeferUpdates(boolean deferUpdates) { + if (mDeferUpdates != deferUpdates) { + mDeferUpdates = deferUpdates; + + if (!mDeferUpdates && mUpdatePending) { + notifyUpdate(); + mUpdatePending = false; + } + } + } + /** * Adds or updates existing apps in the list */ @@ -74,6 +93,10 @@ public class AllAppsStore { private void notifyUpdate() { + if (mDeferUpdates) { + mUpdatePending = true; + return; + } int count = mUpdateListeners.size(); for (int i = 0; i < count; i++) { mUpdateListeners.get(i).onAppsUpdated(); @@ -98,7 +121,26 @@ public class AllAppsStore { mIconContainers.remove(container); } - public void updateAllIcons(IconAction action) { + public void updateIconBadges(Set updatedBadges) { + updateAllIcons((child) -> { + if (child.getTag() instanceof ItemInfo) { + ItemInfo info = (ItemInfo) child.getTag(); + if (mTempKey.updateFromItemInfo(info) && updatedBadges.contains(mTempKey)) { + child.applyBadgeState(info, true /* animate */); + } + } + }); + } + + public void updatePromiseAppProgress(PromiseAppInfo app) { + updateAllIcons((child) -> { + if (child.getTag() == app) { + child.applyProgressLevel(app.level); + } + }); + } + + private void updateAllIcons(IconAction action) { for (int i = mIconContainers.size() - 1; i >= 0; i--) { ViewGroup parent = mIconContainers.get(i); int childCount = parent.getChildCount();