summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonathan Miranda <jonmiranda@google.com>2017-07-30 18:05:43 +0000
committerJonathan Miranda <jonmiranda@google.com>2017-07-30 18:05:43 +0000
commitf880ecca32b10299e3b657a446ce882e004118be (patch)
treeeca84bc02992d23056d6288fac4af55bd898d57a
parentffea4cbf0ddd8bf758d61ab0af1848a2b296fefb (diff)
parent7653a60c74e9babfda1c3754eb4f3060b6e40990 (diff)
downloadandroid_packages_apps_Trebuchet-f880ecca32b10299e3b657a446ce882e004118be.tar.gz
android_packages_apps_Trebuchet-f880ecca32b10299e3b657a446ce882e004118be.tar.bz2
android_packages_apps_Trebuchet-f880ecca32b10299e3b657a446ce882e004118be.zip
[automerger] Optimize updating All Apps Predictions. am: 7653a60c74
Change-Id: Id7ebeee3d4cc605849ac95623ffe6321bc691b7a
-rw-r--r--src/com/android/launcher3/Launcher.java3
-rw-r--r--src/com/android/launcher3/allapps/AllAppsContainerView.java2
-rw-r--r--src/com/android/launcher3/allapps/AlphabeticalAppsList.java81
3 files changed, 69 insertions, 17 deletions
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 4b3148626..4b1812e53 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -959,6 +959,9 @@ public class Launcher extends BaseActivity
} else if (mOnResumeState == State.WIDGETS) {
showWidgetsView(false, false);
}
+ if (mOnResumeState != State.APPS) {
+ tryAndUpdatePredictedApps();
+ }
mOnResumeState = State.NONE;
mPaused = false;
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index 0083d47f2..ede3bea72 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -224,6 +224,8 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
mAppsRecyclerView.setLayoutManager(mLayoutManager);
mAppsRecyclerView.setAdapter(mAdapter);
mAppsRecyclerView.setHasFixedSize(true);
+ // Removes the animation that can occur when updating the predicted apps in place.
+ mAppsRecyclerView.getItemAnimator().setChangeDuration(0);
if (FeatureFlags.LAUNCHER3_PHYSICS) {
mAppsRecyclerView.setSpringAnimationHandler(mSpringAnimationHandler);
}
diff --git a/src/com/android/launcher3/allapps/AlphabeticalAppsList.java b/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
index 608e898ae..ee2756f2c 100644
--- a/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
+++ b/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
@@ -298,14 +298,74 @@ public class AlphabeticalAppsList {
updateAdapterItems();
}
+ private List<AppInfo> processPredictedAppComponents(List<ComponentKey> components) {
+ if (mComponentToAppMap.isEmpty()) {
+ // Apps have not been bound yet.
+ return Collections.emptyList();
+ }
+
+ List<AppInfo> predictedApps = new ArrayList<>();
+ for (ComponentKey ck : components) {
+ AppInfo info = mComponentToAppMap.get(ck);
+ if (info != null) {
+ predictedApps.add(info);
+ } else {
+ if (FeatureFlags.IS_DOGFOOD_BUILD) {
+ Log.e(TAG, "Predicted app not found: " + ck);
+ }
+ }
+ // Stop at the number of predicted apps
+ if (predictedApps.size() == mNumPredictedAppsPerRow) {
+ break;
+ }
+ }
+ return predictedApps;
+ }
+
/**
- * Sets the current set of predicted apps. Since this can be called before we get the full set
- * of applications, we should merge the results only in onAppsUpdated() which is idempotent.
+ * Sets the current set of predicted apps.
+ *
+ * This can be called before we get the full set of applications, we should merge the results
+ * only in onAppsUpdated() which is idempotent.
+ *
+ * If the number of predicted apps is the same as the previous list of predicted apps,
+ * we can optimize by swapping them in place.
*/
public void setPredictedApps(List<ComponentKey> apps) {
mPredictedAppComponents.clear();
mPredictedAppComponents.addAll(apps);
- onAppsUpdated();
+
+ List<AppInfo> newPredictedApps = processPredictedAppComponents(apps);
+ // We only need to do work if any of the visible predicted apps have changed.
+ if (!newPredictedApps.equals(mPredictedApps)) {
+ if (newPredictedApps.size() == mPredictedApps.size()) {
+ swapInNewPredictedApps(newPredictedApps);
+ } else {
+ // We need to update the appIndex of all the items.
+ onAppsUpdated();
+ }
+ }
+ }
+
+ /**
+ * Swaps out the old predicted apps with the new predicted apps, in place. This optimization
+ * allows us to skip an entire relayout that would otherwise be called by notifyDataSetChanged.
+ *
+ * Note: This should only be called if the # of predicted apps is the same.
+ * This method assumes that predicted apps are the first items in the adapter.
+ */
+ private void swapInNewPredictedApps(List<AppInfo> apps) {
+ mPredictedApps.clear();
+ mPredictedApps.addAll(apps);
+
+ int size = apps.size();
+ for (int i = 0; i < size; ++i) {
+ AppInfo info = apps.get(i);
+ AdapterItem appItem = AdapterItem.asPredictedApp(i, "", info, i);
+ mAdapterItems.set(i, appItem);
+ mFilteredApps.set(i, info);
+ mAdapter.notifyItemChanged(i);
+ }
}
/**
@@ -432,20 +492,7 @@ public class AlphabeticalAppsList {
// Process the predicted app components
mPredictedApps.clear();
if (mPredictedAppComponents != null && !mPredictedAppComponents.isEmpty() && !hasFilter()) {
- for (ComponentKey ck : mPredictedAppComponents) {
- AppInfo info = mComponentToAppMap.get(ck);
- if (info != null) {
- mPredictedApps.add(info);
- } else {
- if (FeatureFlags.IS_DOGFOOD_BUILD) {
- Log.e(TAG, "Predicted app not found: " + ck);
- }
- }
- // Stop at the number of predicted apps
- if (mPredictedApps.size() == mNumPredictedAppsPerRow) {
- break;
- }
- }
+ mPredictedApps.addAll(processPredictedAppComponents(mPredictedAppComponents));
if (!mPredictedApps.isEmpty()) {
// Add a section for the predictions