Merge "Preload overview after unfold" into main
diff --git a/aconfig/launcher.aconfig b/aconfig/launcher.aconfig
index aca1b3b..8fddc0f 100644
--- a/aconfig/launcher.aconfig
+++ b/aconfig/launcher.aconfig
@@ -13,3 +13,10 @@
description: "Enables two line label inside all apps."
bug: "270390937"
}
+
+flag {
+ name: "enable_grid_only_overview"
+ namespace: "launcher"
+ description: "Enable a grid-only overview without a focused task."
+ bug: "257950105"
+}
diff --git a/quickstep/res/values-kn/strings.xml b/quickstep/res/values-kn/strings.xml
index 6c84e6f..b7cdd15 100644
--- a/quickstep/res/values-kn/strings.xml
+++ b/quickstep/res/values-kn/strings.xml
@@ -116,7 +116,7 @@
<string name="taskbar_button_back" msgid="8558862226461164514">"ಹಿಂದೆ"</string>
<string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME ಪರಿವರ್ತಕ"</string>
<string name="taskbar_button_recents" msgid="7273376136216613134">"ಇತ್ತೀಚಿನವು"</string>
- <string name="taskbar_button_notifications" msgid="7471740351507357318">"ಅಧಿಸೂಚನೆಗಳು"</string>
+ <string name="taskbar_button_notifications" msgid="7471740351507357318">"ನೋಟಿಫಿಕೇಶನ್ಗಳು"</string>
<string name="taskbar_button_quick_settings" msgid="227662894293189391">"ತ್ವರಿತ ಸೆಟ್ಟಿಂಗ್ಗಳು"</string>
<string name="taskbar_a11y_title" msgid="6432169809852243110">"ಟಾಸ್ಕ್ಬಾರ್"</string>
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"ಟಾಸ್ಕ್ಬಾರ್ ತೋರಿಸಲಾಗಿದೆ"</string>
diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
index 5f0da1c..841fc8f 100644
--- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
+++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
@@ -22,6 +22,8 @@
import static android.provider.Settings.Secure.LAUNCHER_TASKBAR_EDUCATION_SHOWING;
import static android.view.RemoteAnimationTarget.MODE_CLOSING;
import static android.view.RemoteAnimationTarget.MODE_OPENING;
+import static android.view.Surface.ROTATION_0;
+import static android.view.Surface.ROTATION_180;
import static android.view.WindowManager.TRANSIT_CLOSE;
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY;
import static android.view.WindowManager.TRANSIT_OPEN;
@@ -240,6 +242,8 @@
private RemoteAnimationFactory mWallpaperOpenTransitionRunner;
private RemoteTransition mLauncherOpenTransition;
+ private final RemoteAnimationCoordinateTransfer mCoordinateTransfer;
+
private LauncherBackAnimationController mBackAnimationController;
private final AnimatorListenerAdapter mForceInvisibleListener = new AnimatorListenerAdapter() {
@Override
@@ -288,6 +292,7 @@
mOpeningXInterpolator = AnimationUtils.loadInterpolator(context, R.interpolator.app_open_x);
mOpeningInterpolator = AnimationUtils.loadInterpolator(context,
R.interpolator.emphasized_interpolator);
+ mCoordinateTransfer = new RemoteAnimationCoordinateTransfer(mLauncher);
}
@Override
@@ -1389,8 +1394,9 @@
targetRect));
// Hook up floating views to the closing window animators.
- final int rotationChange = getRotationChange(targets);
- Rect windowTargetBounds = getWindowTargetBounds(targets, rotationChange);
+ // note the coordinate of closingWindowStartRect is based on launcher
+ Rect windowTargetBounds = new Rect();
+ closingWindowStartRect.round(windowTargetBounds);
if (floatingIconView != null) {
anim.addAnimatorListener(floatingIconView);
floatingIconView.setOnTargetChangeListener(anim::onTargetPositionChanged);
@@ -1694,8 +1700,18 @@
RectF windowTargetBounds =
new RectF(getWindowTargetBounds(appTargets, getRotationChange(appTargets)));
+
+ final RectF resolveRectF = new RectF(windowTargetBounds);
+ for (RemoteAnimationTarget t : appTargets) {
+ if (t.mode == MODE_CLOSING) {
+ transferRectToTargetCoordinate(
+ t, windowTargetBounds, true, resolveRectF);
+ break;
+ }
+ }
+
Pair<RectFSpringAnim, AnimatorSet> pair = createWallpaperOpenAnimations(
- appTargets, wallpaperTargets, mFromUnlock, windowTargetBounds,
+ appTargets, wallpaperTargets, mFromUnlock, resolveRectF,
QuickStepContract.getWindowCornerRadius(mLauncher),
false /* fromPredictiveBack */);
@@ -1941,6 +1957,52 @@
}
/**
+ * Transfer the rectangle to another coordinate if needed.
+ * @param toLauncher which one is the anchor of this transfer, if true then transfer from
+ * animation target to launcher, false transfer from launcher to animation
+ * target.
+ */
+ public void transferRectToTargetCoordinate(RemoteAnimationTarget target, RectF currentRect,
+ boolean toLauncher, RectF resultRect) {
+ mCoordinateTransfer.transferRectToTargetCoordinate(
+ target, currentRect, toLauncher, resultRect);
+ }
+
+ private static class RemoteAnimationCoordinateTransfer {
+ private final QuickstepLauncher mLauncher;
+ private final Rect mDisplayRect = new Rect();
+ private final Rect mTmpResult = new Rect();
+
+ RemoteAnimationCoordinateTransfer(QuickstepLauncher launcher) {
+ mLauncher = launcher;
+ }
+
+ void transferRectToTargetCoordinate(RemoteAnimationTarget target, RectF currentRect,
+ boolean toLauncher, RectF resultRect) {
+ final int taskRotation = target.windowConfiguration.getRotation();
+ final DeviceProfile profile = mLauncher.getDeviceProfile();
+
+ final int rotationDelta = toLauncher
+ ? android.util.RotationUtils.deltaRotation(taskRotation, profile.rotationHint)
+ : android.util.RotationUtils.deltaRotation(profile.rotationHint, taskRotation);
+ if (rotationDelta != ROTATION_0) {
+ // Get original display size when task is on top but with different rotation
+ if (rotationDelta % 2 != 0 && toLauncher && (profile.rotationHint == ROTATION_0
+ || profile.rotationHint == ROTATION_180)) {
+ mDisplayRect.set(0, 0, profile.heightPx, profile.widthPx);
+ } else {
+ mDisplayRect.set(0, 0, profile.widthPx, profile.heightPx);
+ }
+ currentRect.round(mTmpResult);
+ android.util.RotationUtils.rotateBounds(mTmpResult, mDisplayRect, rotationDelta);
+ resultRect.set(mTmpResult);
+ } else {
+ resultRect.set(currentRect);
+ }
+ }
+ }
+
+ /**
* RectFSpringAnim update listener to be used for app to home animation.
*/
private class SpringAnimRunner implements RectFSpringAnim.OnUpdateListener {
@@ -1962,6 +2024,20 @@
mEndRadius = Math.max(1, targetRect.width()) / 2f;
mSurfaceApplier = new SurfaceTransactionApplier(mDragLayer);
mWindowTargetBounds.set(windowTargetBounds);
+
+ // transfer the coordinate based on animation target.
+ if (mAppTargets != null) {
+ for (RemoteAnimationTarget t : mAppTargets) {
+ if (t.mode == MODE_CLOSING) {
+ final RectF targetBounds = new RectF(mWindowTargetBounds);
+ final RectF result = new RectF();
+ transferRectToTargetCoordinate(
+ t, targetBounds, false, result);
+ result.round(mWindowTargetBounds);
+ break;
+ }
+ }
+ }
}
public float getCornerRadius(float progress) {
@@ -1982,6 +2058,8 @@
}
if (target.mode == MODE_CLOSING) {
+ final RectF before = new RectF(currentRectF);
+ transferRectToTargetCoordinate(target, currentRectF, false, currentRectF);
currentRectF.round(mCurrentRect);
// Scale the target window to match the currentRectF.
diff --git a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
index 87a9ecb..a63f9e8 100644
--- a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
+++ b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
@@ -22,6 +22,7 @@
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_HOTSEAT_PREDICTION_PINNED;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_HOTSEAT_RANKED;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
+import static com.android.launcher3.util.FlagDebugUtils.appendFlag;
import android.animation.Animator;
import android.animation.AnimatorSet;
@@ -61,9 +62,11 @@
import com.android.launcher3.util.OnboardingPrefs;
import com.android.launcher3.views.Snackbar;
+import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.StringJoiner;
import java.util.function.Predicate;
import java.util.stream.Collectors;
@@ -185,7 +188,7 @@
}
private void fillGapsWithPrediction(boolean animate) {
- Log.d(TAG, "fillGapsWithPrediction");
+ Log.d(TAG, "fillGapsWithPrediction flags: " + getStateString(mPauseFlags));
if (mPauseFlags != 0) {
return;
}
@@ -291,6 +294,7 @@
* start and pauses predicted apps update on the hotseat
*/
public void setPauseUIUpdate(boolean paused) {
+ Log.d(TAG, "setPauseUIUpdate parameter `paused` is " + paused);
mPauseFlags = paused
? (mPauseFlags | FLAG_UPDATE_PAUSED)
: (mPauseFlags & ~FLAG_UPDATE_PAUSED);
@@ -515,4 +519,21 @@
&& ((WorkspaceItemInfo) view.getTag()).container
== LauncherSettings.Favorites.CONTAINER_HOTSEAT_PREDICTION;
}
+
+ private static String getStateString(int flags) {
+ StringJoiner str = new StringJoiner("|");
+ appendFlag(str, flags, FLAG_UPDATE_PAUSED, "FLAG_UPDATE_PAUSED");
+ appendFlag(str, flags, FLAG_DRAG_IN_PROGRESS, "FLAG_DRAG_IN_PROGRESS");
+ appendFlag(str, flags, FLAG_FILL_IN_PROGRESS, "FLAG_FILL_IN_PROGRESS");
+ appendFlag(str, flags, FLAG_REMOVING_PREDICTED_ICON,
+ "FLAG_REMOVING_PREDICTED_ICON");
+ return str.toString();
+ }
+
+ public void dump(String prefix, PrintWriter writer) {
+ writer.println(prefix + this.getClass().getSimpleName());
+ writer.println(prefix + "\tFlags: " + getStateString(mPauseFlags));
+ writer.println(prefix + "\tmHotSeatItemsCount: " + mHotSeatItemsCount);
+ writer.println(prefix + "\tmPredictedItems: " + mPredictedItems);
+ }
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index 80ac9be..3a1ed0b 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -347,6 +347,11 @@
mControllers.taskbarAllAppsController.toggle();
}
+ /** Toggles Taskbar All Apps overlay with keyboard ready for search. */
+ public void toggleAllAppsSearch() {
+ mControllers.taskbarAllAppsController.toggleSearch();
+ }
+
@Override
public DeviceProfile getDeviceProfile() {
return mDeviceProfile;
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt
index 12fa17c..eb15cef 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt
@@ -109,7 +109,7 @@
if (!context.isGestureNav) {
if (windowLayoutParams.paramsForRotation != null) {
for (layoutParams in windowLayoutParams.paramsForRotation) {
- layoutParams.providedInsets = windowLayoutParams.providedInsets
+ layoutParams.providedInsets = getProvidedInsets(insetsRoundedCornerFlag)
}
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
index 55d56f0..ba2116d 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
@@ -304,7 +304,7 @@
return;
}
- mTaskbarActivityContext.toggleAllApps();
+ mTaskbarActivityContext.toggleAllAppsSearch();
}
/**
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarScrimViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarScrimViewController.java
index 1c250bf..3a733bf 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarScrimViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarScrimViewController.java
@@ -18,6 +18,7 @@
import static com.android.launcher3.taskbar.bubbles.BubbleBarController.BUBBLE_BAR_ENABLED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BUBBLES_EXPANDED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BUBBLES_MANAGE_MENU_EXPANDED;
+import static com.android.wm.shell.common.bubbles.BubbleConstants.BUBBLE_EXPANDED_SCRIM_ALPHA;
import android.animation.ObjectAnimator;
import android.view.animation.Interpolator;
@@ -35,8 +36,6 @@
public class TaskbarScrimViewController implements TaskbarControllers.LoggableTaskbarController,
TaskbarControllers.BackgroundRendererController {
- private static final float SCRIM_ALPHA = 0.6f;
-
private static final Interpolator SCRIM_ALPHA_IN = new PathInterpolator(0.4f, 0f, 1f, 1f);
private static final Interpolator SCRIM_ALPHA_OUT = new PathInterpolator(0f, 0f, 0.8f, 1f);
@@ -78,8 +77,9 @@
final float scrimAlpha = manageMenuExpanded
// When manage menu shows there's the first scrim and second scrim so figure out
// what the total transparency would be.
- ? (SCRIM_ALPHA + (SCRIM_ALPHA * (1 - SCRIM_ALPHA)))
- : showScrim ? SCRIM_ALPHA : 0;
+ ? (BUBBLE_EXPANDED_SCRIM_ALPHA + (BUBBLE_EXPANDED_SCRIM_ALPHA
+ * (1 - BUBBLE_EXPANDED_SCRIM_ALPHA)))
+ : showScrim ? BUBBLE_EXPANDED_SCRIM_ALPHA : 0;
showScrim(showScrim, scrimAlpha, skipAnim);
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java
index d786d94..e004acc 100644
--- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java
@@ -128,10 +128,19 @@
/** Toggles visibility of {@link TaskbarAllAppsContainerView} in the overlay window. */
public void toggle() {
+ toggle(false);
+ }
+
+ /** Toggles visibility of {@link TaskbarAllAppsContainerView} with the keyboard for search. */
+ public void toggleSearch() {
+ toggle(true);
+ }
+
+ private void toggle(boolean showKeyboard) {
if (isOpen()) {
mSlideInView.close(true);
} else {
- show(true);
+ show(true, showKeyboard);
}
}
@@ -141,6 +150,10 @@
}
private void show(boolean animate) {
+ show(animate, false);
+ }
+
+ private void show(boolean animate, boolean showKeyboard) {
if (mAppsView != null) {
return;
}
@@ -166,7 +179,11 @@
cleanUpOverlay();
});
TaskbarAllAppsViewController viewController = new TaskbarAllAppsViewController(
- mOverlayContext, mSlideInView, mControllers, mSearchSessionController);
+ mOverlayContext,
+ mSlideInView,
+ mControllers,
+ mSearchSessionController,
+ showKeyboard);
viewController.show(animate);
mAppsView = mOverlayContext.getAppsView();
diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java
index 85633e9..3a6d613 100644
--- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java
@@ -41,12 +41,14 @@
private final TaskbarStashController mTaskbarStashController;
private final NavbarButtonsViewController mNavbarButtonsViewController;
private final TaskbarOverlayController mOverlayController;
+ private final boolean mShowKeyboard;
TaskbarAllAppsViewController(
TaskbarOverlayContext context,
TaskbarAllAppsSlideInView slideInView,
TaskbarControllers taskbarControllers,
- TaskbarSearchSessionController searchSessionController) {
+ TaskbarSearchSessionController searchSessionController,
+ boolean showKeyboard) {
mContext = context;
mSlideInView = slideInView;
@@ -54,6 +56,7 @@
mTaskbarStashController = taskbarControllers.taskbarStashController;
mNavbarButtonsViewController = taskbarControllers.navbarButtonsViewController;
mOverlayController = taskbarControllers.taskbarOverlayController;
+ mShowKeyboard = showKeyboard;
mSlideInView.init(new TaskbarAllAppsCallbacks(searchSessionController));
setUpAppDivider();
@@ -120,6 +123,11 @@
@Override
public void onAllAppsTransitionEnd(boolean toAllApps) {
mSearchSessionController.onAllAppsTransitionEnd(toAllApps);
+ if (toAllApps
+ && mShowKeyboard
+ && mAppsView.getSearchUiManager().getEditText() != null) {
+ mAppsView.getSearchUiManager().getEditText().requestFocus();
+ }
}
/** Invoked on back press, returning {@code true} if the search session handled it. */
@@ -128,7 +136,7 @@
}
void onAllAppsAnimationPending(PendingAnimation animation, boolean toAllApps) {
- mSearchSessionController.onAllAppsAnimationPending(animation, toAllApps);
+ mSearchSessionController.onAllAppsAnimationPending(animation, toAllApps, mShowKeyboard);
}
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarSearchSessionController.kt b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarSearchSessionController.kt
index 8a2041f..3d15fbd 100644
--- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarSearchSessionController.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarSearchSessionController.kt
@@ -51,7 +51,11 @@
open fun handleBackInvoked(): Boolean = false
- open fun onAllAppsAnimationPending(animation: PendingAnimation, toAllApps: Boolean) = Unit
+ open fun onAllAppsAnimationPending(
+ animation: PendingAnimation,
+ toAllApps: Boolean,
+ showKeyboard: Boolean,
+ ) = Unit
companion object {
@JvmStatic
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index b50ab97..3ef5699 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -345,9 +345,7 @@
mHotseatPredictionController.setPauseUIUpdate(getTaskbarUIController() == null);
RunnableList result = super.startActivitySafely(v, intent, item);
if (result == null) {
- if (getTaskbarUIController() == null) {
- mHotseatPredictionController.setPauseUIUpdate(false);
- }
+ mHotseatPredictionController.setPauseUIUpdate(false);
} else {
result.add(() -> mHotseatPredictionController.setPauseUIUpdate(false));
}
@@ -1311,5 +1309,8 @@
if (mAppTransitionManager != null) {
mAppTransitionManager.dump(prefix + "\t" + RING_APPEAR_ANIMATION_PREFIX, writer);
}
+ if (mHotseatPredictionController != null) {
+ mHotseatPredictionController.dump(prefix, writer);
+ }
}
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java
index b9221ee..3e7d45e 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java
@@ -72,7 +72,7 @@
@Override
public boolean isTaskbarStashed(Launcher launcher) {
- if (FeatureFlags.ENABLE_GRID_ONLY_OVERVIEW.get()) {
+ if (FeatureFlags.enableGridOnlyOverview()) {
return true;
}
return super.isTaskbarStashed(launcher);
diff --git a/quickstep/src/com/android/quickstep/BaseActivityInterface.java b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
index 5a9d80d..e316175 100644
--- a/quickstep/src/com/android/quickstep/BaseActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
@@ -239,7 +239,7 @@
public final void calculateTaskSize(Context context, DeviceProfile dp, Rect outRect,
PagedOrientationHandler orientedState) {
if (dp.isTablet) {
- if (FeatureFlags.ENABLE_GRID_ONLY_OVERVIEW.get()) {
+ if (FeatureFlags.enableGridOnlyOverview()) {
calculateGridTaskSize(context, dp, outRect, orientedState);
} else {
calculateFocusTaskSize(context, dp, outRect);
@@ -336,7 +336,7 @@
PagedOrientationHandler orientedState) {
Resources res = context.getResources();
Rect potentialTaskRect = new Rect();
- if (FeatureFlags.ENABLE_GRID_ONLY_OVERVIEW.get()) {
+ if (FeatureFlags.enableGridOnlyOverview()) {
calculateGridSize(dp, potentialTaskRect);
} else {
calculateFocusTaskSize(context, dp, potentialTaskRect);
@@ -368,7 +368,7 @@
public final void calculateModalTaskSize(Context context, DeviceProfile dp, Rect outRect,
PagedOrientationHandler orientedState) {
calculateTaskSize(context, dp, outRect, orientedState);
- boolean isGridOnlyOverview = dp.isTablet && FeatureFlags.ENABLE_GRID_ONLY_OVERVIEW.get();
+ boolean isGridOnlyOverview = dp.isTablet && FeatureFlags.enableGridOnlyOverview();
int claimedSpaceBelow = isGridOnlyOverview
? dp.overviewActionsTopMarginPx + dp.overviewActionsHeight + dp.stashedTaskbarHeight
: (dp.heightPx - outRect.bottom - dp.getInsets().bottom);
diff --git a/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java b/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java
index 857c831..1f8ddf0 100644
--- a/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java
+++ b/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java
@@ -404,12 +404,16 @@
AbstractFloatingView.closeAllOpenViewsExcept(mLauncher, false, TYPE_REBIND_SAFE);
float cornerRadius = Utilities.mapRange(
mBackProgress, mWindowScaleStartCornerRadius, mWindowScaleEndCornerRadius);
+ final RectF resolveRectF = new RectF();
+ mQuickstepTransitionManager.transferRectToTargetCoordinate(
+ mBackTarget, mCurrentRect, true, resolveRectF);
+
Pair<RectFSpringAnim, AnimatorSet> pair =
mQuickstepTransitionManager.createWallpaperOpenAnimations(
new RemoteAnimationTarget[]{mBackTarget},
new RemoteAnimationTarget[0],
false /* fromUnlock */,
- mCurrentRect,
+ resolveRectF,
cornerRadius,
mBackInProgress /* fromPredictiveBack */);
startTransitionAnimations(pair.first, pair.second);
diff --git a/quickstep/src/com/android/quickstep/TaskOverlayFactory.java b/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
index 076f4b1..bd3ccb7 100644
--- a/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
+++ b/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
@@ -80,7 +80,7 @@
boolean isInLandscape = orientedState.getTouchRotation() != ROTATION_0;
boolean isTablet = activity.getDeviceProfile().isTablet;
- boolean isGridOnlyOverview = isTablet && FeatureFlags.ENABLE_GRID_ONLY_OVERVIEW.get();
+ boolean isGridOnlyOverview = isTablet && FeatureFlags.enableGridOnlyOverview();
// Add overview actions to the menu when in in-place rotate landscape mode, or in
// grid-only overview.
if ((!canLauncherRotate && isInLandscape) || isGridOnlyOverview) {
diff --git a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
index be66637..b1daac4 100644
--- a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
+++ b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
@@ -87,6 +87,7 @@
private static final String LATENCY_TAG = "StatsLatencyLog";
private static final String IMPRESSION_TAG = "StatsImpressionLog";
private static final boolean IS_VERBOSE = Utilities.isPropertyEnabled(LogConfig.STATSLOG);
+ private static final boolean DEBUG = !Utilities.isRunningInTestHarness();
private static final InstanceId DEFAULT_INSTANCE_ID = InstanceId.fakeInstanceId(0);
// LauncherAtom.ItemInfo.getDefaultInstance() should be used but until launcher proto migrates
// from nano to lite, bake constant to prevent robo test failure.
@@ -326,6 +327,11 @@
if (!Utilities.ATLEAST_R) {
return;
}
+ if (DEBUG) {
+ String name = (event instanceof Enum) ? ((Enum) event).name() :
+ event.getId() + "";
+ Log.d(TAG, name);
+ }
LauncherAppState appState = LauncherAppState.getInstanceNoCreate();
if (mSlice == null && mSliceItem != null) {
diff --git a/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java b/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java
index 4bc41bc..a8a96ce 100644
--- a/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java
+++ b/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java
@@ -15,6 +15,8 @@
*/
package com.android.quickstep.util;
+import static com.android.launcher3.testing.shared.TestProtocol.PAUSE_DETECTED_MESSAGE;
+
import android.content.Context;
import android.content.res.Resources;
import android.util.Log;
@@ -201,7 +203,8 @@
ActiveGestureLog.INSTANCE.addLog(logString);
boolean isFirstDetectedPause = !mHasEverBeenPaused && mIsPaused;
if (mIsPaused) {
- AccessibilityManagerCompat.sendPauseDetectedEventToTest(mContext);
+ AccessibilityManagerCompat.sendTestProtocolEventToTest(mContext,
+ PAUSE_DETECTED_MESSAGE);
mHasEverBeenPaused = true;
}
if (mOnMotionPauseListener != null) {
diff --git a/quickstep/src/com/android/quickstep/views/ClearAllButton.java b/quickstep/src/com/android/quickstep/views/ClearAllButton.java
index 19ac1f8..cfb4d0d 100644
--- a/quickstep/src/com/android/quickstep/views/ClearAllButton.java
+++ b/quickstep/src/com/android/quickstep/views/ClearAllButton.java
@@ -16,7 +16,7 @@
package com.android.quickstep.views;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_GRID_ONLY_OVERVIEW;
+import static com.android.launcher3.config.FeatureFlags.enableGridOnlyOverview;
import android.content.Context;
import android.util.AttributeSet;
@@ -251,7 +251,7 @@
private float getOriginalTranslationY() {
DeviceProfile deviceProfile = mActivity.getDeviceProfile();
if (deviceProfile.isTablet) {
- if (ENABLE_GRID_ONLY_OVERVIEW.get()) {
+ if (enableGridOnlyOverview()) {
return (getRecentsView().getLastComputedTaskSize().height()
+ deviceProfile.overviewTaskThumbnailTopMarginPx) / 2.0f
+ deviceProfile.overviewRowSpacing;
diff --git a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
index b31791a..9141c99 100644
--- a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
+++ b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
@@ -289,7 +289,7 @@
return 0;
}
- if (mDp.isTablet && FeatureFlags.ENABLE_GRID_ONLY_OVERVIEW.get()) {
+ if (mDp.isTablet && FeatureFlags.enableGridOnlyOverview()) {
return mDp.stashedTaskbarHeight;
}
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 7cf47ce..9b41ccd 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -42,11 +42,12 @@
import static com.android.launcher3.Utilities.mapToRange;
import static com.android.launcher3.Utilities.squaredHypot;
import static com.android.launcher3.Utilities.squaredTouchSlop;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_GRID_ONLY_OVERVIEW;
+import static com.android.launcher3.config.FeatureFlags.enableGridOnlyOverview;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_OVERVIEW_ACTIONS_SPLIT;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_CLEAR_ALL;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_DISMISS_SWIPE_UP;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_LAUNCH_SWIPE_DOWN;
+import static com.android.launcher3.testing.shared.TestProtocol.DISMISS_ANIMATION_ENDS_MESSAGE;
import static com.android.launcher3.touch.PagedOrientationHandler.CANVAS_TRANSLATE;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
@@ -1782,7 +1783,7 @@
newFocusedTaskView = getTaskViewAt(1);
}
}
- mFocusedTaskViewId = newFocusedTaskView != null && !ENABLE_GRID_ONLY_OVERVIEW.get()
+ mFocusedTaskViewId = newFocusedTaskView != null && !enableGridOnlyOverview()
? newFocusedTaskView.getTaskViewId() : INVALID_TASK_ID;
updateTaskSize();
if (newFocusedTaskView != null) {
@@ -1900,7 +1901,7 @@
* Returns the number of tasks in the bottom row of the overview grid.
*/
public int getBottomRowTaskCountForTablet() {
- return getTaskViewCount() - mTopRowIdSet.size() - (ENABLE_GRID_ONLY_OVERVIEW.get() ? 0 : 1);
+ return getTaskViewCount() - mTopRowIdSet.size() - (enableGridOnlyOverview() ? 0 : 1);
}
protected void onTaskStackUpdated() {
@@ -1978,7 +1979,7 @@
DeviceProfile dp = mActivity.getDeviceProfile();
setOverviewGridEnabled(
mActivity.getStateManager().getState().displayOverviewTasksAsGrid(dp));
- if (ENABLE_GRID_ONLY_OVERVIEW.get()) {
+ if (enableGridOnlyOverview()) {
mActionsView.updateHiddenFlags(HIDDEN_ACTIONS_IN_MENU, dp.isTablet);
}
setPageSpacing(dp.overviewPageSpacing);
@@ -2140,7 +2141,7 @@
Rect outRect = new Rect(mLastComputedTaskSize);
outRect.offset(
-(primaryScroll - (selectedPageScroll + getOffsetFromScrollPosition(selectedPage))),
- (int) (showAsGrid() && ENABLE_GRID_ONLY_OVERVIEW.get() && !isTopRow
+ (int) (showAsGrid() && enableGridOnlyOverview() && !isTopRow
? mTopBottomRowHeightDiff : 0));
return outRect;
}
@@ -2726,7 +2727,7 @@
boolean runningTaskTileHidden = mRunningTaskTileHidden;
setCurrentTask(runningTaskViewId);
- mFocusedTaskViewId = ENABLE_GRID_ONLY_OVERVIEW.get() ? INVALID_TASK_ID : runningTaskViewId;
+ mFocusedTaskViewId = enableGridOnlyOverview() ? INVALID_TASK_ID : runningTaskViewId;
runOnPageScrollsInitialized(() -> setCurrentPage(getRunningTaskIndex()));
setRunningTaskViewShowScreenshot(false);
setRunningTaskHidden(runningTaskTileHidden);
@@ -2919,7 +2920,7 @@
// Desktop task view is hidden, skip it from grid calculations
continue;
}
- if (!ENABLE_GRID_ONLY_OVERVIEW.get()) {
+ if (!enableGridOnlyOverview()) {
// Only apply x-translation when using legacy overview grid
gridTranslations[i] += mIsRtl ? taskWidthAndSpacing : -taskWidthAndSpacing;
}
@@ -3432,7 +3433,7 @@
int topGridRowSize = mTopRowIdSet.size();
int bottomGridRowSize = taskCount - mTopRowIdSet.size()
- - (ENABLE_GRID_ONLY_OVERVIEW.get() ? 0 : 1);
+ - (enableGridOnlyOverview() ? 0 : 1);
boolean topRowLonger = topGridRowSize > bottomGridRowSize;
boolean bottomRowLonger = bottomGridRowSize > topGridRowSize;
boolean dismissedTaskFromTop = mTopRowIdSet.contains(dismissedTaskViewId);
@@ -3445,7 +3446,7 @@
}
int longRowWidth = Math.max(topGridRowSize, bottomGridRowSize)
* (mLastComputedGridTaskSize.width() + mPageSpacing);
- if (!ENABLE_GRID_ONLY_OVERVIEW.get() && !isStagingFocusedTask) {
+ if (!enableGridOnlyOverview() && !isStagingFocusedTask) {
longRowWidth += mLastComputedTaskSize.width() + mPageSpacing;
}
@@ -3853,7 +3854,7 @@
} else {
// Update focus task and its size.
if (finalIsFocusedTaskDismissed && finalNextFocusedTaskView != null) {
- mFocusedTaskViewId = ENABLE_GRID_ONLY_OVERVIEW.get()
+ mFocusedTaskViewId = enableGridOnlyOverview()
? INVALID_TASK_ID
: finalNextFocusedTaskView.getTaskViewId();
mTopRowIdSet.remove(mFocusedTaskViewId);
@@ -4035,7 +4036,8 @@
}
protected void onDismissAnimationEnds() {
- AccessibilityManagerCompat.sendDismissAnimationEndsEventToTest(getContext());
+ AccessibilityManagerCompat.sendTestProtocolEventToTest(getContext(),
+ DISMISS_ANIMATION_ENDS_MESSAGE);
}
public PendingAnimation createAllTasksDismissAnimation(long duration) {
@@ -4358,7 +4360,7 @@
int midpoint = runningTask == null ? -1 : indexOfChild(runningTask);
int modalMidpoint = getCurrentPage();
boolean isModalGridWithoutFocusedTask =
- showAsGrid && ENABLE_GRID_ONLY_OVERVIEW.get() && mTaskModalness > 0;
+ showAsGrid && enableGridOnlyOverview() && mTaskModalness > 0;
if (isModalGridWithoutFocusedTask) {
modalMidpoint = indexOfChild(mSelectedTask);
}
@@ -4420,7 +4422,7 @@
redrawLiveTile();
}
- if (showAsGrid && ENABLE_GRID_ONLY_OVERVIEW.get() && child instanceof TaskView) {
+ if (showAsGrid && enableGridOnlyOverview() && child instanceof TaskView) {
float totalTranslationY = getVerticalOffsetSize(i, modalOffset);
FloatProperty translationPropertyY =
((TaskView) child).getSecondaryTaskOffsetTranslationProperty();
@@ -4529,7 +4531,7 @@
* @param offsetProgress From 0 to 1 where 0 means no offset and 1 means offset offscreen.
*/
private float getVerticalOffsetSize(int childIndex, float offsetProgress) {
- if (offsetProgress == 0 || !(showAsGrid() && ENABLE_GRID_ONLY_OVERVIEW.get())
+ if (offsetProgress == 0 || !(showAsGrid() && enableGridOnlyOverview())
|| mSelectedTask == null) {
// Don't bother calculating everything below if we won't offset vertically.
return 0;
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index a2976a8..fcaa0d7 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -1137,7 +1137,7 @@
if (dp.isTablet) {
int alignedOptionIndex = 0;
if (getRecentsView().isOnGridBottomRow(menuContainer.getTaskView()) && dp.isLandscape) {
- if (FeatureFlags.ENABLE_GRID_ONLY_OVERVIEW.get()) {
+ if (FeatureFlags.enableGridOnlyOverview()) {
// With no focused task, there is less available space below the tasks, so align
// the arrow to the third option in the menu.
alignedOptionIndex = 2;
diff --git a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
index a67d787..b4221b2 100644
--- a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
+++ b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
@@ -16,9 +16,7 @@
package com.android.quickstep;
import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
-
import static androidx.test.InstrumentationRegistry.getInstrumentation;
-
import static com.android.launcher3.tapl.LauncherInstrumentation.WAIT_TIME_MS;
import static com.android.launcher3.tapl.TestHelpers.getHomeIntentInPackage;
import static com.android.launcher3.tapl.TestHelpers.getLauncherInMyProcess;
@@ -34,7 +32,6 @@
import static com.android.launcher3.util.rule.ShellCommandRule.getLauncherCommand;
import static com.android.launcher3.util.rule.TestStabilityRule.LOCAL;
import static com.android.launcher3.util.rule.TestStabilityRule.PLATFORM_POSTSUBMIT;
-
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
@@ -61,6 +58,7 @@
import com.android.launcher3.util.rule.FailureWatcher;
import com.android.launcher3.util.rule.SamplerRule;
import com.android.launcher3.util.rule.ScreenRecordRule;
+import com.android.launcher3.util.rule.TestIsolationRule;
import com.android.launcher3.util.rule.TestStabilityRule;
import com.android.launcher3.util.rule.ViewCaptureRule;
import com.android.quickstep.views.RecentsView;
@@ -94,9 +92,6 @@
public final TestRule mDisableHeadsUpNotification = disableHeadsUpNotification();
@Rule
- public final TestRule mSetLauncherCommand;
-
- @Rule
public final TestRule mOrderSensitiveRules;
@Rule
@@ -116,19 +111,7 @@
Utilities.enableRunningInTestHarnessForTests();
}
- final ViewCaptureRule viewCaptureRule = new ViewCaptureRule(
- RecentsActivity.ACTIVITY_TRACKER::getCreatedActivity);
- mOrderSensitiveRules = RuleChain
- .outerRule(new SamplerRule())
- .around(new NavigationModeSwitchRule(mLauncher))
- .around(new FailureWatcher(mLauncher, viewCaptureRule::getViewCaptureData))
- .around(viewCaptureRule);
-
- mOtherLauncherActivity = context.getPackageManager().queryIntentActivities(
- getHomeIntentInPackage(context),
- MATCH_DISABLED_COMPONENTS).get(0).activityInfo;
-
- mSetLauncherCommand = (base, desc) -> new Statement() {
+ final TestRule setLauncherCommand = (base, desc) -> new Statement() {
@Override
public void evaluate() throws Throwable {
TestCommandReceiver.callCommand(TestCommandReceiver.ENABLE_TEST_LAUNCHER);
@@ -151,6 +134,21 @@
}
}
};
+
+ final ViewCaptureRule viewCaptureRule = new ViewCaptureRule(
+ RecentsActivity.ACTIVITY_TRACKER::getCreatedActivity);
+ mOrderSensitiveRules = RuleChain
+ .outerRule(new SamplerRule())
+ .around(new NavigationModeSwitchRule(mLauncher))
+ .around(new FailureWatcher(mLauncher, viewCaptureRule::getViewCaptureData))
+ .around(viewCaptureRule)
+ .around(new TestIsolationRule(mLauncher))
+ .around(setLauncherCommand);
+
+ mOtherLauncherActivity = context.getPackageManager().queryIntentActivities(
+ getHomeIntentInPackage(context),
+ MATCH_DISABLED_COMPONENTS).get(0).activityInfo;
+
if (TestHelpers.isInLauncherProcess()) {
mLauncher.setSystemHealthSupplier(startTime -> TestCommandReceiver.callCommand(
TestCommandReceiver.GET_SYSTEM_HEALTH_MESSAGE, startTime.toString()).
diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml
index ee7805f..333fded 100644
--- a/res/values-et/strings.xml
+++ b/res/values-et/strings.xml
@@ -35,7 +35,7 @@
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d lai ja %2$d kõrge"</string>
<string name="widget_preview_context_description" msgid="9045841361655787574">"Vidin <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
- <string name="add_item_request_drag_hint" msgid="8730547755622776606">"Vidina teisaldamiseks avakuval puudutage vidinat ja hoidke seda all"</string>
+ <string name="add_item_request_drag_hint" msgid="8730547755622776606">"Vidina teisaldamiseks avakuval puudutage vidinat pikalt"</string>
<string name="add_to_home_screen" msgid="9168649446635919791">"Lisa avakuvale"</string>
<string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"Vidin <xliff:g id="WIDGET_NAME">%1$s</xliff:g> lisati avakuvale"</string>
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Soovitused"</string>
diff --git a/res/values-kn/strings.xml b/res/values-kn/strings.xml
index 72ab9b2..a35a70b 100644
--- a/res/values-kn/strings.xml
+++ b/res/values-kn/strings.xml
@@ -61,7 +61,7 @@
<string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" ಹೊಂದಿಕೆಯ ಯಾವುದೇ ಅಪ್ಲಿಕೇಶನ್ಗಳು ಕಂಡುಬಂದಿಲ್ಲ"</string>
<string name="label_application" msgid="8531721983832654978">"ಆ್ಯಪ್"</string>
<string name="all_apps_label" msgid="5015784846527570951">"ಎಲ್ಲಾ ಆ್ಯಪ್ಗಳು"</string>
- <string name="notifications_header" msgid="1404149926117359025">"ಅಧಿಸೂಚನೆಗಳು"</string>
+ <string name="notifications_header" msgid="1404149926117359025">"ನೋಟಿಫಿಕೇಶನ್ಗಳು"</string>
<string name="long_press_shortcut_to_add" msgid="5405328730817637737">"ಶಾರ್ಟ್ಕಟ್ ಸರಿಸಲು ಸ್ಪರ್ಶಿಸಿ ಮತ್ತು ಹಿಡಿದುಕೊಳ್ಳಿ."</string>
<string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"ಶಾರ್ಟ್ಕಟ್ ಸರಿಸಲು ಅಥವಾ ಕಸ್ಟಮ್ ಕ್ರಿಯೆಗಳನ್ನು ಬಳಸಲು ಡಬಲ್-ಟ್ಯಾಪ್ ಮಾಡಿ ಮತ್ತು ಹಿಡಿದುಕೊಳ್ಳಿ."</string>
<string name="out_of_space" msgid="6455557115204099579">"ಈ ಹೋಮ್ ಸ್ಕ್ರೀನ್ನಲ್ಲಿ ಸ್ಥಳಾವಕಾಶವಿಲ್ಲ"</string>
diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml
index 54cc691..c73295d 100644
--- a/res/values-mr/strings.xml
+++ b/res/values-mr/strings.xml
@@ -35,7 +35,7 @@
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d रूंद बाय %2$d उंच"</string>
<string name="widget_preview_context_description" msgid="9045841361655787574">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> विजेट"</string>
- <string name="add_item_request_drag_hint" msgid="8730547755622776606">"होम स्क्रीनवर ते हलवण्यासाठी विजेटला स्पर्श करा आणि धरून ठेवा"</string>
+ <string name="add_item_request_drag_hint" msgid="8730547755622776606">"होम स्क्रीनवर हलवण्यासाठी विजेटला स्पर्श करून धरून ठेवा"</string>
<string name="add_to_home_screen" msgid="9168649446635919791">"होम स्क्रीनवर जोडा"</string>
<string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> हे विजेट तुमच्या होम स्क्रीनवर जोडले आहे"</string>
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"सूचना"</string>
diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml
index 3cc6bff..0f0960e 100644
--- a/res/values-zh-rHK/strings.xml
+++ b/res/values-zh-rHK/strings.xml
@@ -104,7 +104,7 @@
<string name="settings_button_text" msgid="8873672322605444408">"主畫面設定"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"已由你的管理員停用"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"允許旋轉主畫面"</string>
- <string name="allow_rotation_desc" msgid="8662546029078692509">"當手機旋轉時"</string>
+ <string name="allow_rotation_desc" msgid="8662546029078692509">"隨手機旋轉"</string>
<string name="notification_dots_title" msgid="9062440428204120317">"通知圓點"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"開啟"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"關閉"</string>
diff --git a/src/com/android/launcher3/AppWidgetsRestoredReceiver.java b/src/com/android/launcher3/AppWidgetsRestoredReceiver.java
index 55b8fcc..ec874b9 100644
--- a/src/com/android/launcher3/AppWidgetsRestoredReceiver.java
+++ b/src/com/android/launcher3/AppWidgetsRestoredReceiver.java
@@ -1,12 +1,28 @@
package com.android.launcher3;
+import static android.os.Process.myUserHandle;
+
+import android.appwidget.AppWidgetHost;
import android.appwidget.AppWidgetManager;
+import android.appwidget.AppWidgetProviderInfo;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
+import android.database.Cursor;
import android.util.Log;
+import androidx.annotation.NonNull;
+import androidx.annotation.WorkerThread;
+
+import com.android.launcher3.LauncherSettings.Favorites;
+import com.android.launcher3.model.LoaderTask;
+import com.android.launcher3.model.ModelDbController;
+import com.android.launcher3.model.WidgetsModel;
+import com.android.launcher3.model.data.LauncherAppWidgetInfo;
+import com.android.launcher3.pm.UserCache;
import com.android.launcher3.provider.RestoreDbTask;
+import com.android.launcher3.util.ContentWriter;
+import com.android.launcher3.util.IntArray;
import com.android.launcher3.widget.LauncherWidgetHolder;
public class AppWidgetsRestoredReceiver extends BroadcastReceiver {
@@ -31,4 +47,131 @@
}
}
}
-}
\ No newline at end of file
+
+ /**
+ * Updates the app widgets whose id has changed during the restore process.
+ */
+ @WorkerThread
+ public static void restoreAppWidgetIds(Context context, ModelDbController controller,
+ int[] oldWidgetIds, int[] newWidgetIds, @NonNull AppWidgetHost host) {
+ if (WidgetsModel.GO_DISABLE_WIDGETS) {
+ Log.e(TAG, "Skipping widget ID remap as widgets not supported");
+ host.deleteHost();
+ return;
+ }
+ if (!RestoreDbTask.isPending(context)) {
+ // Someone has already gone through our DB once, probably LoaderTask. Skip any further
+ // modifications of the DB.
+ Log.e(TAG, "Skipping widget ID remap as DB already in use");
+ for (int widgetId : newWidgetIds) {
+ Log.d(TAG, "Deleting widgetId: " + widgetId);
+ host.deleteAppWidgetId(widgetId);
+ }
+ return;
+ }
+
+ final AppWidgetManager widgets = AppWidgetManager.getInstance(context);
+
+ Log.d(TAG, "restoreAppWidgetIds: "
+ + "oldWidgetIds=" + IntArray.wrap(oldWidgetIds).toConcatString()
+ + ", newWidgetIds=" + IntArray.wrap(newWidgetIds).toConcatString());
+
+ // TODO(b/234700507): Remove the logs after the bug is fixed
+ logDatabaseWidgetInfo(controller);
+
+ for (int i = 0; i < oldWidgetIds.length; i++) {
+ Log.i(TAG, "Widget state restore id " + oldWidgetIds[i] + " => " + newWidgetIds[i]);
+
+ final AppWidgetProviderInfo provider = widgets.getAppWidgetInfo(newWidgetIds[i]);
+ final int state;
+ if (LoaderTask.isValidProvider(provider)) {
+ // This will ensure that we show 'Click to setup' UI if required.
+ state = LauncherAppWidgetInfo.FLAG_UI_NOT_READY;
+ } else {
+ state = LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY;
+ }
+
+ // b/135926478: Work profile widget restore is broken in platform. This forces us to
+ // recreate the widget during loading with the correct host provider.
+ long mainProfileId = UserCache.INSTANCE.get(context)
+ .getSerialNumberForUser(myUserHandle());
+ long controllerProfileId = controller.getSerialNumberForUser(myUserHandle());
+ String oldWidgetId = Integer.toString(oldWidgetIds[i]);
+ final String where = "appWidgetId=? and (restored & 1) = 1 and profileId=?";
+ String profileId = Long.toString(mainProfileId);
+ final String[] args = new String[] { oldWidgetId, profileId };
+ Log.d(TAG, "restoreAppWidgetIds: querying profile id=" + profileId
+ + " with controller profile ID=" + controllerProfileId);
+ int result = new ContentWriter(context,
+ new ContentWriter.CommitParams(controller, where, args))
+ .put(LauncherSettings.Favorites.APPWIDGET_ID, newWidgetIds[i])
+ .put(LauncherSettings.Favorites.RESTORED, state)
+ .commit();
+ if (result == 0) {
+ // TODO(b/234700507): Remove the logs after the bug is fixed
+ Log.e(TAG, "restoreAppWidgetIds: remapping failed since the widget is not in"
+ + " the database anymore");
+ try (Cursor cursor = controller.getDb().query(
+ Favorites.TABLE_NAME,
+ new String[]{Favorites.APPWIDGET_ID},
+ "appWidgetId=?", new String[]{oldWidgetId}, null, null, null)) {
+ if (!cursor.moveToFirst()) {
+ // The widget no long exists.
+ Log.d(TAG, "Deleting widgetId: " + newWidgetIds[i] + " with old id: "
+ + oldWidgetId);
+ host.deleteAppWidgetId(newWidgetIds[i]);
+ }
+ }
+ }
+ }
+
+ LauncherAppState app = LauncherAppState.getInstanceNoCreate();
+ if (app != null) {
+ app.getModel().forceReload();
+ }
+ }
+
+ private static void logDatabaseWidgetInfo(ModelDbController controller) {
+ try (Cursor cursor = controller.getDb().query(Favorites.TABLE_NAME,
+ new String[]{Favorites.APPWIDGET_ID, Favorites.RESTORED, Favorites.PROFILE_ID},
+ Favorites.APPWIDGET_ID + "!=" + LauncherAppWidgetInfo.NO_ID, null,
+ null, null, null)) {
+ IntArray widgetIdList = new IntArray();
+ IntArray widgetRestoreList = new IntArray();
+ IntArray widgetProfileIdList = new IntArray();
+
+ if (cursor.moveToFirst()) {
+ final int widgetIdColumnIndex = cursor.getColumnIndex(Favorites.APPWIDGET_ID);
+ final int widgetRestoredColumnIndex = cursor.getColumnIndex(Favorites.RESTORED);
+ final int widgetProfileIdIndex = cursor.getColumnIndex(Favorites.PROFILE_ID);
+ while (!cursor.isAfterLast()) {
+ int widgetId = cursor.getInt(widgetIdColumnIndex);
+ int widgetRestoredFlag = cursor.getInt(widgetRestoredColumnIndex);
+ int widgetProfileId = cursor.getInt(widgetProfileIdIndex);
+
+ widgetIdList.add(widgetId);
+ widgetRestoreList.add(widgetRestoredFlag);
+ widgetProfileIdList.add(widgetProfileId);
+ cursor.moveToNext();
+ }
+ }
+
+ StringBuilder builder = new StringBuilder();
+ builder.append("[");
+ for (int i = 0; i < widgetIdList.size(); i++) {
+ builder.append("[")
+ .append(widgetIdList.get(i))
+ .append(", ")
+ .append(widgetRestoreList.get(i))
+ .append(", ")
+ .append(widgetProfileIdList.get(i))
+ .append("]");
+ }
+ builder.append("]");
+ Log.d(TAG, "restoreAppWidgetIds: all widget ids in database: "
+ + builder.toString());
+ } catch (Exception ex) {
+ Log.e(TAG, "Getting widget ids from the database failed", ex);
+ }
+ }
+}
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index e7d1db4..cde3536 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -1715,7 +1715,7 @@
/** Gets the space that the overview actions will take, including bottom margin. */
public int getOverviewActionsClaimedSpace() {
- int overviewActionsSpace = isTablet && FeatureFlags.ENABLE_GRID_ONLY_OVERVIEW.get()
+ int overviewActionsSpace = isTablet && FeatureFlags.enableGridOnlyOverview()
? 0
: (overviewActionsTopMarginPx + overviewActionsHeight);
return overviewActionsSpace + getOverviewActionsClaimedSpaceBelow();
diff --git a/src/com/android/launcher3/FastScrollRecyclerView.java b/src/com/android/launcher3/FastScrollRecyclerView.java
index c16b319..67ed55d 100644
--- a/src/com/android/launcher3/FastScrollRecyclerView.java
+++ b/src/com/android/launcher3/FastScrollRecyclerView.java
@@ -16,6 +16,8 @@
package com.android.launcher3;
+import static com.android.launcher3.testing.shared.TestProtocol.SCROLL_FINISHED_MESSAGE;
+
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
@@ -170,7 +172,8 @@
super.onScrollStateChanged(state);
if (state == SCROLL_STATE_IDLE) {
- AccessibilityManagerCompat.sendScrollFinishedEventToTest(getContext());
+ AccessibilityManagerCompat.sendTestProtocolEventToTest(getContext(),
+ SCROLL_FINISHED_MESSAGE);
}
}
diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java
index e3de79e..c619bc5 100644
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -18,7 +18,6 @@
import static com.android.launcher3.LauncherPrefs.GRID_NAME;
import static com.android.launcher3.Utilities.dpiFromPx;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_TWO_PANEL_HOME;
import static com.android.launcher3.testing.shared.ResourceUtils.INVALID_RESOURCE_HANDLE;
import static com.android.launcher3.util.DisplayController.CHANGE_DENSITY;
import static com.android.launcher3.util.DisplayController.CHANGE_NAVIGATION_MODE;
@@ -316,7 +315,7 @@
int type = displayInfo.supportedBounds.stream()
.mapToInt(bounds -> displayInfo.isTablet(bounds) ? flagTablet : flagPhone)
.reduce(0, (a, b) -> a | b);
- if ((type == (flagPhone | flagTablet)) && ENABLE_TWO_PANEL_HOME.get()) {
+ if (type == (flagPhone | flagTablet)) {
// device has profiles supporting both phone and table modes
return TYPE_MULTI_DISPLAY;
} else if (type == flagTablet) {
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index 4b4a4a5..5ce88a3 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -19,6 +19,7 @@
import static com.android.app.animation.Interpolators.SCROLL;
import static com.android.launcher3.compat.AccessibilityManagerCompat.isAccessibilityEnabled;
import static com.android.launcher3.compat.AccessibilityManagerCompat.isObservedEventType;
+import static com.android.launcher3.testing.shared.TestProtocol.SCROLL_FINISHED_MESSAGE;
import static com.android.launcher3.touch.OverScroll.OVERSCROLL_DAMP_FACTOR;
import static com.android.launcher3.touch.PagedOrientationHandler.VIEW_SCROLL_BY;
import static com.android.launcher3.touch.PagedOrientationHandler.VIEW_SCROLL_TO;
@@ -492,7 +493,8 @@
*/
protected void onPageEndTransition() {
mCurrentPageScrollDiff = 0;
- AccessibilityManagerCompat.sendScrollFinishedEventToTest(getContext());
+ AccessibilityManagerCompat.sendTestProtocolEventToTest(getContext(),
+ SCROLL_FINISHED_MESSAGE);
AccessibilityManagerCompat.sendCustomAccessibilityEvent(getPageAt(mCurrentPage),
AccessibilityEvent.TYPE_VIEW_FOCUSED, null);
if (mOnPageTransitionEndCallback != null) {
diff --git a/src/com/android/launcher3/allapps/WorkModeSwitch.java b/src/com/android/launcher3/allapps/WorkModeSwitch.java
index 28a3312..144381c 100644
--- a/src/com/android/launcher3/allapps/WorkModeSwitch.java
+++ b/src/com/android/launcher3/allapps/WorkModeSwitch.java
@@ -17,7 +17,6 @@
import static com.android.launcher3.workprofile.PersonalWorkSlidingTabStrip.getTabWidth;
-import android.animation.LayoutTransition;
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
@@ -92,8 +91,6 @@
setInsets(mActivityContext.getDeviceProfile().getInsets());
updateStringFromCache();
-
- getLayoutTransition().enableTransitionType(LayoutTransition.CHANGING);
}
@Override
diff --git a/src/com/android/launcher3/compat/AccessibilityManagerCompat.java b/src/com/android/launcher3/compat/AccessibilityManagerCompat.java
index 24cc0ac..d37b1f0 100644
--- a/src/com/android/launcher3/compat/AccessibilityManagerCompat.java
+++ b/src/com/android/launcher3/compat/AccessibilityManagerCompat.java
@@ -74,38 +74,12 @@
Log.d(TestProtocol.PERMANENT_DIAG_TAG, "sendStateEventToTest: " + stateOrdinal);
}
- public static void sendScrollFinishedEventToTest(Context context) {
+ public static void sendTestProtocolEventToTest(Context context, String testProtocolEvent) {
final AccessibilityManager accessibilityManager = getAccessibilityManagerForTest(context);
if (accessibilityManager == null) return;
- sendEventToTest(accessibilityManager, context, TestProtocol.SCROLL_FINISHED_MESSAGE, null);
+ sendEventToTest(accessibilityManager, context, testProtocolEvent, null);
}
-
- public static void sendPauseDetectedEventToTest(Context context) {
- final AccessibilityManager accessibilityManager = getAccessibilityManagerForTest(context);
- if (accessibilityManager == null) return;
-
- sendEventToTest(accessibilityManager, context, TestProtocol.PAUSE_DETECTED_MESSAGE, null);
- }
-
- public static void sendDismissAnimationEndsEventToTest(Context context) {
- final AccessibilityManager accessibilityManager = getAccessibilityManagerForTest(context);
- if (accessibilityManager == null) return;
-
- sendEventToTest(accessibilityManager, context, TestProtocol.DISMISS_ANIMATION_ENDS_MESSAGE,
- null);
- }
-
- /**
- * Notify running tests of a folder opened.
- */
- public static void sendFolderOpenedEventToTest(Context context) {
- final AccessibilityManager accessibilityManager = getAccessibilityManagerForTest(context);
- if (accessibilityManager == null) return;
-
- sendEventToTest(accessibilityManager, context, TestProtocol.FOLDER_OPENED_MESSAGE, null);
- }
-
private static void sendEventToTest(
AccessibilityManager accessibilityManager,
Context context, String eventTag, Bundle data) {
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 8a887a0..a136ef0 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -27,6 +27,7 @@
import androidx.annotation.VisibleForTesting;
import com.android.launcher3.BuildConfig;
+import com.android.launcher3.Flags;
import com.android.launcher3.Utilities;
import java.util.function.Predicate;
@@ -184,16 +185,8 @@
"Enables predictive back animation from all apps and widgets to home");
// TODO(Block 11): Clean up flags
- public static final BooleanFlag ENABLE_TWO_PANEL_HOME = getDebugFlag(270392643,
- "ENABLE_TWO_PANEL_HOME", ENABLED,
- "Uses two panel on home screen. Only applicable on large screen devices.");
-
- public static final BooleanFlag FOLDABLE_WORKSPACE_REORDER = getDebugFlag(270395070,
- "FOLDABLE_WORKSPACE_REORDER", DISABLED,
- "In foldables, when reordering the icons and widgets, is now going to use both sides");
-
public static final BooleanFlag FOLDABLE_SINGLE_PAGE = getDebugFlag(270395274,
- "FOLDABLE_SINGLE_PAGE", ENABLED, "Use a single page for the workspace");
+ "FOLDABLE_SINGLE_PAGE", DISABLED, "Use a single page for the workspace");
public static final BooleanFlag ENABLE_PARAMETRIZE_REORDER = getDebugFlag(289420844,
"ENABLE_PARAMETRIZE_REORDER", DISABLED,
@@ -315,9 +308,14 @@
+ "start receiving the events");
// TODO(Block 23): Clean up flags
+ // Aconfig migration complete for ENABLE_GRID_ONLY_OVERVIEW.
+ @VisibleForTesting
public static final BooleanFlag ENABLE_GRID_ONLY_OVERVIEW = getDebugFlag(270397206,
"ENABLE_GRID_ONLY_OVERVIEW", TEAMFOOD,
"Enable a grid-only overview without a focused task.");
+ public static boolean enableGridOnlyOverview() {
+ return ENABLE_GRID_ONLY_OVERVIEW.get() || Flags.enableGridOnlyOverview();
+ }
public static final BooleanFlag ENABLE_CURSOR_HOVER_STATES = getDebugFlag(243191650,
"ENABLE_CURSOR_HOVER_STATES", TEAMFOOD,
diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java
index 55a539a..fc36ce6 100644
--- a/src/com/android/launcher3/folder/Folder.java
+++ b/src/com/android/launcher3/folder/Folder.java
@@ -25,6 +25,7 @@
import static com.android.launcher3.config.FeatureFlags.ALWAYS_USE_HARDWARE_OPTIMIZATION_FOR_FOLDER_ANIMATIONS;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_FOLDER_LABEL_UPDATED;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ITEM_DROP_COMPLETED;
+import static com.android.launcher3.testing.shared.TestProtocol.FOLDER_OPENED_MESSAGE;
import static com.android.launcher3.util.window.RefreshRateTracker.getSingleFrameMs;
import android.animation.Animator;
@@ -692,7 +693,8 @@
public void onAnimationEnd(Animator animation) {
setState(STATE_OPEN);
announceAccessibilityChanges();
- AccessibilityManagerCompat.sendFolderOpenedEventToTest(getContext());
+ AccessibilityManagerCompat.sendTestProtocolEventToTest(getContext(),
+ FOLDER_OPENED_MESSAGE);
mContent.setFocusOnFirstChild();
}
diff --git a/src/com/android/launcher3/provider/RestoreDbTask.java b/src/com/android/launcher3/provider/RestoreDbTask.java
index 10005e5..4725dd1 100644
--- a/src/com/android/launcher3/provider/RestoreDbTask.java
+++ b/src/com/android/launcher3/provider/RestoreDbTask.java
@@ -28,8 +28,6 @@
import android.app.backup.BackupManager;
import android.appwidget.AppWidgetHost;
-import android.appwidget.AppWidgetManager;
-import android.appwidget.AppWidgetProviderInfo;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
@@ -44,26 +42,20 @@
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
-import androidx.annotation.WorkerThread;
+import com.android.launcher3.AppWidgetsRestoredReceiver;
import com.android.launcher3.InvariantDeviceProfile;
-import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherPrefs;
-import com.android.launcher3.LauncherSettings;
import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.Utilities;
import com.android.launcher3.logging.FileLog;
import com.android.launcher3.model.DeviceGridState;
-import com.android.launcher3.model.LoaderTask;
import com.android.launcher3.model.ModelDbController;
-import com.android.launcher3.model.WidgetsModel;
import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
-import com.android.launcher3.pm.UserCache;
import com.android.launcher3.provider.LauncherDbUtils.SQLiteTransaction;
import com.android.launcher3.uioverrides.ApiWrapper;
-import com.android.launcher3.util.ContentWriter;
import com.android.launcher3.util.IntArray;
import com.android.launcher3.util.LogConfig;
@@ -385,13 +377,11 @@
.putSync(RESTORE_DEVICE.to(new DeviceGridState(context).getDeviceType()));
}
- @WorkerThread
- @VisibleForTesting
- void restoreAppWidgetIdsIfExists(Context context, ModelDbController controller) {
+ private void restoreAppWidgetIdsIfExists(Context context, ModelDbController controller) {
LauncherPrefs lp = LauncherPrefs.get(context);
if (lp.has(APP_WIDGET_IDS, OLD_APP_WIDGET_IDS)) {
AppWidgetHost host = new AppWidgetHost(context, APPWIDGET_HOST_ID);
- restoreAppWidgetIds(context, controller,
+ AppWidgetsRestoredReceiver.restoreAppWidgetIds(context, controller,
IntArray.fromConcatString(lp.get(OLD_APP_WIDGET_IDS)).toArray(),
IntArray.fromConcatString(lp.get(APP_WIDGET_IDS)).toArray(),
host);
@@ -402,133 +392,6 @@
lp.remove(APP_WIDGET_IDS, OLD_APP_WIDGET_IDS);
}
- /**
- * Updates the app widgets whose id has changed during the restore process.
- */
- @WorkerThread
- private void restoreAppWidgetIds(Context context, ModelDbController controller,
- int[] oldWidgetIds, int[] newWidgetIds, @NonNull AppWidgetHost host) {
- if (WidgetsModel.GO_DISABLE_WIDGETS) {
- Log.e(TAG, "Skipping widget ID remap as widgets not supported");
- host.deleteHost();
- return;
- }
- if (!RestoreDbTask.isPending(context)) {
- // Someone has already gone through our DB once, probably LoaderTask. Skip any further
- // modifications of the DB.
- Log.e(TAG, "Skipping widget ID remap as DB already in use");
- for (int widgetId : newWidgetIds) {
- Log.d(TAG, "Deleting widgetId: " + widgetId);
- host.deleteAppWidgetId(widgetId);
- }
- return;
- }
-
- final AppWidgetManager widgets = AppWidgetManager.getInstance(context);
-
- Log.d(TAG, "restoreAppWidgetIds: "
- + "oldWidgetIds=" + IntArray.wrap(oldWidgetIds).toConcatString()
- + ", newWidgetIds=" + IntArray.wrap(newWidgetIds).toConcatString());
-
- // TODO(b/234700507): Remove the logs after the bug is fixed
- logDatabaseWidgetInfo(controller);
-
- for (int i = 0; i < oldWidgetIds.length; i++) {
- Log.i(TAG, "Widget state restore id " + oldWidgetIds[i] + " => " + newWidgetIds[i]);
-
- final AppWidgetProviderInfo provider = widgets.getAppWidgetInfo(newWidgetIds[i]);
- final int state;
- if (LoaderTask.isValidProvider(provider)) {
- // This will ensure that we show 'Click to setup' UI if required.
- state = LauncherAppWidgetInfo.FLAG_UI_NOT_READY;
- } else {
- state = LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY;
- }
-
- // b/135926478: Work profile widget restore is broken in platform. This forces us to
- // recreate the widget during loading with the correct host provider.
- long mainProfileId = UserCache.INSTANCE.get(context)
- .getSerialNumberForUser(myUserHandle());
- long controllerProfileId = controller.getSerialNumberForUser(myUserHandle());
- String oldWidgetId = Integer.toString(oldWidgetIds[i]);
- final String where = "appWidgetId=? and (restored & 1) = 1 and profileId=?";
- String profileId = Long.toString(mainProfileId);
- final String[] args = new String[] { oldWidgetId, profileId };
- Log.d(TAG, "restoreAppWidgetIds: querying profile id=" + profileId
- + " with controller profile ID=" + controllerProfileId);
- int result = new ContentWriter(context,
- new ContentWriter.CommitParams(controller, where, args))
- .put(LauncherSettings.Favorites.APPWIDGET_ID, newWidgetIds[i])
- .put(LauncherSettings.Favorites.RESTORED, state)
- .commit();
- if (result == 0) {
- // TODO(b/234700507): Remove the logs after the bug is fixed
- Log.e(TAG, "restoreAppWidgetIds: remapping failed since the widget is not in"
- + " the database anymore");
- try (Cursor cursor = controller.getDb().query(
- Favorites.TABLE_NAME,
- new String[]{Favorites.APPWIDGET_ID},
- "appWidgetId=?", new String[]{oldWidgetId}, null, null, null)) {
- if (!cursor.moveToFirst()) {
- // The widget no long exists.
- Log.d(TAG, "Deleting widgetId: " + newWidgetIds[i] + " with old id: "
- + oldWidgetId);
- host.deleteAppWidgetId(newWidgetIds[i]);
- }
- }
- }
- }
-
- LauncherAppState app = LauncherAppState.getInstanceNoCreate();
- if (app != null) {
- app.getModel().forceReload();
- }
- }
-
- private static void logDatabaseWidgetInfo(ModelDbController controller) {
- try (Cursor cursor = controller.getDb().query(Favorites.TABLE_NAME,
- new String[]{Favorites.APPWIDGET_ID, Favorites.RESTORED, Favorites.PROFILE_ID},
- Favorites.APPWIDGET_ID + "!=" + LauncherAppWidgetInfo.NO_ID, null,
- null, null, null)) {
- IntArray widgetIdList = new IntArray();
- IntArray widgetRestoreList = new IntArray();
- IntArray widgetProfileIdList = new IntArray();
-
- if (cursor.moveToFirst()) {
- final int widgetIdColumnIndex = cursor.getColumnIndex(Favorites.APPWIDGET_ID);
- final int widgetRestoredColumnIndex = cursor.getColumnIndex(Favorites.RESTORED);
- final int widgetProfileIdIndex = cursor.getColumnIndex(Favorites.PROFILE_ID);
- while (!cursor.isAfterLast()) {
- int widgetId = cursor.getInt(widgetIdColumnIndex);
- int widgetRestoredFlag = cursor.getInt(widgetRestoredColumnIndex);
- int widgetProfileId = cursor.getInt(widgetProfileIdIndex);
-
- widgetIdList.add(widgetId);
- widgetRestoreList.add(widgetRestoredFlag);
- widgetProfileIdList.add(widgetProfileId);
- cursor.moveToNext();
- }
- }
-
- StringBuilder builder = new StringBuilder();
- builder.append("[");
- for (int i = 0; i < widgetIdList.size(); i++) {
- builder.append("[")
- .append(widgetIdList.get(i))
- .append(", ")
- .append(widgetRestoreList.get(i))
- .append(", ")
- .append(widgetProfileIdList.get(i))
- .append("]");
- }
- builder.append("]");
- Log.d(TAG, "restoreAppWidgetIds: all widget ids in database: "
- + builder.toString());
- } catch (Exception ex) {
- Log.e(TAG, "Getting widget ids from the database failed", ex);
- }
- }
-
public static void setRestoredAppWidgetIds(Context context, @NonNull int[] oldIds,
@NonNull int[] newIds) {
LauncherPrefs.get(context).putSync(
diff --git a/src/com/android/launcher3/testing/TestInformationHandler.java b/src/com/android/launcher3/testing/TestInformationHandler.java
index 07a1b82..a75f326 100644
--- a/src/com/android/launcher3/testing/TestInformationHandler.java
+++ b/src/com/android/launcher3/testing/TestInformationHandler.java
@@ -16,7 +16,7 @@
package com.android.launcher3.testing;
import static com.android.launcher3.allapps.AllAppsStore.DEFER_UPDATES_TEST;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_GRID_ONLY_OVERVIEW;
+import static com.android.launcher3.config.FeatureFlags.enableGridOnlyOverview;
import static com.android.launcher3.config.FeatureFlags.FOLDABLE_SINGLE_PAGE;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
@@ -32,6 +32,7 @@
import android.view.WindowInsets;
import androidx.annotation.Nullable;
+import androidx.core.view.WindowInsetsCompat;
import com.android.launcher3.CellLayout;
import com.android.launcher3.DeviceProfile;
@@ -142,6 +143,14 @@
}, this::getCurrentActivity);
}
+ case TestProtocol.REQUEST_IME_INSETS: {
+ return getUIProperty(Bundle::putParcelable, activity -> {
+ WindowInsetsCompat insets = WindowInsetsCompat.toWindowInsetsCompat(
+ activity.getWindow().getDecorView().getRootWindowInsets());
+ return insets.getInsets(WindowInsetsCompat.Type.ime()).toPlatformInsets();
+ }, this::getCurrentActivity);
+ }
+
case TestProtocol.REQUEST_ICON_HEIGHT: {
response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD,
mDeviceProfile.allAppsCellHeightPx);
@@ -249,7 +258,7 @@
case TestProtocol.REQUEST_FLAG_ENABLE_GRID_ONLY_OVERVIEW: {
response.putBoolean(TestProtocol.TEST_INFO_RESPONSE_FIELD,
- ENABLE_GRID_ONLY_OVERVIEW.get());
+ enableGridOnlyOverview());
return response;
}
diff --git a/tests/Android.bp b/tests/Android.bp
index d45e9eb..9bb8787 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -55,6 +55,7 @@
"src/com/android/launcher3/util/rule/SamplerRule.java",
"src/com/android/launcher3/util/rule/ScreenRecordRule.java",
"src/com/android/launcher3/util/rule/ShellCommandRule.java",
+ "src/com/android/launcher3/util/rule/TestIsolationRule.java",
"src/com/android/launcher3/util/rule/TestStabilityRule.java",
"src/com/android/launcher3/util/rule/TISBindRule.java",
"src/com/android/launcher3/util/viewcapture_analysis/*.java",
diff --git a/tests/shared/com/android/launcher3/testing/shared/TestProtocol.java b/tests/shared/com/android/launcher3/testing/shared/TestProtocol.java
index 9c95397..30ec5cc 100644
--- a/tests/shared/com/android/launcher3/testing/shared/TestProtocol.java
+++ b/tests/shared/com/android/launcher3/testing/shared/TestProtocol.java
@@ -28,6 +28,7 @@
public static final String PAUSE_DETECTED_MESSAGE = "TAPL_PAUSE_DETECTED";
public static final String DISMISS_ANIMATION_ENDS_MESSAGE = "TAPL_DISMISS_ANIMATION_ENDS";
public static final String FOLDER_OPENED_MESSAGE = "TAPL_FOLDER_OPENED";
+ public static final String SEARCH_RESULT_COMPLETE = "SEARCH_RESULT_COMPLETE";
public static final int NORMAL_STATE_ORDINAL = 0;
public static final int SPRING_LOADED_STATE_ORDINAL = 1;
public static final int OVERVIEW_STATE_ORDINAL = 2;
@@ -102,6 +103,7 @@
public static final String REQUEST_WIDGETS_SCROLL_Y = "widgets-scroll-y";
public static final String REQUEST_TARGET_INSETS = "target-insets";
public static final String REQUEST_WINDOW_INSETS = "window-insets";
+ public static final String REQUEST_IME_INSETS = "ime-insets";
public static final String REQUEST_PID = "pid";
public static final String REQUEST_FORCE_GC = "gc";
public static final String REQUEST_RECENT_TASKS_LIST = "recent-tasks-list";
diff --git a/tests/src/com/android/launcher3/provider/RestoreDbTaskTest.java b/tests/src/com/android/launcher3/provider/RestoreDbTaskTest.java
index 15f6177..73bb586 100644
--- a/tests/src/com/android/launcher3/provider/RestoreDbTaskTest.java
+++ b/tests/src/com/android/launcher3/provider/RestoreDbTaskTest.java
@@ -19,30 +19,17 @@
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
-import static com.android.launcher3.LauncherPrefs.APP_WIDGET_IDS;
-import static com.android.launcher3.LauncherPrefs.OLD_APP_WIDGET_IDS;
-import static com.android.launcher3.LauncherPrefs.RESTORE_DEVICE;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_DESKTOP;
import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
import static com.android.launcher3.LauncherSettings.Favorites.TABLE_NAME;
-import static com.android.launcher3.widget.LauncherWidgetHolder.APPWIDGET_HOST_ID;
-
-import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
-import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.mockito.Mockito.when;
import android.app.backup.BackupManager;
-import android.appwidget.AppWidgetHost;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
@@ -56,7 +43,6 @@
import androidx.test.filters.SmallTest;
import com.android.launcher3.LauncherAppState;
-import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.model.ModelDbController;
@@ -66,10 +52,6 @@
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.Mockito;
-
-import java.util.Arrays;
-import java.util.stream.IntStream;
/**
* Tests for {@link RestoreDbTask}
@@ -84,21 +66,11 @@
private LauncherModelHelper mModelHelper;
private Context mContext;
- private RestoreDbTask mTask;
- private ModelDbController mMockController;
- private SQLiteDatabase mMockDb;
- private Cursor mMockCursor;
- private LauncherPrefs mPrefs;
@Before
public void setup() {
mModelHelper = new LauncherModelHelper();
mContext = mModelHelper.sandboxContext;
- mTask = new RestoreDbTask();
- mMockController = Mockito.mock(ModelDbController.class);
- mMockDb = mock(SQLiteDatabase.class);
- mMockCursor = mock(Cursor.class);
- mPrefs = new LauncherPrefs(mContext);
}
@After
@@ -176,7 +148,8 @@
assertEquals(10, getItemCountForProfile(db, myProfileId_old));
assertEquals(6, getItemCountForProfile(db, workProfileId_old));
- mTask.sanitizeDB(mContext, controller, controller.getDb(), bm);
+ RestoreDbTask task = new RestoreDbTask();
+ task.sanitizeDB(mContext, controller, controller.getDb(), bm);
// All the data has been migrated to the new user ids
assertEquals(0, getItemCountForProfile(db, myProfileId_old));
@@ -205,7 +178,8 @@
assertEquals(10, getItemCountForProfile(db, myProfileId_old));
assertEquals(6, getItemCountForProfile(db, workProfileId_old));
- mTask.sanitizeDB(mContext, controller, controller.getDb(), bm);
+ RestoreDbTask task = new RestoreDbTask();
+ task.sanitizeDB(mContext, controller, controller.getDb(), bm);
// All the data has been migrated to the new user ids
assertEquals(0, getItemCountForProfile(db, myProfileId_old));
@@ -214,83 +188,6 @@
assertEquals(10, getCount(db, "select * from favorites"));
}
- @Test
- public void givenLauncherPrefsHasNoIds_whenRestoreAppWidgetIdsIfExists_thenIdsAreRemoved() {
- // When
- mTask.restoreAppWidgetIdsIfExists(mContext, mMockController);
- // Then
- assertThat(mPrefs.has(OLD_APP_WIDGET_IDS, APP_WIDGET_IDS)).isFalse();
- }
-
- @Test
- public void givenNoPendingRestore_WhenRestoreAppWidgetIds_ThenRemoveNewWidgetIds() {
- // Given
- AppWidgetHost expectedHost = new AppWidgetHost(mContext, APPWIDGET_HOST_ID);
- int[] expectedOldIds = generateOldWidgetIds(expectedHost);
- int[] expectedNewIds = generateNewWidgetIds(expectedHost, expectedOldIds);
- when(mMockController.getDb()).thenReturn(mMockDb);
- mPrefs.remove(RESTORE_DEVICE);
-
- // When
- RestoreDbTask.setRestoredAppWidgetIds(mContext, expectedOldIds, expectedNewIds);
- mTask.restoreAppWidgetIdsIfExists(mContext, mMockController);
-
- // Then
- assertThat(expectedHost.getAppWidgetIds()).isEqualTo(expectedOldIds);
- assertThat(mPrefs.has(OLD_APP_WIDGET_IDS, APP_WIDGET_IDS)).isFalse();
- verifyZeroInteractions(mMockController);
- }
-
- @Test
- public void givenRestoreWithNonExistingWidgets_WhenRestoreAppWidgetIds_ThenRemoveNewIds() {
- // Given
- AppWidgetHost expectedHost = new AppWidgetHost(mContext, APPWIDGET_HOST_ID);
- int[] expectedOldIds = generateOldWidgetIds(expectedHost);
- int[] expectedNewIds = generateNewWidgetIds(expectedHost, expectedOldIds);
- when(mMockController.getDb()).thenReturn(mMockDb);
- when(mMockDb.query(any(), any(), any(), any(), any(), any(), any())).thenReturn(
- mMockCursor);
- when(mMockCursor.moveToFirst()).thenReturn(false);
- RestoreDbTask.setPending(mContext);
-
- // When
- RestoreDbTask.setRestoredAppWidgetIds(mContext, expectedOldIds, expectedNewIds);
- mTask.restoreAppWidgetIdsIfExists(mContext, mMockController);
-
- // Then
- assertThat(expectedHost.getAppWidgetIds()).isEqualTo(expectedOldIds);
- assertThat(mPrefs.has(OLD_APP_WIDGET_IDS, APP_WIDGET_IDS)).isFalse();
- verify(mMockController, times(expectedOldIds.length)).update(any(), any(), any(), any());
- }
-
- @Test
- public void givenRestore_WhenRestoreAppWidgetIds_ThenAddNewIds() {
- // Given
- AppWidgetHost expectedHost = new AppWidgetHost(mContext, APPWIDGET_HOST_ID);
- int[] expectedOldIds = generateOldWidgetIds(expectedHost);
- int[] expectedNewIds = generateNewWidgetIds(expectedHost, expectedOldIds);
- int[] allExpectedIds = IntStream.concat(
- Arrays.stream(expectedOldIds),
- Arrays.stream(expectedNewIds)
- ).toArray();
-
- when(mMockController.getDb()).thenReturn(mMockDb);
- when(mMockDb.query(any(), any(), any(), any(), any(), any(), any()))
- .thenReturn(mMockCursor);
- when(mMockCursor.moveToFirst()).thenReturn(true);
- when(mMockCursor.isAfterLast()).thenReturn(true);
- RestoreDbTask.setPending(mContext);
-
- // When
- RestoreDbTask.setRestoredAppWidgetIds(mContext, expectedOldIds, expectedNewIds);
- mTask.restoreAppWidgetIdsIfExists(mContext, mMockController);
-
- // Then
- assertThat(expectedHost.getAppWidgetIds()).isEqualTo(allExpectedIds);
- assertThat(mPrefs.has(OLD_APP_WIDGET_IDS, APP_WIDGET_IDS)).isFalse();
- verify(mMockController, times(expectedOldIds.length)).update(any(), any(), any(), any());
- }
-
private void addIconsBulk(MyModelDbController controller,
int count, int screen, long profileId) {
int columns = LauncherAppState.getIDP(mContext).numColumns;
@@ -373,19 +270,6 @@
}
}
- private int[] generateOldWidgetIds(AppWidgetHost host) {
- // generate some widget ids in case there are none
- host.allocateAppWidgetId();
- host.allocateAppWidgetId();
- return host.getAppWidgetIds();
- }
-
- private int[] generateNewWidgetIds(AppWidgetHost host, int[] oldWidgetIds) {
- // map as many new ids as old ids
- return Arrays.stream(oldWidgetIds)
- .map(id -> host.allocateAppWidgetId()).toArray();
- }
-
private class MyModelDbController extends ModelDbController {
public final LongSparseArray<UserHandle> users = new LongSparseArray<>();
diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
index 5240e6a..707781e 100644
--- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
+++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
@@ -16,11 +16,9 @@
package com.android.launcher3.ui;
import static androidx.test.InstrumentationRegistry.getInstrumentation;
-
import static com.android.launcher3.testing.shared.TestProtocol.ICON_MISSING;
import static com.android.launcher3.ui.TaplTestsLauncher3.getAppPackageName;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
-
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@@ -68,6 +66,7 @@
import com.android.launcher3.util.rule.SamplerRule;
import com.android.launcher3.util.rule.ScreenRecordRule;
import com.android.launcher3.util.rule.ShellCommandRule;
+import com.android.launcher3.util.rule.TestIsolationRule;
import com.android.launcher3.util.rule.TestStabilityRule;
import com.android.launcher3.util.rule.ViewCaptureRule;
@@ -206,7 +205,8 @@
final RuleChain inner = RuleChain
.outerRule(new PortraitLandscapeRunner(this))
.around(new FailureWatcher(mLauncher, viewCaptureRule::getViewCaptureData))
- .around(viewCaptureRule);
+ .around(viewCaptureRule)
+ .around(new TestIsolationRule(mLauncher));
return TestHelpers.isInLauncherProcess()
? RuleChain.outerRule(ShellCommandRule.setDefaultLauncher()).around(inner)
diff --git a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
index abb193a..0316f84 100644
--- a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
+++ b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
@@ -627,4 +627,28 @@
allApps.unfreeze();
}
}
+
+ @PlatinumTest(focusArea = "launcher")
+ @Test
+ public void testAddAndDeletePageAndFling() {
+ Workspace workspace = mLauncher.getWorkspace();
+ // Get the first app from the hotseat
+ HomeAppIcon hotSeatIcon = workspace.getHotseatAppIcon(0);
+ String appName = hotSeatIcon.getIconName();
+
+ // Add one page by dragging app to page 1.
+ workspace.dragIcon(hotSeatIcon, workspace.pagesPerScreen());
+ assertEquals("Incorrect Page count Number",
+ workspace.pagesPerScreen() * 2,
+ workspace.getPageCount());
+
+ // Delete one page by dragging app to hot seat.
+ workspace.getWorkspaceAppIcon(appName).dragToHotseat(0);
+
+ // Refresh workspace to avoid using stale container error.
+ workspace = mLauncher.getWorkspace();
+ assertEquals("Incorrect Page count Number",
+ workspace.pagesPerScreen(),
+ workspace.getPageCount());
+ }
}
diff --git a/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java b/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java
index 9dca24b..64ab206 100644
--- a/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java
+++ b/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java
@@ -16,7 +16,6 @@
package com.android.launcher3.ui.widget;
import static com.android.launcher3.ui.TaplTestsLauncher3.getAppPackageName;
-
import static org.junit.Assert.assertNotNull;
import android.platform.test.annotations.PlatinumTest;
@@ -96,4 +95,26 @@
mLauncher.getWorkspace().getWorkspaceAppIcon("Shortcut")
.launch(getAppPackageName());
}
+
+ /**
+ * Test dragging a widget to the workspace and resize it.
+ */
+ @Test
+ public void testResizeWidget() throws Throwable {
+ new FavoriteItemsTransaction(mTargetContext).commitAndLoadHome(mLauncher);
+
+ waitForLauncherCondition("Workspace didn't finish loading", l -> !l.isWorkspaceLoading());
+
+ final LauncherAppWidgetProviderInfo widgetInfo =
+ TestViewHelpers.findWidgetProvider(false /* hasConfigureScreen */);
+
+ WidgetResizeFrame resizeFrame = mLauncher
+ .getWorkspace()
+ .openAllWidgets()
+ .getWidget(widgetInfo.getLabel(mTargetContext.getPackageManager()))
+ .dragWidgetToWorkspace();
+
+ assertNotNull("Widget resize frame not shown after widget add", resizeFrame);
+ resizeFrame.resize();
+ }
}
diff --git a/tests/src/com/android/launcher3/ui/workspace/TwoPanelWorkspaceTest.java b/tests/src/com/android/launcher3/ui/workspace/TwoPanelWorkspaceTest.java
index 0b2f335..62a8179 100644
--- a/tests/src/com/android/launcher3/ui/workspace/TwoPanelWorkspaceTest.java
+++ b/tests/src/com/android/launcher3/ui/workspace/TwoPanelWorkspaceTest.java
@@ -178,14 +178,15 @@
public void testDragIconToPage3() {
Workspace workspace = mLauncher.getWorkspace();
- workspace.dragIcon(workspace.getHotseatAppIcon("Phone"), 3);
+ // b/299522368 sometimes the phone app is not present in the hotseat.
+ workspace.dragIcon(workspace.getHotseatAppIcon("Chrome"), 3);
executeOnLauncher(launcher -> {
assertPagesExist(launcher, 0, 1, 2, 3);
assertItemsOnPage(launcher, 0, "Play Store", "Maps");
assertPageEmpty(launcher, 1);
assertPageEmpty(launcher, 2);
- assertItemsOnPage(launcher, 3, "Phone");
+ assertItemsOnPage(launcher, 3, "Chrome");
});
}
diff --git a/tests/src/com/android/launcher3/util/rule/TestIsolationRule.java b/tests/src/com/android/launcher3/util/rule/TestIsolationRule.java
new file mode 100644
index 0000000..5cc4c5e
--- /dev/null
+++ b/tests/src/com/android/launcher3/util/rule/TestIsolationRule.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.util.rule;
+
+import androidx.annotation.NonNull;
+
+import com.android.launcher3.tapl.LauncherInstrumentation;
+
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+/**
+ * Isolates tests from some of the state created by the previous test.
+ */
+public class TestIsolationRule implements TestRule {
+ final LauncherInstrumentation mLauncher;
+
+ public TestIsolationRule(LauncherInstrumentation launcher) {
+ mLauncher = launcher;
+ }
+
+ @NonNull
+ @Override
+ public Statement apply(@NonNull Statement base, @NonNull Description description) {
+ return new Statement() {
+ @Override
+ public void evaluate() throws Throwable {
+ base.evaluate();
+ // Make sure that Launcher workspace looks correct.
+ mLauncher.goHome();
+ }
+ };
+ }
+}
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index 1bbef36..872fe6f 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -341,6 +341,11 @@
.getParcelable(TestProtocol.TEST_INFO_RESPONSE_FIELD);
}
+ Insets getImeInsets() {
+ return getTestInfo(TestProtocol.REQUEST_IME_INSETS)
+ .getParcelable(TestProtocol.TEST_INFO_RESPONSE_FIELD);
+ }
+
public boolean isTablet() {
return getTestInfo(TestProtocol.REQUEST_IS_TABLET)
.getBoolean(TestProtocol.TEST_INFO_RESPONSE_FIELD);
@@ -2111,7 +2116,11 @@
? containerBounds.right + 1
: containerBounds.left - 1;
}
- int y = containerBounds.top + containerBounds.height() / 2;
+ // If IME is visible and overlaps the container bounds, touch above it.
+ int bottomBound = Math.min(
+ containerBounds.bottom,
+ getRealDisplaySize().y - getImeInsets().bottom);
+ int y = (bottomBound - containerBounds.top) / 2;
final long downTime = SystemClock.uptimeMillis();
final Point tapTarget = new Point(x, y);
diff --git a/tests/tapl/com/android/launcher3/tapl/SearchResultFromQsb.java b/tests/tapl/com/android/launcher3/tapl/SearchResultFromQsb.java
index 0895d93..513d6bb 100644
--- a/tests/tapl/com/android/launcher3/tapl/SearchResultFromQsb.java
+++ b/tests/tapl/com/android/launcher3/tapl/SearchResultFromQsb.java
@@ -20,6 +20,8 @@
import androidx.test.uiautomator.By;
import androidx.test.uiautomator.UiObject2;
+import com.android.launcher3.testing.shared.TestProtocol;
+
import java.util.ArrayList;
/**
@@ -43,8 +45,11 @@
public void searchForInput(String input) {
try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
"want to search for result with an input");
- LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) {
- mLauncher.waitForLauncherObject(INPUT_RES).setText(input);
+ LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) {
+ mLauncher.executeAndWaitForLauncherEvent(
+ () -> mLauncher.waitForLauncherObject(INPUT_RES).setText(input),
+ event -> TestProtocol.SEARCH_RESULT_COMPLETE.equals(event.getClassName()),
+ () -> "Didn't receive a search result completed message", "searching");
}
}
diff --git a/tests/tapl/com/android/launcher3/tapl/WidgetResizeFrame.java b/tests/tapl/com/android/launcher3/tapl/WidgetResizeFrame.java
index 8f51d04..ec1cbd8 100644
--- a/tests/tapl/com/android/launcher3/tapl/WidgetResizeFrame.java
+++ b/tests/tapl/com/android/launcher3/tapl/WidgetResizeFrame.java
@@ -15,6 +15,16 @@
*/
package com.android.launcher3.tapl;
+import static com.android.launcher3.tapl.Launchable.DEFAULT_DRAG_STEPS;
+import static org.junit.Assert.assertTrue;
+
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.os.SystemClock;
+import android.view.MotionEvent;
+
+import androidx.test.uiautomator.UiObject2;
+
/** The resize frame that is shown for a widget on the workspace. */
public class WidgetResizeFrame {
@@ -34,4 +44,36 @@
mLauncher.getDevice().pressHome();
}
}
+
+ /** Resizes the widget to double its height, and returns the resize frame. */
+ public WidgetResizeFrame resize() {
+ try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
+ LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
+ "want to resize the widget frame.")) {
+ UiObject2 widget = mLauncher.waitForLauncherObject("widget_resize_frame");
+ UiObject2 bottomResizeHandle =
+ mLauncher.waitForLauncherObject("widget_resize_bottom_handle");
+ Rect originalWidgetSize = widget.getVisibleBounds();
+ Point targetStart = bottomResizeHandle.getVisibleCenter();
+ Point targetDest = bottomResizeHandle.getVisibleCenter();
+ targetDest.offset(0, originalWidgetSize.height());
+
+ final long downTime = SystemClock.uptimeMillis();
+ mLauncher.sendPointer(downTime, downTime, MotionEvent.ACTION_DOWN, targetStart,
+ LauncherInstrumentation.GestureScope.DONT_EXPECT_PILFER);
+ mLauncher.movePointer(targetStart, targetDest, DEFAULT_DRAG_STEPS,
+ true, downTime, downTime, true,
+ LauncherInstrumentation.GestureScope.DONT_EXPECT_PILFER);
+ mLauncher.sendPointer(downTime, downTime, MotionEvent.ACTION_UP, targetDest,
+ LauncherInstrumentation.GestureScope.DONT_EXPECT_PILFER);
+
+ try (LauncherInstrumentation.Closable c2 = mLauncher.addContextLayer(
+ "want to return resized widget resize frame")) {
+ float newHeight = mLauncher.waitForLauncherObject(
+ "widget_resize_frame").getVisibleBounds().height();
+ assertTrue("Widget not resized.", newHeight >= originalWidgetSize.height() * 2);
+ return this;
+ }
+ }
+ }
}