Merge "Fix two issues with splitting from Taskbar" into tm-qpr-dev
diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
index ea7eba3..da28cfa 100644
--- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
+++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
@@ -52,6 +52,7 @@
import static com.android.launcher3.config.FeatureFlags.KEYGUARD_ANIMATION;
import static com.android.launcher3.config.FeatureFlags.SEPARATE_RECENTS_ACTIVITY;
import static com.android.launcher3.model.data.ItemInfo.NO_MATCHING_ID;
+import static com.android.launcher3.util.DisplayController.isTransientTaskbar;
import static com.android.launcher3.util.MultiPropertyFactory.MULTI_PROPERTY_VALUE;
import static com.android.launcher3.util.window.RefreshRateTracker.getSingleFrameMs;
import static com.android.launcher3.views.FloatingIconView.SHAPE_PROGRESS_DURATION;
@@ -122,7 +123,6 @@
import com.android.launcher3.touch.PagedOrientationHandler;
import com.android.launcher3.uioverrides.QuickstepLauncher;
import com.android.launcher3.util.ActivityOptionsWrapper;
-import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.DynamicResource;
import com.android.launcher3.util.ObjectWrapper;
import com.android.launcher3.util.RunnableList;
@@ -448,7 +448,7 @@
}
if (mDeviceProfile.isTaskbarPresentInApps
&& !target.willShowImeOnTarget
- && !DisplayController.isTransientTaskbar(mLauncher)) {
+ && !isTransientTaskbar(mLauncher)) {
// Animate to above the taskbar.
bounds.bottom -= target.contentInsets.bottom;
}
@@ -635,7 +635,7 @@
RectF launcherIconBounds = new RectF();
FloatingIconView floatingView = getFloatingIconView(mLauncher, v,
- mLauncher.getTaskbarUIController() == null
+ (mLauncher.getTaskbarUIController() == null || !isTransientTaskbar(mLauncher))
? null
: mLauncher.getTaskbarUIController().findMatchingView(v),
!appTargetsAreTranslucent, launcherIconBounds, true /* isOpening */);
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index 57e11de..62713ca 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -316,7 +316,6 @@
return mTransientTaskbarBounds;
}
- @VisibleForTesting
@Override
public StatsLogManager getStatsLogManager() {
// Used to mock, can't mock a default interface method directly
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
index 8c21778..e0acd3e 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
@@ -25,6 +25,8 @@
import static com.android.launcher3.config.FeatureFlags.FORCE_PERSISTENT_TASKBAR;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_LONGPRESS_HIDE;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_LONGPRESS_SHOW;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TRANSIENT_TASKBAR_HIDE;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TRANSIENT_TASKBAR_SHOW;
import static com.android.launcher3.taskbar.Utilities.appendFlag;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BOUNCER_SHOWING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SHOWING;
@@ -972,6 +974,11 @@
mActivity.getStatsLogManager().logger().log(LAUNCHER_TASKBAR_LONGPRESS_SHOW);
}
}
+ if (hasAnyFlag(changedFlags, FLAG_STASHED_IN_APP_AUTO)) {
+ mActivity.getStatsLogManager().logger().log(hasAnyFlag(FLAG_STASHED_IN_APP_AUTO)
+ ? LAUNCHER_TRANSIENT_TASKBAR_HIDE
+ : LAUNCHER_TRANSIENT_TASKBAR_SHOW);
+ }
}
private void notifyStashChange(boolean visible, boolean stashed) {
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java b/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java
index a02f3de..c7cd39c 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java
@@ -32,6 +32,7 @@
import static com.android.launcher3.anim.Interpolators.DEACCEL_3;
import static com.android.launcher3.anim.Interpolators.EMPHASIZED_ACCELERATE;
import static com.android.launcher3.anim.Interpolators.EMPHASIZED_DECELERATE;
+import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
import static com.android.launcher3.anim.Interpolators.FINAL_FRAME;
import static com.android.launcher3.anim.Interpolators.INSTANT;
import static com.android.launcher3.anim.Interpolators.LINEAR;
@@ -103,7 +104,10 @@
}
config.setInterpolator(ANIM_OVERVIEW_ACTIONS_FADE, clampToProgress(LINEAR, 0, 0.25f));
- config.setInterpolator(ANIM_SCRIM_FADE, clampToProgress(LINEAR, 0.33f, 1));
+ config.setInterpolator(ANIM_SCRIM_FADE,
+ fromState == OVERVIEW_SPLIT_SELECT
+ ? clampToProgress(LINEAR, 0.33f, 1)
+ : LINEAR);
config.setInterpolator(ANIM_WORKSPACE_SCALE, DEACCEL);
config.setInterpolator(ANIM_WORKSPACE_FADE, ACCEL);
@@ -112,7 +116,10 @@
// Overview is going offscreen, so keep it at its current scale and opacity.
config.setInterpolator(ANIM_OVERVIEW_SCALE, FINAL_FRAME);
config.setInterpolator(ANIM_OVERVIEW_FADE, FINAL_FRAME);
- config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_X, EMPHASIZED_DECELERATE);
+ config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_X,
+ fromState == OVERVIEW_SPLIT_SELECT
+ ? EMPHASIZED_DECELERATE
+ : clampToProgress(FAST_OUT_SLOW_IN, 0, 0.75f));
config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_Y, FINAL_FRAME);
// Scroll RecentsView to page 0 as it goes offscreen, if necessary.
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index d1aaef1..b7e6378 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -378,6 +378,11 @@
"Enables taskbar pinning to allow user to switch between transient and persistent "
+ "taskbar flavors");
+ public static final BooleanFlag ENABLE_WORKSPACE_LOADING_OPTIMIZATION = getDebugFlag(251502424,
+ "ENABLE_WORKSPACE_LOADING_OPTIMIZATION", false, "load the current workspace screen "
+ + "visible to the user before the rest rather than loading all of them at once."
+ );
+
public static final BooleanFlag ENABLE_GRID_ONLY_OVERVIEW = getDebugFlag(270397206,
"ENABLE_GRID_ONLY_OVERVIEW", false,
"Enable a grid-only overview without a focused task.");
diff --git a/src/com/android/launcher3/logging/StatsLogManager.java b/src/com/android/launcher3/logging/StatsLogManager.java
index 5f6df27..cf710da 100644
--- a/src/com/android/launcher3/logging/StatsLogManager.java
+++ b/src/com/android/launcher3/logging/StatsLogManager.java
@@ -636,6 +636,12 @@
@UiEvent(doc = "User scrolled up on the search result page.")
LAUNCHER_ALLAPPS_SEARCH_SCROLLED_UP(1286),
+
+ @UiEvent(doc = "User or automatic timeout has hidden transient taskbar.")
+ LAUNCHER_TRANSIENT_TASKBAR_HIDE(1330),
+
+ @UiEvent(doc = "User has swiped upwards from the gesture handle to show transient taskbar.")
+ LAUNCHER_TRANSIENT_TASKBAR_SHOW(1331),
;
// ADD MORE
diff --git a/src/com/android/launcher3/model/BaseLauncherBinder.java b/src/com/android/launcher3/model/BaseLauncherBinder.java
index 8519a3e..91ace27 100644
--- a/src/com/android/launcher3/model/BaseLauncherBinder.java
+++ b/src/com/android/launcher3/model/BaseLauncherBinder.java
@@ -27,6 +27,7 @@
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherModel.CallbackTask;
import com.android.launcher3.LauncherSettings;
+import com.android.launcher3.Workspace;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.model.BgDataModel.Callbacks;
import com.android.launcher3.model.BgDataModel.FixedContainerItems;
@@ -42,8 +43,10 @@
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashSet;
import java.util.List;
import java.util.Objects;
+import java.util.Set;
import java.util.concurrent.Executor;
/**
@@ -77,6 +80,36 @@
* Binds all loaded data to actual views on the main thread.
*/
public void bindWorkspace(boolean incrementBindId) {
+ if (FeatureFlags.ENABLE_WORKSPACE_LOADING_OPTIMIZATION.get()) {
+ DisjointWorkspaceBinder workspaceBinder =
+ initWorkspaceBinder(incrementBindId, mBgDataModel.collectWorkspaceScreens());
+ workspaceBinder.bindCurrentWorkspacePages();
+ workspaceBinder.bindOtherWorkspacePages();
+ } else {
+ bindWorkspaceAllAtOnce(incrementBindId);
+ }
+ }
+
+ /**
+ * Initializes the WorkspaceBinder for binding.
+ *
+ * @param incrementBindId this is used to stop previously started binding tasks that are
+ * obsolete but still queued.
+ * @param workspacePages this allows the Launcher to add the correct workspace screens.
+ */
+ public DisjointWorkspaceBinder initWorkspaceBinder(boolean incrementBindId,
+ IntArray workspacePages) {
+
+ synchronized (mBgDataModel) {
+ if (incrementBindId) {
+ mBgDataModel.lastBindId++;
+ }
+ mMyBindingId = mBgDataModel.lastBindId;
+ return new DisjointWorkspaceBinder(workspacePages);
+ }
+ }
+
+ private void bindWorkspaceAllAtOnce(boolean incrementBindId) {
// Save a copy of all the bg-thread collections
ArrayList<ItemInfo> workspaceItems = new ArrayList<>();
ArrayList<LauncherAppWidgetInfo> appWidgets = new ArrayList<>();
@@ -95,7 +128,7 @@
}
for (Callbacks cb : mCallbacksList) {
- new WorkspaceBinder(cb, mUiExecutor, mApp, mBgDataModel, mMyBindingId,
+ new UnifiedWorkspaceBinder(cb, mUiExecutor, mApp, mBgDataModel, mMyBindingId,
workspaceItems, appWidgets, extraItems, orderedScreenIds).bind();
}
}
@@ -180,7 +213,7 @@
return idleLock;
}
- private class WorkspaceBinder {
+ private class UnifiedWorkspaceBinder {
private final Executor mUiExecutor;
private final Callbacks mCallbacks;
@@ -194,7 +227,7 @@
private final IntArray mOrderedScreenIds;
private final ArrayList<FixedContainerItems> mExtraItems;
- WorkspaceBinder(Callbacks callbacks,
+ UnifiedWorkspaceBinder(Callbacks callbacks,
Executor uiExecutor,
LauncherAppState app,
BgDataModel bgDataModel,
@@ -320,4 +353,115 @@
});
}
}
+
+ private class DisjointWorkspaceBinder {
+ private final IntArray mOrderedScreenIds;
+ private final IntSet mCurrentScreenIds = new IntSet();
+ private final Set<Integer> mBoundItemIds = new HashSet<>();
+
+ protected DisjointWorkspaceBinder(IntArray orderedScreenIds) {
+ mOrderedScreenIds = orderedScreenIds;
+
+ for (Callbacks cb : mCallbacksList) {
+ mCurrentScreenIds.addAll(cb.getPagesToBindSynchronously(orderedScreenIds));
+ }
+ if (mCurrentScreenIds.size() == 0) {
+ mCurrentScreenIds.add(Workspace.FIRST_SCREEN_ID);
+ }
+ }
+
+ /**
+ * Binds the currently loaded items in the Data Model. Also signals to the Callbacks[]
+ * that these items have been bound and their respective screens are ready to be shown.
+ *
+ * If this method is called after all the items on the workspace screen have already been
+ * loaded, it will bind all workspace items immediately, and bindOtherWorkspacePages() will
+ * not bind any items.
+ */
+ protected void bindCurrentWorkspacePages() {
+ // Save a copy of all the bg-thread collections
+ ArrayList<ItemInfo> workspaceItems;
+ ArrayList<LauncherAppWidgetInfo> appWidgets;
+
+ synchronized (mBgDataModel) {
+ workspaceItems = new ArrayList<>(mBgDataModel.workspaceItems);
+ appWidgets = new ArrayList<>(mBgDataModel.appWidgets);
+ }
+
+ workspaceItems.forEach(it -> mBoundItemIds.add(it.id));
+ appWidgets.forEach(it -> mBoundItemIds.add(it.id));
+
+ sortWorkspaceItemsSpatially(mApp.getInvariantDeviceProfile(), workspaceItems);
+
+ // Tell the workspace that we're about to start binding items
+ executeCallbacksTask(c -> {
+ c.clearPendingBinds();
+ c.startBinding();
+ }, mUiExecutor);
+
+ // Bind workspace screens
+ executeCallbacksTask(c -> c.bindScreens(mOrderedScreenIds), mUiExecutor);
+
+ bindWorkspaceItems(workspaceItems);
+ bindAppWidgets(appWidgets);
+
+ executeCallbacksTask(c -> {
+ MODEL_EXECUTOR.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
+ c.onInitialBindComplete(mCurrentScreenIds, new RunnableList());
+ }, mUiExecutor);
+ }
+
+ protected void bindOtherWorkspacePages() {
+ // Save a copy of all the bg-thread collections
+ ArrayList<ItemInfo> workspaceItems;
+ ArrayList<LauncherAppWidgetInfo> appWidgets;
+
+ synchronized (mBgDataModel) {
+ workspaceItems = new ArrayList<>(mBgDataModel.workspaceItems);
+ appWidgets = new ArrayList<>(mBgDataModel.appWidgets);
+ }
+
+ workspaceItems.removeIf(it -> mBoundItemIds.contains(it.id));
+ appWidgets.removeIf(it -> mBoundItemIds.contains(it.id));
+
+ sortWorkspaceItemsSpatially(mApp.getInvariantDeviceProfile(), workspaceItems);
+
+ bindWorkspaceItems(workspaceItems);
+ bindAppWidgets(appWidgets);
+
+ executeCallbacksTask(c -> c.finishBindingItems(mCurrentScreenIds), mUiExecutor);
+ mUiExecutor.execute(() -> {
+ MODEL_EXECUTOR.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
+ ItemInstallQueue.INSTANCE.get(mApp.getContext())
+ .resumeModelPush(FLAG_LOADER_RUNNING);
+ });
+
+ for (Callbacks cb : mCallbacksList) {
+ cb.bindStringCache(mBgDataModel.stringCache.clone());
+ }
+ }
+
+ private void bindWorkspaceItems(final ArrayList<ItemInfo> workspaceItems) {
+ // Bind the workspace items
+ int count = workspaceItems.size();
+ for (int i = 0; i < count; i += ITEMS_CHUNK) {
+ final int start = i;
+ final int chunkSize = (i + ITEMS_CHUNK <= count) ? ITEMS_CHUNK : (count - i);
+ executeCallbacksTask(
+ c -> c.bindItems(workspaceItems.subList(start, start + chunkSize), false),
+ mUiExecutor);
+ }
+ }
+
+ private void bindAppWidgets(List<LauncherAppWidgetInfo> appWidgets) {
+ // Bind the widgets, one at a time
+ int count = appWidgets.size();
+ for (int i = 0; i < count; i++) {
+ final ItemInfo widget = appWidgets.get(i);
+ executeCallbacksTask(
+ c -> c.bindItems(Collections.singletonList(widget), false),
+ mUiExecutor);
+ }
+ }
+ }
}
diff --git a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
index fef1708..f910a92 100644
--- a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
+++ b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
@@ -510,7 +510,6 @@
@Test
@PortraitLandscape
- @ScreenRecord // (b/256659409)
public void testUninstallFromAllApps() throws Exception {
installDummyAppAndWaitForUIUpdate();
try {
@@ -519,6 +518,8 @@
allApps.freeze();
try {
workspace = allApps.getAppIcon(DUMMY_APP_NAME).uninstall();
+ // After the toast clears, then the model tries to commit the uninstall transaction
+ mLauncher.waitForModelQueueCleared();
} finally {
allApps.unfreeze();
}