Merge "Add unit tests for LoaderTask" 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/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index b024418..aeb453c 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -306,7 +306,7 @@
<dimen name="taskbar_home_button_left_margin_kids">48dp</dimen>
<dimen name="taskbar_icon_size_kids">32dp</dimen>
<dimen name="taskbar_all_apps_button_translation_x_offset">6dp</dimen>
-
+ <dimen name="taskbar_all_apps_search_button_translation_x_offset">4.5dp</dimen>
<!-- Transient taskbar -->
<dimen name="transient_taskbar_padding">12dp</dimen>
@@ -317,6 +317,8 @@
<dimen name="transient_taskbar_stashed_height">32dp</dimen>
<dimen name="transient_taskbar_all_apps_button_translation_x_offset">4dp</dimen>
<dimen name="transient_taskbar_stash_spring_velocity_dp_per_s">400dp</dimen>
+ <dimen name="taskbar_tooltip_vertical_padding">8dp</dimen>
+ <dimen name="taskbar_tooltip_horizontal_padding">16dp</dimen>
<!-- An additional touch slop to prevent x-axis movement during the swipe up to show taskbar -->
<dimen name="transient_taskbar_clamped_offset_bound">16dp</dimen>
@@ -368,6 +370,7 @@
<dimen name="bubblebar_stashed_handle_height">@dimen/taskbar_stashed_handle_height</dimen>
<dimen name="bubblebar_pointer_size">8dp</dimen>
<dimen name="bubblebar_elevation">1dp</dimen>
+ <dimen name="bubblebar_hotseat_adjustment_threshold">90dp</dimen>
<dimen name="bubblebar_icon_size">50dp</dimen>
<dimen name="bubblebar_badge_size">24dp</dimen>
diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
index f8ea932..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;
@@ -151,6 +153,7 @@
import com.android.quickstep.views.RecentsView;
import com.android.systemui.animation.ActivityLaunchAnimator;
import com.android.systemui.animation.DelegateLaunchAnimatorController;
+import com.android.systemui.animation.LaunchableView;
import com.android.systemui.animation.RemoteAnimationDelegate;
import com.android.systemui.shared.system.BlurUtils;
import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
@@ -239,6 +242,8 @@
private RemoteAnimationFactory mWallpaperOpenTransitionRunner;
private RemoteTransition mLauncherOpenTransition;
+ private final RemoteAnimationCoordinateTransfer mCoordinateTransfer;
+
private LauncherBackAnimationController mBackAnimationController;
private final AnimatorListenerAdapter mForceInvisibleListener = new AnimatorListenerAdapter() {
@Override
@@ -287,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
@@ -1388,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);
@@ -1693,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 */);
@@ -1777,7 +1794,7 @@
@Nullable
private static ContainerAnimationRunner from(View v, Launcher launcher,
StartingWindowListener startingWindowListener, RunnableList onEndCallback) {
- View viewToUse = findViewWithBackground(v);
+ View viewToUse = findLaunchableViewWithBackground(v);
if (viewToUse == null) {
viewToUse = v;
}
@@ -1820,11 +1837,15 @@
new ActivityLaunchAnimator.AnimationDelegate(controller, callback, listener));
}
- /** Finds the closest parent of [view] (inclusive) with a background drawable. */
+ /**
+ * Finds the closest parent of [view] (inclusive) that implements {@link LaunchableView} and
+ * has a background drawable.
+ */
@Nullable
- private static View findViewWithBackground(View view) {
+ private static <T extends View & LaunchableView> T findLaunchableViewWithBackground(
+ View view) {
View current = view;
- while (current.getBackground() == null) {
+ while (current.getBackground() == null || !(current instanceof LaunchableView)) {
if (!(current.getParent() instanceof View)) {
return null;
}
@@ -1832,7 +1853,7 @@
current = (View) view.getParent();
}
- return current;
+ return (T) current;
}
@Override
@@ -1936,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 {
@@ -1957,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) {
@@ -1977,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/statehandlers/DesktopVisibilityController.java b/quickstep/src/com/android/launcher3/statehandlers/DesktopVisibilityController.java
index d7a4f76..42e6809 100644
--- a/quickstep/src/com/android/launcher3/statehandlers/DesktopVisibilityController.java
+++ b/quickstep/src/com/android/launcher3/statehandlers/DesktopVisibilityController.java
@@ -160,7 +160,9 @@
if (mInOverviewState) {
setLauncherViewsVisibility(View.VISIBLE);
markLauncherResumed();
- } else if (mFreeformTasksVisible) {
+ } else if (mFreeformTasksVisible && !mGestureInProgress) {
+ // Switching out of overview state and gesture finished.
+ // If freeform tasks are still visible, hide launcher again.
setLauncherViewsVisibility(View.INVISIBLE);
markLauncherPaused();
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
index 4e834ec..e6dfe0f 100644
--- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
@@ -41,6 +41,7 @@
import com.android.launcher3.logging.InstanceId;
import com.android.launcher3.logging.InstanceIdSequence;
import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.taskbar.bubbles.BubbleBarController;
import com.android.launcher3.uioverrides.QuickstepLauncher;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.MultiPropertyFactory;
@@ -202,10 +203,18 @@
return mTaskbarLauncherStateController.applyState(fromInit ? 0 : duration, startAnimation);
}
+ @Override
public void refreshResumedState() {
onLauncherResumedOrPaused(mLauncher.hasBeenResumed());
}
+ @Override
+ public void adjustHotseatForBubbleBar(boolean isBubbleBarVisible) {
+ if (mLauncher.getHotseat() != null) {
+ mLauncher.getHotseat().adjustForBubbleBar(isBubbleBarVisible);
+ }
+ }
+
/**
* Create Taskbar animation when going from an app to Launcher as part of recents transition.
* @param toState If known, the state we will end up in when reaching Launcher.
@@ -327,6 +336,21 @@
return mTaskbarInAppDisplayProgress.value > 0;
}
+ public boolean isBubbleBarEnabled() {
+ return BubbleBarController.BUBBLE_BAR_ENABLED;
+ }
+
+ /** Whether the bubble bar has any bubbles. */
+ public boolean hasBubbles() {
+ if (mControllers == null) {
+ return false;
+ }
+ if (mControllers.bubbleControllers.isEmpty()) {
+ return false;
+ }
+ return mControllers.bubbleControllers.get().bubbleBarViewController.hasBubbles();
+ }
+
@Override
public void onExpandPip() {
super.onExpandPip();
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index 0b83a88..0aa02f2 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -27,11 +27,13 @@
import static com.android.launcher3.AbstractFloatingView.TYPE_REBIND_SAFE;
import static com.android.launcher3.AbstractFloatingView.TYPE_TASKBAR_OVERLAY_PROXY;
import static com.android.launcher3.Utilities.isRunningInTestHarness;
+import static com.android.launcher3.config.FeatureFlags.ENABLE_TASKBAR_NO_RECREATION;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_FOLDER_OPEN;
import static com.android.launcher3.taskbar.TaskbarAutohideSuspendController.FLAG_AUTOHIDE_SUSPEND_DRAGGING;
import static com.android.launcher3.taskbar.TaskbarAutohideSuspendController.FLAG_AUTOHIDE_SUSPEND_FULLSCREEN;
import static com.android.launcher3.taskbar.TaskbarManager.FLAG_HIDE_NAVBAR_WINDOW;
import static com.android.launcher3.testing.shared.ResourceUtils.getBoolByName;
+import static com.android.launcher3.util.VibratorWrapper.EFFECT_CLICK;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_VISIBLE;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_VOICE_INTERACTION_WINDOW_SHOWING;
@@ -57,6 +59,7 @@
import android.view.RoundedCorner;
import android.view.Surface;
import android.view.View;
+import android.view.WindowInsets;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.Toast;
@@ -108,6 +111,7 @@
import com.android.launcher3.util.SettingsCache;
import com.android.launcher3.util.SplitConfigurationOptions.SplitSelectSource;
import com.android.launcher3.util.TraceHelper;
+import com.android.launcher3.util.VibratorWrapper;
import com.android.launcher3.util.ViewCache;
import com.android.launcher3.views.ActivityContext;
import com.android.quickstep.views.RecentsView;
@@ -225,20 +229,23 @@
}
// Construct controllers.
+ RotationButtonController rotationButtonController = new RotationButtonController(this,
+ c.getColor(R.color.floating_rotation_button_light_color),
+ c.getColor(R.color.floating_rotation_button_dark_color),
+ R.drawable.ic_sysbar_rotate_button_ccw_start_0,
+ R.drawable.ic_sysbar_rotate_button_ccw_start_90,
+ R.drawable.ic_sysbar_rotate_button_cw_start_0,
+ R.drawable.ic_sysbar_rotate_button_cw_start_90,
+ () -> getDisplay().getRotation());
+ rotationButtonController.setBgExecutor(Executors.THREAD_POOL_EXECUTOR);
+
mControllers = new TaskbarControllers(this,
new TaskbarDragController(this),
buttonController,
isDesktopMode
? new DesktopNavbarButtonsViewController(this, navButtonsView)
: new NavbarButtonsViewController(this, navButtonsView),
- new RotationButtonController(this,
- c.getColor(R.color.floating_rotation_button_light_color),
- c.getColor(R.color.floating_rotation_button_dark_color),
- R.drawable.ic_sysbar_rotate_button_ccw_start_0,
- R.drawable.ic_sysbar_rotate_button_ccw_start_90,
- R.drawable.ic_sysbar_rotate_button_cw_start_0,
- R.drawable.ic_sysbar_rotate_button_cw_start_90,
- () -> getDisplay().getRotation()),
+ rotationButtonController,
new TaskbarDragLayerController(this, mDragLayer),
new TaskbarViewController(this, taskbarView),
new TaskbarScrimViewController(this, taskbarScrimView),
@@ -298,6 +305,11 @@
mNavMode = DisplayController.getNavigationMode(this);
}
+ /** Called when the visibility of the bubble bar changed. */
+ public void bubbleBarVisibilityChanged(boolean isVisible) {
+ mControllers.uiController.adjustHotseatForBubbleBar(isVisible);
+ mControllers.taskbarViewController.resetIconAlignmentController();
+ }
public void init(@NonNull TaskbarSharedState sharedState) {
mImeDrawsImeNavBar = getBoolByName(IME_DRAWS_IME_NAV_BAR_RES_NAME, getResources(), false);
@@ -323,11 +335,11 @@
mIsDestroyed = false;
}
- if (!mAddedWindow) {
+ if (!ENABLE_TASKBAR_NO_RECREATION.get() && !mAddedWindow) {
mWindowManager.addView(mDragLayer, mWindowLayoutParams);
mAddedWindow = true;
} else {
- mWindowManager.updateViewLayout(mDragLayer, mWindowLayoutParams);
+ notifyUpdateLayoutParams();
}
}
@@ -343,6 +355,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;
@@ -674,7 +691,7 @@
mIsDestroyed = true;
setUIController(TaskbarUIController.DEFAULT);
mControllers.onDestroy();
- if (!FLAG_HIDE_NAVBAR_WINDOW) {
+ if (!ENABLE_TASKBAR_NO_RECREATION.get() && !FLAG_HIDE_NAVBAR_WINDOW) {
mWindowManager.removeViewImmediate(mDragLayer);
mAddedWindow = false;
}
@@ -806,7 +823,7 @@
}
mWindowLayoutParams.height = height;
mControllers.taskbarInsetsController.onTaskbarOrBubblebarWindowHeightOrInsetsChanged();
- mWindowManager.updateViewLayout(mDragLayer, mWindowLayoutParams);
+ notifyUpdateLayoutParams();
}
/**
@@ -849,7 +866,22 @@
} else {
mWindowLayoutParams.flags |= FLAG_NOT_FOCUSABLE;
}
- mWindowManager.updateViewLayout(mDragLayer, mWindowLayoutParams);
+ notifyUpdateLayoutParams();
+ }
+
+ /**
+ * Applies forcibly show flag to taskbar window iff transient taskbar is unstashed.
+ */
+ public void applyForciblyShownFlagWhileTransientTaskbarUnstashed(boolean shouldForceShow) {
+ if (!DisplayController.isTransientTaskbar(this)) {
+ return;
+ }
+ if (shouldForceShow) {
+ mWindowLayoutParams.forciblyShownTypes |= WindowInsets.Type.navigationBars();
+ } else {
+ mWindowLayoutParams.forciblyShownTypes &= ~WindowInsets.Type.navigationBars();
+ }
+ notifyUpdateLayoutParams();
}
/**
@@ -958,8 +990,8 @@
}
} catch (NullPointerException
- | ActivityNotFoundException
- | SecurityException e) {
+ | ActivityNotFoundException
+ | SecurityException e) {
Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT)
.show();
Log.e(TAG, "Unable to launch. tag=" + info + " intent=" + intent, e);
@@ -1053,6 +1085,7 @@
/**
* Called when we detect a long press in the nav region before passing the gesture slop.
+ *
* @return Whether taskbar handled the long press, and thus should cancel the gesture.
*/
public boolean onLongPressToUnstashTaskbar() {
@@ -1063,6 +1096,7 @@
* Called when we want to unstash taskbar when user performs swipes up gesture.
*/
public void onSwipeToUnstashTaskbar() {
+ VibratorWrapper.INSTANCE.get(this).vibrate(EFFECT_CLICK);
mControllers.taskbarStashController.updateAndAnimateTransientTaskbar(/* stash= */ false);
mControllers.taskbarEduTooltipController.hide();
}
@@ -1121,7 +1155,7 @@
* Called when we detect a motion down or up/cancel in the nav region while stashed.
*
* @param animateForward Whether to animate towards the unstashed hint state or back to stashed.
- * @param forceUnstash Whether we force the unstash hint.
+ * @param forceUnstash Whether we force the unstash hint.
*/
public void startTaskbarUnstashHint(boolean animateForward, boolean forceUnstash) {
// TODO(b/270395798): Clean up forceUnstash after removing long-press unstashing code.
@@ -1229,12 +1263,16 @@
mWindowLayoutParams.privateFlags &=
~WindowManager.LayoutParams.PRIVATE_FLAG_EXCLUDE_FROM_SCREEN_MAGNIFICATION;
}
- mWindowManager.updateViewLayout(mDragLayer, mWindowLayoutParams);
+ notifyUpdateLayoutParams();
}
void notifyUpdateLayoutParams() {
if (mDragLayer.isAttachedToWindow()) {
- mWindowManager.updateViewLayout(mDragLayer, mWindowLayoutParams);
+ if (ENABLE_TASKBAR_NO_RECREATION.get()) {
+ mWindowManager.updateViewLayout(mDragLayer.getRootView(), mWindowLayoutParams);
+ } else {
+ mWindowManager.updateViewLayout(mDragLayer, mWindowLayoutParams);
+ }
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDividerPopupController.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarDividerPopupController.kt
index 83a3343..a2c61ce 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDividerPopupController.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDividerPopupController.kt
@@ -18,6 +18,10 @@
import android.view.View
import com.android.launcher3.LauncherPrefs
import com.android.launcher3.LauncherPrefs.Companion.TASKBAR_PINNING
+import com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_DIVIDER_MENU_CLOSE
+import com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_DIVIDER_MENU_OPEN
+import com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_PINNED
+import com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_UNPINNED
import com.android.launcher3.taskbar.TaskbarDividerPopupView.Companion.createAndPopulate
import java.io.PrintWriter
@@ -27,6 +31,7 @@
private lateinit var controllers: TaskbarControllers
private val launcherPrefs = LauncherPrefs.get(context)
+ private val statsLogManager = context.statsLogManager
fun init(taskbarControllers: TaskbarControllers) {
controllers = taskbarControllers
@@ -41,6 +46,7 @@
popupView.onCloseCallback =
callback@{ didPreferenceChange ->
+ statsLogManager.logger().log(LAUNCHER_TASKBAR_DIVIDER_MENU_CLOSE)
context.dragLayer.post { context.onPopupVisibilityChanged(false) }
if (!didPreferenceChange) {
@@ -49,8 +55,10 @@
if (launcherPrefs.get(TASKBAR_PINNING)) {
animateTransientToPersistentTaskbar()
+ statsLogManager.logger().log(LAUNCHER_TASKBAR_PINNED)
} else {
animatePersistentToTransientTaskbar()
+ statsLogManager.logger().log(LAUNCHER_TASKBAR_UNPINNED)
}
}
popupView.changePreference = {
@@ -58,6 +66,7 @@
}
context.onPopupVisibilityChanged(true)
popupView.show()
+ statsLogManager.logger().log(LAUNCHER_TASKBAR_DIVIDER_MENU_OPEN)
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDividerPopupView.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarDividerPopupView.kt
index e215bc9..b200858 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDividerPopupView.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDividerPopupView.kt
@@ -59,6 +59,7 @@
return taskMenuViewWithArrow.populateForView(view)
}
}
+
private lateinit var dividerView: View
private val menuWidth =
@@ -178,13 +179,19 @@
override fun closeComplete() {
onCloseCallback(didPreferenceChange)
+ onCloseCallback = {}
super.closeComplete()
}
private fun onClickAlwaysShowTaskbarSwitchOption() {
didPreferenceChange = true
changePreference()
+ changePreference = {}
// Allow switch animation to finish and then close the popup.
- postDelayed(DIVIDER_POPUP_CLOSING_DELAY) { close(true) }
+ postDelayed(DIVIDER_POPUP_CLOSING_DELAY) {
+ if (isOpen) {
+ close(false)
+ }
+ }
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
index 3c7196a..4ad5c88 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
@@ -259,6 +259,8 @@
DraggableView originalView, int dragLayerX, int dragLayerY, DragSource source,
ItemInfo dragInfo, Rect dragRegion, float initialDragViewScale,
float dragViewScaleOnDrop, DragOptions options) {
+ mActivity.hideKeyboard();
+
mOptions = options;
mRegistrationX = mMotionDown.x - dragLayerX;
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarHoverToolTipController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarHoverToolTipController.java
index c3ec1e5..2c72b2c 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarHoverToolTipController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarHoverToolTipController.java
@@ -35,8 +35,6 @@
import android.view.MotionEvent;
import android.view.View;
-import androidx.annotation.VisibleForTesting;
-
import com.android.app.animation.Interpolators;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.BubbleTextView;
@@ -51,8 +49,7 @@
*/
public class TaskbarHoverToolTipController implements View.OnHoverListener {
- @VisibleForTesting protected static final int HOVER_TOOL_TIP_REVEAL_START_DELAY = 400;
- private static final int HOVER_TOOL_TIP_REVEAL_DURATION = 300;
+ private static final int HOVER_TOOL_TIP_REVEAL_DURATION = 250;
private static final int HOVER_TOOL_TIP_EXIT_DURATION = 150;
private final Handler mHoverToolTipHandler = new Handler(Looper.getMainLooper());
@@ -84,6 +81,12 @@
R.style.ArrowTipTaskbarStyle);
mHoverToolTipView = new ArrowTipView(arrowContextWrapper, /* isPointingUp = */ false,
R.layout.arrow_toast);
+ int verticalPadding = arrowContextWrapper.getResources().getDimensionPixelSize(
+ R.dimen.taskbar_tooltip_vertical_padding);
+ int horizontalPadding = arrowContextWrapper.getResources().getDimensionPixelSize(
+ R.dimen.taskbar_tooltip_horizontal_padding);
+ mHoverToolTipView.findViewById(R.id.text).setPadding(horizontalPadding, verticalPadding,
+ horizontalPadding, verticalPadding);
AnimatorSet hoverCloseAnimator = new AnimatorSet();
ObjectAnimator textCloseAnimator = ObjectAnimator.ofInt(mHoverToolTipView, TEXT_ALPHA, 0);
@@ -101,17 +104,18 @@
mHoverToolTipView.setCustomCloseAnimation(hoverCloseAnimator);
AnimatorSet hoverOpenAnimator = new AnimatorSet();
- ObjectAnimator textOpenAnimator = ObjectAnimator.ofInt(mHoverToolTipView, TEXT_ALPHA, 255);
- textOpenAnimator.setInterpolator(Interpolators.clampToProgress(LINEAR, 0.33f, 1f));
- ObjectAnimator scaleOpenAnimator = ObjectAnimator.ofFloat(mHoverToolTipView, SCALE_Y, 1f);
+ ObjectAnimator textOpenAnimator =
+ ObjectAnimator.ofInt(mHoverToolTipView, TEXT_ALPHA, 0, 255);
+ textOpenAnimator.setInterpolator(Interpolators.clampToProgress(LINEAR, 0.15f, 0.75f));
+ ObjectAnimator scaleOpenAnimator =
+ ObjectAnimator.ofFloat(mHoverToolTipView, SCALE_Y, 0f, 1f);
scaleOpenAnimator.setInterpolator(Interpolators.EMPHASIZED);
- ObjectAnimator alphaOpenAnimator = ObjectAnimator.ofFloat(mHoverToolTipView, ALPHA, 1f);
- alphaOpenAnimator.setInterpolator(Interpolators.clampToProgress(LINEAR, 0.1f, 0.33f));
+ ObjectAnimator alphaOpenAnimator = ObjectAnimator.ofFloat(mHoverToolTipView, ALPHA, 0f, 1f);
+ alphaOpenAnimator.setInterpolator(Interpolators.clampToProgress(LINEAR, 0f, 0.33f));
hoverOpenAnimator.playTogether(
scaleOpenAnimator,
textOpenAnimator,
alphaOpenAnimator);
- hoverOpenAnimator.setStartDelay(HOVER_TOOL_TIP_REVEAL_START_DELAY);
hoverOpenAnimator.setDuration(HOVER_TOOL_TIP_REVEAL_DURATION);
mHoverToolTipView.setCustomOpenAnimation(hoverOpenAnimator);
@@ -120,8 +124,6 @@
mHoverToolTipView.setPivotY(bottom);
mHoverToolTipView.setY(mTaskbarView.getTop() - (bottom - top));
});
- mHoverToolTipView.setScaleY(0f);
- mHoverToolTipView.setAlpha(0f);
}
@Override
@@ -137,6 +139,15 @@
mActivity.setAutohideSuspendFlag(FLAG_AUTOHIDE_SUSPEND_HOVERING_ICONS, false);
return true;
} else if (!isAnyOtherFloatingViewOpen && event.getAction() == ACTION_HOVER_ENTER) {
+ if (!mActivity.isTaskbarWindowFullscreen()) {
+ // First time we want to animate a tooltip open, we set the drag layer to
+ // fullscreen so the tooltip will fit within the window. This causes a layout
+ // pass which will trigger a hover exit and hover enter event while still
+ // hovering the view, so we do not animate open on the first hover enter if we
+ // are not already in fullscreen.
+ mActivity.setTaskbarWindowFullscreen(true);
+ return false;
+ }
// If hovering above a taskbar icon starts, animate the tooltip open. Do not
// reveal if any floating views such as folders or edu pop-ups are open.
startRevealHoverToolTip();
@@ -147,8 +158,7 @@
}
private void startRevealHoverToolTip() {
- mHoverToolTipHandler.postDelayed(mRevealHoverToolTipRunnable,
- HOVER_TOOL_TIP_REVEAL_START_DELAY);
+ mHoverToolTipHandler.post(mRevealHoverToolTipRunnable);
}
private void revealHoverToolTip() {
@@ -158,14 +168,12 @@
if (mHoverView instanceof FolderIcon && !((FolderIcon) mHoverView).getIconVisible()) {
return;
}
- mActivity.setTaskbarWindowFullscreen(true);
Rect iconViewBounds = Utilities.getViewBounds(mHoverView);
mHoverToolTipView.showAtLocation(mToolTipText, iconViewBounds.centerX(),
mTaskbarView.getTop(), /* shouldAutoClose= */ false);
}
private void startHideHoverToolTip() {
- mHoverToolTipHandler.removeCallbacks(mRevealHoverToolTipRunnable);
int accessibilityHideTimeout = AccessibilityManagerCompat.getRecommendedTimeoutMillis(
mActivity, /* originalTimeout= */ 0, FLAG_CONTENT_TEXT);
mHoverToolTipHandler.postDelayed(mHideHoverToolTipRunnable, accessibilityHideTimeout);
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt
index c51a7ec..eb15cef 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt
@@ -15,9 +15,9 @@
*/
package com.android.launcher3.taskbar
-import android.inputmethodservice.InputMethodService.ENABLE_HIDE_IME_CAPTION_BAR
import android.graphics.Insets
import android.graphics.Region
+import android.inputmethodservice.InputMethodService.ENABLE_HIDE_IME_CAPTION_BAR
import android.os.Binder
import android.os.IBinder
import android.view.Gravity
@@ -41,6 +41,7 @@
import com.android.launcher3.DeviceProfile
import com.android.launcher3.R
import com.android.launcher3.anim.AlphaUpdateListener
+import com.android.launcher3.config.FeatureFlags.ENABLE_TASKBAR_NO_RECREATION
import com.android.launcher3.taskbar.TaskbarControllers.LoggableTaskbarController
import com.android.launcher3.util.DisplayController
import java.io.PrintWriter
@@ -97,7 +98,14 @@
0
}
- windowLayoutParams.providedInsets = getProvidedInsets(insetsRoundedCornerFlag)
+ windowLayoutParams.providedInsets =
+ if (ENABLE_TASKBAR_NO_RECREATION.get()) {
+ getProvidedInsets(controllers.sharedState!!.insetsFrameProviders!!,
+ insetsRoundedCornerFlag)
+ } else {
+ getProvidedInsets(insetsRoundedCornerFlag)
+ }
+
if (!context.isGestureNav) {
if (windowLayoutParams.paramsForRotation != null) {
for (layoutParams in windowLayoutParams.paramsForRotation) {
@@ -154,6 +162,26 @@
}
/**
+ * This is for when ENABLE_TASKBAR_NO_RECREATION is enabled. We generate one instance of
+ * providedInsets and use it across the entire lifecycle of TaskbarManager. The only thing
+ * we need to reset is nav bar flags based on insetsRoundedCornerFlag.
+ */
+ private fun getProvidedInsets(providedInsets: Array<InsetsFrameProvider>,
+ insetsRoundedCornerFlag: Int): Array<InsetsFrameProvider> {
+ val navBarsFlag =
+ (if (context.isGestureNav) FLAG_SUPPRESS_SCRIM else 0) or insetsRoundedCornerFlag
+ for (provider in providedInsets) {
+ if (provider.type == navigationBars()) {
+ provider.setFlags(
+ navBarsFlag,
+ FLAG_SUPPRESS_SCRIM or FLAG_INSETS_ROUNDED_CORNER
+ )
+ }
+ }
+ return providedInsets
+ }
+
+ /**
* The inset types and number of insets provided have to match for both gesture nav and button
* nav. The values and the order of the elements in array are allowed to differ.
* Reason being WM does not allow types and number of insets changing for a given window once it
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
index 90f7bea..88ae349 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
@@ -18,6 +18,7 @@
import static com.android.app.animation.Interpolators.EMPHASIZED;
import static com.android.launcher3.taskbar.TaskbarKeyguardController.MASK_ANY_SYSUI_LOCKED;
import static com.android.launcher3.taskbar.TaskbarStashController.FLAG_IN_APP;
+import static com.android.launcher3.taskbar.TaskbarStashController.FLAG_IN_OVERVIEW;
import static com.android.launcher3.taskbar.TaskbarStashController.FLAG_IN_STASHED_LAUNCHER_STATE;
import static com.android.launcher3.taskbar.TaskbarViewController.ALPHA_INDEX_HOME;
import static com.android.launcher3.util.FlagDebugUtils.appendFlag;
@@ -416,6 +417,9 @@
controllers.bubbleStashController.setBubblesShowingOnOverview(onOverview);
});
+ mControllers.taskbarStashController.updateStateForFlag(FLAG_IN_OVERVIEW,
+ mLauncherState == LauncherState.OVERVIEW);
+
AnimatorSet animatorSet = new AnimatorSet();
if (hasAnyFlag(changedFlags, FLAG_LAUNCHER_IN_STATE_TRANSITION)) {
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
index c423fb3..ba2116d 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
@@ -23,6 +23,7 @@
import static com.android.launcher3.LauncherPrefs.TASKBAR_PINNING;
import static com.android.launcher3.LauncherPrefs.TASKBAR_PINNING_KEY;
import static com.android.launcher3.LauncherState.OVERVIEW;
+import static com.android.launcher3.config.FeatureFlags.ENABLE_TASKBAR_NO_RECREATION;
import static com.android.launcher3.util.DisplayController.TASKBAR_NOT_DESTROYED_TAG;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import static com.android.launcher3.util.FlagDebugUtils.formatFlagChange;
@@ -45,6 +46,8 @@
import android.provider.Settings;
import android.util.Log;
import android.view.Display;
+import android.view.WindowManager;
+import android.widget.FrameLayout;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -64,6 +67,7 @@
import com.android.quickstep.RecentsActivity;
import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.TouchInteractionService;
+import com.android.quickstep.util.AssistUtils;
import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.unfold.UnfoldTransitionProgressProvider;
import com.android.systemui.unfold.util.ScopedUnfoldTransitionProgressProvider;
@@ -104,6 +108,9 @@
Settings.Secure.NAV_BAR_KIDS_MODE);
private final Context mContext;
+ private WindowManager mWindowManager;
+ private FrameLayout mTaskbarRootLayout;
+ private boolean mAddedWindow;
private final TaskbarNavButtonController mNavButtonController;
private final ComponentCallbacks mComponentCallbacks;
@@ -175,8 +182,13 @@
Display display =
service.getSystemService(DisplayManager.class).getDisplay(DEFAULT_DISPLAY);
mContext = service.createWindowContext(display, TYPE_NAVIGATION_BAR_PANEL, null);
+ if (ENABLE_TASKBAR_NO_RECREATION.get()) {
+ mWindowManager = mContext.getSystemService(WindowManager.class);
+ mTaskbarRootLayout = new FrameLayout(mContext);
+ }
mNavButtonController = new TaskbarNavButtonController(service,
- SystemUiProxy.INSTANCE.get(mContext), new Handler());
+ SystemUiProxy.INSTANCE.get(mContext), new Handler(),
+ AssistUtils.newInstance(mContext));
mComponentCallbacks = new ComponentCallbacks() {
private Configuration mOldConfig = mContext.getResources().getConfiguration();
@@ -256,10 +268,15 @@
LauncherPrefs.get(mContext).removeListener(mTaskbarPinningPreferenceChangeListener,
TASKBAR_PINNING);
mTaskbarActivityContext.onDestroy();
- if (!FLAG_HIDE_NAVBAR_WINDOW) {
+ if (!FLAG_HIDE_NAVBAR_WINDOW || ENABLE_TASKBAR_NO_RECREATION.get()) {
mTaskbarActivityContext = null;
}
}
+ DeviceProfile dp = mUserUnlocked ?
+ LauncherAppState.getIDP(mContext).getDeviceProfile(mContext) : null;
+ if (dp == null || !isTaskbarPresent(dp)) {
+ removeTaskbarRootViewFromWindow();
+ }
}
/**
@@ -287,7 +304,7 @@
return;
}
- mTaskbarActivityContext.toggleAllApps();
+ mTaskbarActivityContext.toggleAllAppsSearch();
}
/**
@@ -308,6 +325,7 @@
mUserUnlocked = true;
LauncherAppState.getIDP(mContext).addOnChangeListener(mIdpChangeListener);
recreateTaskbar();
+ addTaskbarRootViewToWindow();
}
/**
@@ -388,10 +406,9 @@
return;
}
- if (mTaskbarActivityContext == null) {
+ if (ENABLE_TASKBAR_NO_RECREATION.get() || mTaskbarActivityContext == null) {
mTaskbarActivityContext = new TaskbarActivityContext(mContext, dp,
- mNavButtonController,
- mUnfoldProgressProvider);
+ mNavButtonController, mUnfoldProgressProvider);
} else {
mTaskbarActivityContext.updateDeviceProfile(dp);
}
@@ -402,6 +419,13 @@
createTaskbarUIControllerForActivity(mActivity));
}
+ if (ENABLE_TASKBAR_NO_RECREATION.get()) {
+ addTaskbarRootViewToWindow();
+ mTaskbarRootLayout.removeAllViews();
+ mTaskbarRootLayout.addView(mTaskbarActivityContext.getDragLayer());
+ mTaskbarActivityContext.notifyUpdateLayoutParams();
+ }
+
// We to wait until user unlocks the device to attach listener.
LauncherPrefs.get(mContext).addListener(mTaskbarPinningPreferenceChangeListener,
TASKBAR_PINNING);
@@ -523,6 +547,22 @@
}
}
+ private void addTaskbarRootViewToWindow() {
+ if (ENABLE_TASKBAR_NO_RECREATION.get() && !mAddedWindow
+ && mTaskbarActivityContext != null) {
+ mWindowManager.addView(mTaskbarRootLayout,
+ mTaskbarActivityContext.getWindowLayoutParams());
+ mAddedWindow = true;
+ }
+ }
+
+ private void removeTaskbarRootViewFromWindow() {
+ if (ENABLE_TASKBAR_NO_RECREATION.get() && mAddedWindow) {
+ mWindowManager.removeViewImmediate(mTaskbarRootLayout);
+ mAddedWindow = false;
+ }
+ }
+
/** Temp logs for b/254119092. */
public void debugWhyTaskbarNotDestroyed(String debugReason) {
StringJoiner log = new StringJoiner("\n");
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java
index 6d86b1e..533785f 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java
@@ -109,15 +109,17 @@
private final TouchInteractionService mService;
private final SystemUiProxy mSystemUiProxy;
private final Handler mHandler;
+ private final AssistUtils mAssistUtils;
@Nullable private StatsLogManager mStatsLogManager;
private final Runnable mResetLongPress = this::resetScreenUnpin;
public TaskbarNavButtonController(TouchInteractionService service,
- SystemUiProxy systemUiProxy, Handler handler) {
+ SystemUiProxy systemUiProxy, Handler handler, AssistUtils assistUtils) {
mService = service;
mSystemUiProxy = systemUiProxy;
mHandler = handler;
+ mAssistUtils = assistUtils;
}
public void onButtonClick(@TaskbarButton int buttonType, View view) {
@@ -313,8 +315,7 @@
return;
}
// Attempt to start Assist with AssistUtils, otherwise fall back to SysUi's implementation.
- if (!AssistUtils.newInstance(mService.getApplicationContext()).tryStartAssistOverride(
- INVOCATION_TYPE_HOME_BUTTON_LONG_PRESS)) {
+ if (!mAssistUtils.tryStartAssistOverride(INVOCATION_TYPE_HOME_BUTTON_LONG_PRESS)) {
Bundle args = new Bundle();
args.putInt(INVOCATION_TYPE_KEY, INVOCATION_TYPE_HOME_BUTTON_LONG_PRESS);
mSystemUiProxy.startAssistant(args);
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/TaskbarSharedState.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarSharedState.java
index 66ca7d9..abbd18b 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarSharedState.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarSharedState.java
@@ -15,15 +15,28 @@
*/
package com.android.launcher3.taskbar;
+import static android.view.InsetsFrameProvider.SOURCE_DISPLAY;
+import static android.view.WindowInsets.Type.mandatorySystemGestures;
+import static android.view.WindowInsets.Type.navigationBars;
+import static android.view.WindowInsets.Type.systemGestures;
+import static android.view.WindowInsets.Type.tappableElement;
+
import static com.android.launcher3.taskbar.LauncherTaskbarUIController.DISPLAY_PROGRESS_COUNT;
import android.app.PendingIntent;
+import android.os.Binder;
+import android.os.IBinder;
+import android.view.InsetsFrameProvider;
/**
* State shared across different taskbar instance
*/
public class TaskbarSharedState {
+ private final IBinder mInsetsOwner = new Binder();
+ private static int INDEX_LEFT = 0;
+ private static int INDEX_RIGHT = 1;
+
// TaskbarManager#onSystemUiFlagsChanged
public int sysuiStateFlags;
@@ -48,4 +61,14 @@
// Taskbar System Action
public PendingIntent taskbarSystemActionPendingIntent;
+
+ public final InsetsFrameProvider[] insetsFrameProviders = new InsetsFrameProvider[] {
+ new InsetsFrameProvider(mInsetsOwner, 0, navigationBars()),
+ new InsetsFrameProvider(mInsetsOwner, 0, tappableElement()),
+ new InsetsFrameProvider(mInsetsOwner, 0, mandatorySystemGestures()),
+ new InsetsFrameProvider(mInsetsOwner, INDEX_LEFT, systemGestures())
+ .setSource(SOURCE_DISPLAY),
+ new InsetsFrameProvider(mInsetsOwner, INDEX_RIGHT, systemGestures())
+ .setSource(SOURCE_DISPLAY)
+ };
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
index b5b453b..ee4db73 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
@@ -33,6 +33,7 @@
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import static com.android.launcher3.util.FlagDebugUtils.appendFlag;
import static com.android.launcher3.util.FlagDebugUtils.formatFlagChange;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BUBBLES_EXPANDED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SHOWING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SWITCHER_SHOWING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_VISIBLE;
@@ -96,6 +97,7 @@
public static final int FLAG_STASHED_IN_APP_AUTO = 1 << 9; // Autohide (transient taskbar).
public static final int FLAG_STASHED_SYSUI = 1 << 10; // app pinning,...
public static final int FLAG_STASHED_DEVICE_LOCKED = 1 << 11; // device is locked: keyguard, ...
+ public static final int FLAG_IN_OVERVIEW = 1 << 12; // launcher is in overview
// If any of these flags are enabled, isInApp should return true.
private static final int FLAGS_IN_APP = FLAG_IN_APP | FLAG_IN_SETUP;
@@ -1015,9 +1017,12 @@
updateStateForFlag(FLAG_STASHED_IN_APP_SYSUI, hasAnyFlag(systemUiStateFlags,
SYSUI_STATE_NOTIFICATION_PANEL_VISIBLE));
- updateStateForFlag(FLAG_STASHED_SYSUI,
- hasAnyFlag(systemUiStateFlags, SYSUI_STATE_SCREEN_PINNING));
+ boolean stashForBubbles = hasAnyFlag(FLAG_IN_OVERVIEW)
+ && hasAnyFlag(systemUiStateFlags, SYSUI_STATE_BUBBLES_EXPANDED)
+ && DisplayController.isTransientTaskbar(mActivity);
+ updateStateForFlag(FLAG_STASHED_SYSUI,
+ hasAnyFlag(systemUiStateFlags, SYSUI_STATE_SCREEN_PINNING) || stashForBubbles);
boolean isLocked = hasAnyFlag(systemUiStateFlags, MASK_ANY_SYSUI_LOCKED)
&& !hasAnyFlag(systemUiStateFlags, SYSUI_STATE_STATUS_BAR_KEYGUARD_GOING_AWAY);
updateStateForFlag(FLAG_STASHED_DEVICE_LOCKED, isLocked);
@@ -1097,6 +1102,7 @@
TaskbarAutohideSuspendController.FLAG_AUTOHIDE_SUSPEND_TRANSIENT_TASKBAR,
!hasAnyFlag(FLAG_STASHED_IN_APP_AUTO));
}
+ mActivity.applyForciblyShownFlagWhileTransientTaskbarUnstashed(!isStashedInApp());
}
private void notifyStashChange(boolean visible, boolean stashed) {
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
index 6fad655..139e8f0 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
@@ -43,7 +43,6 @@
import com.android.systemui.shared.recents.model.Task;
import java.io.PrintWriter;
-import java.util.Arrays;
import java.util.Collections;
import java.util.stream.Stream;
@@ -336,4 +335,7 @@
.stream()
.map(mControllers.taskbarPopupController::createSplitShortcutFactory);
}
+
+ /** Adjusts the hotseat for the bubble bar. */
+ public void adjustHotseatForBubbleBar(boolean isBubbleBarVisible) {}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
index fa5a1ae..0e5ab71 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
@@ -18,6 +18,7 @@
import static android.content.pm.PackageManager.FEATURE_PC;
import static android.view.accessibility.AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED;
+import static com.android.launcher3.config.FeatureFlags.ENABLE_ALL_APPS_SEARCH_IN_TASKBAR;
import static com.android.launcher3.config.FeatureFlags.ENABLE_CURSOR_HOVER_STATES;
import static com.android.launcher3.icons.IconNormalizer.ICON_VISIBLE_AREA_FACTOR;
@@ -33,6 +34,8 @@
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.FrameLayout;
+import androidx.annotation.DimenRes;
+import androidx.annotation.DrawableRes;
import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -90,11 +93,11 @@
// Only non-null when device supports having an All Apps button.
private @Nullable IconButtonView mTaskbarDivider;
- private View mQsb;
+ private final View mQsb;
- private float mTransientTaskbarMinWidth;
+ private final float mTransientTaskbarMinWidth;
- private float mTransientTaskbarAllAppsButtonTranslationXOffset;
+ private final float mTaskbarAllAppsButtonTranslationXOffset;
private boolean mShouldTryStartAlign;
@@ -120,12 +123,9 @@
boolean isTransientTaskbar = DisplayController.isTransientTaskbar(mActivityContext)
&& !TaskbarManager.isPhoneMode(mActivityContext.getDeviceProfile());
mIsRtl = Utilities.isRtl(resources);
- mTransientTaskbarMinWidth = mContext.getResources().getDimension(
- R.dimen.transient_taskbar_min_width);
- mTransientTaskbarAllAppsButtonTranslationXOffset =
- resources.getDimension(isTransientTaskbar
- ? R.dimen.transient_taskbar_all_apps_button_translation_x_offset
- : R.dimen.taskbar_all_apps_button_translation_x_offset);
+ mTransientTaskbarMinWidth = resources.getDimension(R.dimen.transient_taskbar_min_width);
+ mTaskbarAllAppsButtonTranslationXOffset =
+ resources.getDimension(getAllAppsButtonTranslationXOffset(isTransientTaskbar));
onDeviceProfileChanged(mActivityContext.getDeviceProfile());
@@ -149,9 +149,8 @@
if (!mActivityContext.getPackageManager().hasSystemFeature(FEATURE_PC)) {
mAllAppsButton = (IconButtonView) LayoutInflater.from(context)
.inflate(R.layout.taskbar_all_apps_button, this, false);
- mAllAppsButton.setIconDrawable(resources.getDrawable(isTransientTaskbar
- ? R.drawable.ic_transient_taskbar_all_apps_button
- : R.drawable.ic_taskbar_all_apps_button));
+ mAllAppsButton.setIconDrawable(resources.getDrawable(
+ getAllAppsButton(isTransientTaskbar)));
mAllAppsButton.setScaleX(mIsRtl ? -1 : 1);
mAllAppsButton.setPadding(mItemPadding, mItemPadding, mItemPadding, mItemPadding);
mAllAppsButton.setForegroundTint(
@@ -171,6 +170,30 @@
mQsb = LayoutInflater.from(context).inflate(R.layout.search_container_hotseat, this, false);
}
+ @DrawableRes
+ private int getAllAppsButton(boolean isTransientTaskbar) {
+ if (ENABLE_ALL_APPS_SEARCH_IN_TASKBAR.get()) {
+ return isTransientTaskbar
+ ? R.drawable.ic_transient_taskbar_all_apps_search_button
+ : R.drawable.ic_taskbar_all_apps_search_button;
+ } else {
+ return isTransientTaskbar
+ ? R.drawable.ic_transient_taskbar_all_apps_button
+ : R.drawable.ic_taskbar_all_apps_button;
+ }
+ }
+
+ @DimenRes
+ private int getAllAppsButtonTranslationXOffset(boolean isTransientTaskbar) {
+ if (isTransientTaskbar) {
+ return R.dimen.transient_taskbar_all_apps_button_translation_x_offset;
+ } else {
+ return ENABLE_ALL_APPS_SEARCH_IN_TASKBAR.get()
+ ? R.dimen.taskbar_all_apps_search_button_translation_x_offset
+ : R.dimen.taskbar_all_apps_button_translation_x_offset;
+ }
+ }
+
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
@@ -336,7 +359,7 @@
if (mAllAppsButton != null) {
mAllAppsButton.setTranslationXForTaskbarAllAppsIcon(getChildCount() > 0
- ? mTransientTaskbarAllAppsButtonTranslationXOffset : 0f);
+ ? mTaskbarAllAppsButtonTranslationXOffset : 0f);
addView(mAllAppsButton, mIsRtl ? getChildCount() : 0);
// if only all apps button present, don't include divider view.
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
index 3d22e78..54840f1 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
@@ -448,6 +448,11 @@
}
}
+ /** Resets the icon alignment controller so that it can be recreated again later. */
+ void resetIconAlignmentController() {
+ mIconAlignControllerLazy = null;
+ }
+
/**
* Creates an animation for aligning the Taskbar icons with the provided Launcher device profile
*/
@@ -564,9 +569,18 @@
continue;
}
- float hotseatIconCenter = hotseatPadding.left
- + (hotseatCellSize + borderSpacing) * positionInHotseat
- + hotseatCellSize / 2f;
+ float hotseatAdjustedBorderSpace =
+ launcherDp.getHotseatAdjustedBorderSpaceForBubbleBar(child.getContext());
+ float hotseatIconCenter;
+ if (bubbleBarHasBubbles() && hotseatAdjustedBorderSpace != 0) {
+ hotseatIconCenter = hotseatPadding.left + hotseatCellSize
+ + (hotseatCellSize + hotseatAdjustedBorderSpace) * positionInHotseat
+ + hotseatCellSize / 2f;
+ } else {
+ hotseatIconCenter = hotseatPadding.left
+ + (hotseatCellSize + borderSpacing) * positionInHotseat
+ + hotseatCellSize / 2f;
+ }
float childCenter = (child.getLeft() + child.getRight()) / 2f;
float toX = hotseatIconCenter - childCenter;
if (child instanceof Reorderable) {
@@ -588,6 +602,11 @@
return controller;
}
+ private boolean bubbleBarHasBubbles() {
+ return mControllers.bubbleControllers.isPresent()
+ && mControllers.bubbleControllers.get().bubbleBarViewController.hasBubbles();
+ }
+
public void onRotationChanged(DeviceProfile deviceProfile) {
if (!mControllers.uiController.isIconAlignedWithHotseat()) {
// We only translate on rotation when icon is aligned with hotseat
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/TaskbarAllAppsSlideInView.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java
index 537d2c6..001c3bc 100644
--- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java
@@ -21,12 +21,16 @@
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Rect;
+import android.os.Handler;
+import android.os.Looper;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Interpolator;
import android.window.OnBackInvokedDispatcher;
+import androidx.annotation.Nullable;
+
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Insettable;
import com.android.launcher3.R;
@@ -40,8 +44,11 @@
/** Wrapper for taskbar all apps with slide-in behavior. */
public class TaskbarAllAppsSlideInView extends AbstractSlideInView<TaskbarOverlayContext>
implements Insettable, DeviceProfile.OnDeviceProfileChangeListener {
+ private final Handler mHandler;
+
private TaskbarAllAppsContainerView mAppsView;
private float mShiftRange;
+ private @Nullable Runnable mShowOnFullyAttachedToWindowRunnable;
// Initialized in init.
private TaskbarAllAppsCallbacks mAllAppsCallbacks;
@@ -53,6 +60,7 @@
public TaskbarAllAppsSlideInView(Context context, AttributeSet attrs,
int defStyleAttr) {
super(context, attrs, defStyleAttr);
+ mHandler = new Handler(Looper.myLooper());
}
void init(TaskbarAllAppsCallbacks callbacks) {
@@ -65,14 +73,14 @@
return;
}
mIsOpen = true;
- attachToContainer();
addOnAttachStateChangeListener(new OnAttachStateChangeListener() {
@Override
public void onViewAttachedToWindow(View v) {
removeOnAttachStateChangeListener(this);
// Wait for view and its descendants to be fully attached before starting open.
- post(() -> showOnFullyAttachedToWindow(animate));
+ mShowOnFullyAttachedToWindowRunnable = () -> showOnFullyAttachedToWindow(animate);
+ mHandler.post(mShowOnFullyAttachedToWindowRunnable);
}
@Override
@@ -80,6 +88,7 @@
removeOnAttachStateChangeListener(this);
}
});
+ attachToContainer();
}
private void showOnFullyAttachedToWindow(boolean animate) {
@@ -114,6 +123,10 @@
@Override
protected void handleClose(boolean animate) {
+ if (mShowOnFullyAttachedToWindowRunnable != null) {
+ mHandler.removeCallbacks(mShowOnFullyAttachedToWindowRunnable);
+ mShowOnFullyAttachedToWindowRunnable = null;
+ }
if (mIsOpen) {
mAllAppsCallbacks.onAllAppsTransitionStart(false);
}
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/taskbar/bubbles/BubbleBarController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java
index 24db380..bd11efd 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java
@@ -137,6 +137,7 @@
private static class BubbleBarViewUpdate {
boolean expandedChanged;
boolean expanded;
+ boolean shouldShowEducation;
String selectedBubbleKey;
String suppressedBubbleKey;
String unsuppressedBubbleKey;
@@ -151,6 +152,7 @@
BubbleBarViewUpdate(BubbleBarUpdate update) {
expandedChanged = update.expandedChanged;
expanded = update.expanded;
+ shouldShowEducation = update.shouldShowEducation;
selectedBubbleKey = update.selectedBubbleKey;
suppressedBubbleKey = update.suppressedBubbleKey;
unsuppressedBubbleKey = update.unsupressedBubbleKey;
@@ -188,8 +190,10 @@
mBubbleStashedHandleViewController = bubbleControllers.bubbleStashedHandleViewController;
bubbleControllers.runAfterInit(() -> {
- mBubbleBarViewController.setHiddenForBubbles(!BUBBLE_BAR_ENABLED);
- mBubbleStashedHandleViewController.setHiddenForBubbles(!BUBBLE_BAR_ENABLED);
+ mBubbleBarViewController.setHiddenForBubbles(
+ !BUBBLE_BAR_ENABLED || mBubbles.isEmpty());
+ mBubbleStashedHandleViewController.setHiddenForBubbles(
+ !BUBBLE_BAR_ENABLED || mBubbles.isEmpty());
mBubbleBarViewController.setUpdateSelectedBubbleAfterCollapse(
key -> setSelectedBubble(mBubbles.get(key)));
});
@@ -366,7 +370,9 @@
mBubbleStashController.animateToInitialState(update.expanded);
}
}
-
+ if (update.shouldShowEducation) {
+ mBubbleBarViewController.prepareToShowEducation();
+ }
if (update.expandedChanged) {
if (update.expanded != mBubbleBarViewController.isExpanded()) {
mBubbleBarViewController.setExpandedFromSysui(update.expanded);
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java
index 20b8e3b..065dd58 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java
@@ -18,6 +18,7 @@
import static android.view.View.INVISIBLE;
import static android.view.View.VISIBLE;
+import android.graphics.Point;
import android.graphics.Rect;
import android.util.Log;
import android.view.MotionEvent;
@@ -74,7 +75,8 @@
// Whether the bar is hidden for a sysui state.
private boolean mHiddenForSysui;
// Whether the bar is hidden because there are no bubbles.
- private boolean mHiddenForNoBubbles;
+ private boolean mHiddenForNoBubbles = true;
+ private boolean mShouldShowEducation;
public BubbleBarViewController(TaskbarActivityContext activity, BubbleBarView barView) {
mActivity = activity;
@@ -98,7 +100,7 @@
mBarView.getLayoutParams().height = mActivity.getDeviceProfile().taskbarHeight;
mBubbleBarScale.updateValue(1f);
mBubbleClickListener = v -> onBubbleClicked(v);
- mBubbleBarClickListener = v -> setExpanded(true);
+ mBubbleBarClickListener = v -> onBubbleBarClicked();
mBubbleDragController.setupBubbleBarView(mBarView);
mBarView.setOnClickListener(mBubbleBarClickListener);
mBarView.addOnLayoutChangeListener((view, i, i1, i2, i3, i4, i5, i6, i7) ->
@@ -121,6 +123,21 @@
}
}
+ private void onBubbleBarClicked() {
+ if (mShouldShowEducation) {
+ mShouldShowEducation = false;
+ // Get the bubble bar bounds on screen
+ Rect bounds = new Rect();
+ mBarView.getBoundsOnScreen(bounds);
+ // Calculate user education reference position in Screen coordinates
+ Point position = new Point(bounds.centerX(), bounds.top);
+ // Show user education relative to the reference point
+ mSystemUiProxy.showUserEducation(position);
+ } else {
+ setExpanded(true);
+ }
+ }
+
//
// The below animators are exposed to BubbleStashController so it can manage the stashing
// animation.
@@ -195,6 +212,7 @@
if (mHiddenForNoBubbles != hidden) {
mHiddenForNoBubbles = hidden;
updateVisibilityForStateChange();
+ mActivity.bubbleBarVisibilityChanged(!hidden);
}
}
@@ -326,6 +344,12 @@
}
}
+ /** Marks as should show education and shows the bubble bar in a collapsed state */
+ public void prepareToShowEducation() {
+ mShouldShowEducation = true;
+ mBubbleStashController.showBubbleBar(false /* expand the bubbles */);
+ }
+
/**
* Updates the dragged bubble view in the bubble bar view, and notifies SystemUI
* that a bubble is being dragged to dismiss.
diff --git a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayController.java b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayController.java
index d4e2be9..9126c4b 100644
--- a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayController.java
@@ -62,12 +62,30 @@
@Override
public void onTaskCreated(int taskId, ComponentName componentName) {
// Created task will be below existing overlay, so move out of the way.
- hideWindow();
+ hideWindowOnTaskStackChange();
}
@Override
public void onTaskMovedToFront(int taskId) {
// New front task will be below existing overlay, so move out of the way.
+ hideWindowOnTaskStackChange();
+ }
+
+ @Override
+ public void onTaskStackChanged() {
+ // The other callbacks are insufficient for All Apps, because there are many cases where
+ // it can relaunch the same task already behind it. However, this callback needs to be a
+ // no-op when only EDU is shown, because going between the EDU steps invokes this
+ // callback.
+ if (mControllers.getSharedState() != null
+ && mControllers.getSharedState().allAppsVisible) {
+ hideWindowOnTaskStackChange();
+ }
+ }
+
+ private void hideWindowOnTaskStackChange() {
+ // A task was launched while overlay window was open, so stash Taskbar.
+ mControllers.taskbarStashController.updateAndAnimateTransientTaskbar(true);
hideWindow();
}
};
@@ -199,8 +217,10 @@
@Override
protected void handleClose(boolean animate) {
- mTaskbarContext.getDragLayer().removeView(this);
- Optional.ofNullable(mOverlayContext).ifPresent(c -> closeAllOpenViews(c, animate));
+ if (mIsOpen) {
+ mTaskbarContext.getDragLayer().removeView(this);
+ Optional.ofNullable(mOverlayContext).ifPresent(c -> closeAllOpenViews(c, animate));
+ }
}
@Override
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index b50ab97..1756117 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -73,10 +73,13 @@
import android.os.IBinder;
import android.os.SystemProperties;
import android.os.Trace;
+import android.util.AttributeSet;
import android.util.Log;
import android.view.Display;
import android.view.HapticFeedbackConstants;
import android.view.View;
+import android.widget.AnalogClock;
+import android.widget.TextClock;
import android.window.BackEvent;
import android.window.OnBackAnimationCallback;
import android.window.OnBackInvokedDispatcher;
@@ -133,7 +136,6 @@
import com.android.launcher3.uioverrides.touchcontrollers.TransposedQuickSwitchTouchController;
import com.android.launcher3.uioverrides.touchcontrollers.TwoButtonNavbarTouchController;
import com.android.launcher3.util.ActivityOptionsWrapper;
-import com.android.launcher3.util.BackPressHandler;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.Executors;
import com.android.launcher3.util.IntSet;
@@ -153,6 +155,7 @@
import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.TaskUtils;
import com.android.quickstep.TouchInteractionService.TISBinder;
+import com.android.quickstep.util.AsyncClockEventDelegate;
import com.android.quickstep.util.GroupTask;
import com.android.quickstep.util.LauncherUnfoldAnimationController;
import com.android.quickstep.util.QuickstepOnboardingPrefs;
@@ -214,6 +217,8 @@
private SplitWithKeyboardShortcutController mSplitWithKeyboardShortcutController;
private SplitToWorkspaceController mSplitToWorkspaceController;
+ private AsyncClockEventDelegate mAsyncClockEventDelegate;
+
/**
* If Launcher restarted while in the middle of an Overview split select, it needs this data to
* recover. In all other cases this will remain null.
@@ -345,9 +350,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));
}
@@ -483,6 +486,10 @@
mSplitSelectStateController.onDestroy();
}
+ if (mAsyncClockEventDelegate != null) {
+ mAsyncClockEventDelegate.onDestroy();
+ }
+
super.onDestroy();
mHotseatPredictionController.destroy();
mSplitWithKeyboardShortcutController.onDestroy();
@@ -693,6 +700,14 @@
}
super.onPause();
+
+ if (ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE.get()) {
+ // If Launcher pauses before both split apps are selected, exit split screen.
+ if (!mSplitSelectStateController.isBothSplitAppsConfirmed()) {
+ mSplitSelectStateController.getSplitAnimationController()
+ .playPlaceholderDismissAnim(this);
+ }
+ }
}
@Override
@@ -739,15 +754,6 @@
}
@Override
- protected void onScreenOnChanged(boolean isOn) {
- super.onScreenOnChanged(isOn);
- if (!isOn) {
- RecentsView recentsView = getOverviewPanel();
- recentsView.finishRecentsAnimation(true /* toRecents */, null);
- }
- }
-
- @Override
public void onAllAppsTransition(float progress) {
super.onAllAppsTransition(progress);
onTaskbarInAppDisplayProgressUpdate(progress, ALL_APPS_PAGE_PROGRESS_INDEX);
@@ -1272,6 +1278,16 @@
return overviewCommandHelper == null || overviewCommandHelper.canStartHomeSafely();
}
+ @Override
+ public boolean isBubbleBarEnabled() {
+ return (mTaskbarUIController != null && mTaskbarUIController.isBubbleBarEnabled());
+ }
+
+ @Override
+ public boolean hasBubbles() {
+ return (mTaskbarUIController != null && mTaskbarUIController.hasBubbles());
+ }
+
private static final class LauncherTaskViewController extends
TaskViewTouchController<Launcher> {
@@ -1311,5 +1327,31 @@
if (mAppTransitionManager != null) {
mAppTransitionManager.dump(prefix + "\t" + RING_APPEAR_ANIMATION_PREFIX, writer);
}
+ if (mHotseatPredictionController != null) {
+ mHotseatPredictionController.dump(prefix, writer);
+ }
+ }
+
+ @Override
+ public View onCreateView(View parent, String name, Context context, AttributeSet attrs) {
+ switch (name) {
+ case "TextClock", "android.widget.TextClock" -> {
+ TextClock tc = new TextClock(context, attrs);
+ if (mAsyncClockEventDelegate == null) {
+ mAsyncClockEventDelegate = new AsyncClockEventDelegate(this);
+ }
+ tc.setClockEventDelegate(mAsyncClockEventDelegate);
+ return tc;
+ }
+ case "AnalogClock", "android.widget.AnalogClock" -> {
+ AnalogClock ac = new AnalogClock(context, attrs);
+ if (mAsyncClockEventDelegate == null) {
+ mAsyncClockEventDelegate = new AsyncClockEventDelegate(this);
+ }
+ ac.setClockEventDelegate(mAsyncClockEventDelegate);
+ return ac;
+ }
+ }
+ return super.onCreateView(parent, name, context, attrs);
}
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepWidgetHolder.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepWidgetHolder.java
index f7bef03..f66bc60 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepWidgetHolder.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepWidgetHolder.java
@@ -37,6 +37,7 @@
import com.android.launcher3.widget.LauncherAppWidgetHostView;
import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
import com.android.launcher3.widget.LauncherWidgetHolder;
+import com.android.launcher3.widget.custom.CustomWidgetManager;
import java.util.ArrayList;
import java.util.Collections;
@@ -237,6 +238,14 @@
@Override
public LauncherAppWidgetHostView createView(@NonNull Context context, int appWidgetId,
@NonNull LauncherAppWidgetProviderInfo appWidget) {
+
+ if (appWidget.isCustomWidget()) {
+ LauncherAppWidgetHostView lahv = new LauncherAppWidgetHostView(context);
+ lahv.setAppWidget(appWidgetId, appWidget);
+ CustomWidgetManager.INSTANCE.get(context).onViewCreated(lahv);
+ return lahv;
+ }
+
LauncherAppWidgetHostView widgetView = getPendingView(appWidgetId);
if (widgetView != null) {
removePendingView(appWidgetId);
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/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index 9b8dd5f..ca4f0ea 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -1189,7 +1189,8 @@
break;
}
ActiveGestureLog.INSTANCE.addLog(
- /* event= */ "onSettledOnEndTarget " + endTarget,
+ new ActiveGestureLog.CompoundString("onSettledOnEndTarget ")
+ .append(endTarget.name()),
/* gestureEvent= */ ON_SETTLED_ON_END_TARGET);
}
@@ -2215,7 +2216,8 @@
TaskView nextTask = mRecentsView == null ? null : mRecentsView.getNextPageTaskView();
if (nextTask != null) {
int[] taskIds = nextTask.getTaskIds();
- StringBuilder nextTaskLog = new StringBuilder();
+ ActiveGestureLog.CompoundString nextTaskLog = new ActiveGestureLog.CompoundString(
+ "Launching task: ");
for (TaskIdAttributeContainer c : nextTask.getTaskIdAttributeContainers()) {
if (c == null) {
continue;
@@ -2234,7 +2236,7 @@
if (!hasTaskPreviouslyAppeared) {
ActiveGestureLog.INSTANCE.trackEvent(EXPECTING_TASK_APPEARED);
}
- ActiveGestureLog.INSTANCE.addLog("Launching task: " + nextTaskLog);
+ ActiveGestureLog.INSTANCE.addLog(nextTaskLog);
nextTask.launchTask(success -> {
resultCallback.accept(success);
if (success) {
@@ -2310,9 +2312,12 @@
// previous quickswitch task launch, then cancel the animation back to the app
RemoteAnimationTarget appearedTaskTarget = appearedTaskTargets[0];
TaskInfo taskInfo = appearedTaskTarget.taskInfo;
- ActiveGestureLog.INSTANCE.addLog("Unexpected task appeared"
- + " id=" + taskInfo.taskId
- + " pkg=" + taskInfo.baseIntent.getComponent().getPackageName());
+ ActiveGestureLog.INSTANCE.addLog(
+ new ActiveGestureLog.CompoundString("Unexpected task appeared")
+ .append(" id=")
+ .append(taskInfo.taskId)
+ .append(" pkg=")
+ .append(taskInfo.baseIntent.getComponent().getPackageName()));
finishRecentsAnimationOnTasksAppeared(null /* onFinishComplete */);
} else if (handleTaskAppeared(appearedTaskTargets)) {
Optional<RemoteAnimationTarget> taskTargetOptional =
diff --git a/quickstep/src/com/android/quickstep/BaseActivityInterface.java b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
index 5a9d80d..3f88139 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);
@@ -437,11 +437,13 @@
}
protected void runOnInitBackgroundStateUI(Runnable callback) {
- mOnInitBackgroundStateUICallback = callback;
ACTIVITY_TYPE activity = getCreatedActivity();
if (activity != null && activity.getStateManager().getState() == mBackgroundState) {
+ callback.run();
onInitBackgroundStateUI();
+ return;
}
+ mOnInitBackgroundStateUICallback = callback;
}
private void onInitBackgroundStateUI() {
diff --git a/quickstep/src/com/android/quickstep/GestureState.java b/quickstep/src/com/android/quickstep/GestureState.java
index c2d8c62..49ec85e 100644
--- a/quickstep/src/com/android/quickstep/GestureState.java
+++ b/quickstep/src/com/android/quickstep/GestureState.java
@@ -410,7 +410,8 @@
mEndTarget = target;
mStateCallback.setState(STATE_END_TARGET_SET);
ActiveGestureLog.INSTANCE.addLog(
- /* event= */ "setEndTarget " + mEndTarget,
+ new ActiveGestureLog.CompoundString("setEndTarget ")
+ .append(mEndTarget.name()),
/* gestureEvent= */ SET_END_TARGET);
switch (mEndTarget) {
case HOME:
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/OverviewCommandHelper.java b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
index 42bf1ac..833bf5f 100644
--- a/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
+++ b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
@@ -78,6 +78,14 @@
*/
private int mTaskFocusIndexOverride = -1;
+ /**
+ * Whether we should incoming toggle commands while a previous toggle command is still ongoing.
+ * This serves as a rate-limiter to prevent overlapping animations that can clobber each other
+ * and prevent clean-up callbacks from running. This thus prevents a recurring set of bugs with
+ * janky recents animations and unresponsive home and overview buttons.
+ */
+ private boolean mWaitForToggleCommandComplete = false;
+
public OverviewCommandHelper(TouchInteractionService service,
OverviewComponentObserver observer,
TaskAnimationManager taskAnimationManager) {
@@ -160,15 +168,20 @@
private boolean launchTask(RecentsView recents, @Nullable TaskView taskView, CommandInfo cmd) {
RunnableList callbackList = null;
if (taskView != null) {
+ mWaitForToggleCommandComplete = true;
taskView.setEndQuickswitchCuj(true);
callbackList = taskView.launchTasks();
}
if (callbackList != null) {
- callbackList.add(() -> scheduleNextTask(cmd));
+ callbackList.add(() -> {
+ scheduleNextTask(cmd);
+ mWaitForToggleCommandComplete = false;
+ });
return false;
} else {
recents.startHome();
+ mWaitForToggleCommandComplete = false;
return true;
}
}
@@ -178,6 +191,9 @@
* task is deferred until {@link #scheduleNextTask} is called
*/
private <T extends StatefulActivity<?>> boolean executeCommand(CommandInfo cmd) {
+ if (mWaitForToggleCommandComplete && cmd.type == TYPE_TOGGLE) {
+ return true;
+ }
BaseActivityInterface<?, T> activityInterface =
mOverviewComponentObserver.getActivityInterface();
RecentsView recents = activityInterface.getVisibleRecentsView();
@@ -359,6 +375,7 @@
pw.println(" pendingCommandType=" + mPendingCommands.get(0).type);
}
pw.println(" mTaskFocusIndexOverride=" + mTaskFocusIndexOverride);
+ pw.println(" mWaitForToggleCommandComplete=" + mWaitForToggleCommandComplete);
}
private static class CommandInfo {
diff --git a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java b/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java
index 031d409..9be9294 100644
--- a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java
+++ b/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java
@@ -44,9 +44,7 @@
}
case TestProtocol.REQUEST_BACKGROUND_TO_OVERVIEW_SWIPE_HEIGHT: {
- final float swipeHeight =
- LayoutUtils.getShelfTrackingDistance(mContext, mDeviceProfile,
- PagedOrientationHandler.PORTRAIT);
+ final float swipeHeight = mDeviceProfile.heightPx / 2f;
response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD, (int) swipeHeight);
return response;
}
diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java
index 99dd634..5da41ae 100644
--- a/quickstep/src/com/android/quickstep/SystemUiProxy.java
+++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java
@@ -31,6 +31,7 @@
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ShortcutInfo;
+import android.graphics.Point;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.Handler;
@@ -731,6 +732,18 @@
}
}
+ /**
+ * Tells SysUI to show user education relative to the reference point provided.
+ * @param position the bubble bar top center position in Screen coordinates.
+ */
+ public void showUserEducation(Point position) {
+ try {
+ mBubbles.showUserEducation(position.x, position.y);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed call showUserEducation");
+ }
+ }
+
//
// Splitscreen
//
diff --git a/quickstep/src/com/android/quickstep/TaskAnimationManager.java b/quickstep/src/com/android/quickstep/TaskAnimationManager.java
index 0de4ffc..f5a7ecc 100644
--- a/quickstep/src/com/android/quickstep/TaskAnimationManager.java
+++ b/quickstep/src/com/android/quickstep/TaskAnimationManager.java
@@ -201,8 +201,9 @@
RecentsView recentsView =
activityInterface.getCreatedActivity().getOverviewPanel();
if (recentsView != null) {
- ActiveGestureLog.INSTANCE.addLog("Launching side task id="
- + appearedTaskTarget.taskId);
+ ActiveGestureLog.INSTANCE.addLog(
+ new ActiveGestureLog.CompoundString("Launching side task id=")
+ .append(appearedTaskTarget.taskId));
recentsView.launchSideTaskInLiveTileMode(appearedTaskTarget.taskId,
appearedTaskTargets,
new RemoteAnimationTarget[0] /* wallpaper */,
@@ -331,7 +332,7 @@
* Finishes the running recents animation.
* @param forceFinish will synchronously finish the controller
*/
- private void finishRunningRecentsAnimation(boolean toHome, boolean forceFinish) {
+ public void finishRunningRecentsAnimation(boolean toHome, boolean forceFinish) {
if (mController != null) {
ActiveGestureLog.INSTANCE.addLog(
/* event= */ "finishRunningRecentsAnimation", toHome);
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/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index c1680de..c615d5f 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -28,6 +28,7 @@
import static com.android.launcher3.MotionEventsUtils.isTrackpadMultiFingerSwipe;
import static com.android.launcher3.config.FeatureFlags.ENABLE_TRACKPAD_GESTURE;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
+import static com.android.launcher3.util.window.WindowManagerProxy.MIN_TABLET_WIDTH;
import static com.android.quickstep.GestureState.DEFAULT_STATE;
import static com.android.quickstep.GestureState.TrackpadGestureType.getTrackpadGestureType;
import static com.android.quickstep.InputConsumer.TYPE_CURSOR_HOVER;
@@ -68,6 +69,7 @@
import android.os.IBinder;
import android.os.Looper;
import android.os.SystemClock;
+import android.os.Trace;
import android.util.Log;
import android.view.Choreographer;
import android.view.InputDevice;
@@ -100,6 +102,7 @@
import com.android.launcher3.util.LockedUserState;
import com.android.launcher3.util.OnboardingPrefs;
import com.android.launcher3.util.SafeCloseable;
+import com.android.launcher3.util.ScreenOnTracker;
import com.android.launcher3.util.TraceHelper;
import com.android.quickstep.inputconsumers.AccessibilityInputConsumer;
import com.android.quickstep.inputconsumers.AssistantInputConsumer;
@@ -449,6 +452,8 @@
private final AbsSwipeUpHandler.Factory mFallbackSwipeHandlerFactory =
this::createFallbackSwipeHandler;
+ private final ScreenOnTracker.ScreenOnListener mScreenOnListener = this::onScreenOnChanged;
+
private ActivityManagerWrapper mAM;
private OverviewCommandHelper mOverviewCommandHelper;
private OverviewComponentObserver mOverviewComponentObserver;
@@ -485,6 +490,8 @@
LockedUserState.get(this).runOnUserUnlocked(mTaskbarManager::onUserUnlocked);
mDeviceState.addNavigationModeChangedCallback(this::onNavigationModeChanged);
sConnected = true;
+
+ ScreenOnTracker.INSTANCE.get(this).addListener(mScreenOnListener);
}
private void disposeEventHandlers(String reason) {
@@ -657,6 +664,8 @@
mTaskbarManager.destroy();
sConnected = false;
+
+ ScreenOnTracker.INSTANCE.get(this).removeListener(mScreenOnListener);
super.onDestroy();
}
@@ -666,6 +675,17 @@
return mTISBinder;
}
+ protected void onScreenOnChanged(boolean isOn) {
+ if (isOn) {
+ return;
+ }
+ long currentTime = SystemClock.uptimeMillis();
+ MotionEvent cancelEvent = MotionEvent.obtain(
+ currentTime, currentTime, ACTION_CANCEL, 0f, 0f, 0);
+ onInputEvent(cancelEvent);
+ cancelEvent.recycle();
+ }
+
private void onInputEvent(InputEvent ev) {
if (!(ev instanceof MotionEvent)) {
Log.e(TAG, "Unknown event " + ev);
@@ -729,29 +749,42 @@
}
if (mUncheckedConsumer != InputConsumer.NO_OP) {
- switch (event.getActionMasked()) {
+ switch (action) {
case ACTION_DOWN:
// fall through
case ACTION_UP:
ActiveGestureLog.INSTANCE.addLog(
- /* event= */ "onMotionEvent(" + (int) event.getRawX() + ", "
- + (int) event.getRawY() + "): "
- + MotionEvent.actionToString(event.getActionMasked()) + ", "
- + MotionEvent.classificationToString(event.getClassification()),
- /* gestureEvent= */ event.getActionMasked() == ACTION_DOWN
+ new CompoundString("onMotionEvent(")
+ .append((int) event.getRawX())
+ .append(", ")
+ .append((int) event.getRawY())
+ .append("): ")
+ .append(MotionEvent.actionToString(action))
+ .append(", ")
+ .append(MotionEvent.classificationToString(
+ event.getClassification())),
+ /* gestureEvent= */ action == ACTION_DOWN
? MOTION_DOWN
: MOTION_UP);
break;
case ACTION_MOVE:
- ActiveGestureLog.INSTANCE.addLog("onMotionEvent: "
- + MotionEvent.actionToString(event.getActionMasked()) + ","
- + MotionEvent.classificationToString(event.getClassification())
- + ", pointerCount: " + event.getPointerCount(), MOTION_MOVE);
+ ActiveGestureLog.INSTANCE.addLog(
+ new CompoundString("onMotionEvent: ")
+ .append(MotionEvent.actionToString(action))
+ .append(",")
+ .append(MotionEvent.classificationToString(
+ event.getClassification()))
+ .append(", pointerCount: ")
+ .append(event.getPointerCount()),
+ MOTION_MOVE);
break;
default: {
- ActiveGestureLog.INSTANCE.addLog("onMotionEvent: "
- + MotionEvent.actionToString(event.getActionMasked()) + ","
- + MotionEvent.classificationToString(event.getClassification()));
+ ActiveGestureLog.INSTANCE.addLog(
+ new CompoundString("onMotionEvent: ")
+ .append(MotionEvent.actionToString(action))
+ .append(",")
+ .append(MotionEvent.classificationToString(
+ event.getClassification())));
}
}
}
@@ -1210,7 +1243,9 @@
}
private void preloadOverview(boolean fromInit) {
+ Trace.beginSection("preloadOverview(fromInit=" + fromInit + ")");
preloadOverview(fromInit, false);
+ Trace.endSection();
}
private void preloadOverview(boolean fromInit, boolean forSUWAllSet) {
@@ -1260,7 +1295,10 @@
// We only care about the existing background activity.
return;
}
- if (mOverviewComponentObserver.canHandleConfigChanges(activity.getComponentName(),
+ Configuration oldConfig = activity.getResources().getConfiguration();
+ boolean isFoldUnfold = isTablet(oldConfig) != isTablet(newConfig);
+ if (!isFoldUnfold && mOverviewComponentObserver.canHandleConfigChanges(
+ activity.getComponentName(),
activity.getResources().getConfiguration().diff(newConfig))) {
// Since navBar gestural height are different between portrait and landscape,
// can handle orientation changes and refresh navigation gestural region through
@@ -1275,6 +1313,10 @@
preloadOverview(false /* fromInit */);
}
+ private static boolean isTablet(Configuration config) {
+ return config.smallestScreenWidthDp >= MIN_TABLET_WIDTH;
+ }
+
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] rawArgs) {
// Dump everything
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressInputConsumer.java
index a9accb7..0b11b00 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressInputConsumer.java
@@ -15,6 +15,8 @@
*/
package com.android.quickstep.inputconsumers;
+import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
+
import android.content.Context;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
@@ -52,7 +54,7 @@
if (longPressRunnable != null) {
setActive(motionEvent);
- longPressRunnable.run();
+ MAIN_EXECUTOR.post(longPressRunnable);
}
}
}
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
index 4c66504..7e61167 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
@@ -417,8 +417,9 @@
private void finishTouchTracking(MotionEvent ev) {
TraceHelper.INSTANCE.beginSection(UP_EVT);
+ boolean isCanceled = ev.getActionMasked() == ACTION_CANCEL;
if (mPassedWindowMoveSlop && mInteractionHandler != null) {
- if (ev.getActionMasked() == ACTION_CANCEL) {
+ if (isCanceled) {
mInteractionHandler.onGestureCancelled();
} else {
mVelocityTracker.computeCurrentVelocity(PX_PER_MS);
@@ -440,8 +441,10 @@
if (mActiveCallbacks != null && mInteractionHandler != null) {
if (mTaskAnimationManager.isRecentsAnimationRunning()) {
// The animation started, but with no movement, in this case, there will be no
- // animateToProgress so we have to manually finish here.
- mTaskAnimationManager.finishRunningRecentsAnimation(false /* toHome */);
+ // animateToProgress so we have to manually finish here. In the case of
+ // ACTION_CANCEL, someone else may be doing something so finish synchronously.
+ mTaskAnimationManager.finishRunningRecentsAnimation(false /* toHome */,
+ isCanceled /* forceFinish */);
} else {
// The animation hasn't started yet, so insert a replacement handler into the
// callbacks which immediately finishes the animation after it starts.
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/ActiveGestureLog.java b/quickstep/src/com/android/quickstep/util/ActiveGestureLog.java
index cca4d52..d6a2e93 100644
--- a/quickstep/src/com/android/quickstep/util/ActiveGestureLog.java
+++ b/quickstep/src/com/android/quickstep/util/ActiveGestureLog.java
@@ -46,7 +46,7 @@
private static final int TYPE_INTEGER = 2;
private static final int TYPE_BOOL_TRUE = 3;
private static final int TYPE_BOOL_FALSE = 4;
- private static final int TYPE_INPUT_CONSUMER = 5;
+ private static final int TYPE_COMPOUND_STRING = 5;
private static final int TYPE_GESTURE_EVENT = 6;
private final EventLog[] logs;
@@ -81,7 +81,13 @@
}
public void addLog(CompoundString compoundString) {
- addLog(TYPE_INPUT_CONSUMER, "", 0, compoundString, null);
+ addLog(TYPE_COMPOUND_STRING, "", 0, compoundString, null);
+ }
+
+ public void addLog(
+ CompoundString compoundString,
+ @Nullable ActiveGestureErrorDetector.GestureEvent gestureEvent) {
+ addLog(TYPE_COMPOUND_STRING, "", 0, compoundString, gestureEvent);
}
/**
@@ -185,7 +191,7 @@
case TYPE_INTEGER:
msg.append(": ").append((int) eventEntry.extras);
break;
- case TYPE_INPUT_CONSUMER:
+ case TYPE_COMPOUND_STRING:
msg.append(eventEntry.mCompoundString);
break;
case TYPE_GESTURE_EVENT:
@@ -314,6 +320,15 @@
return this;
}
+ public CompoundString append(int num) {
+ if (mIsNoOp) {
+ return this;
+ }
+ mSubstrings.add(Integer.toString(num));
+
+ return this;
+ }
+
@Override
public String toString() {
if (mIsNoOp) {
diff --git a/quickstep/src/com/android/quickstep/util/AsyncClockEventDelegate.java b/quickstep/src/com/android/quickstep/util/AsyncClockEventDelegate.java
new file mode 100644
index 0000000..0dee5b3
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/util/AsyncClockEventDelegate.java
@@ -0,0 +1,125 @@
+/*
+ * 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.quickstep.util;
+
+import static android.content.Intent.ACTION_TIMEZONE_CHANGED;
+import static android.content.Intent.ACTION_TIME_CHANGED;
+
+import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Handler;
+import android.provider.Settings;
+import android.util.ArrayMap;
+import android.widget.TextClock.ClockEventDelegate;
+
+import androidx.annotation.WorkerThread;
+
+import com.android.launcher3.util.SettingsCache;
+import com.android.launcher3.util.SettingsCache.OnChangeListener;
+import com.android.launcher3.util.SimpleBroadcastReceiver;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Extension of {@link ClockEventDelegate} to support async event registration
+ */
+public class AsyncClockEventDelegate extends ClockEventDelegate implements OnChangeListener {
+
+ private final Context mContext;
+ private final SimpleBroadcastReceiver mReceiver =
+ new SimpleBroadcastReceiver(this::onClockEventReceived);
+
+ private final ArrayMap<BroadcastReceiver, Handler> mTimeEventReceivers = new ArrayMap<>();
+ private final List<ContentObserver> mFormatObservers = new ArrayList<>();
+ private final Uri mFormatUri = Settings.System.getUriFor(Settings.System.TIME_12_24);
+
+ private boolean mFormatRegistered = false;
+ private boolean mDestroyed = false;
+
+ public AsyncClockEventDelegate(Context context) {
+ super(context);
+ mContext = context;
+
+ UI_HELPER_EXECUTOR.execute(() ->
+ mReceiver.register(mContext, ACTION_TIME_CHANGED, ACTION_TIMEZONE_CHANGED));
+ }
+
+ @Override
+ public void registerTimeChangeReceiver(BroadcastReceiver receiver, Handler handler) {
+ synchronized (mTimeEventReceivers) {
+ mTimeEventReceivers.put(receiver, handler == null ? new Handler() : handler);
+ }
+ }
+
+ @Override
+ public void unregisterTimeChangeReceiver(BroadcastReceiver receiver) {
+ synchronized (mTimeEventReceivers) {
+ mTimeEventReceivers.remove(receiver);
+ }
+ }
+
+ @Override
+ public void registerFormatChangeObserver(ContentObserver observer, int userHandle) {
+ synchronized (mFormatObservers) {
+ if (!mFormatRegistered && !mDestroyed) {
+ SettingsCache.INSTANCE.get(mContext).register(mFormatUri, this);
+ mFormatRegistered = true;
+ }
+ mFormatObservers.add(observer);
+ }
+ }
+
+ @Override
+ public void unregisterFormatChangeObserver(ContentObserver observer) {
+ synchronized (mFormatObservers) {
+ mFormatObservers.remove(observer);
+ }
+ }
+
+ @Override
+ public void onSettingsChanged(boolean isEnabled) {
+ if (mDestroyed) {
+ return;
+ }
+ synchronized (mFormatObservers) {
+ mFormatObservers.forEach(o -> o.dispatchChange(false, mFormatUri));
+ }
+ }
+ @WorkerThread
+ private void onClockEventReceived(Intent intent) {
+ if (mDestroyed) {
+ return;
+ }
+ synchronized (mReceiver) {
+ mTimeEventReceivers.forEach((r, h) -> h.post(() -> r.onReceive(mContext, intent)));
+ }
+ }
+
+ /**
+ * Unregisters all system callbacks and destroys this delegate
+ */
+ public void onDestroy() {
+ mDestroyed = true;
+ SettingsCache.INSTANCE.get(mContext).unregister(mFormatUri, this);
+ UI_HELPER_EXECUTOR.execute(() -> mReceiver.unregisterReceiverSafely(mContext));
+ }
+}
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/util/SplitSelectDataHolder.kt b/quickstep/src/com/android/quickstep/util/SplitSelectDataHolder.kt
index 69c4197..95f1fbf 100644
--- a/quickstep/src/com/android/quickstep/util/SplitSelectDataHolder.kt
+++ b/quickstep/src/com/android/quickstep/util/SplitSelectDataHolder.kt
@@ -368,7 +368,8 @@
}
private fun isInitialTaskIntentSet(): Boolean {
- return initialTaskId != INVALID_TASK_ID || initialIntent != null
+ return initialTaskId != INVALID_TASK_ID || initialIntent != null ||
+ initialPendingIntent != null
}
fun getInitialTaskId(): Int {
@@ -404,6 +405,7 @@
secondUser = null
initialIntent = null
secondIntent = null
+ initialPendingIntent = null
secondPendingIntent = null
itemInfo = null
splitEvent = null
diff --git a/quickstep/src/com/android/quickstep/util/TaskRemovedDuringLaunchListener.java b/quickstep/src/com/android/quickstep/util/TaskRemovedDuringLaunchListener.java
index c22e0bc..d7b3431 100644
--- a/quickstep/src/com/android/quickstep/util/TaskRemovedDuringLaunchListener.java
+++ b/quickstep/src/com/android/quickstep/util/TaskRemovedDuringLaunchListener.java
@@ -94,8 +94,10 @@
final Runnable taskLaunchFailedCallback = mTaskLaunchFailedCallback;
RecentsModel.INSTANCE.getNoCreate().isTaskRemoved(mLaunchedTaskId, (taskRemoved) -> {
if (taskRemoved) {
- ActiveGestureLog.INSTANCE.addLog("Launch failed, task (id=" + launchedTaskId
- + ") finished mid transition");
+ ActiveGestureLog.INSTANCE.addLog(
+ new ActiveGestureLog.CompoundString("Launch failed, task (id=")
+ .append(launchedTaskId)
+ .append(") finished mid transition"));
taskLaunchFailedCallback.run();
}
}, (task) -> true /* filter */);
diff --git a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
index 25b9bdc..b9ff272 100644
--- a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
+++ b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
@@ -343,8 +343,7 @@
boolean isRtlEnabled = !mIsRecentsRtl;
mPositionHelper.updateThumbnailMatrix(
mThumbnailPosition, mThumbnailData, mTaskRect.width(), mTaskRect.height(),
- mDp.widthPx, mDp.heightPx, mDp.taskbarHeight, mDp.isTablet,
- mOrientationState.getRecentsActivityRotation(), isRtlEnabled);
+ mDp.isTablet, mOrientationState.getRecentsActivityRotation(), isRtlEnabled);
mPositionHelper.getMatrix().invert(mInversePositionMatrix);
if (DEBUG) {
Log.d(TAG, " taskRect: " + mTaskRect);
@@ -353,7 +352,7 @@
float fullScreenProgress = Utilities.boundToRange(this.fullScreenProgress.value, 0, 1);
mCurrentFullscreenParams.setProgress(fullScreenProgress, recentsViewScale.value,
- /* taskViewScale= */1f, mTaskRect.width(), mDp, mPositionHelper);
+ /* taskViewScale= */1f);
// Apply thumbnail matrix
float taskWidth = mTaskRect.width();
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/DesktopTaskView.java b/quickstep/src/com/android/quickstep/views/DesktopTaskView.java
index b08e80f..5135345 100644
--- a/quickstep/src/com/android/quickstep/views/DesktopTaskView.java
+++ b/quickstep/src/com/android/quickstep/views/DesktopTaskView.java
@@ -499,8 +499,7 @@
for (int i = 0; i < mSnapshotViewMap.size(); i++) {
if (i == 0) {
// All snapshots share the same params. Only update it with the first snapshot.
- updateFullscreenParams(mSnapshotDrawParams,
- mSnapshotView.getPreviewPositionHelper());
+ updateFullscreenParams(mSnapshotDrawParams);
}
mSnapshotViewMap.valueAt(i).setFullscreenParams(mSnapshotDrawParams);
}
diff --git a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
index eb7598d..437009f 100644
--- a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
@@ -16,7 +16,6 @@
package com.android.quickstep.views;
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
-
import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.CLEAR_ALL_BUTTON;
import static com.android.launcher3.LauncherState.EDIT_MODE;
@@ -136,6 +135,10 @@
@Override
public void onStateTransitionStart(LauncherState toState) {
setOverviewStateEnabled(toState.overviewUi);
+ if (toState.overviewUi) {
+ // If overview is enabled, we want to update at the start
+ updateOverviewStateForDesktop(true);
+ }
setOverviewGridEnabled(toState.displayOverviewTasksAsGrid(mActivity.getDeviceProfile()));
setOverviewFullscreenEnabled(toState.getOverviewFullscreenProgress() == 1);
if (toState == OVERVIEW_MODAL_TASK) {
@@ -162,6 +165,11 @@
runActionOnRemoteHandles(remoteTargetHandle ->
remoteTargetHandle.getTaskViewSimulator().setDrawsBelowRecents(true));
}
+
+ if (!finalState.overviewUi) {
+ // If overview is disabled, we want to update at the end
+ updateOverviewStateForDesktop(false);
+ }
}
@Override
@@ -273,4 +281,11 @@
SystemUiProxy.INSTANCE.get(mActivity).showDesktopApps(mActivity.getDisplayId());
}
}
+
+ private void updateOverviewStateForDesktop(boolean enabled) {
+ DesktopVisibilityController controller = mActivity.getDesktopVisibilityController();
+ if (controller != null) {
+ controller.setOverviewStateEnabled(enabled);
+ }
+ }
}
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/TaskThumbnailView.java b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
index f746203..dff0580 100644
--- a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
@@ -558,13 +558,12 @@
.getRecentsActivityRotation();
boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
mPreviewPositionHelper.updateThumbnailMatrix(mPreviewRect, mThumbnailData,
- getMeasuredWidth(), getMeasuredHeight(), dp.widthPx, dp.heightPx,
- dp.taskbarHeight, dp.isTablet, currentRotation, isRtl);
+ getMeasuredWidth(), getMeasuredHeight(), dp.isTablet, currentRotation, isRtl);
mBitmapShader.setLocalMatrix(mPreviewPositionHelper.getMatrix());
mPaint.setShader(mBitmapShader);
}
- getTaskView().updateCurrentFullscreenParams(mPreviewPositionHelper);
+ getTaskView().updateCurrentFullscreenParams();
invalidate();
}
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index a2976a8..1bd385e 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -110,7 +110,6 @@
import com.android.quickstep.util.TransformParams;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.recents.model.ThumbnailData;
-import com.android.systemui.shared.recents.utilities.PreviewPositionHelper;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.QuickStepContract;
@@ -1137,7 +1136,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;
@@ -1708,21 +1707,20 @@
}
protected void updateSnapshotRadius() {
- updateCurrentFullscreenParams(mSnapshotView.getPreviewPositionHelper());
+ updateCurrentFullscreenParams();
mSnapshotView.setFullscreenParams(mCurrentFullscreenParams);
}
- void updateCurrentFullscreenParams(PreviewPositionHelper previewPositionHelper) {
- updateFullscreenParams(mCurrentFullscreenParams, previewPositionHelper);
+ void updateCurrentFullscreenParams() {
+ updateFullscreenParams(mCurrentFullscreenParams);
}
- protected void updateFullscreenParams(TaskView.FullscreenDrawParams fullscreenParams,
- PreviewPositionHelper previewPositionHelper) {
+ protected void updateFullscreenParams(TaskView.FullscreenDrawParams fullscreenParams) {
if (getRecentsView() == null) {
return;
}
fullscreenParams.setProgress(mFullscreenProgress, getRecentsView().getScaleX(),
- getScaleX(), getWidth(), mActivity.getDeviceProfile(), previewPositionHelper);
+ getScaleX());
}
/**
@@ -1893,8 +1891,7 @@
/**
* Sets the progress in range [0, 1]
*/
- public void setProgress(float fullscreenProgress, float parentScale, float taskViewScale,
- int previewWidth, DeviceProfile dp, PreviewPositionHelper pph) {
+ public void setProgress(float fullscreenProgress, float parentScale, float taskViewScale) {
mCurrentDrawnCornerRadius =
Utilities.mapRange(fullscreenProgress, mCornerRadius, mWindowCornerRadius)
/ parentScale / taskViewScale;
diff --git a/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarHoverToolTipControllerTest.java b/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarHoverToolTipControllerTest.java
index 6c0d44d..1b208a7 100644
--- a/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarHoverToolTipControllerTest.java
+++ b/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarHoverToolTipControllerTest.java
@@ -18,11 +18,11 @@
import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
import static com.android.launcher3.taskbar.TaskbarAutohideSuspendController.FLAG_AUTOHIDE_SUSPEND_HOVERING_ICONS;
-import static com.android.launcher3.taskbar.TaskbarHoverToolTipController.HOVER_TOOL_TIP_REVEAL_START_DELAY;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doAnswer;
@@ -125,16 +125,31 @@
public void onHover_hoverEnterIcon_revealToolTip() {
when(mMotionEvent.getAction()).thenReturn(MotionEvent.ACTION_HOVER_ENTER);
when(mMotionEvent.getActionMasked()).thenReturn(MotionEvent.ACTION_HOVER_ENTER);
+ when(taskbarActivityContext.isTaskbarWindowFullscreen()).thenReturn(true);
boolean hoverHandled =
mTaskbarHoverToolTipController.onHover(mHoverBubbleTextView, mMotionEvent);
-
- // Verify fullscreen is not set until the delayed runnable to reveal the tooltip has run
- verify(taskbarActivityContext, never()).setTaskbarWindowFullscreen(true);
waitForIdleSync();
+
assertThat(hoverHandled).isTrue();
verify(taskbarActivityContext).setAutohideSuspendFlag(FLAG_AUTOHIDE_SUSPEND_HOVERING_ICONS,
true);
+ verify(taskbarActivityContext, never()).setTaskbarWindowFullscreen(anyBoolean());
+ }
+
+ @Test
+ public void onHover_hoverEnterIcon_setFullScreenFirstHover() {
+ when(mMotionEvent.getAction()).thenReturn(MotionEvent.ACTION_HOVER_ENTER);
+ when(mMotionEvent.getActionMasked()).thenReturn(MotionEvent.ACTION_HOVER_ENTER);
+ when(taskbarActivityContext.isTaskbarWindowFullscreen()).thenReturn(false);
+
+ boolean hoverHandled =
+ mTaskbarHoverToolTipController.onHover(mHoverBubbleTextView, mMotionEvent);
+ waitForIdleSync();
+
+ assertThat(hoverHandled).isFalse();
+ verify(taskbarActivityContext, never()).setAutohideSuspendFlag(
+ FLAG_AUTOHIDE_SUSPEND_HOVERING_ICONS, true);
verify(taskbarActivityContext).setTaskbarWindowFullscreen(true);
}
@@ -156,17 +171,16 @@
public void onHover_hoverEnterFolderIcon_revealToolTip() {
when(mMotionEvent.getAction()).thenReturn(MotionEvent.ACTION_HOVER_ENTER);
when(mMotionEvent.getActionMasked()).thenReturn(MotionEvent.ACTION_HOVER_ENTER);
+ when(taskbarActivityContext.isTaskbarWindowFullscreen()).thenReturn(true);
boolean hoverHandled =
mTaskbarHoverToolTipController.onHover(mHoverFolderIcon, mMotionEvent);
-
- // Verify fullscreen is not set until the delayed runnable to reveal the tooltip has run
- verify(taskbarActivityContext, never()).setTaskbarWindowFullscreen(true);
waitForIdleSync();
+
assertThat(hoverHandled).isTrue();
verify(taskbarActivityContext).setAutohideSuspendFlag(FLAG_AUTOHIDE_SUSPEND_HOVERING_ICONS,
true);
- verify(taskbarActivityContext).setTaskbarWindowFullscreen(true);
+ verify(taskbarActivityContext, never()).setTaskbarWindowFullscreen(anyBoolean());
}
@Test
@@ -222,7 +236,6 @@
}
private void waitForIdleSync() {
- mTestableLooper.moveTimeForward(HOVER_TOOL_TIP_REVEAL_START_DELAY + 1);
mTestableLooper.processAllMessages();
}
}
diff --git a/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarNavButtonControllerTest.java b/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarNavButtonControllerTest.java
index b3d04c6..58be345 100644
--- a/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarNavButtonControllerTest.java
+++ b/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarNavButtonControllerTest.java
@@ -17,6 +17,7 @@
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_PINNING;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
@@ -33,6 +34,7 @@
import com.android.quickstep.OverviewCommandHelper;
import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.TouchInteractionService;
+import com.android.quickstep.util.AssistUtils;
import org.junit.Before;
import org.junit.Test;
@@ -54,6 +56,8 @@
@Mock
Handler mockHandler;
@Mock
+ AssistUtils mockAssistUtils;
+ @Mock
StatsLogManager mockStatsLogManager;
@Mock
StatsLogManager.StatsLogger mockStatsLogger;
@@ -79,7 +83,7 @@
.thenReturn(mockTaskbarActivityContext);
doReturn(mockStatsLogManager).when(mockTaskbarActivityContext).getStatsLogManager();
mNavButtonController = new TaskbarNavButtonController(mockService,
- mockSystemUiProxy, mockHandler);
+ mockSystemUiProxy, mockHandler, mockAssistUtils);
}
@Test
@@ -108,16 +112,42 @@
}
@Test
- public void testLongPressHome_enabled() {
+ public void testLongPressHome_enabled_withoutOverride() {
mNavButtonController.setAssistantLongPressEnabled(true /*assistantLongPressEnabled*/);
+ when(mockAssistUtils.tryStartAssistOverride(anyInt())).thenReturn(false);
+
mNavButtonController.onButtonLongClick(BUTTON_HOME, mockView);
+ verify(mockAssistUtils, times(1)).tryStartAssistOverride(anyInt());
verify(mockSystemUiProxy, times(1)).startAssistant(any());
}
@Test
- public void testLongPressHome_disabled() {
- mNavButtonController.setAssistantLongPressEnabled(false /*assistantLongPressEnabled*/);
+ public void testLongPressHome_enabled_withOverride() {
+ mNavButtonController.setAssistantLongPressEnabled(true /*assistantLongPressEnabled*/);
+ when(mockAssistUtils.tryStartAssistOverride(anyInt())).thenReturn(true);
+
mNavButtonController.onButtonLongClick(BUTTON_HOME, mockView);
+ verify(mockAssistUtils, times(1)).tryStartAssistOverride(anyInt());
+ verify(mockSystemUiProxy, never()).startAssistant(any());
+ }
+
+ @Test
+ public void testLongPressHome_disabled_withoutOverride() {
+ mNavButtonController.setAssistantLongPressEnabled(false /*assistantLongPressEnabled*/);
+ when(mockAssistUtils.tryStartAssistOverride(anyInt())).thenReturn(false);
+
+ mNavButtonController.onButtonLongClick(BUTTON_HOME, mockView);
+ verify(mockAssistUtils, never()).tryStartAssistOverride(anyInt());
+ verify(mockSystemUiProxy, never()).startAssistant(any());
+ }
+
+ @Test
+ public void testLongPressHome_disabled_withOverride() {
+ mNavButtonController.setAssistantLongPressEnabled(false /*assistantLongPressEnabled*/);
+ when(mockAssistUtils.tryStartAssistOverride(anyInt())).thenReturn(true);
+
+ mNavButtonController.onButtonLongClick(BUTTON_HOME, mockView);
+ verify(mockAssistUtils, never()).tryStartAssistOverride(anyInt());
verify(mockSystemUiProxy, never()).startAssistant(any());
}
diff --git a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
index a67d787..23b5d30 100644
--- a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
+++ b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
@@ -61,6 +61,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 +95,6 @@
public final TestRule mDisableHeadsUpNotification = disableHeadsUpNotification();
@Rule
- public final TestRule mSetLauncherCommand;
-
- @Rule
public final TestRule mOrderSensitiveRules;
@Rule
@@ -116,19 +114,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 +137,22 @@
}
}
};
+
+ final ViewCaptureRule viewCaptureRule = new ViewCaptureRule(
+ RecentsActivity.ACTIVITY_TRACKER::getCreatedActivity);
+ mOrderSensitiveRules = RuleChain
+ .outerRule(new SamplerRule())
+ .around(new TestStabilityRule())
+ .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/quickstep/tests/src/com/android/quickstep/FullscreenDrawParamsTest.kt b/quickstep/tests/src/com/android/quickstep/FullscreenDrawParamsTest.kt
index bb1afdf..db06b6b 100644
--- a/quickstep/tests/src/com/android/quickstep/FullscreenDrawParamsTest.kt
+++ b/quickstep/tests/src/com/android/quickstep/FullscreenDrawParamsTest.kt
@@ -16,17 +16,13 @@
package com.android.quickstep
import android.content.Context
-import android.graphics.Rect
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.launcher3.FakeInvariantDeviceProfileTest
import com.android.quickstep.util.TaskCornerRadius
import com.android.quickstep.views.TaskView.FullscreenDrawParams
-import com.android.systemui.shared.recents.model.ThumbnailData
-import com.android.systemui.shared.recents.utilities.PreviewPositionHelper
import com.android.systemui.shared.system.QuickStepContract
import com.google.common.truth.Truth.assertThat
-import kotlin.math.roundToInt
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -39,10 +35,6 @@
@RunWith(AndroidJUnit4::class)
class FullscreenDrawParamsTest : FakeInvariantDeviceProfileTest() {
- private val TASK_SCALE = 0.7f
- private var mThumbnailData: ThumbnailData = mock(ThumbnailData::class.java)
-
- private val mPreviewPositionHelper = PreviewPositionHelper()
private lateinit var params: FullscreenDrawParams
@Before
@@ -53,32 +45,11 @@
@Test
fun setStartProgress_correctCornerRadiusForTablet() {
initializeVarsForTablet()
- val dp = newDP()
- val previewRect = Rect(0, 0, 100, 100)
- val canvasWidth = (dp.widthPx * TASK_SCALE).roundToInt()
- val canvasHeight = (dp.heightPx * TASK_SCALE).roundToInt()
- val currentRotation = 0
- val isRtl = false
- mPreviewPositionHelper.updateThumbnailMatrix(
- previewRect,
- mThumbnailData,
- canvasWidth,
- canvasHeight,
- dp.widthPx,
- dp.heightPx,
- dp.taskbarHeight,
- dp.isTablet,
- currentRotation,
- isRtl
- )
params.setProgress(
/* fullscreenProgress= */ 0f,
/* parentScale= */ 1.0f,
- /* taskViewScale= */ 1.0f,
- /* previewWidth= */ 0,
- dp,
- mPreviewPositionHelper
+ /* taskViewScale= */ 1.0f
)
val expectedRadius = TaskCornerRadius.get(context)
@@ -88,32 +59,11 @@
@Test
fun setFullProgress_correctCornerRadiusForTablet() {
initializeVarsForTablet()
- val dp = newDP()
- val previewRect = Rect(0, 0, 100, 100)
- val canvasWidth = (dp.widthPx * TASK_SCALE).roundToInt()
- val canvasHeight = (dp.heightPx * TASK_SCALE).roundToInt()
- val currentRotation = 0
- val isRtl = false
- mPreviewPositionHelper.updateThumbnailMatrix(
- previewRect,
- mThumbnailData,
- canvasWidth,
- canvasHeight,
- dp.widthPx,
- dp.heightPx,
- dp.taskbarHeight,
- dp.isTablet,
- currentRotation,
- isRtl
- )
params.setProgress(
/* fullscreenProgress= */ 1.0f,
/* parentScale= */ 1.0f,
- /* taskViewScale= */ 1.0f,
- /* previewWidth= */ 0,
- dp,
- mPreviewPositionHelper
+ /* taskViewScale= */ 1.0f
)
val expectedRadius = QuickStepContract.getWindowCornerRadius(context)
@@ -123,32 +73,11 @@
@Test
fun setStartProgress_correctCornerRadiusForPhone() {
initializeVarsForPhone()
- val dp = newDP()
- val previewRect = Rect(0, 0, 100, 100)
- val canvasWidth = (dp.widthPx * TASK_SCALE).roundToInt()
- val canvasHeight = (dp.heightPx * TASK_SCALE).roundToInt()
- val currentRotation = 0
- val isRtl = false
- mPreviewPositionHelper.updateThumbnailMatrix(
- previewRect,
- mThumbnailData,
- canvasWidth,
- canvasHeight,
- dp.widthPx,
- dp.heightPx,
- dp.taskbarHeight,
- dp.isTablet,
- currentRotation,
- isRtl
- )
params.setProgress(
/* fullscreenProgress= */ 0f,
/* parentScale= */ 1.0f,
- /* taskViewScale= */ 1.0f,
- /* previewWidth= */ 0,
- dp,
- mPreviewPositionHelper
+ /* taskViewScale= */ 1.0f
)
val expectedRadius = TaskCornerRadius.get(context)
@@ -158,32 +87,11 @@
@Test
fun setFullProgress_correctCornerRadiusForPhone() {
initializeVarsForPhone()
- val dp = newDP()
- val previewRect = Rect(0, 0, 100, 100)
- val canvasWidth = (dp.widthPx * TASK_SCALE).roundToInt()
- val canvasHeight = (dp.heightPx * TASK_SCALE).roundToInt()
- val currentRotation = 0
- val isRtl = false
- mPreviewPositionHelper.updateThumbnailMatrix(
- previewRect,
- mThumbnailData,
- canvasWidth,
- canvasHeight,
- dp.widthPx,
- dp.heightPx,
- dp.taskbarHeight,
- dp.isTablet,
- currentRotation,
- isRtl
- )
params.setProgress(
/* fullscreenProgress= */ 1.0f,
/* parentScale= */ 1.0f,
- /* taskViewScale= */ 1.0f,
- /* previewWidth= */ 0,
- dp,
- mPreviewPositionHelper
+ /* taskViewScale= */ 1.0f
)
val expectedRadius = QuickStepContract.getWindowCornerRadius(context)
@@ -207,10 +115,7 @@
spyParams.setProgress(
/* fullscreenProgress= */ 0f,
/* parentScale= */ 1.0f,
- /* taskViewScale= */ 1.0f,
- /* unused previewWidth= */ -1,
- /* unusedDp= */ null,
- /* unused previewPositionHelper= */ null
+ /* taskViewScale= */ 1.0f
)
assertThat(spyParams.mCurrentDrawnCornerRadius).isEqualTo(display1TaskRadius)
@@ -218,10 +123,7 @@
spyParams.setProgress(
/* fullscreenProgress= */ 0f,
/* parentScale= */ 1.0f,
- /* taskViewScale= */ 1.0f,
- /* unused previewWidth= */ -1,
- /* unusedDp= */ null,
- /* unused previewPositionHelper= */ null
+ /* taskViewScale= */ 1.0f
)
assertThat(spyParams.mCurrentDrawnCornerRadius).isEqualTo(display2TaskRadius)
}
@@ -243,10 +145,7 @@
spyParams.setProgress(
/* fullscreenProgress= */ 1.0f,
/* parentScale= */ 1.0f,
- /* taskViewScale= */ 1.0f,
- /* unused previewWidth= */ -1,
- /* unusedDp= */ null,
- /* unused previewPositionHelper= */ null
+ /* taskViewScale= */ 1.0f
)
assertThat(spyParams.mCurrentDrawnCornerRadius).isEqualTo(display1WindowRadius)
@@ -255,9 +154,6 @@
/* fullscreenProgress= */ 1.0f,
/* parentScale= */ 1.0f,
/* taskViewScale= */ 1.0f,
- /* unused previewWidth= */ -1,
- /* unusedDp= */ null,
- /* unused previewPositionHelper= */ null
)
assertThat(spyParams.mCurrentDrawnCornerRadius).isEqualTo(display2WindowRadius)
}
diff --git a/quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java b/quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java
index 20aa410..a89eab5 100644
--- a/quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java
+++ b/quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java
@@ -49,7 +49,6 @@
@Test
@NavigationModeSwitch
- @Stability(flavors = LOCAL | PLATFORM_POSTSUBMIT) // b/187761685
public void testStressPressHome() {
for (int i = 0; i < STRESS_REPEAT_COUNT; ++i) {
// Destroy Launcher activity.
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
index 25f90ca..5531c6e 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
@@ -16,11 +16,13 @@
package com.android.quickstep;
+import static com.android.launcher3.config.FeatureFlags.ENABLE_CURSOR_HOVER_STATES;
import static com.android.launcher3.testing.shared.TestProtocol.FLAKY_QUICK_SWITCH_TO_PREVIOUS_APP;
import static com.android.launcher3.ui.TaplTestsLauncher3.getAppPackageName;
import static com.android.launcher3.util.rule.TestStabilityRule.LOCAL;
import static com.android.launcher3.util.rule.TestStabilityRule.PLATFORM_POSTSUBMIT;
import static com.android.quickstep.TaskbarModeSwitchRule.Mode.PERSISTENT;
+import static com.android.quickstep.TaskbarModeSwitchRule.Mode.TRANSIENT;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
@@ -50,6 +52,7 @@
import com.android.launcher3.ui.PortraitLandscapeRunner.PortraitLandscape;
import com.android.launcher3.ui.TaplTestsLauncher3;
import com.android.launcher3.util.DisplayController;
+import com.android.launcher3.util.TestUtil;
import com.android.launcher3.util.Wait;
import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord;
import com.android.launcher3.util.rule.TestStabilityRule;
@@ -242,6 +245,19 @@
isInState(() -> LauncherState.OVERVIEW));
}
+ @Test
+ @TaskbarModeSwitch(mode = TRANSIENT)
+ public void testSwitchToOverviewWithStashedTaskbar() throws Exception {
+ try (AutoCloseable flag = TestUtil.overrideFlag(ENABLE_CURSOR_HOVER_STATES, true)) {
+ startTestAppsWithCheck();
+ // Set ignoreTaskbarVisibility, as transient taskbar will be stashed after app launch.
+ mLauncher.setIgnoreTaskbarVisibility(true);
+ mLauncher.getLaunchedAppState().switchToOverview();
+ } finally {
+ mLauncher.setIgnoreTaskbarVisibility(false);
+ }
+ }
+
@Ignore
@Test
@NavigationModeSwitch
@@ -271,24 +287,6 @@
}
@Test
- @PortraitLandscape
- public void testAllAppsFromHome() throws Exception {
- // Test opening all apps
- assertNotNull("switchToAllApps() returned null",
- mLauncher.getWorkspace().switchToAllApps());
-
- TaplTestsLauncher3.runAllAppsTest(this, mLauncher.getAllApps());
-
- // Testing pressHome.
- assertTrue("Launcher internal state is not All Apps",
- isInState(() -> LauncherState.ALL_APPS));
- assertNotNull("pressHome returned null", mLauncher.goHome());
- assertTrue("Launcher internal state is not Home",
- isInState(() -> LauncherState.NORMAL));
- assertNotNull("getHome returned null", mLauncher.getWorkspace());
- }
-
- @Test
@NavigationModeSwitch
@PortraitLandscape
@PlatinumTest(focusArea = "launcher")
@@ -502,7 +500,6 @@
}
@Test
- @ScreenRecord // b/242163205
public void testDisableRotationCheckForPhone() throws Exception {
assumeFalse(mLauncher.isTablet());
try {
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsSplitscreen.java b/quickstep/tests/src/com/android/quickstep/TaplTestsSplitscreen.java
index a90c326..cc56faf 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsSplitscreen.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsSplitscreen.java
@@ -37,6 +37,7 @@
import org.junit.After;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -107,6 +108,7 @@
}
@Test
+ @Ignore("Enable once App Pairs flagged on. These cause memory leaks b/297135374")
public void testSaveAppPairMenuItemExistsOnSplitPair() throws Exception {
assumeTrue("App pairs feature is currently not enabled, no test needed",
FeatureFlags.ENABLE_APP_PAIRS.get());
@@ -122,6 +124,7 @@
}
@Test
+ @Ignore("Enable once App Pairs flagged on. These cause memory leaks b/297135374")
public void testSaveAppPairMenuItemDoesNotExistOnSingleTask() throws Exception {
assumeTrue("App pairs feature is currently not enabled, no test needed",
FeatureFlags.ENABLE_APP_PAIRS.get());
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsTransientTaskbar.java b/quickstep/tests/src/com/android/quickstep/TaplTestsTransientTaskbar.java
index 3869bf7..b3cec4e 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsTransientTaskbar.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsTransientTaskbar.java
@@ -66,12 +66,10 @@
@Test
@TaskbarModeSwitch(mode = TRANSIENT)
- public void testClickHoveredTaskbarToGoHome() {
+ public void testClickHoveredTaskbarToGoHome() throws Exception {
try (AutoCloseable flag = TestUtil.overrideFlag(ENABLE_CURSOR_HOVER_STATES, true)) {
getTaskbar().getAppIcon(TEST_APP_NAME).launch(TEST_APP_PACKAGE);
mLauncher.getLaunchedAppState().clickStashedTaskbarToGoHome();
- } catch (Exception e) {
- throw new RuntimeException(e);
}
}
}
diff --git a/quickstep/tests/src/com/android/quickstep/util/SplitSelectDataHolderTest.kt b/quickstep/tests/src/com/android/quickstep/util/SplitSelectDataHolderTest.kt
index fc767fa..c6c5be4 100644
--- a/quickstep/tests/src/com/android/quickstep/util/SplitSelectDataHolderTest.kt
+++ b/quickstep/tests/src/com/android/quickstep/util/SplitSelectDataHolderTest.kt
@@ -381,7 +381,7 @@
}
@Test
- fun clearState() {
+ fun clearState_task() {
splitSelectDataHolder.setInitialTaskSelect(
sampleTaskInfo,
STAGE_POSITION_TOP_OR_LEFT,
@@ -392,4 +392,18 @@
splitSelectDataHolder.resetState()
assertFalse(splitSelectDataHolder.isSplitSelectActive())
}
+
+ @Test
+ fun clearState_intent() {
+ splitSelectDataHolder.setInitialTaskSelect(
+ sampleIntent,
+ STAGE_POSITION_TOP_OR_LEFT,
+ sampleItemInfo,
+ null,
+ INVALID_TASK_ID
+ )
+ splitSelectDataHolder.setSecondTask(sampleIntent, sampleUser)
+ splitSelectDataHolder.resetState()
+ assertFalse(splitSelectDataHolder.isSplitSelectActive())
+ }
}
diff --git a/res/drawable-sw720dp/ic_transient_taskbar_all_apps_search_button.xml b/res/drawable-sw720dp/ic_transient_taskbar_all_apps_search_button.xml
new file mode 100644
index 0000000..654f0b3
--- /dev/null
+++ b/res/drawable-sw720dp/ic_transient_taskbar_all_apps_search_button.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="52dp"
+ android:height="52dp"
+ android:viewportWidth="52"
+ android:viewportHeight="52">
+ <path
+ android:pathData="M39.4,17.5c0,3.1 -2.5,5.5 -5.5,5.5c-3.1,0 -5.5,-2.5 -5.5,-5.5s2.5,-5.5 5.5,-5.5C36.9,12 39.4,14.5 39.4,17.5z"
+ android:fillColor="#FF000000"/>
+ <path
+ android:pathData="M23.1,17.5c0,3.1 -2.5,5.5 -5.5,5.5S12,20.6 12,17.5s2.5,-5.5 5.5,-5.5S23.1,14.5 23.1,17.5z"
+ android:fillColor="#FF000000"/>
+ <path
+ android:pathData="M17.5,33.9m-5.5,0a5.5,5.5 0,1 1,11 0a5.5,5.5 0,1 1,-11 0"
+ android:fillColor="#FF000000"/>
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M33.9,30c2.1,0 3.9,1.7 3.9,3.9s-1.7,3.9 -3.9,3.9S30,36.1 30,33.9S31.8,30 33.9,30M33.9,28.3c-3.1,0 -5.6,2.5 -5.6,5.6c0,3.1 2.5,5.6 5.6,5.6c3.1,0 5.6,-2.5 5.6,-5.6C39.5,30.8 37,28.3 33.9,28.3L33.9,28.3z"/>
+ <path
+ android:pathData="M36.9,37L43.2,43.3"
+ android:strokeWidth="1.7"
+ android:fillColor="#00000000"
+ android:strokeColor="#000000"/>
+</vector>
diff --git a/res/drawable/ic_taskbar_all_apps_search_button.xml b/res/drawable/ic_taskbar_all_apps_search_button.xml
new file mode 100644
index 0000000..8fbe539
--- /dev/null
+++ b/res/drawable/ic_taskbar_all_apps_search_button.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="44dp"
+ android:height="44dp"
+ android:viewportWidth="44"
+ android:viewportHeight="44">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M34.1,14.9c0,2.7 -2.2,4.9 -4.9,4.9s-4.9,-2.2 -4.9,-4.9s2.2,-4.9 4.9,-4.9S34.1,12.2 34.1,14.9z"/>
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M19.7,14.9c0,2.7 -2.2,4.9 -4.9,4.9S10,17.6 10,14.9s2.2,-4.9 4.9,-4.9S19.7,12.2 19.7,14.9z"/>
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M14.9,29.2m-4.9,0a4.9,4.9 0,1 1,9.8 0a4.9,4.9 0,1 1,-9.8 0"/>
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M29.3,25.9c1.9,0 3.4,1.5 3.4,3.4c0,1.9 -1.5,3.4 -3.4,3.4s-3.4,-1.5 -3.4,-3.4C25.9,27.4 27.4,25.9 29.3,25.9M29.3,24.4c-2.7,0 -4.9,2.2 -4.9,4.9s2.2,4.9 4.9,4.9c2.7,0 4.9,-2.2 4.9,-4.9S32,24.4 29.3,24.4L29.3,24.4z"/>
+ <path
+ android:pathData="M31.9,32L37.4,37.5"
+ android:strokeWidth="1.5"
+ android:fillColor="#00000000"
+ android:strokeColor="#000000"/>
+</vector>
diff --git a/res/drawable/ic_transient_taskbar_all_apps_search_button.xml b/res/drawable/ic_transient_taskbar_all_apps_search_button.xml
new file mode 100644
index 0000000..59a666b
--- /dev/null
+++ b/res/drawable/ic_transient_taskbar_all_apps_search_button.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="48dp"
+ android:height="48dp"
+ android:viewportWidth="48"
+ android:viewportHeight="48">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M37.4,15.5c0,3.1 -2.5,5.5 -5.5,5.5c-3.1,0 -5.5,-2.5 -5.5,-5.5s2.5,-5.5 5.5,-5.5C34.9,10 37.4,12.5 37.4,15.5z"/>
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M21.1,15.5c0,3.1 -2.5,5.5 -5.5,5.5S10,18.6 10,15.5s2.5,-5.5 5.5,-5.5S21.1,12.5 21.1,15.5z"/>
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M15.5,31.9m-5.5,0a5.5,5.5 0,1 1,11 0a5.5,5.5 0,1 1,-11 0"/>
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M31.9,28c2.1,0 3.9,1.7 3.9,3.9s-1.7,3.9 -3.9,3.9c-2.1,0 -3.9,-1.7 -3.9,-3.9S29.8,28 31.9,28M31.9,26.3c-3.1,0 -5.6,2.5 -5.6,5.6c0,3.1 2.5,5.6 5.6,5.6c3.1,0 5.6,-2.5 5.6,-5.6C37.5,28.8 35,26.3 31.9,26.3L31.9,26.3z"/>
+ <path
+ android:pathData="M34.9,35L41.2,41.3"
+ android:strokeWidth="1.7"
+ android:fillColor="#00000000"
+ android:strokeColor="#000000"/>
+</vector>
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/res/values/config.xml b/res/values/config.xml
index 8f9731c..cd9c9de 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -241,4 +241,7 @@
<item>@dimen/iconSize66dp</item>
<item>@dimen/iconSize72dp</item>
</integer-array>
+
+ <!-- Used for custom widgets -->
+ <array name="custom_widget_providers"/>
</resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 1079e00..c6fce28 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -385,6 +385,9 @@
<dimen name="taskbar_button_margin_split">0dp</dimen>
<dimen name="taskbar_button_margin_6_5">0dp</dimen>
+ <!-- Bubble bar (placeholders to compile in Launcher3 without Quickstep) -->
+ <dimen name="bubblebar_hotseat_adjustment_threshold">0dp</dimen>
+
<!-- Size of the maximum radius for the enforced rounded rectangles. -->
<dimen name="enforced_rounded_corner_max_radius">16dp</dimen>
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/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index 347c7af..9b57799 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -397,8 +397,8 @@
}
protected boolean shouldUseTheme() {
- return mDisplay == DISPLAY_WORKSPACE || mDisplay == DISPLAY_FOLDER
- || mDisplay == DISPLAY_TASKBAR;
+ return (mDisplay == DISPLAY_WORKSPACE || mDisplay == DISPLAY_FOLDER
+ || mDisplay == DISPLAY_TASKBAR) && Themes.isThemedIconEnabled(getContext());
}
/**
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index a48c928..c05afc9 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -205,9 +205,11 @@
public int hotseatBarEndOffset;
public int hotseatQsbSpace;
public int springLoadedHotseatBarTopMarginPx;
- // Start is the side next to the nav bar, end is the side next to the workspace
- public final int hotseatBarSidePaddingStartPx;
- public final int hotseatBarSidePaddingEndPx;
+ // These 2 values are only used for isVerticalBar
+ // Padding between edge of screen and hotseat
+ public final int mHotseatBarEdgePaddingPx;
+ // Space between hotseat and workspace (not used in responsive)
+ public final int mHotseatBarWorkspaceSpacePx;
public int hotseatQsbWidth; // only used when isQsbInline
public final int hotseatQsbHeight;
public final int hotseatQsbVisualHeight;
@@ -217,6 +219,9 @@
private final int mMinHotseatQsbWidthPx;
private final int mMaxHotseatIconSpacePx;
public final int inlineNavButtonsEndSpacingPx;
+ // Space required for the bubble bar between the hotseat and the edge of the screen. If there's
+ // not enough space, the hotseat will adjust itself for the bubble bar.
+ private final int mBubbleBarSpaceThresholdPx;
// Bottom sheets
public int bottomSheetTopPadding;
@@ -294,6 +299,7 @@
public final int taskbarIconSize;
// If true, used to layout taskbar in 3 button navigation mode.
public final boolean startAlignTaskbar;
+ public final boolean isTransientTaskbar;
// DragController
public int flingToDeleteThresholdVelocity;
@@ -361,7 +367,11 @@
}
}
- if (DisplayController.isTransientTaskbar(context)) {
+ isTransientTaskbar = DisplayController.isTransientTaskbar(context);
+ if (!isTaskbarPresent) {
+ taskbarIconSize = taskbarHeight = stashedTaskbarHeight = taskbarBottomMargin = 0;
+ startAlignTaskbar = false;
+ } else if (isTransientTaskbar) {
float invTransientIconSizeDp = inv.transientTaskbarIconSize[mTypeIndex];
taskbarIconSize = pxFromDp(invTransientIconSizeDp, mMetrics);
taskbarHeight = Math.round((taskbarIconSize * ICON_VISIBLE_AREA_FACTOR)
@@ -497,46 +507,56 @@
numShownAllAppsColumns =
isTwoPanels ? inv.numDatabaseAllAppsColumns : inv.numAllAppsColumns;
- int hotseatBarBottomSpace = pxFromDp(inv.hotseatBarBottomSpace[mTypeIndex], mMetrics);
+ int hotseatBarBottomSpace;
int minQsbMargin = res.getDimensionPixelSize(R.dimen.min_qsb_margin);
if (mIsResponsiveGrid) {
HotseatSpecs hotseatSpecs =
HotseatSpecs.create(new ResourceHelper(context,
isTwoPanels ? inv.hotseatSpecsTwoPanelId : inv.hotseatSpecsId));
- mResponsiveHotseatSpec = hotseatSpecs.getCalculatedHeightSpec(heightPx);
+ mResponsiveHotseatSpec =
+ isVerticalBarLayout() ? hotseatSpecs.getCalculatedWidthSpec(widthPx)
+ : hotseatSpecs.getCalculatedHeightSpec(heightPx);
hotseatQsbSpace = mResponsiveHotseatSpec.getHotseatQsbSpace();
+ hotseatBarBottomSpace =
+ isVerticalBarLayout() ? 0 : mResponsiveHotseatSpec.getEdgePadding();
+ mHotseatBarEdgePaddingPx =
+ isVerticalBarLayout() ? mResponsiveHotseatSpec.getEdgePadding() : 0;
+ mHotseatBarWorkspaceSpacePx = 0;
} else {
hotseatQsbSpace = pxFromDp(inv.hotseatQsbSpace[mTypeIndex], mMetrics);
+ hotseatBarBottomSpace = pxFromDp(inv.hotseatBarBottomSpace[mTypeIndex], mMetrics);
+ mHotseatBarEdgePaddingPx =
+ isVerticalBarLayout() ? workspacePageIndicatorHeight : 0;
+ mHotseatBarWorkspaceSpacePx =
+ res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_side_padding);
}
- // Have a little space between the inset and the QSB
- if (mInsets.bottom + minQsbMargin > hotseatBarBottomSpace) {
- int availableSpace = hotseatQsbSpace - (mInsets.bottom - hotseatBarBottomSpace);
+ if (!isVerticalBarLayout()) {
+ // Have a little space between the inset and the QSB
+ if (mInsets.bottom + minQsbMargin > hotseatBarBottomSpace) {
+ int availableSpace = hotseatQsbSpace - (mInsets.bottom - hotseatBarBottomSpace);
- // Only change the spaces if there is space
- if (availableSpace > 0) {
- // Make sure there is enough space between hotseat/QSB and QSB/navBar
- if (availableSpace < minQsbMargin * 2) {
- minQsbMargin = availableSpace / 2;
- hotseatQsbSpace = minQsbMargin;
- } else {
- hotseatQsbSpace -= minQsbMargin;
+ // Only change the spaces if there is space
+ if (availableSpace > 0) {
+ // Make sure there is enough space between hotseat/QSB and QSB/navBar
+ if (availableSpace < minQsbMargin * 2) {
+ minQsbMargin = availableSpace / 2;
+ hotseatQsbSpace = minQsbMargin;
+ } else {
+ hotseatQsbSpace -= minQsbMargin;
+ }
}
- }
- hotseatBarBottomSpacePx = mInsets.bottom + minQsbMargin;
+ hotseatBarBottomSpacePx = mInsets.bottom + minQsbMargin;
- } else {
- hotseatBarBottomSpacePx = hotseatBarBottomSpace;
+ } else {
+ hotseatBarBottomSpacePx = hotseatBarBottomSpace;
+ }
}
springLoadedHotseatBarTopMarginPx = res.getDimensionPixelSize(
R.dimen.spring_loaded_hotseat_top_margin);
- hotseatBarSidePaddingEndPx =
- res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_side_padding);
- // Add a bit of space between nav bar and hotseat in vertical bar layout.
- hotseatBarSidePaddingStartPx = isVerticalBarLayout() ? workspacePageIndicatorHeight : 0;
- updateHotseatSizes(pxFromDp(inv.iconSize[INDEX_DEFAULT], mMetrics));
+ updateHotseatSizes(pxFromDp(inv.iconSize[mTypeIndex], mMetrics));
if (areNavButtonsInline && !isPhone) {
inlineNavButtonsEndSpacingPx =
res.getDimensionPixelSize(inv.inlineNavButtonsEndSpacing);
@@ -553,6 +573,9 @@
hotseatBarEndOffset = 0;
}
+ mBubbleBarSpaceThresholdPx =
+ res.getDimensionPixelSize(R.dimen.bubblebar_hotseat_adjustment_threshold);
+
// Needs to be calculated after hotseatBarSizePx is correct,
// for the available height to be correct
if (mIsResponsiveGrid) {
@@ -562,10 +585,9 @@
int availableResponsiveWidth =
availableWidthPx - (isVerticalBarLayout() ? hotseatBarSizePx : 0);
int numColumns = getPanelCount() * inv.numColumns;
- // don't use availableHeightPx because it subtracts bottom padding,
- // but the workspace go behind it
- int availableResponsiveHeight =
- heightPx - mInsets.top - (isVerticalBarLayout() ? 0 : hotseatBarSizePx);
+ // don't use availableHeightPx because it subtracts mInsets.bottom
+ int availableResponsiveHeight = heightPx - mInsets.top
+ - (isVerticalBarLayout() ? 0 : hotseatBarSizePx);
mResponsiveWidthSpec = workspaceSpecs.getCalculatedWidthSpec(numColumns,
availableResponsiveWidth);
mResponsiveHeightSpec = workspaceSpecs.getCalculatedHeightSpec(inv.numRows,
@@ -738,8 +760,8 @@
hotseatCellHeightPx = getIconSizeWithOverlap(hotseatIconSizePx);
if (isVerticalBarLayout()) {
- hotseatBarSizePx = hotseatIconSizePx + hotseatBarSidePaddingStartPx
- + hotseatBarSidePaddingEndPx;
+ hotseatBarSizePx = hotseatIconSizePx + mHotseatBarEdgePaddingPx
+ + mHotseatBarWorkspaceSpacePx;
} else if (isQsbInline) {
hotseatBarSizePx = Math.max(hotseatIconSizePx, hotseatQsbVisualHeight)
+ hotseatBarBottomSpacePx;
@@ -1007,6 +1029,7 @@
iconSizePx = mIconSizeSteps.getIconSmallerThan(cellWidthPx);
}
+ // TODO(b/296400197): isVerticalBar shouldn't show labels anymore
iconDrawablePaddingPx = getNormalizedIconDrawablePadding();
int iconTextHeight = Utilities.calculateTextHeight(iconTextSizePx);
int cellContentHeight = iconSizePx + iconDrawablePaddingPx + iconTextHeight;
@@ -1491,7 +1514,8 @@
if (isVerticalBarLayout()) {
if (mIsResponsiveGrid) {
padding.top = mResponsiveHeightSpec.getStartPaddingPx();
- padding.bottom = mResponsiveHeightSpec.getEndPaddingPx();
+ padding.bottom = Math.max(0,
+ mResponsiveHeightSpec.getEndPaddingPx() - mInsets.bottom);
if (isSeascape()) {
padding.left = hotseatBarSizePx + mResponsiveWidthSpec.getEndPaddingPx();
padding.right = mResponsiveWidthSpec.getStartPaddingPx();
@@ -1504,9 +1528,9 @@
padding.bottom = edgeMarginPx;
if (isSeascape()) {
padding.left = hotseatBarSizePx;
- padding.right = hotseatBarSidePaddingStartPx;
+ padding.right = mHotseatBarEdgePaddingPx;
} else {
- padding.left = hotseatBarSidePaddingStartPx;
+ padding.left = mHotseatBarEdgePaddingPx;
padding.right = hotseatBarSizePx;
}
}
@@ -1540,6 +1564,32 @@
paddings.bottom -= insets.bottom;
}
+
+ /**
+ * Returns the new border space that should be used between hotseat icons after adjusting it to
+ * the bubble bar.
+ *
+ * <p>If there's no adjustment needed, this method returns {@code 0}.
+ */
+ public float getHotseatAdjustedBorderSpaceForBubbleBar(Context context) {
+ // only need to adjust when QSB is on top of the hotseat.
+ if (isQsbInline) {
+ return 0;
+ }
+
+ // no need to adjust if there's enough space for the bubble bar to the right of the hotseat.
+ if (getHotseatLayoutPadding(context).right > mBubbleBarSpaceThresholdPx) {
+ return 0;
+ }
+
+ // The adjustment is shrinking the hotseat's width by 1 icon on either side.
+ int iconsWidth =
+ iconSizePx * numShownHotseatIcons + hotseatBorderSpace * (numShownHotseatIcons - 1);
+ int newWidth = iconsWidth - 2 * iconSizePx;
+ // Evenly space the icons within the boundaries of the new width.
+ return (float) (newWidth - iconSizePx * numShownHotseatIcons) / (numShownHotseatIcons - 1);
+ }
+
/**
* Returns the padding for hotseat view
*/
@@ -1560,11 +1610,11 @@
+ diffOverlapFactor), 0);
if (isSeascape()) {
- hotseatBarPadding.set(mInsets.left + hotseatBarSidePaddingStartPx, paddingTop,
- hotseatBarSidePaddingEndPx, paddingBottom);
+ hotseatBarPadding.set(mInsets.left + mHotseatBarEdgePaddingPx, paddingTop,
+ mHotseatBarWorkspaceSpacePx, paddingBottom);
} else {
- hotseatBarPadding.set(hotseatBarSidePaddingEndPx, paddingTop,
- mInsets.right + hotseatBarSidePaddingStartPx, paddingBottom);
+ hotseatBarPadding.set(mHotseatBarWorkspaceSpacePx, paddingTop,
+ mInsets.right + mHotseatBarEdgePaddingPx, paddingBottom);
}
} else if (isTaskbarPresent) {
// Center the QSB vertically with hotseat
@@ -1700,7 +1750,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();
@@ -1910,10 +1960,10 @@
writer.println(prefix + "\tinv.hotseatColumnSpan: " + inv.hotseatColumnSpan[mTypeIndex]);
writer.println(prefix + pxToDpStr("hotseatCellHeightPx", hotseatCellHeightPx));
writer.println(prefix + pxToDpStr("hotseatBarBottomSpacePx", hotseatBarBottomSpacePx));
- writer.println(prefix + pxToDpStr("hotseatBarSidePaddingStartPx",
- hotseatBarSidePaddingStartPx));
- writer.println(prefix + pxToDpStr("hotseatBarSidePaddingEndPx",
- hotseatBarSidePaddingEndPx));
+ writer.println(prefix + pxToDpStr("mHotseatBarEdgePaddingPx",
+ mHotseatBarEdgePaddingPx));
+ writer.println(prefix + pxToDpStr("mHotseatBarWorkspaceSpacePx",
+ mHotseatBarWorkspaceSpacePx));
writer.println(prefix + pxToDpStr("hotseatBarEndOffset", hotseatBarEndOffset));
writer.println(prefix + pxToDpStr("hotseatQsbSpace", hotseatQsbSpace));
writer.println(prefix + pxToDpStr("hotseatQsbHeight", hotseatQsbHeight));
@@ -2147,5 +2197,4 @@
mIsGestureMode, mViewScaleProvider, mOverrideProvider);
}
}
-
}
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/Hotseat.java b/src/com/android/launcher3/Hotseat.java
index 03afba1..3b12b86 100644
--- a/src/com/android/launcher3/Hotseat.java
+++ b/src/com/android/launcher3/Hotseat.java
@@ -16,6 +16,12 @@
package com.android.launcher3;
+import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_X;
+import static com.android.launcher3.util.MultiTranslateDelegate.INDEX_BUBBLE_ADJUSTMENT_ANIM;
+
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
@@ -27,6 +33,10 @@
import android.view.ViewGroup;
import android.widget.FrameLayout;
+import com.android.launcher3.util.HorizontalInsettableView;
+import com.android.launcher3.util.MultiTranslateDelegate;
+import com.android.launcher3.views.ActivityContext;
+
/**
* View class that represents the bottom row of the home screen.
*/
@@ -34,6 +44,7 @@
// Ratio of empty space, qsb should take up to appear visually centered.
public static final float QSB_CENTER_FACTOR = .325f;
+ private static final int BUBBLE_BAR_ADJUSTMENT_ANIMATION_DURATION_MS = 250;
@ViewDebug.ExportedProperty(category = "launcher")
private boolean mHasVerticalHotseat;
@@ -72,9 +83,36 @@
}
public void resetLayout(boolean hasVerticalHotseat) {
+ ActivityContext activityContext = ActivityContext.lookupContext(getContext());
+ boolean bubbleBarEnabled = activityContext.isBubbleBarEnabled();
+ boolean hasBubbles = activityContext.hasBubbles();
removeAllViewsInLayout();
mHasVerticalHotseat = hasVerticalHotseat;
DeviceProfile dp = mActivity.getDeviceProfile();
+
+ if (bubbleBarEnabled) {
+ float adjustedBorderSpace = dp.getHotseatAdjustedBorderSpaceForBubbleBar(getContext());
+ if (hasBubbles && Float.compare(adjustedBorderSpace, 0f) != 0) {
+ getShortcutsAndWidgets().setTranslationProvider(child -> {
+ int index = getShortcutsAndWidgets().indexOfChild(child);
+ float borderSpaceDelta = adjustedBorderSpace - dp.hotseatBorderSpace;
+ return dp.iconSizePx + index * borderSpaceDelta;
+ });
+ if (mQsb instanceof HorizontalInsettableView) {
+ HorizontalInsettableView insettableQsb = (HorizontalInsettableView) mQsb;
+ final float insetFraction = (float) dp.iconSizePx / dp.hotseatQsbWidth;
+ // post this to the looper so that QSB has a chance to redraw itself, e.g.
+ // after device rotation
+ mQsb.post(() -> insettableQsb.setHorizontalInsets(insetFraction));
+ }
+ } else {
+ getShortcutsAndWidgets().setTranslationProvider(null);
+ if (mQsb instanceof HorizontalInsettableView) {
+ ((HorizontalInsettableView) mQsb).setHorizontalInsets(0);
+ }
+ }
+ }
+
resetCellSize(dp);
if (hasVerticalHotseat) {
setGridSize(1, dp.numShownHotseatIcons);
@@ -83,6 +121,62 @@
}
}
+ /**
+ * Adjust the hotseat icons for the bubble bar.
+ *
+ * <p>When the bubble bar becomes visible, if needed, this method animates the hotseat icons
+ * to reduce the spacing between them and make room for the bubble bar. The QSB width is
+ * animated as well to align with the hotseat icons.
+ *
+ * <p>When the bubble bar goes away, any adjustments that were previously made are reversed.
+ */
+ public void adjustForBubbleBar(boolean isBubbleBarVisible) {
+ DeviceProfile dp = mActivity.getDeviceProfile();
+ float adjustedBorderSpace = dp.getHotseatAdjustedBorderSpaceForBubbleBar(getContext());
+ if (Float.compare(adjustedBorderSpace, 0f) == 0) {
+ return;
+ }
+
+ ShortcutAndWidgetContainer icons = getShortcutsAndWidgets();
+ AnimatorSet animatorSet = new AnimatorSet();
+ float borderSpaceDelta = adjustedBorderSpace - dp.hotseatBorderSpace;
+
+ // update the translation provider for future layout passes of hotseat icons.
+ if (isBubbleBarVisible) {
+ icons.setTranslationProvider(child -> {
+ int index = icons.indexOfChild(child);
+ return dp.iconSizePx + index * borderSpaceDelta;
+ });
+ } else {
+ icons.setTranslationProvider(null);
+ }
+
+ for (int i = 0; i < icons.getChildCount(); i++) {
+ View child = icons.getChildAt(i);
+ float tx = isBubbleBarVisible ? dp.iconSizePx + i * borderSpaceDelta : 0;
+ if (child instanceof Reorderable) {
+ MultiTranslateDelegate mtd = ((Reorderable) child).getTranslateDelegate();
+ animatorSet.play(
+ mtd.getTranslationX(INDEX_BUBBLE_ADJUSTMENT_ANIM).animateToValue(tx));
+ } else {
+ animatorSet.play(ObjectAnimator.ofFloat(child, VIEW_TRANSLATE_X, tx));
+ }
+ }
+ if (mQsb instanceof HorizontalInsettableView) {
+ HorizontalInsettableView horizontalInsettableQsb = (HorizontalInsettableView) mQsb;
+ ValueAnimator qsbAnimator = ValueAnimator.ofFloat(0f, 1f);
+ qsbAnimator.addUpdateListener(animation -> {
+ float fraction = qsbAnimator.getAnimatedFraction();
+ float insetFraction = isBubbleBarVisible
+ ? (float) dp.iconSizePx * fraction / dp.hotseatQsbWidth
+ : (float) dp.iconSizePx * (1 - fraction) / dp.hotseatQsbWidth;
+ horizontalInsettableQsb.setHorizontalInsets(insetFraction);
+ });
+ animatorSet.play(qsbAnimator);
+ }
+ animatorSet.setDuration(BUBBLE_BAR_ADJUSTMENT_ANIMATION_DURATION_MS).start();
+ }
+
@Override
public void setInsets(Rect insets) {
FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams();
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/Launcher.java b/src/com/android/launcher3/Launcher.java
index 606b2c4..b8e7737 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -68,6 +68,7 @@
import static com.android.launcher3.logging.StatsLogManager.StatsLatencyLogger.LatencyType.WARM;
import static com.android.launcher3.model.ItemInstallQueue.FLAG_ACTIVITY_PAUSED;
import static com.android.launcher3.model.ItemInstallQueue.FLAG_DRAG_AND_DROP;
+import static com.android.launcher3.model.data.LauncherAppWidgetInfo.CUSTOM_WIDGET_ID;
import static com.android.launcher3.popup.SystemShortcut.APP_INFO;
import static com.android.launcher3.popup.SystemShortcut.INSTALL;
import static com.android.launcher3.popup.SystemShortcut.WIDGETS;
@@ -144,6 +145,7 @@
import com.android.launcher3.allapps.AllAppsTransitionController;
import com.android.launcher3.allapps.BaseSearchConfig;
import com.android.launcher3.allapps.DiscoveryBounce;
+import com.android.launcher3.anim.AnimationSuccessListener;
import com.android.launcher3.anim.PropertyListBuilder;
import com.android.launcher3.apppairs.AppPairIcon;
import com.android.launcher3.celllayout.CellPosMapper;
@@ -885,7 +887,7 @@
if (widgetInfo != null) {
// Since the view was just bound, also launch the configure activity if needed
LauncherAppWidgetProviderInfo provider = mAppWidgetManager
- .getLauncherAppWidgetInfo(widgetId);
+ .getLauncherAppWidgetInfo(widgetId, info.getTargetComponent());
if (provider != null) {
new WidgetAddFlowHandler(provider)
.startConfigActivity(this, widgetInfo,
@@ -1499,7 +1501,8 @@
AppWidgetHostView hostView, LauncherAppWidgetProviderInfo appWidgetInfo) {
if (appWidgetInfo == null) {
- appWidgetInfo = mAppWidgetManager.getLauncherAppWidgetInfo(appWidgetId);
+ appWidgetInfo = mAppWidgetManager.getLauncherAppWidgetInfo(appWidgetId,
+ itemInfo.getTargetComponent());
}
if (hostView == null) {
@@ -1727,7 +1730,16 @@
if (getStateManager().isInStableState(ALL_APPS)) {
getStateManager().goToState(NORMAL, alreadyOnHome);
} else {
- showAllAppsFromIntent(alreadyOnHome);
+ AbstractFloatingView.closeAllOpenViews(this);
+ getStateManager().goToState(ALL_APPS, true /* animated */,
+ new AnimationSuccessListener() {
+ @Override
+ public void onAnimationSuccess(Animator animator) {
+ if (mAppsView.getSearchUiManager().getEditText() != null) {
+ mAppsView.getSearchUiManager().getEditText().requestFocus();
+ }
+ }
+ });
}
}
@@ -1985,8 +1997,8 @@
// In this case, we either need to start an activity to get permission to bind
// the widget, or we need to start an activity to configure the widget, or both.
if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET) {
- appWidgetId = CustomWidgetManager.INSTANCE.get(this).getWidgetIdForCustomProvider(
- info.componentName);
+ appWidgetId = CustomWidgetManager.INSTANCE.get(this)
+ .allocateCustomAppWidgetId(info.componentName);
} else {
appWidgetId = getAppWidgetHolder().allocateAppWidgetId();
}
@@ -2313,6 +2325,7 @@
* <p>
* Implementation of the method from LauncherModel.Callbacks.
*/
+ @Override
public void startBinding() {
TraceHelper.INSTANCE.beginSection("startBinding");
// Floating panels (except the full widget sheet) are associated with individual icons. If
@@ -2632,9 +2645,10 @@
}
}
} else {
- appWidgetInfo = mAppWidgetManager.getLauncherAppWidgetInfo(item.appWidgetId);
+ appWidgetInfo = mAppWidgetManager.getLauncherAppWidgetInfo(item.appWidgetId,
+ item.getTargetComponent());
if (appWidgetInfo == null) {
- if (item.appWidgetId <= LauncherAppWidgetInfo.CUSTOM_WIDGET_ID) {
+ if (item.appWidgetId <= CUSTOM_WIDGET_ID) {
removalReason =
"CustomWidgetManager cannot find provider from that widget id.";
} else {
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/ShortcutAndWidgetContainer.java b/src/com/android/launcher3/ShortcutAndWidgetContainer.java
index 5e7f21b..b22b690 100644
--- a/src/com/android/launcher3/ShortcutAndWidgetContainer.java
+++ b/src/com/android/launcher3/ShortcutAndWidgetContainer.java
@@ -21,6 +21,7 @@
import static com.android.launcher3.CellLayout.FOLDER;
import static com.android.launcher3.CellLayout.HOTSEAT;
import static com.android.launcher3.CellLayout.WORKSPACE;
+import static com.android.launcher3.util.MultiTranslateDelegate.INDEX_BUBBLE_ADJUSTMENT_ANIM;
import static com.android.launcher3.util.MultiTranslateDelegate.INDEX_WIDGET_CENTERING;
import android.app.WallpaperManager;
@@ -33,6 +34,8 @@
import android.view.View;
import android.view.ViewGroup;
+import androidx.annotation.Nullable;
+
import com.android.launcher3.CellLayout.ContainerType;
import com.android.launcher3.celllayout.CellLayoutLayoutParams;
import com.android.launcher3.folder.FolderIcon;
@@ -62,6 +65,9 @@
private final ActivityContext mActivity;
private boolean mInvertIfRtl = false;
+ @Nullable
+ private TranslationProvider mTranslationProvider = null;
+
public ShortcutAndWidgetContainer(Context context, @ContainerType int containerType) {
super(context);
mActivity = ActivityContext.lookupContext(context);
@@ -229,6 +235,16 @@
childLeft, childTop, childLeft + lp.width, childTop + lp.height);
}
child.layout(childLeft, childTop, childLeft + lp.width, childTop + lp.height);
+ if (mTranslationProvider != null) {
+ final float tx = mTranslationProvider.getTranslationX(child);
+ if (child instanceof Reorderable) {
+ ((Reorderable) child).getTranslateDelegate()
+ .getTranslationX(INDEX_BUBBLE_ADJUSTMENT_ANIM)
+ .setValue(tx);
+ } else {
+ child.setTranslationX(tx);
+ }
+ }
if (lp.dropped) {
lp.dropped = false;
@@ -298,4 +314,13 @@
cl.clearFolderLeaveBehind();
}
}
+
+ void setTranslationProvider(@Nullable TranslationProvider provider) {
+ mTranslationProvider = provider;
+ }
+
+ /** Provides translation values to apply when laying out child views. */
+ interface TranslationProvider {
+ float getTranslationX(View child);
+ }
}
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index e8c6ff9..7b27a71 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -16,13 +16,14 @@
package com.android.launcher3;
+import static android.graphics.drawable.AdaptiveIconDrawable.getExtraInsetFraction;
+
import static com.android.launcher3.icons.BitmapInfo.FLAG_THEMED;
-import static com.android.launcher3.model.data.ItemInfoWithIcon.FLAG_ICON_BADGED;
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT;
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT;
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_TYPE_MAIN;
-import android.annotation.TargetApi;
+import android.annotation.SuppressLint;
import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.app.Person;
@@ -33,6 +34,9 @@
import android.content.pm.ShortcutInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BlendMode;
+import android.graphics.BlendModeColorFilter;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.LightingColorFilter;
@@ -43,8 +47,10 @@
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.AdaptiveIconDrawable;
+import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
+import android.graphics.drawable.InsetDrawable;
import android.os.Build;
import android.os.Build.VERSION_CODES;
import android.os.DeadObjectException;
@@ -59,6 +65,7 @@
import android.text.style.TtsSpan;
import android.util.DisplayMetrics;
import android.util.Log;
+import android.util.Pair;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;
@@ -68,10 +75,13 @@
import androidx.annotation.ChecksSdkIntAtLeast;
import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.WorkerThread;
import androidx.core.graphics.ColorUtils;
import com.android.launcher3.dragndrop.FolderAdaptiveIcon;
import com.android.launcher3.graphics.TintedDrawableSpan;
+import com.android.launcher3.icons.LauncherIcons;
import com.android.launcher3.icons.ShortcutCachingLogic;
import com.android.launcher3.icons.ThemedIconDrawable;
import com.android.launcher3.model.data.ItemInfo;
@@ -571,103 +581,112 @@
}
/**
- * Returns the full drawable for info without any flattening or pre-processing.
+ * Returns the full drawable for info as multiple layers of AdaptiveIconDrawable. The second
+ * drawable in the Pair is the badge used with the icon.
*
- * @param shouldThemeIcon If true, will theme icons when applicable
- * @param outObj this is set to the internal data associated with {@code info},
- * eg {@link LauncherActivityInfo} or {@link ShortcutInfo}.
+ * @param useTheme If true, will theme icons when applicable
*/
- @TargetApi(Build.VERSION_CODES.TIRAMISU)
- public static Drawable getFullDrawable(Context context, ItemInfo info, int width, int height,
- boolean shouldThemeIcon, Object[] outObj, boolean[] outIsIconThemed) {
- Drawable icon = loadFullDrawableWithoutTheme(context, info, width, height, outObj);
- if (ATLEAST_T && icon instanceof AdaptiveIconDrawable && shouldThemeIcon) {
- AdaptiveIconDrawable aid = (AdaptiveIconDrawable) icon.mutate();
- Drawable mono = aid.getMonochrome();
- if (mono != null && Themes.isThemedIconEnabled(context)) {
- outIsIconThemed[0] = true;
- int[] colors = ThemedIconDrawable.getColors(context);
- mono = mono.mutate();
- mono.setTint(colors[1]);
- return new AdaptiveIconDrawable(new ColorDrawable(colors[0]), mono);
- }
- }
- return icon;
- }
-
- private static Drawable loadFullDrawableWithoutTheme(Context context, ItemInfo info,
- int width, int height, Object[] outObj) {
- ActivityContext activity = ActivityContext.lookupContext(context);
+ @SuppressLint("UseCompatLoadingForDrawables")
+ @Nullable
+ @WorkerThread
+ public static <T extends Context & ActivityContext> Pair<AdaptiveIconDrawable, Drawable>
+ getFullDrawable(T context, ItemInfo info, int width, int height, boolean useTheme) {
+ useTheme &= Themes.isThemedIconEnabled(context);
LauncherAppState appState = LauncherAppState.getInstance(context);
+ Drawable mainIcon = null;
+
+ Drawable badge = null;
+ if ((info instanceof ItemInfoWithIcon iiwi) && !iiwi.usingLowResIcon()) {
+ badge = iiwi.bitmap.getBadgeDrawable(context, useTheme);
+ }
+
if (info instanceof PendingAddShortcutInfo) {
ShortcutConfigActivityInfo activityInfo =
((PendingAddShortcutInfo) info).getActivityInfo(context);
- outObj[0] = activityInfo;
- return activityInfo.getFullResIcon(appState.getIconCache());
- }
- if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) {
+ mainIcon = activityInfo.getFullResIcon(appState.getIconCache());
+ } else if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) {
LauncherActivityInfo activityInfo = context.getSystemService(LauncherApps.class)
.resolveActivity(info.getIntent(), info.user);
- outObj[0] = activityInfo;
- return activityInfo == null ? null : LauncherAppState.getInstance(context)
- .getIconProvider().getIcon(
- activityInfo, activity.getDeviceProfile().inv.fillResIconDpi);
+ if (activityInfo == null) {
+ return null;
+ }
+ mainIcon = appState.getIconProvider().getIcon(
+ activityInfo, appState.getInvariantDeviceProfile().fillResIconDpi);
} else if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
- List<ShortcutInfo> si = ShortcutKey.fromItemInfo(info)
+ List<ShortcutInfo> siList = ShortcutKey.fromItemInfo(info)
.buildRequest(context)
.query(ShortcutRequest.ALL);
- if (si.isEmpty()) {
+ if (siList.isEmpty()) {
return null;
} else {
- outObj[0] = si.get(0);
- return ShortcutCachingLogic.getIcon(context, si.get(0),
+ ShortcutInfo si = siList.get(0);
+ mainIcon = ShortcutCachingLogic.getIcon(context, si,
appState.getInvariantDeviceProfile().fillResIconDpi);
+ // Only fetch badge if the icon is on workspace
+ if (info.id != ItemInfo.NO_ID && badge == null) {
+ badge = appState.getIconCache().getShortcutInfoBadge(si)
+ .newIcon(context, FLAG_THEMED);
+ }
}
} else if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_FOLDER) {
FolderAdaptiveIcon icon = FolderAdaptiveIcon.createFolderAdaptiveIcon(
- activity, info.id, new Point(width, height));
+ context, info.id, new Point(width, height));
if (icon == null) {
return null;
}
- outObj[0] = icon;
- return icon;
- } else if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_SEARCH_ACTION
- && info instanceof ItemInfoWithIcon) {
- return ((ItemInfoWithIcon) info).bitmap.newIcon(context);
- } else {
+ mainIcon = icon;
+ badge = icon.getBadge();
+ }
+
+ if (mainIcon == null) {
return null;
}
- }
-
- /**
- * For apps icons and shortcut icons that have badges, this method creates a drawable that can
- * later on be rendered on top of the layers for the badges. For app icons, work profile badges
- * can only be applied. For deep shortcuts, when dragged from the pop up container, there's no
- * badge. When dragged from workspace or folder, it may contain app AND/OR work profile badge
- **/
- @TargetApi(Build.VERSION_CODES.O)
- public static Drawable getBadge(Context context, ItemInfo info, Object obj,
- boolean isIconThemed) {
- LauncherAppState appState = LauncherAppState.getInstance(context);
- if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
- boolean iconBadged = (info instanceof ItemInfoWithIcon)
- && (((ItemInfoWithIcon) info).runtimeStatusFlags & FLAG_ICON_BADGED) > 0;
- if ((info.id == ItemInfo.NO_ID && !iconBadged)
- || !(obj instanceof ShortcutInfo)) {
- // The item is not yet added on home screen.
- return new ColorDrawable(Color.TRANSPARENT);
- }
- ShortcutInfo si = (ShortcutInfo) obj;
- return LauncherAppState.getInstance(appState.getContext())
- .getIconCache().getShortcutInfoBadge(si).newIcon(context, FLAG_THEMED);
- } else if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_FOLDER) {
- return ((FolderAdaptiveIcon) obj).getBadge();
+ AdaptiveIconDrawable result;
+ if (mainIcon instanceof AdaptiveIconDrawable aid) {
+ result = aid;
} else {
- return Process.myUserHandle().equals(info.user)
- ? new ColorDrawable(Color.TRANSPARENT)
- : context.getDrawable(isIconThemed
- ? R.drawable.ic_work_app_badge_themed : R.drawable.ic_work_app_badge);
+ // Wrap the main icon in AID
+ try (LauncherIcons li = LauncherIcons.obtain(context)) {
+ result = li.wrapToAdaptiveIcon(mainIcon);
+ }
}
+ if (result == null) {
+ return null;
+ }
+
+ // Inject monochrome icon drawable
+ if (ATLEAST_T && useTheme) {
+ result.mutate();
+ int[] colors = ThemedIconDrawable.getColors(context);
+ Drawable mono = result.getMonochrome();
+
+ if (mono != null) {
+ mono.setTint(colors[1]);
+ } else if (info instanceof ItemInfoWithIcon iiwi) {
+ // Inject a previously generated monochrome icon
+ Bitmap monoBitmap = iiwi.bitmap.getMono();
+ if (monoBitmap != null) {
+ // Use BitmapDrawable instead of FastBitmapDrawable so that the colorState is
+ // preserved in constantState
+ mono = new BitmapDrawable(monoBitmap);
+ mono.setColorFilter(new BlendModeColorFilter(colors[1], BlendMode.SRC_IN));
+ // Inset the drawable according to the AdaptiveIconDrawable layers
+ mono = new InsetDrawable(mono, getExtraInsetFraction() / 2);
+ }
+ }
+ if (mono != null) {
+ result = new AdaptiveIconDrawable(new ColorDrawable(colors[0]), mono);
+ }
+ }
+
+ if (badge == null) {
+ badge = Process.myUserHandle().equals(info.user)
+ ? new ColorDrawable(Color.TRANSPARENT)
+ : context.getDrawable(useTheme
+ ? R.drawable.ic_work_app_badge_themed
+ : R.drawable.ic_work_app_badge);
+ }
+ return Pair.create(result, badge);
}
public static float squaredHypot(float x, float y) {
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 8be8fed..a1a3974 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -3413,7 +3413,8 @@
if (item.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_ID_NOT_VALID)) {
widgetInfo = widgetHelper.findProvider(item.providerName, item.user);
} else {
- widgetInfo = widgetHelper.getLauncherAppWidgetInfo(item.appWidgetId);
+ widgetInfo = widgetHelper.getLauncherAppWidgetInfo(item.appWidgetId,
+ item.getTargetComponent());
}
if (widgetInfo != 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 4285755..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;
@@ -141,7 +142,7 @@
// TODO(Block 6): Clean up flags
public static final BooleanFlag ENABLE_ALL_APPS_SEARCH_IN_TASKBAR = getDebugFlag(270393900,
- "ENABLE_ALL_APPS_SEARCH_IN_TASKBAR", DISABLED,
+ "ENABLE_ALL_APPS_SEARCH_IN_TASKBAR", TEAMFOOD,
"Enables Search box in Taskbar All Apps.");
public static final BooleanFlag SECONDARY_DRAG_N_DROP_TO_PIN = getDebugFlag(270395140,
@@ -175,22 +176,17 @@
"MULTI_SELECT_EDIT_MODE", DISABLED, "Enable new multi-select edit mode "
+ "for home screen");
+ public static final BooleanFlag SMARTSPACE_AS_A_WIDGET = getDebugFlag(299181941,
+ "SMARTSPACE_AS_A_WIDGET", DISABLED, "Enable SmartSpace as a widget");
+
// TODO(Block 10): Clean up flags
public static final BooleanFlag ENABLE_BACK_SWIPE_LAUNCHER_ANIMATION = getDebugFlag(270614790,
"ENABLE_BACK_SWIPE_LAUNCHER_ANIMATION", DISABLED,
"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,
@@ -213,6 +209,10 @@
public static final BooleanFlag ENABLE_TRANSIENT_TASKBAR = getDebugFlag(270395798,
"ENABLE_TRANSIENT_TASKBAR", ENABLED, "Enables transient taskbar.");
+ public static final BooleanFlag ENABLE_TASKBAR_NO_RECREATION = getDebugFlag(299193589,
+ "ENABLE_TASKBAR_NO_RECREATION", DISABLED,
+ "Enables taskbar with no recreation from lifecycle changes of TaskbarActivityContext.");
+
// TODO(Block 16): Clean up flags
// When enabled the promise icon is visible in all apps while installation an app.
public static final BooleanFlag PROMISE_APPS_IN_ALL_APPS = getDebugFlag(270390012,
@@ -308,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/dragndrop/DragView.java b/src/com/android/launcher3/dragndrop/DragView.java
index adfdc89..c2d9e02 100644
--- a/src/com/android/launcher3/dragndrop/DragView.java
+++ b/src/com/android/launcher3/dragndrop/DragView.java
@@ -20,7 +20,6 @@
import static android.view.View.MeasureSpec.makeMeasureSpec;
import static com.android.launcher3.LauncherAnimUtils.VIEW_ALPHA;
-import static com.android.launcher3.Utilities.getBadge;
import static com.android.launcher3.icons.FastBitmapDrawable.getDisabledColorFilter;
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
@@ -45,6 +44,7 @@
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
+import android.util.Pair;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
@@ -244,13 +244,12 @@
public void setItemInfo(final ItemInfo info) {
// Load the adaptive icon on a background thread and add the view in ui thread.
MODEL_EXECUTOR.getHandler().postAtFrontOfQueue(() -> {
- Object[] outObj = new Object[1];
- boolean[] outIsIconThemed = new boolean[1];
int w = mWidth;
int h = mHeight;
- Drawable dr = Utilities.getFullDrawable(mActivity, info, w, h,
- true /* shouldThemeIcon */, outObj, outIsIconThemed);
- if (dr instanceof AdaptiveIconDrawable) {
+ Pair<AdaptiveIconDrawable, Drawable> fullDrawable = Utilities.getFullDrawable(
+ mActivity, info, w, h, true /* shouldThemeIcon */);
+ if (fullDrawable != null) {
+ AdaptiveIconDrawable adaptiveIcon = fullDrawable.first;
int blurMargin = (int) mActivity.getResources()
.getDimension(R.dimen.blur_size_medium_outline) / 2;
@@ -258,24 +257,15 @@
bounds.inset(blurMargin, blurMargin);
// Badge is applied after icon normalization so the bounds for badge should not
// be scaled down due to icon normalization.
- mBadge = getBadge(mActivity, info, outObj[0], outIsIconThemed[0]);
+ mBadge = fullDrawable.second;
FastBitmapDrawable.setBadgeBounds(mBadge, bounds);
- // Do not draw the background in case of folder as its translucent
- final boolean shouldDrawBackground = !(dr instanceof FolderAdaptiveIcon);
-
try (LauncherIcons li = LauncherIcons.obtain(mActivity)) {
- Drawable nDr; // drawable to be normalized
- if (shouldDrawBackground) {
- nDr = dr;
- } else {
- // Since we just want the scale, avoid heavy drawing operations
- nDr = new AdaptiveIconDrawable(new ColorDrawable(Color.BLACK), null);
- }
- Utilities.scaleRectAboutCenter(bounds,
- li.getNormalizer().getScale(nDr, null, null, null));
+ // Since we just want the scale, avoid heavy drawing operations
+ Utilities.scaleRectAboutCenter(bounds, li.getNormalizer().getScale(
+ new AdaptiveIconDrawable(new ColorDrawable(Color.BLACK), null),
+ null, null, null));
}
- AdaptiveIconDrawable adaptiveIcon = (AdaptiveIconDrawable) dr;
// Shrink very tiny bit so that the clip path is smaller than the original bitmap
// that has anti aliased edges and shadows.
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/logging/StatsLogManager.java b/src/com/android/launcher3/logging/StatsLogManager.java
index 265378c..4307566 100644
--- a/src/com/android/launcher3/logging/StatsLogManager.java
+++ b/src/com/android/launcher3/logging/StatsLogManager.java
@@ -654,7 +654,19 @@
LAUNCHER_APP_PAIR_SAVE(1456),
@UiEvent(doc = "App launched through pending intent")
- LAUNCHER_APP_LAUNCH_PENDING_INTENT(1394)
+ LAUNCHER_APP_LAUNCH_PENDING_INTENT(1394),
+
+ @UiEvent(doc = "User long pressed on taskbar divider icon to open popup menu")
+ LAUNCHER_TASKBAR_DIVIDER_MENU_OPEN(1488),
+
+ @UiEvent(doc = "User long pressed on taskbar divider icon to close popup menu")
+ LAUNCHER_TASKBAR_DIVIDER_MENU_CLOSE(1489),
+
+ @UiEvent(doc = "User has pinned taskbar using taskbar divider menu")
+ LAUNCHER_TASKBAR_PINNED(1490),
+
+ @UiEvent(doc = "User has unpinned taskbar using taskbar divider menu")
+ LAUNCHER_TASKBAR_UNPINNED(1491)
// ADD MORE
;
diff --git a/src/com/android/launcher3/model/GridSizeMigrationUtil.java b/src/com/android/launcher3/model/GridSizeMigrationUtil.java
index c233872..78875a3 100644
--- a/src/com/android/launcher3/model/GridSizeMigrationUtil.java
+++ b/src/com/android/launcher3/model/GridSizeMigrationUtil.java
@@ -539,8 +539,8 @@
verifyPackage(cn.getPackageName());
int widgetId = c.getInt(indexAppWidgetId);
- LauncherAppWidgetProviderInfo pInfo =
- widgetManagerHelper.getLauncherAppWidgetInfo(widgetId);
+ LauncherAppWidgetProviderInfo pInfo = widgetManagerHelper
+ .getLauncherAppWidgetInfo(widgetId, cn);
Point spans = null;
if (pInfo != null) {
spans = pInfo.getMinSpans();
diff --git a/src/com/android/launcher3/model/LoaderTask.java b/src/com/android/launcher3/model/LoaderTask.java
index 0e68db2..08a6cf0 100644
--- a/src/com/android/launcher3/model/LoaderTask.java
+++ b/src/com/android/launcher3/model/LoaderTask.java
@@ -95,6 +95,7 @@
import com.android.launcher3.util.TraceHelper;
import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
import com.android.launcher3.widget.WidgetManagerHelper;
+import com.android.launcher3.widget.custom.CustomWidgetManager;
import java.util.ArrayList;
import java.util.Collections;
@@ -740,8 +741,13 @@
ComponentKey providerKey = new ComponentKey(component, c.user);
if (!mWidgetProvidersMap.containsKey(providerKey)) {
- mWidgetProvidersMap.put(providerKey,
- widgetHelper.findProvider(component, c.user));
+ if (customWidget) {
+ mWidgetProvidersMap.put(providerKey, CustomWidgetManager.INSTANCE
+ .get(mApp.getContext()).getWidgetProvider(component));
+ } else {
+ mWidgetProvidersMap.put(providerKey,
+ widgetHelper.findProvider(component, c.user));
+ }
}
final AppWidgetProviderInfo provider = mWidgetProvidersMap.get(providerKey);
@@ -814,7 +820,8 @@
return;
}
LauncherAppWidgetProviderInfo widgetProviderInfo =
- widgetHelper.getLauncherAppWidgetInfo(appWidgetId);
+ widgetHelper.getLauncherAppWidgetInfo(appWidgetId,
+ appWidgetInfo.getTargetComponent());
if (widgetProviderInfo != null
&& (appWidgetInfo.spanX < widgetProviderInfo.minSpanX
|| appWidgetInfo.spanY < widgetProviderInfo.minSpanY)) {
diff --git a/src/com/android/launcher3/model/data/AppInfo.java b/src/com/android/launcher3/model/data/AppInfo.java
index 7e6cbef..6c2f589 100644
--- a/src/com/android/launcher3/model/data/AppInfo.java
+++ b/src/com/android/launcher3/model/data/AppInfo.java
@@ -23,8 +23,6 @@
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.LauncherActivityInfo;
-import android.os.Build;
-import android.os.Process;
import android.os.UserHandle;
import android.os.UserManager;
@@ -177,12 +175,6 @@
info.runtimeStatusFlags |= (appInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0
? FLAG_SYSTEM_NO : FLAG_SYSTEM_YES;
- if (appInfo.targetSdkVersion >= Build.VERSION_CODES.O
- && Process.myUserHandle().equals(lai.getUser())) {
- // The icon for a non-primary user is badged, hence it's not exactly an adaptive icon.
- info.runtimeStatusFlags |= FLAG_ADAPTIVE_ICON;
- }
-
// Sets the progress level, installation and incremental download flags.
info.setProgressLevel(
PackageManagerHelper.getLoadingProgress(lai),
diff --git a/src/com/android/launcher3/model/data/ItemInfoWithIcon.java b/src/com/android/launcher3/model/data/ItemInfoWithIcon.java
index b4a935a..dc180d8 100644
--- a/src/com/android/launcher3/model/data/ItemInfoWithIcon.java
+++ b/src/com/android/launcher3/model/data/ItemInfoWithIcon.java
@@ -83,17 +83,6 @@
public static final int FLAG_SYSTEM_MASK = FLAG_SYSTEM_YES | FLAG_SYSTEM_NO;
/**
- * Flag indicating that the icon is an {@link android.graphics.drawable.AdaptiveIconDrawable}
- * that can be optimized in various way.
- */
- public static final int FLAG_ADAPTIVE_ICON = 1 << 8;
-
- /**
- * Flag indicating that the icon is badged.
- */
- public static final int FLAG_ICON_BADGED = 1 << 9;
-
- /**
* The icon is being installed. If {@link WorkspaceItemInfo#FLAG_RESTORED_ICON} or
* {@link WorkspaceItemInfo#FLAG_AUTOINSTALL_ICON} is set, then the icon is either being
* installed or is in a broken state.
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/responsive/HotseatSpecs.kt b/src/com/android/launcher3/responsive/HotseatSpecs.kt
index 482508d..d578b08 100644
--- a/src/com/android/launcher3/responsive/HotseatSpecs.kt
+++ b/src/com/android/launcher3/responsive/HotseatSpecs.kt
@@ -21,14 +21,20 @@
import com.android.launcher3.R
import com.android.launcher3.util.ResourceHelper
-class HotseatSpecs(val specs: List<HotseatSpec>) {
+class HotseatSpecs(val widthSpecs: List<HotseatSpec>, val heightSpecs: List<HotseatSpec>) {
fun getCalculatedHeightSpec(availableHeight: Int): CalculatedHotseatSpec {
- val spec = specs.firstOrNull { availableHeight <= it.maxAvailableSize }
+ val spec = heightSpecs.firstOrNull { availableHeight <= it.maxAvailableSize }
check(spec != null) { "No available height spec found within $availableHeight." }
return CalculatedHotseatSpec(availableHeight, spec)
}
+ fun getCalculatedWidthSpec(availableWidth: Int): CalculatedHotseatSpec {
+ val spec = widthSpecs.firstOrNull { availableWidth <= it.maxAvailableSize }
+ check(spec != null) { "No available width spec found within $availableWidth." }
+ return CalculatedHotseatSpec(availableWidth, spec)
+ }
+
companion object {
private const val XML_HOTSEAT_SPEC = "hotseatSpec"
@@ -36,7 +42,9 @@
fun create(resourceHelper: ResourceHelper): HotseatSpecs {
val parser = ResponsiveSpecsParser(resourceHelper)
val specs = parser.parseXML(XML_HOTSEAT_SPEC, ::HotseatSpec)
- return HotseatSpecs(specs.filter { it.specType == ResponsiveSpec.SpecType.HEIGHT })
+ val (widthSpecs, heightSpecs) =
+ specs.partition { it.specType == ResponsiveSpec.SpecType.WIDTH }
+ return HotseatSpecs(widthSpecs, heightSpecs)
}
}
}
@@ -44,7 +52,8 @@
data class HotseatSpec(
val maxAvailableSize: Int,
val specType: ResponsiveSpec.SpecType,
- val hotseatQsbSpace: SizeSpec
+ val hotseatQsbSpace: SizeSpec,
+ val edgePadding: SizeSpec
) {
init {
@@ -63,7 +72,8 @@
R.styleable.ResponsiveSpec_specType,
ResponsiveSpec.SpecType.HEIGHT.ordinal
)],
- hotseatQsbSpace = specs.getOrError(SizeSpec.XmlTags.HOTSEAT_QSB_SPACE)
+ hotseatQsbSpace = specs.getOrError(SizeSpec.XmlTags.HOTSEAT_QSB_SPACE),
+ edgePadding = specs.getOrError(SizeSpec.XmlTags.EDGE_PADDING)
)
fun isValid(): Boolean {
@@ -82,7 +92,10 @@
}
private fun allSpecsAreValid(): Boolean {
- return hotseatQsbSpace.isValid() && hotseatQsbSpace.onlyFixedSize()
+ return hotseatQsbSpace.isValid() &&
+ hotseatQsbSpace.onlyFixedSize() &&
+ edgePadding.isValid() &&
+ edgePadding.onlyFixedSize()
}
companion object {
@@ -95,13 +108,18 @@
var hotseatQsbSpace: Int = 0
private set
+ var edgePadding: Int = 0
+ private set
+
init {
hotseatQsbSpace = spec.hotseatQsbSpace.getCalculatedValue(availableSpace)
+ edgePadding = spec.edgePadding.getCalculatedValue(availableSpace)
}
override fun hashCode(): Int {
var result = availableSpace.hashCode()
result = 31 * result + hotseatQsbSpace.hashCode()
+ result = 31 * result + edgePadding.hashCode()
result = 31 * result + spec.hashCode()
return result
}
@@ -110,12 +128,14 @@
return other is CalculatedHotseatSpec &&
availableSpace == other.availableSpace &&
hotseatQsbSpace == other.hotseatQsbSpace &&
+ edgePadding == other.edgePadding &&
spec == other.spec
}
override fun toString(): String {
return "${this::class.simpleName}(" +
"availableSpace=$availableSpace, hotseatQsbSpace=$hotseatQsbSpace, " +
+ "edgePadding=$edgePadding, " +
"${spec::class.simpleName}.maxAvailableSize=${spec.maxAvailableSize}" +
")"
}
diff --git a/src/com/android/launcher3/responsive/SizeSpec.kt b/src/com/android/launcher3/responsive/SizeSpec.kt
index c868c9f..2db843b 100644
--- a/src/com/android/launcher3/responsive/SizeSpec.kt
+++ b/src/com/android/launcher3/responsive/SizeSpec.kt
@@ -121,6 +121,7 @@
const val GUTTER = "gutter"
const val CELL_SIZE = "cellSize"
const val HOTSEAT_QSB_SPACE = "hotseatQsbSpace"
+ const val EDGE_PADDING = "edgePadding"
}
companion object {
diff --git a/src/com/android/launcher3/testing/TestInformationHandler.java b/src/com/android/launcher3/testing/TestInformationHandler.java
index 5d412ff..a75f326 100644
--- a/src/com/android/launcher3/testing/TestInformationHandler.java
+++ b/src/com/android/launcher3/testing/TestInformationHandler.java
@@ -16,8 +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.ENABLE_TRACKPAD_GESTURE;
+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;
@@ -33,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;
@@ -143,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);
@@ -236,12 +244,6 @@
return response;
}
- case TestProtocol.REQUEST_IS_TRACKPAD_GESTURE_ENABLED: {
- response.putBoolean(TestProtocol.TEST_INFO_RESPONSE_FIELD,
- ENABLE_TRACKPAD_GESTURE.get());
- return response;
- }
-
case TestProtocol.REQUEST_ALL_APPS_TOP_PADDING: {
return getLauncherUIProperty(Bundle::putInt,
l -> l.getAppsView().getActiveRecyclerView().getClipBounds().top);
@@ -256,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/src/com/android/launcher3/testing/TestLogging.java b/src/com/android/launcher3/testing/TestLogging.java
index 3db2ddf..70691f8 100644
--- a/src/com/android/launcher3/testing/TestLogging.java
+++ b/src/com/android/launcher3/testing/TestLogging.java
@@ -70,15 +70,12 @@
public static void recordMotionEvent(String sequence, String message, MotionEvent event) {
final int action = event.getAction();
if (Utilities.isRunningInTestHarness() && action != MotionEvent.ACTION_MOVE) {
- // "Expecting" in TAPL ACTION_DOWN, UP and CANCEL events was thought to be producing
- // considerable noise in tests due to failed checks for expected events. So we are not
- // sending them to TAPL.
+ // "Expecting" in TAPL motion events was thought to be producing considerable noise in
+ // tests due to failed checks for expected events. So we are not sending them to TAPL.
// Other events, such as EVENT_PILFER_POINTERS produce less noise and are thought to
// be more useful.
- final boolean reportToTapl = action != MotionEvent.ACTION_DOWN
- && action != MotionEvent.ACTION_UP
- && action != MotionEvent.ACTION_CANCEL;
- recordEventSlow(sequence, message + ": " + event, reportToTapl);
+ // That's why we pass false as the value for the 'reportToTapl' parameter.
+ recordEventSlow(sequence, message + ": " + event, false);
registerEventNotFromTest(event);
}
}
diff --git a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
index 6a972eb..dc4621e 100644
--- a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
+++ b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
@@ -582,7 +582,8 @@
? splitInfo.dividerHeightPercent
: splitInfo.dividerWidthPercent;
- float scale = (float) outRect.height() / dp.availableHeightPx;
+ int taskbarHeight = dp.isTransientTaskbar ? 0 : dp.taskbarHeight;
+ float scale = (float) outRect.height() / (dp.availableHeightPx - taskbarHeight);
float topTaskHeight = dp.availableHeightPx * topLeftTaskPercent;
float scaledTopTaskHeight = topTaskHeight * scale;
float dividerHeight = dp.availableHeightPx * dividerBarPercent;
@@ -639,7 +640,8 @@
// Reset unused translations
primarySnapshot.setTranslationY(0);
} else {
- float scale = (float) totalThumbnailHeight / dp.availableHeightPx;
+ int taskbarHeight = dp.isTransientTaskbar ? 0 : dp.taskbarHeight;
+ float scale = (float) totalThumbnailHeight / (dp.availableHeightPx - taskbarHeight);
float topTaskHeight = dp.availableHeightPx * taskPercent;
float finalDividerHeight = Math.round(totalThumbnailHeight * dividerScale);
float scaledTopTaskHeight = topTaskHeight * scale;
diff --git a/src/com/android/launcher3/util/MultiTranslateDelegate.java b/src/com/android/launcher3/util/MultiTranslateDelegate.java
index 1cb7a45..0e32ba7 100644
--- a/src/com/android/launcher3/util/MultiTranslateDelegate.java
+++ b/src/com/android/launcher3/util/MultiTranslateDelegate.java
@@ -40,6 +40,9 @@
// Specific for widgets
public static final int INDEX_WIDGET_CENTERING = 3;
+ // Specific for hotseat items when adjusting for bubbles
+ public static final int INDEX_BUBBLE_ADJUSTMENT_ANIM = 3;
+
public static final int COUNT = 5;
private final MultiPropertyFactory<View> mTranslationX;
diff --git a/src/com/android/launcher3/views/ActivityContext.java b/src/com/android/launcher3/views/ActivityContext.java
index 84ea871..7b82195 100644
--- a/src/com/android/launcher3/views/ActivityContext.java
+++ b/src/com/android/launcher3/views/ActivityContext.java
@@ -442,6 +442,16 @@
return CellPosMapper.DEFAULT;
}
+ /** Whether bubbles are enabled. */
+ default boolean isBubbleBarEnabled() {
+ return false;
+ }
+
+ /** Whether the bubble bar has bubbles. */
+ default boolean hasBubbles() {
+ return false;
+ }
+
/**
* Returns the ActivityContext associated with the given Context, or throws an exception if
* the Context is not associated with any ActivityContext.
diff --git a/src/com/android/launcher3/views/ArrowTipView.java b/src/com/android/launcher3/views/ArrowTipView.java
index b44dbeb..2f0da03 100644
--- a/src/com/android/launcher3/views/ArrowTipView.java
+++ b/src/com/android/launcher3/views/ArrowTipView.java
@@ -155,7 +155,7 @@
setOrientation(LinearLayout.VERTICAL);
mArrowView = findViewById(R.id.arrow);
- updateArrowTipInView();
+ updateArrowTipInView(mIsPointingUp);
setAlpha(0);
// Create default open animator.
@@ -364,17 +364,18 @@
// Adjust the tooltip vertically.
@Px int viewHeight = getHeight();
+ boolean isPointingUp = mIsPointingUp;
if (mIsPointingUp
? (yCoordUpPointingTip + viewHeight > parentViewHeight)
: (yCoordDownPointingTip - viewHeight < 0)) {
// Flip the view if it exceeds the vertical bounds of screen.
- mIsPointingUp = !mIsPointingUp;
- updateArrowTipInView();
+ isPointingUp = !mIsPointingUp;
}
+ updateArrowTipInView(isPointingUp);
// Place the tooltip such that its top is at yCoordUpPointingTip if arrow is displayed
// pointing upwards, otherwise place it such that its bottom is at
// yCoordDownPointingTip.
- setY(mIsPointingUp ? yCoordUpPointingTip : yCoordDownPointingTip - viewHeight);
+ setY(isPointingUp ? yCoordUpPointingTip : yCoordDownPointingTip - viewHeight);
// Adjust the arrow's relative position on tooltip to make sure the actual position of
// arrow's pointed tip is always at arrowXCoord.
@@ -391,10 +392,10 @@
return this;
}
- private void updateArrowTipInView() {
+ private void updateArrowTipInView(boolean isPointingUp) {
ViewGroup.LayoutParams arrowLp = mArrowView.getLayoutParams();
ShapeDrawable arrowDrawable = new ShapeDrawable(TriangleShape.create(
- arrowLp.width, arrowLp.height, mIsPointingUp));
+ arrowLp.width, arrowLp.height, isPointingUp));
Paint arrowPaint = arrowDrawable.getPaint();
@Px int arrowTipRadius = getContext().getResources()
.getDimensionPixelSize(R.dimen.arrow_toast_corner_radius);
@@ -403,7 +404,7 @@
mArrowView.setBackground(arrowDrawable);
// Add negative margin so that the rounded corners on base of arrow are not visible.
removeView(mArrowView);
- if (mIsPointingUp) {
+ if (isPointingUp) {
addView(mArrowView, 0);
((ViewGroup.MarginLayoutParams) arrowLp).setMargins(0, 0, 0, -1 * arrowTipRadius);
} else {
diff --git a/src/com/android/launcher3/views/FloatingIconView.java b/src/com/android/launcher3/views/FloatingIconView.java
index 41b98c7..32c70a3 100644
--- a/src/com/android/launcher3/views/FloatingIconView.java
+++ b/src/com/android/launcher3/views/FloatingIconView.java
@@ -18,7 +18,6 @@
import static android.view.Gravity.LEFT;
import static com.android.app.animation.Interpolators.LINEAR;
-import static com.android.launcher3.Utilities.getBadge;
import static com.android.launcher3.Utilities.getFullDrawable;
import static com.android.launcher3.Utilities.mapToRange;
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
@@ -36,6 +35,7 @@
import android.os.CancellationSignal;
import android.util.AttributeSet;
import android.util.Log;
+import android.util.Pair;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
@@ -288,28 +288,20 @@
} else {
int width = (int) pos.width();
int height = (int) pos.height();
- Object[] tmpObjArray = new Object[1];
- boolean[] outIsIconThemed = new boolean[1];
+ Pair<AdaptiveIconDrawable, Drawable> fullIcon = null;
if (supportsAdaptiveIcons) {
- boolean shouldThemeIcon = btvIcon instanceof FastBitmapDrawable
- && ((FastBitmapDrawable) btvIcon).isThemed();
- drawable = getFullDrawable(
- l, info, width, height, shouldThemeIcon, tmpObjArray, outIsIconThemed);
- if (drawable instanceof AdaptiveIconDrawable) {
- badge = getBadge(l, info, tmpObjArray[0], outIsIconThemed[0]);
- } else {
- // The drawable we get back is not an adaptive icon, so we need to use the
- // BubbleTextView icon that is already legacy treated.
- drawable = btvIcon;
- }
+ boolean shouldThemeIcon = (btvIcon instanceof FastBitmapDrawable fbd)
+ && fbd.isCreatedForTheme();
+ fullIcon = getFullDrawable(l, info, width, height, shouldThemeIcon);
+ } else if (!(originalView instanceof BubbleTextView)) {
+ fullIcon = getFullDrawable(l, info, width, height, true /* shouldThemeIcon */);
+ }
+
+ if (fullIcon != null) {
+ drawable = fullIcon.first;
+ badge = fullIcon.second;
} else {
- if (originalView instanceof BubbleTextView) {
- // Similar to DragView, we simply use the BubbleTextView icon here.
- drawable = btvIcon;
- } else {
- drawable = getFullDrawable(l, info, width, height, true /* shouldThemeIcon */,
- tmpObjArray, outIsIconThemed);
- }
+ drawable = btvIcon;
}
}
diff --git a/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java
index 76a044d..f64fd05 100644
--- a/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java
+++ b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java
@@ -23,9 +23,11 @@
import android.graphics.Rect;
import android.os.Build;
import android.os.Handler;
+import android.os.Parcelable;
import android.os.SystemClock;
import android.os.Trace;
import android.util.Log;
+import android.util.SparseArray;
import android.util.SparseBooleanArray;
import android.util.SparseIntArray;
import android.view.MotionEvent;
@@ -498,4 +500,13 @@
*/
void notifyBoundChangeOnPreLayout(View v, int left, int top, int right, int bottom);
}
+
+ @Override
+ protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) {
+ try {
+ super.dispatchRestoreInstanceState(container);
+ } catch (Exception e) {
+ Log.i(TAG, "Exception: " + e);
+ }
+ }
}
diff --git a/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfo.java b/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfo.java
index 10aef9a..ef51d15 100644
--- a/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfo.java
+++ b/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfo.java
@@ -67,7 +67,7 @@
*/
public int maxSpanY;
- private boolean mIsMinSizeFulfilled;
+ protected boolean mIsMinSizeFulfilled;
public static LauncherAppWidgetProviderInfo fromProviderInfo(Context context,
AppWidgetProviderInfo info) {
diff --git a/src/com/android/launcher3/widget/WidgetManagerHelper.java b/src/com/android/launcher3/widget/WidgetManagerHelper.java
index 737cdbd..0860e72 100644
--- a/src/com/android/launcher3/widget/WidgetManagerHelper.java
+++ b/src/com/android/launcher3/widget/WidgetManagerHelper.java
@@ -57,10 +57,15 @@
/**
* @see AppWidgetManager#getAppWidgetInfo(int)
*/
- public LauncherAppWidgetProviderInfo getLauncherAppWidgetInfo(int appWidgetId) {
- if (appWidgetId <= LauncherAppWidgetInfo.CUSTOM_WIDGET_ID) {
- return CustomWidgetManager.INSTANCE.get(mContext).getWidgetProvider(appWidgetId);
+ public LauncherAppWidgetProviderInfo getLauncherAppWidgetInfo(
+ int appWidgetId, ComponentName componentName) {
+
+ // For custom widgets.
+ if (appWidgetId <= LauncherAppWidgetInfo.CUSTOM_WIDGET_ID && !CustomWidgetManager
+ .INSTANCE.get(mContext).getWidgetIdForCustomProvider(componentName).equals("")) {
+ return CustomWidgetManager.INSTANCE.get(mContext).getWidgetProvider(componentName);
}
+
AppWidgetProviderInfo info = mAppWidgetManager.getAppWidgetInfo(appWidgetId);
return info == null ? null : LauncherAppWidgetProviderInfo.fromProviderInfo(mContext, info);
}
diff --git a/src/com/android/launcher3/widget/custom/CustomAppWidgetProviderInfo.java b/src/com/android/launcher3/widget/custom/CustomAppWidgetProviderInfo.java
index 8b3bbce..44571a6 100644
--- a/src/com/android/launcher3/widget/custom/CustomAppWidgetProviderInfo.java
+++ b/src/com/android/launcher3/widget/custom/CustomAppWidgetProviderInfo.java
@@ -33,14 +33,15 @@
public class CustomAppWidgetProviderInfo extends LauncherAppWidgetProviderInfo
implements Parcelable {
- public final int providerId;
+ public final String providerId;
- protected CustomAppWidgetProviderInfo(Parcel parcel, boolean readSelf, int providerId) {
+ protected CustomAppWidgetProviderInfo(Parcel parcel, boolean readSelf, String providerId) {
super(parcel);
if (readSelf) {
- this.providerId = parcel.readInt();
+ this.providerId = parcel.readString();
- provider = new ComponentName(parcel.readString(), CLS_CUSTOM_WIDGET_PREFIX + providerId);
+ provider = new ComponentName(parcel.readString(),
+ CLS_CUSTOM_WIDGET_PREFIX + parcel.readString());
label = parcel.readString();
initialLayout = parcel.readInt();
@@ -58,7 +59,10 @@
}
@Override
- public void initSpans(Context context, InvariantDeviceProfile idp) { }
+ public void initSpans(Context context, InvariantDeviceProfile idp) {
+ mIsMinSizeFulfilled = Math.min(spanX, minSpanX) <= idp.numColumns
+ && Math.min(spanY, minSpanY) <= idp.numRows;
+ }
@Override
public String getLabel(PackageManager packageManager) {
@@ -73,8 +77,9 @@
@Override
public void writeToParcel(Parcel out, int flags) {
super.writeToParcel(out, flags);
- out.writeInt(providerId);
+ out.writeString(providerId);
out.writeString(provider.getPackageName());
+ out.writeString(provider.getClassName());
out.writeString(label);
out.writeInt(initialLayout);
@@ -93,7 +98,7 @@
@Override
public CustomAppWidgetProviderInfo createFromParcel(Parcel parcel) {
- return new CustomAppWidgetProviderInfo(parcel, true, 0);
+ return new CustomAppWidgetProviderInfo(parcel, true, "");
}
@Override
diff --git a/src/com/android/launcher3/widget/custom/CustomWidgetManager.java b/src/com/android/launcher3/widget/custom/CustomWidgetManager.java
index 2e2a968..7cf0221 100644
--- a/src/com/android/launcher3/widget/custom/CustomWidgetManager.java
+++ b/src/com/android/launcher3/widget/custom/CustomWidgetManager.java
@@ -16,7 +16,8 @@
package com.android.launcher3.widget.custom;
-import static com.android.launcher3.widget.LauncherAppWidgetProviderInfo.CLS_CUSTOM_WIDGET_PREFIX;
+import static com.android.launcher3.config.FeatureFlags.SMARTSPACE_AS_A_WIDGET;
+import static com.android.launcher3.model.data.LauncherAppWidgetInfo.CUSTOM_WIDGET_ID;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProviderInfo;
@@ -24,12 +25,12 @@
import android.content.Context;
import android.os.Parcel;
import android.os.Process;
-import android.util.SparseArray;
+import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import com.android.launcher3.model.data.LauncherAppWidgetInfo;
+import com.android.launcher3.R;
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.launcher3.util.PackageUserKey;
@@ -39,8 +40,11 @@
import com.android.systemui.plugins.CustomWidgetPlugin;
import com.android.systemui.plugins.PluginListener;
+import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.function.Consumer;
import java.util.stream.Stream;
@@ -52,24 +56,37 @@
public static final MainThreadInitializedObject<CustomWidgetManager> INSTANCE =
new MainThreadInitializedObject<>(CustomWidgetManager::new);
+ private static final String TAG = "CustomWidgetManager";
private final Context mContext;
- /**
- * auto provider Id is an ever-increasing number that serves as the providerId whenever a new
- * custom widget has been connected.
- */
- private int mAutoProviderId = 0;
- private final SparseArray<CustomWidgetPlugin> mPlugins;
+ private final HashMap<String, CustomWidgetPlugin> mPlugins;
private final List<CustomAppWidgetProviderInfo> mCustomWidgets;
- private final SparseArray<ComponentName> mWidgetsIdMap;
+ private final HashMap<ComponentName, String> mWidgetsIdMap;
private Consumer<PackageUserKey> mWidgetRefreshCallback;
private CustomWidgetManager(Context context) {
mContext = context;
- mPlugins = new SparseArray<>();
+ mPlugins = new HashMap<>();
mCustomWidgets = new ArrayList<>();
- mWidgetsIdMap = new SparseArray<>();
+ mWidgetsIdMap = new HashMap<>();
PluginManagerWrapper.INSTANCE.get(context)
.addPluginListener(this, CustomWidgetPlugin.class, true);
+
+ if (SMARTSPACE_AS_A_WIDGET.get()) {
+ for (String s: context.getResources()
+ .getStringArray(R.array.custom_widget_providers)) {
+ try {
+ Class<?> cls = Class.forName(s);
+ CustomWidgetPlugin plugin = (CustomWidgetPlugin)
+ cls.getDeclaredConstructor(Context.class).newInstance(context);
+ mPlugins.put(plugin.getId(), plugin);
+ onPluginConnected(mPlugins.get(plugin.getId()), context);
+ } catch (ClassNotFoundException | InstantiationException | IllegalAccessException
+ | ClassCastException | NoSuchMethodException
+ | InvocationTargetException e) {
+ Log.e(TAG, "Exception found when trying to add custom widgets: " + e);
+ }
+ }
+ }
}
@Override
@@ -79,28 +96,41 @@
@Override
public void onPluginConnected(CustomWidgetPlugin plugin, Context context) {
- mPlugins.put(mAutoProviderId, plugin);
List<AppWidgetProviderInfo> providers = AppWidgetManager.getInstance(context)
.getInstalledProvidersForProfile(Process.myUserHandle());
if (providers.isEmpty()) return;
Parcel parcel = Parcel.obtain();
providers.get(0).writeToParcel(parcel, 0);
parcel.setDataPosition(0);
- CustomAppWidgetProviderInfo info = newInfo(mAutoProviderId, plugin, parcel, context);
+ CustomAppWidgetProviderInfo info = newInfo(plugin.getId(), plugin, parcel, context);
parcel.recycle();
mCustomWidgets.add(info);
- mWidgetsIdMap.put(mAutoProviderId, info.provider);
- mWidgetRefreshCallback.accept(null);
- mAutoProviderId++;
+ mWidgetsIdMap.put(info.provider, plugin.getId());
}
@Override
public void onPluginDisconnected(CustomWidgetPlugin plugin) {
- int providerId = findProviderId(plugin);
- if (providerId == -1) return;
- mPlugins.remove(providerId);
- mCustomWidgets.remove(getWidgetProvider(providerId));
- mWidgetsIdMap.remove(providerId);
+ String providerId = plugin.getId();
+ if (mPlugins.containsKey(providerId)) {
+ mPlugins.remove(providerId);
+ }
+
+ ComponentName cn = null;
+ for (Map.Entry entry: mWidgetsIdMap.entrySet()) {
+ if (entry.getValue().equals(providerId)) {
+ cn = (ComponentName) entry.getKey();
+ }
+ }
+
+ if (cn != null) {
+ mWidgetsIdMap.remove(cn);
+ for (int i = 0; i < mCustomWidgets.size(); i++) {
+ if (mCustomWidgets.get(i).getComponent().equals(cn)) {
+ mCustomWidgets.remove(i);
+ return;
+ }
+ }
+ }
}
/**
@@ -131,12 +161,11 @@
/**
* Returns the widget id for a specific provider.
*/
- public int getWidgetIdForCustomProvider(@NonNull ComponentName provider) {
- int index = mWidgetsIdMap.indexOfValue(provider);
- if (index >= 0) {
- return LauncherAppWidgetInfo.CUSTOM_WIDGET_ID - mWidgetsIdMap.keyAt(index);
+ public String getWidgetIdForCustomProvider(@NonNull ComponentName provider) {
+ if (mWidgetsIdMap.containsKey(provider)) {
+ return mWidgetsIdMap.get(provider);
} else {
- return AppWidgetManager.INVALID_APPWIDGET_ID;
+ return "";
}
}
@@ -144,38 +173,26 @@
* Returns the widget provider in respect to given widget id.
*/
@Nullable
- public LauncherAppWidgetProviderInfo getWidgetProvider(int widgetId) {
- ComponentName cn = mWidgetsIdMap.get(LauncherAppWidgetInfo.CUSTOM_WIDGET_ID - widgetId);
+ public LauncherAppWidgetProviderInfo getWidgetProvider(ComponentName componentName) {
for (LauncherAppWidgetProviderInfo info : mCustomWidgets) {
- if (info.provider.equals(cn)) return info;
+ if (info.provider.equals(componentName)) return info;
}
return null;
}
- private static CustomAppWidgetProviderInfo newInfo(int providerId, CustomWidgetPlugin plugin,
+ private static CustomAppWidgetProviderInfo newInfo(String providerId, CustomWidgetPlugin plugin,
Parcel parcel, Context context) {
CustomAppWidgetProviderInfo info = new CustomAppWidgetProviderInfo(
parcel, false, providerId);
- info.provider = new ComponentName(
- context.getPackageName(), CLS_CUSTOM_WIDGET_PREFIX + providerId);
-
- info.label = plugin.getLabel();
- info.resizeMode = plugin.getResizeMode();
-
- info.spanX = plugin.getSpanX();
- info.spanY = plugin.getSpanY();
- info.minSpanX = plugin.getMinSpanX();
- info.minSpanY = plugin.getMinSpanY();
+ plugin.updateWidgetInfo(info, context);
return info;
}
- private int findProviderId(CustomWidgetPlugin plugin) {
- for (int i = 0; i < mPlugins.size(); i++) {
- int providerId = mPlugins.keyAt(i);
- if (mPlugins.get(providerId) == plugin) {
- return providerId;
- }
- }
- return -1;
+ /**
+ * Returns an id to set as the appWidgetId for a custom widget.
+ */
+ public int allocateCustomAppWidgetId(ComponentName componentName) {
+ return CUSTOM_WIDGET_ID - mCustomWidgets.indexOf(getWidgetProvider(componentName));
}
+
}
diff --git a/src_plugins/com/android/systemui/plugins/CustomWidgetPlugin.java b/src_plugins/com/android/systemui/plugins/CustomWidgetPlugin.java
index 56ebcc5..af4f22c 100644
--- a/src_plugins/com/android/systemui/plugins/CustomWidgetPlugin.java
+++ b/src_plugins/com/android/systemui/plugins/CustomWidgetPlugin.java
@@ -17,6 +17,8 @@
package com.android.systemui.plugins;
import android.appwidget.AppWidgetHostView;
+import android.appwidget.AppWidgetProviderInfo;
+import android.content.Context;
import com.android.systemui.plugins.annotations.ProvidesInterface;
@@ -30,42 +32,20 @@
int VERSION = 1;
/**
- * The label to display to the user in the AppWidget picker.
- */
- String getLabel();
-
- /**
- * The default width of the widget when added to a host, in dp. The widget will get
- * at least this width, and will often be given more, depending on the host.
- */
- int getSpanX();
-
- /**
- * The default height of the widget when added to a host, in dp. The widget will get
- * at least this height, and will often be given more, depending on the host.
- */
- int getSpanY();
-
- /**
- * Minimum width (in dp) which the widget can be resized to. This field has no effect if it
- * is greater than minWidth or if horizontal resizing isn't enabled.
- */
- int getMinSpanX();
-
- /**
- * Minimum height (in dp) which the widget can be resized to. This field has no effect if it
- * is greater than minHeight or if vertical resizing isn't enabled.
- */
- int getMinSpanY();
-
- /**
- * The rules by which a widget can be resized.
- */
- int getResizeMode();
-
- /**
* Notify the plugin that container of the widget has been rendered, where the custom widget
* can be attached to.
*/
void onViewCreated(AppWidgetHostView parent);
+
+ /**
+ * Get the UUID for the custom widget.
+ */
+ String getId();
+
+ /**
+ * Used to modify a widgets' info.
+ */
+ default void updateWidgetInfo(AppWidgetProviderInfo info, Context context) {
+
+ }
}
diff --git a/tests/Android.bp b/tests/Android.bp
index d40efce..9bb8787 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -42,6 +42,7 @@
filegroup {
name: "launcher-oop-tests-src",
srcs: [
+ "src/com/android/launcher3/allapps/OopTaplOpenCloseAllApps.java",
"src/com/android/launcher3/ui/AbstractLauncherUiTest.java",
"src/com/android/launcher3/ui/PortraitLandscapeRunner.java",
"src/com/android/launcher3/ui/TaplTestsLauncher3.java",
@@ -54,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/assets/dumpTests/DeviceProfileDumpTest/phonePortrait.txt b/tests/assets/dumpTests/DeviceProfileDumpTest/phonePortrait.txt
new file mode 100644
index 0000000..b8f4c0b
--- /dev/null
+++ b/tests/assets/dumpTests/DeviceProfileDumpTest/phonePortrait.txt
@@ -0,0 +1,127 @@
+DeviceProfile:
+ 1 dp = 2.625 px
+ isTablet:false
+ isPhone:true
+ transposeLayoutWithOrientation:true
+ isGestureMode:true
+ isLandscape:false
+ isMultiWindowMode:false
+ isTwoPanels:false
+ windowX: 0.0px (0.0dp)
+ windowY: 0.0px (0.0dp)
+ widthPx: 1080.0px (411.42856dp)
+ heightPx: 2400.0px (914.2857dp)
+ availableWidthPx: 1080.0px (411.42856dp)
+ availableHeightPx: 2219.0px (845.3333dp)
+ mInsets.left: 0.0px (0.0dp)
+ mInsets.top: 118.0px (44.95238dp)
+ mInsets.right: 0.0px (0.0dp)
+ mInsets.bottom: 63.0px (24.0dp)
+ aspectRatio:2.2222223
+ isResponsiveGrid:false
+ isScalableGrid:false
+ inv.numRows: 5
+ inv.numColumns: 5
+ inv.numSearchContainerColumns: 5
+ minCellSize: PointF(0.0, 0.0)dp
+ cellWidthPx: 159.0px (60.57143dp)
+ cellHeightPx: 229.0px (87.2381dp)
+ getCellSize().x: 207.0px (78.85714dp)
+ getCellSize().y: 383.0px (145.90475dp)
+ cellLayoutBorderSpacePx Horizontal: 0.0px (0.0dp)
+ cellLayoutBorderSpacePx Vertical: 0.0px (0.0dp)
+ cellLayoutPaddingPx.left: 21.0px (8.0dp)
+ cellLayoutPaddingPx.top: 28.0px (10.666667dp)
+ cellLayoutPaddingPx.right: 21.0px (8.0dp)
+ cellLayoutPaddingPx.bottom: 28.0px (10.666667dp)
+ iconSizePx: 147.0px (56.0dp)
+ iconTextSizePx: 38.0px (14.476191dp)
+ iconDrawablePaddingPx: 12.0px (4.571429dp)
+ inv.numFolderRows: 4
+ inv.numFolderColumns: 4
+ folderCellWidthPx: 195.0px (74.28571dp)
+ folderCellHeightPx: 230.0px (87.61905dp)
+ folderChildIconSizePx: 147.0px (56.0dp)
+ folderChildTextSizePx: 38.0px (14.476191dp)
+ folderChildDrawablePaddingPx: 4.0px (1.5238096dp)
+ folderCellLayoutBorderSpacePx.x: 0.0px (0.0dp)
+ folderCellLayoutBorderSpacePx.y: 0.0px (0.0dp)
+ folderContentPaddingLeftRight: 21.0px (8.0dp)
+ folderTopPadding: 63.0px (24.0dp)
+ folderFooterHeight: 147.0px (56.0dp)
+ bottomSheetTopPadding: 146.0px (55.61905dp)
+ bottomSheetOpenDuration: 267
+ bottomSheetCloseDuration: 267
+ bottomSheetWorkspaceScale: 1.0
+ bottomSheetDepth: 0.0
+ allAppsShiftRange: 788.0px (300.1905dp)
+ allAppsTopPadding: 0.0px (0.0dp)
+ allAppsOpenDuration: 600
+ allAppsCloseDuration: 300
+ allAppsIconSizePx: 147.0px (56.0dp)
+ allAppsIconTextSizePx: 38.0px (14.476191dp)
+ allAppsIconDrawablePaddingPx: 21.0px (8.0dp)
+ allAppsCellHeightPx: 315.0px (120.0dp)
+ allAppsCellWidthPx: 189.0px (72.0dp)
+ allAppsBorderSpacePxX: 42.0px (16.0dp)
+ allAppsBorderSpacePxY: 42.0px (16.0dp)
+ numShownAllAppsColumns: 5
+ allAppsLeftRightPadding: 0.0px (0.0dp)
+ allAppsLeftRightMargin: 0.0px (0.0dp)
+ hotseatBarSizePx: 273.0px (104.0dp)
+ inv.hotseatColumnSpan: 5
+ hotseatCellHeightPx: 166.0px (63.238094dp)
+ hotseatBarBottomSpacePx: 126.0px (48.0dp)
+ mHotseatBarEdgePaddingPx: 0.0px (0.0dp)
+ mHotseatBarWorkspaceSpacePx: 0.0px (0.0dp)
+ hotseatBarEndOffset: 0.0px (0.0dp)
+ hotseatQsbSpace: 0.0px (0.0dp)
+ hotseatQsbHeight: 0.0px (0.0dp)
+ springLoadedHotseatBarTopMarginPx: 200.0px (76.190475dp)
+ getHotseatLayoutPadding(context).top: 0.0px (0.0dp)
+ getHotseatLayoutPadding(context).bottom: 107.0px (40.761906dp)
+ getHotseatLayoutPadding(context).left: 21.0px (8.0dp)
+ getHotseatLayoutPadding(context).right: 21.0px (8.0dp)
+ numShownHotseatIcons: 5
+ hotseatBorderSpace: 0.0px (0.0dp)
+ isQsbInline: false
+ hotseatQsbWidth: 0.0px (0.0dp)
+ isTaskbarPresent:false
+ isTaskbarPresentInApps:false
+ taskbarHeight: 0.0px (0.0dp)
+ stashedTaskbarHeight: 0.0px (0.0dp)
+ taskbarBottomMargin: 0.0px (0.0dp)
+ taskbarIconSize: 0.0px (0.0dp)
+ desiredWorkspaceHorizontalMarginPx: 21.0px (8.0dp)
+ workspacePadding.left: 0.0px (0.0dp)
+ workspacePadding.top: 0.0px (0.0dp)
+ workspacePadding.right: 0.0px (0.0dp)
+ workspacePadding.bottom: 245.0px (93.333336dp)
+ iconScale: 1.0px (0.3809524dp)
+ cellScaleToFit : 1.0px (0.3809524dp)
+ extraSpace: 773.0px (294.4762dp)
+ unscaled extraSpace: 773.0px (294.4762dp)
+ maxEmptySpace: 0.0px (0.0dp)
+ workspaceTopPadding: 0.0px (0.0dp)
+ workspaceBottomPadding: 0.0px (0.0dp)
+ overviewTaskMarginPx: 0.0px (0.0dp)
+ overviewTaskIconSizePx: 0.0px (0.0dp)
+ overviewTaskIconDrawableSizePx: 0.0px (0.0dp)
+ overviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)
+ overviewTaskThumbnailTopMarginPx: 0.0px (0.0dp)
+ overviewActionsTopMarginPx: 0.0px (0.0dp)
+ overviewActionsHeight: 0.0px (0.0dp)
+ overviewActionsClaimedSpaceBelow: 63.0px (24.0dp)
+ overviewActionsButtonSpacing: 0.0px (0.0dp)
+ overviewPageSpacing: 0.0px (0.0dp)
+ overviewRowSpacing: 0.0px (0.0dp)
+ overviewGridSideMargin: 0.0px (0.0dp)
+ dropTargetBarTopMarginPx: 84.0px (32.0dp)
+ dropTargetBarSizePx: 147.0px (56.0dp)
+ dropTargetBarBottomMarginPx: 42.0px (16.0dp)
+ getCellLayoutSpringLoadShrunkTop(): 391.0px (148.95238dp)
+ getCellLayoutSpringLoadShrunkBottom(): 1927.0px (734.0952dp)
+ workspaceSpringLoadedMinNextPageVisiblePx: 63.0px (24.0dp)
+ getWorkspaceSpringLoadScale(): 0.7781155px (0.29642496dp)
+ getCellLayoutHeight(): 1974.0px (752.0dp)
+ getCellLayoutWidth(): 1080.0px (411.42856dp)
diff --git a/tests/assets/dumpTests/DeviceProfileDumpTest/phonePortrait3Button.txt b/tests/assets/dumpTests/DeviceProfileDumpTest/phonePortrait3Button.txt
new file mode 100644
index 0000000..a512277
--- /dev/null
+++ b/tests/assets/dumpTests/DeviceProfileDumpTest/phonePortrait3Button.txt
@@ -0,0 +1,127 @@
+DeviceProfile:
+ 1 dp = 2.625 px
+ isTablet:false
+ isPhone:true
+ transposeLayoutWithOrientation:true
+ isGestureMode:false
+ isLandscape:false
+ isMultiWindowMode:false
+ isTwoPanels:false
+ windowX: 0.0px (0.0dp)
+ windowY: 0.0px (0.0dp)
+ widthPx: 1080.0px (411.42856dp)
+ heightPx: 2400.0px (914.2857dp)
+ availableWidthPx: 1080.0px (411.42856dp)
+ availableHeightPx: 2156.0px (821.3333dp)
+ mInsets.left: 0.0px (0.0dp)
+ mInsets.top: 118.0px (44.95238dp)
+ mInsets.right: 0.0px (0.0dp)
+ mInsets.bottom: 126.0px (48.0dp)
+ aspectRatio:2.2222223
+ isResponsiveGrid:false
+ isScalableGrid:false
+ inv.numRows: 5
+ inv.numColumns: 5
+ inv.numSearchContainerColumns: 5
+ minCellSize: PointF(0.0, 0.0)dp
+ cellWidthPx: 159.0px (60.57143dp)
+ cellHeightPx: 229.0px (87.2381dp)
+ getCellSize().x: 207.0px (78.85714dp)
+ getCellSize().y: 379.0px (144.38095dp)
+ cellLayoutBorderSpacePx Horizontal: 0.0px (0.0dp)
+ cellLayoutBorderSpacePx Vertical: 0.0px (0.0dp)
+ cellLayoutPaddingPx.left: 21.0px (8.0dp)
+ cellLayoutPaddingPx.top: 28.0px (10.666667dp)
+ cellLayoutPaddingPx.right: 21.0px (8.0dp)
+ cellLayoutPaddingPx.bottom: 28.0px (10.666667dp)
+ iconSizePx: 147.0px (56.0dp)
+ iconTextSizePx: 38.0px (14.476191dp)
+ iconDrawablePaddingPx: 12.0px (4.571429dp)
+ inv.numFolderRows: 4
+ inv.numFolderColumns: 4
+ folderCellWidthPx: 195.0px (74.28571dp)
+ folderCellHeightPx: 230.0px (87.61905dp)
+ folderChildIconSizePx: 147.0px (56.0dp)
+ folderChildTextSizePx: 38.0px (14.476191dp)
+ folderChildDrawablePaddingPx: 4.0px (1.5238096dp)
+ folderCellLayoutBorderSpacePx.x: 0.0px (0.0dp)
+ folderCellLayoutBorderSpacePx.y: 0.0px (0.0dp)
+ folderContentPaddingLeftRight: 21.0px (8.0dp)
+ folderTopPadding: 63.0px (24.0dp)
+ folderFooterHeight: 147.0px (56.0dp)
+ bottomSheetTopPadding: 146.0px (55.61905dp)
+ bottomSheetOpenDuration: 267
+ bottomSheetCloseDuration: 267
+ bottomSheetWorkspaceScale: 1.0
+ bottomSheetDepth: 0.0
+ allAppsShiftRange: 788.0px (300.1905dp)
+ allAppsTopPadding: 0.0px (0.0dp)
+ allAppsOpenDuration: 600
+ allAppsCloseDuration: 300
+ allAppsIconSizePx: 147.0px (56.0dp)
+ allAppsIconTextSizePx: 38.0px (14.476191dp)
+ allAppsIconDrawablePaddingPx: 21.0px (8.0dp)
+ allAppsCellHeightPx: 315.0px (120.0dp)
+ allAppsCellWidthPx: 189.0px (72.0dp)
+ allAppsBorderSpacePxX: 42.0px (16.0dp)
+ allAppsBorderSpacePxY: 42.0px (16.0dp)
+ numShownAllAppsColumns: 5
+ allAppsLeftRightPadding: 0.0px (0.0dp)
+ allAppsLeftRightMargin: 0.0px (0.0dp)
+ hotseatBarSizePx: 294.0px (112.0dp)
+ inv.hotseatColumnSpan: 5
+ hotseatCellHeightPx: 166.0px (63.238094dp)
+ hotseatBarBottomSpacePx: 147.0px (56.0dp)
+ mHotseatBarEdgePaddingPx: 0.0px (0.0dp)
+ mHotseatBarWorkspaceSpacePx: 0.0px (0.0dp)
+ hotseatBarEndOffset: 0.0px (0.0dp)
+ hotseatQsbSpace: 0.0px (0.0dp)
+ hotseatQsbHeight: 0.0px (0.0dp)
+ springLoadedHotseatBarTopMarginPx: 200.0px (76.190475dp)
+ getHotseatLayoutPadding(context).top: 0.0px (0.0dp)
+ getHotseatLayoutPadding(context).bottom: 128.0px (48.761906dp)
+ getHotseatLayoutPadding(context).left: 21.0px (8.0dp)
+ getHotseatLayoutPadding(context).right: 21.0px (8.0dp)
+ numShownHotseatIcons: 5
+ hotseatBorderSpace: 0.0px (0.0dp)
+ isQsbInline: false
+ hotseatQsbWidth: 0.0px (0.0dp)
+ isTaskbarPresent:false
+ isTaskbarPresentInApps:false
+ taskbarHeight: 0.0px (0.0dp)
+ stashedTaskbarHeight: 0.0px (0.0dp)
+ taskbarBottomMargin: 0.0px (0.0dp)
+ taskbarIconSize: 0.0px (0.0dp)
+ desiredWorkspaceHorizontalMarginPx: 21.0px (8.0dp)
+ workspacePadding.left: 0.0px (0.0dp)
+ workspacePadding.top: 0.0px (0.0dp)
+ workspacePadding.right: 0.0px (0.0dp)
+ workspacePadding.bottom: 203.0px (77.333336dp)
+ iconScale: 1.0px (0.3809524dp)
+ cellScaleToFit : 1.0px (0.3809524dp)
+ extraSpace: 752.0px (286.4762dp)
+ unscaled extraSpace: 752.0px (286.4762dp)
+ maxEmptySpace: 0.0px (0.0dp)
+ workspaceTopPadding: 0.0px (0.0dp)
+ workspaceBottomPadding: 0.0px (0.0dp)
+ overviewTaskMarginPx: 0.0px (0.0dp)
+ overviewTaskIconSizePx: 0.0px (0.0dp)
+ overviewTaskIconDrawableSizePx: 0.0px (0.0dp)
+ overviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)
+ overviewTaskThumbnailTopMarginPx: 0.0px (0.0dp)
+ overviewActionsTopMarginPx: 0.0px (0.0dp)
+ overviewActionsHeight: 0.0px (0.0dp)
+ overviewActionsClaimedSpaceBelow: 126.0px (48.0dp)
+ overviewActionsButtonSpacing: 0.0px (0.0dp)
+ overviewPageSpacing: 0.0px (0.0dp)
+ overviewRowSpacing: 0.0px (0.0dp)
+ overviewGridSideMargin: 0.0px (0.0dp)
+ dropTargetBarTopMarginPx: 84.0px (32.0dp)
+ dropTargetBarSizePx: 147.0px (56.0dp)
+ dropTargetBarBottomMarginPx: 42.0px (16.0dp)
+ getCellLayoutSpringLoadShrunkTop(): 391.0px (148.95238dp)
+ getCellLayoutSpringLoadShrunkBottom(): 1906.0px (726.0952dp)
+ workspaceSpringLoadedMinNextPageVisiblePx: 63.0px (24.0dp)
+ getWorkspaceSpringLoadScale(): 0.77572966px (0.29551607dp)
+ getCellLayoutHeight(): 1953.0px (744.0dp)
+ getCellLayoutWidth(): 1080.0px (411.42856dp)
diff --git a/tests/assets/dumpTests/DeviceProfileDumpTest/phoneVerticalBar.txt b/tests/assets/dumpTests/DeviceProfileDumpTest/phoneVerticalBar.txt
new file mode 100644
index 0000000..a3a8dc5
--- /dev/null
+++ b/tests/assets/dumpTests/DeviceProfileDumpTest/phoneVerticalBar.txt
@@ -0,0 +1,127 @@
+DeviceProfile:
+ 1 dp = 2.625 px
+ isTablet:false
+ isPhone:true
+ transposeLayoutWithOrientation:true
+ isGestureMode:true
+ isLandscape:true
+ isMultiWindowMode:false
+ isTwoPanels:false
+ windowX: 0.0px (0.0dp)
+ windowY: 0.0px (0.0dp)
+ widthPx: 2400.0px (914.2857dp)
+ heightPx: 1080.0px (411.42856dp)
+ availableWidthPx: 2282.0px (869.3333dp)
+ availableHeightPx: 943.0px (359.2381dp)
+ mInsets.left: 118.0px (44.95238dp)
+ mInsets.top: 74.0px (28.190475dp)
+ mInsets.right: 0.0px (0.0dp)
+ mInsets.bottom: 63.0px (24.0dp)
+ aspectRatio:2.2222223
+ isResponsiveGrid:false
+ isScalableGrid:false
+ inv.numRows: 5
+ inv.numColumns: 5
+ inv.numSearchContainerColumns: 5
+ minCellSize: PointF(0.0, 0.0)dp
+ cellWidthPx: 152.0px (57.904762dp)
+ cellHeightPx: 166.0px (63.238094dp)
+ getCellSize().x: 393.0px (149.71428dp)
+ getCellSize().y: 180.0px (68.57143dp)
+ cellLayoutBorderSpacePx Horizontal: 0.0px (0.0dp)
+ cellLayoutBorderSpacePx Vertical: 0.0px (0.0dp)
+ cellLayoutPaddingPx.left: 53.0px (20.190475dp)
+ cellLayoutPaddingPx.top: 0.0px (0.0dp)
+ cellLayoutPaddingPx.right: 53.0px (20.190475dp)
+ cellLayoutPaddingPx.bottom: 40.0px (15.238095dp)
+ iconSizePx: 147.0px (56.0dp)
+ iconTextSizePx: 0.0px (0.0dp)
+ iconDrawablePaddingPx: 0.0px (0.0dp)
+ inv.numFolderRows: 4
+ inv.numFolderColumns: 4
+ folderCellWidthPx: 163.0px (62.095238dp)
+ folderCellHeightPx: 192.0px (73.14286dp)
+ folderChildIconSizePx: 123.0px (46.857143dp)
+ folderChildTextSizePx: 32.0px (12.190476dp)
+ folderChildDrawablePaddingPx: 3.0px (1.1428572dp)
+ folderCellLayoutBorderSpacePx.x: 0.0px (0.0dp)
+ folderCellLayoutBorderSpacePx.y: 0.0px (0.0dp)
+ folderContentPaddingLeftRight: 21.0px (8.0dp)
+ folderTopPadding: 53.0px (20.190475dp)
+ folderFooterHeight: 123.0px (46.857143dp)
+ bottomSheetTopPadding: 114.0px (43.42857dp)
+ bottomSheetOpenDuration: 267
+ bottomSheetCloseDuration: 267
+ bottomSheetWorkspaceScale: 1.0
+ bottomSheetDepth: 0.0
+ allAppsShiftRange: 788.0px (300.1905dp)
+ allAppsTopPadding: 0.0px (0.0dp)
+ allAppsOpenDuration: 600
+ allAppsCloseDuration: 300
+ allAppsIconSizePx: 147.0px (56.0dp)
+ allAppsIconTextSizePx: 38.0px (14.476191dp)
+ allAppsIconDrawablePaddingPx: 21.0px (8.0dp)
+ allAppsCellHeightPx: 321.0px (122.28571dp)
+ allAppsCellWidthPx: 189.0px (72.0dp)
+ allAppsBorderSpacePxX: 42.0px (16.0dp)
+ allAppsBorderSpacePxY: 42.0px (16.0dp)
+ numShownAllAppsColumns: 5
+ allAppsLeftRightPadding: 0.0px (0.0dp)
+ allAppsLeftRightMargin: 0.0px (0.0dp)
+ hotseatBarSizePx: 252.0px (96.0dp)
+ inv.hotseatColumnSpan: 5
+ hotseatCellHeightPx: 166.0px (63.238094dp)
+ hotseatBarBottomSpacePx: 0.0px (0.0dp)
+ mHotseatBarEdgePaddingPx: 63.0px (24.0dp)
+ mHotseatBarWorkspaceSpacePx: 42.0px (16.0dp)
+ hotseatBarEndOffset: 0.0px (0.0dp)
+ hotseatQsbSpace: 0.0px (0.0dp)
+ hotseatQsbHeight: 0.0px (0.0dp)
+ springLoadedHotseatBarTopMarginPx: 118.0px (44.95238dp)
+ getHotseatLayoutPadding(context).top: 64.0px (24.380953dp)
+ getHotseatLayoutPadding(context).bottom: 112.0px (42.666668dp)
+ getHotseatLayoutPadding(context).left: 42.0px (16.0dp)
+ getHotseatLayoutPadding(context).right: 63.0px (24.0dp)
+ numShownHotseatIcons: 5
+ hotseatBorderSpace: 0.0px (0.0dp)
+ isQsbInline: false
+ hotseatQsbWidth: 0.0px (0.0dp)
+ isTaskbarPresent:false
+ isTaskbarPresentInApps:false
+ taskbarHeight: 0.0px (0.0dp)
+ stashedTaskbarHeight: 0.0px (0.0dp)
+ taskbarBottomMargin: 0.0px (0.0dp)
+ taskbarIconSize: 0.0px (0.0dp)
+ desiredWorkspaceHorizontalMarginPx: 0.0px (0.0dp)
+ workspacePadding.left: 10.0px (3.8095238dp)
+ workspacePadding.top: 0.0px (0.0dp)
+ workspacePadding.right: 199.0px (75.809525dp)
+ workspacePadding.bottom: 0.0px (0.0dp)
+ iconScale: 1.0px (0.3809524dp)
+ cellScaleToFit : 1.0px (0.3809524dp)
+ extraSpace: 73.0px (27.809525dp)
+ unscaled extraSpace: 73.0px (27.809525dp)
+ maxEmptySpace: 0.0px (0.0dp)
+ workspaceTopPadding: 0.0px (0.0dp)
+ workspaceBottomPadding: 0.0px (0.0dp)
+ overviewTaskMarginPx: 0.0px (0.0dp)
+ overviewTaskIconSizePx: 0.0px (0.0dp)
+ overviewTaskIconDrawableSizePx: 0.0px (0.0dp)
+ overviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)
+ overviewTaskThumbnailTopMarginPx: 0.0px (0.0dp)
+ overviewActionsTopMarginPx: 0.0px (0.0dp)
+ overviewActionsHeight: 0.0px (0.0dp)
+ overviewActionsClaimedSpaceBelow: 63.0px (24.0dp)
+ overviewActionsButtonSpacing: 0.0px (0.0dp)
+ overviewPageSpacing: 0.0px (0.0dp)
+ overviewRowSpacing: 0.0px (0.0dp)
+ overviewGridSideMargin: 0.0px (0.0dp)
+ dropTargetBarTopMarginPx: 16.0px (6.095238dp)
+ dropTargetBarSizePx: 95.0px (36.190475dp)
+ dropTargetBarBottomMarginPx: 16.0px (6.095238dp)
+ getCellLayoutSpringLoadShrunkTop(): 201.0px (76.57143dp)
+ getCellLayoutSpringLoadShrunkBottom(): 952.0px (362.66666dp)
+ workspaceSpringLoadedMinNextPageVisiblePx: 63.0px (24.0dp)
+ getWorkspaceSpringLoadScale(): 0.79639447px (0.30338836dp)
+ getCellLayoutHeight(): 943.0px (359.2381dp)
+ getCellLayoutWidth(): 2073.0px (789.7143dp)
diff --git a/tests/assets/dumpTests/DeviceProfileDumpTest/phoneVerticalBar3Button.txt b/tests/assets/dumpTests/DeviceProfileDumpTest/phoneVerticalBar3Button.txt
new file mode 100644
index 0000000..55066cb
--- /dev/null
+++ b/tests/assets/dumpTests/DeviceProfileDumpTest/phoneVerticalBar3Button.txt
@@ -0,0 +1,127 @@
+DeviceProfile:
+ 1 dp = 2.625 px
+ isTablet:false
+ isPhone:true
+ transposeLayoutWithOrientation:true
+ isGestureMode:false
+ isLandscape:true
+ isMultiWindowMode:false
+ isTwoPanels:false
+ windowX: 0.0px (0.0dp)
+ windowY: 0.0px (0.0dp)
+ widthPx: 2400.0px (914.2857dp)
+ heightPx: 1080.0px (411.42856dp)
+ availableWidthPx: 2156.0px (821.3333dp)
+ availableHeightPx: 1006.0px (383.2381dp)
+ mInsets.left: 118.0px (44.95238dp)
+ mInsets.top: 74.0px (28.190475dp)
+ mInsets.right: 126.0px (48.0dp)
+ mInsets.bottom: 0.0px (0.0dp)
+ aspectRatio:2.2222223
+ isResponsiveGrid:false
+ isScalableGrid:false
+ inv.numRows: 5
+ inv.numColumns: 5
+ inv.numSearchContainerColumns: 5
+ minCellSize: PointF(0.0, 0.0)dp
+ cellWidthPx: 152.0px (57.904762dp)
+ cellHeightPx: 166.0px (63.238094dp)
+ getCellSize().x: 368.0px (140.19048dp)
+ getCellSize().y: 193.0px (73.52381dp)
+ cellLayoutBorderSpacePx Horizontal: 0.0px (0.0dp)
+ cellLayoutBorderSpacePx Vertical: 0.0px (0.0dp)
+ cellLayoutPaddingPx.left: 53.0px (20.190475dp)
+ cellLayoutPaddingPx.top: 0.0px (0.0dp)
+ cellLayoutPaddingPx.right: 53.0px (20.190475dp)
+ cellLayoutPaddingPx.bottom: 40.0px (15.238095dp)
+ iconSizePx: 147.0px (56.0dp)
+ iconTextSizePx: 0.0px (0.0dp)
+ iconDrawablePaddingPx: 0.0px (0.0dp)
+ inv.numFolderRows: 4
+ inv.numFolderColumns: 4
+ folderCellWidthPx: 173.0px (65.90476dp)
+ folderCellHeightPx: 205.0px (78.09524dp)
+ folderChildIconSizePx: 131.0px (49.904762dp)
+ folderChildTextSizePx: 34.0px (12.952381dp)
+ folderChildDrawablePaddingPx: 4.0px (1.5238096dp)
+ folderCellLayoutBorderSpacePx.x: 0.0px (0.0dp)
+ folderCellLayoutBorderSpacePx.y: 0.0px (0.0dp)
+ folderContentPaddingLeftRight: 21.0px (8.0dp)
+ folderTopPadding: 56.0px (21.333334dp)
+ folderFooterHeight: 131.0px (49.904762dp)
+ bottomSheetTopPadding: 114.0px (43.42857dp)
+ bottomSheetOpenDuration: 267
+ bottomSheetCloseDuration: 267
+ bottomSheetWorkspaceScale: 1.0
+ bottomSheetDepth: 0.0
+ allAppsShiftRange: 788.0px (300.1905dp)
+ allAppsTopPadding: 0.0px (0.0dp)
+ allAppsOpenDuration: 600
+ allAppsCloseDuration: 300
+ allAppsIconSizePx: 147.0px (56.0dp)
+ allAppsIconTextSizePx: 38.0px (14.476191dp)
+ allAppsIconDrawablePaddingPx: 21.0px (8.0dp)
+ allAppsCellHeightPx: 321.0px (122.28571dp)
+ allAppsCellWidthPx: 189.0px (72.0dp)
+ allAppsBorderSpacePxX: 42.0px (16.0dp)
+ allAppsBorderSpacePxY: 42.0px (16.0dp)
+ numShownAllAppsColumns: 5
+ allAppsLeftRightPadding: 0.0px (0.0dp)
+ allAppsLeftRightMargin: 0.0px (0.0dp)
+ hotseatBarSizePx: 252.0px (96.0dp)
+ inv.hotseatColumnSpan: 5
+ hotseatCellHeightPx: 166.0px (63.238094dp)
+ hotseatBarBottomSpacePx: 0.0px (0.0dp)
+ mHotseatBarEdgePaddingPx: 63.0px (24.0dp)
+ mHotseatBarWorkspaceSpacePx: 42.0px (16.0dp)
+ hotseatBarEndOffset: 0.0px (0.0dp)
+ hotseatQsbSpace: 0.0px (0.0dp)
+ hotseatQsbHeight: 0.0px (0.0dp)
+ springLoadedHotseatBarTopMarginPx: 118.0px (44.95238dp)
+ getHotseatLayoutPadding(context).top: 64.0px (24.380953dp)
+ getHotseatLayoutPadding(context).bottom: 49.0px (18.666666dp)
+ getHotseatLayoutPadding(context).left: 42.0px (16.0dp)
+ getHotseatLayoutPadding(context).right: 189.0px (72.0dp)
+ numShownHotseatIcons: 5
+ hotseatBorderSpace: 0.0px (0.0dp)
+ isQsbInline: false
+ hotseatQsbWidth: 0.0px (0.0dp)
+ isTaskbarPresent:false
+ isTaskbarPresentInApps:false
+ taskbarHeight: 0.0px (0.0dp)
+ stashedTaskbarHeight: 0.0px (0.0dp)
+ taskbarBottomMargin: 0.0px (0.0dp)
+ taskbarIconSize: 0.0px (0.0dp)
+ desiredWorkspaceHorizontalMarginPx: 0.0px (0.0dp)
+ workspacePadding.left: 10.0px (3.8095238dp)
+ workspacePadding.top: 0.0px (0.0dp)
+ workspacePadding.right: 199.0px (75.809525dp)
+ workspacePadding.bottom: 0.0px (0.0dp)
+ iconScale: 1.0px (0.3809524dp)
+ cellScaleToFit : 1.0px (0.3809524dp)
+ extraSpace: 136.0px (51.809525dp)
+ unscaled extraSpace: 136.0px (51.809525dp)
+ maxEmptySpace: 0.0px (0.0dp)
+ workspaceTopPadding: 0.0px (0.0dp)
+ workspaceBottomPadding: 0.0px (0.0dp)
+ overviewTaskMarginPx: 0.0px (0.0dp)
+ overviewTaskIconSizePx: 0.0px (0.0dp)
+ overviewTaskIconDrawableSizePx: 0.0px (0.0dp)
+ overviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)
+ overviewTaskThumbnailTopMarginPx: 0.0px (0.0dp)
+ overviewActionsTopMarginPx: 0.0px (0.0dp)
+ overviewActionsHeight: 0.0px (0.0dp)
+ overviewActionsClaimedSpaceBelow: 0.0px (0.0dp)
+ overviewActionsButtonSpacing: 0.0px (0.0dp)
+ overviewPageSpacing: 0.0px (0.0dp)
+ overviewRowSpacing: 0.0px (0.0dp)
+ overviewGridSideMargin: 0.0px (0.0dp)
+ dropTargetBarTopMarginPx: 16.0px (6.095238dp)
+ dropTargetBarSizePx: 95.0px (36.190475dp)
+ dropTargetBarBottomMarginPx: 16.0px (6.095238dp)
+ getCellLayoutSpringLoadShrunkTop(): 201.0px (76.57143dp)
+ getCellLayoutSpringLoadShrunkBottom(): 1008.0px (384.0dp)
+ workspaceSpringLoadedMinNextPageVisiblePx: 63.0px (24.0dp)
+ getWorkspaceSpringLoadScale(): 0.8021869px (0.305595dp)
+ getCellLayoutHeight(): 1006.0px (383.2381dp)
+ getCellLayoutWidth(): 1947.0px (741.7143dp)
diff --git a/tests/assets/dumpTests/DeviceProfileDumpTest/tabletLandscape.txt b/tests/assets/dumpTests/DeviceProfileDumpTest/tabletLandscape.txt
new file mode 100644
index 0000000..6e764c2
--- /dev/null
+++ b/tests/assets/dumpTests/DeviceProfileDumpTest/tabletLandscape.txt
@@ -0,0 +1,127 @@
+DeviceProfile:
+ 1 dp = 2.0 px
+ isTablet:true
+ isPhone:false
+ transposeLayoutWithOrientation:false
+ isGestureMode:true
+ isLandscape:true
+ isMultiWindowMode:false
+ isTwoPanels:false
+ windowX: 0.0px (0.0dp)
+ windowY: 0.0px (0.0dp)
+ widthPx: 2560.0px (1280.0dp)
+ heightPx: 1600.0px (800.0dp)
+ availableWidthPx: 2560.0px (1280.0dp)
+ availableHeightPx: 1496.0px (748.0dp)
+ mInsets.left: 0.0px (0.0dp)
+ mInsets.top: 104.0px (52.0dp)
+ mInsets.right: 0.0px (0.0dp)
+ mInsets.bottom: 0.0px (0.0dp)
+ aspectRatio:1.6
+ isResponsiveGrid:false
+ isScalableGrid:true
+ inv.numRows: 5
+ inv.numColumns: 6
+ inv.numSearchContainerColumns: 3
+ minCellSize: PointF(120.0, 104.0)dp
+ cellWidthPx: 240.0px (120.0dp)
+ cellHeightPx: 208.0px (104.0dp)
+ getCellSize().x: 240.0px (120.0dp)
+ getCellSize().y: 208.0px (104.0dp)
+ cellLayoutBorderSpacePx Horizontal: 128.0px (64.0dp)
+ cellLayoutBorderSpacePx Vertical: 32.0px (16.0dp)
+ cellLayoutPaddingPx.left: 59.0px (29.5dp)
+ cellLayoutPaddingPx.top: 25.0px (12.5dp)
+ cellLayoutPaddingPx.right: 59.0px (29.5dp)
+ cellLayoutPaddingPx.bottom: 59.0px (29.5dp)
+ iconSizePx: 120.0px (60.0dp)
+ iconTextSizePx: 28.0px (14.0dp)
+ iconDrawablePaddingPx: 9.0px (4.5dp)
+ inv.numFolderRows: 3
+ inv.numFolderColumns: 3
+ folderCellWidthPx: 240.0px (120.0dp)
+ folderCellHeightPx: 208.0px (104.0dp)
+ folderChildIconSizePx: 120.0px (60.0dp)
+ folderChildTextSizePx: 28.0px (14.0dp)
+ folderChildDrawablePaddingPx: 11.0px (5.5dp)
+ folderCellLayoutBorderSpacePx.x: 0.0px (0.0dp)
+ folderCellLayoutBorderSpacePx.y: 0.0px (0.0dp)
+ folderContentPaddingLeftRight: 0.0px (0.0dp)
+ folderTopPadding: 48.0px (24.0dp)
+ folderFooterHeight: 112.0px (56.0dp)
+ bottomSheetTopPadding: 104.0px (52.0dp)
+ bottomSheetOpenDuration: 500
+ bottomSheetCloseDuration: 500
+ bottomSheetWorkspaceScale: 0.97
+ bottomSheetDepth: 0.0
+ allAppsShiftRange: 1496.0px (748.0dp)
+ allAppsTopPadding: 104.0px (52.0dp)
+ allAppsOpenDuration: 500
+ allAppsCloseDuration: 500
+ allAppsIconSizePx: 120.0px (60.0dp)
+ allAppsIconTextSizePx: 28.0px (14.0dp)
+ allAppsIconDrawablePaddingPx: 9.0px (4.5dp)
+ allAppsCellHeightPx: 284.0px (142.0dp)
+ allAppsCellWidthPx: 252.0px (126.0dp)
+ allAppsBorderSpacePxX: 32.0px (16.0dp)
+ allAppsBorderSpacePxY: 32.0px (16.0dp)
+ numShownAllAppsColumns: 6
+ allAppsLeftRightPadding: 32.0px (16.0dp)
+ allAppsLeftRightMargin: 412.0px (206.0dp)
+ hotseatBarSizePx: 200.0px (100.0dp)
+ inv.hotseatColumnSpan: 4
+ hotseatCellHeightPx: 135.0px (67.5dp)
+ hotseatBarBottomSpacePx: 80.0px (40.0dp)
+ mHotseatBarEdgePaddingPx: 0.0px (0.0dp)
+ mHotseatBarWorkspaceSpacePx: 0.0px (0.0dp)
+ hotseatBarEndOffset: 0.0px (0.0dp)
+ hotseatQsbSpace: 0.0px (0.0dp)
+ hotseatQsbHeight: 0.0px (0.0dp)
+ springLoadedHotseatBarTopMarginPx: 128.0px (64.0dp)
+ getHotseatLayoutPadding(context).top: 0.0px (0.0dp)
+ getHotseatLayoutPadding(context).bottom: 65.0px (32.5dp)
+ getHotseatLayoutPadding(context).left: 668.0px (334.0dp)
+ getHotseatLayoutPadding(context).right: 668.0px (334.0dp)
+ numShownHotseatIcons: 6
+ hotseatBorderSpace: 100.0px (50.0dp)
+ isQsbInline: false
+ hotseatQsbWidth: 1224.0px (612.0dp)
+ isTaskbarPresent:false
+ isTaskbarPresentInApps:true
+ taskbarHeight: 0.0px (0.0dp)
+ stashedTaskbarHeight: 0.0px (0.0dp)
+ taskbarBottomMargin: 0.0px (0.0dp)
+ taskbarIconSize: 0.0px (0.0dp)
+ desiredWorkspaceHorizontalMarginPx: 240.0px (120.0dp)
+ workspacePadding.left: 181.0px (90.5dp)
+ workspacePadding.top: 0.0px (0.0dp)
+ workspacePadding.right: 181.0px (90.5dp)
+ workspacePadding.bottom: 244.0px (122.0dp)
+ iconScale: 1.0px (0.5dp)
+ cellScaleToFit : 1.0px (0.5dp)
+ extraSpace: 80.0px (40.0dp)
+ unscaled extraSpace: 80.0px (40.0dp)
+ maxEmptySpace: 200.0px (100.0dp)
+ workspaceTopPadding: 25.0px (12.5dp)
+ workspaceBottomPadding: 55.0px (27.5dp)
+ overviewTaskMarginPx: 0.0px (0.0dp)
+ overviewTaskIconSizePx: 0.0px (0.0dp)
+ overviewTaskIconDrawableSizePx: 0.0px (0.0dp)
+ overviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)
+ overviewTaskThumbnailTopMarginPx: 0.0px (0.0dp)
+ overviewActionsTopMarginPx: 0.0px (0.0dp)
+ overviewActionsHeight: 0.0px (0.0dp)
+ overviewActionsClaimedSpaceBelow: 0.0px (0.0dp)
+ overviewActionsButtonSpacing: 0.0px (0.0dp)
+ overviewPageSpacing: 0.0px (0.0dp)
+ overviewRowSpacing: 0.0px (0.0dp)
+ overviewGridSideMargin: 0.0px (0.0dp)
+ dropTargetBarTopMarginPx: 0.0px (0.0dp)
+ dropTargetBarSizePx: 144.0px (72.0dp)
+ dropTargetBarBottomMarginPx: 64.0px (32.0dp)
+ getCellLayoutSpringLoadShrunkTop(): 312.0px (156.0dp)
+ getCellLayoutSpringLoadShrunkBottom(): 1272.0px (636.0dp)
+ workspaceSpringLoadedMinNextPageVisiblePx: 48.0px (24.0dp)
+ getWorkspaceSpringLoadScale(): 0.76677316px (0.38338658dp)
+ getCellLayoutHeight(): 1252.0px (626.0dp)
+ getCellLayoutWidth(): 2198.0px (1099.0dp)
diff --git a/tests/assets/dumpTests/DeviceProfileDumpTest/tabletLandscape3Button.txt b/tests/assets/dumpTests/DeviceProfileDumpTest/tabletLandscape3Button.txt
new file mode 100644
index 0000000..7650082
--- /dev/null
+++ b/tests/assets/dumpTests/DeviceProfileDumpTest/tabletLandscape3Button.txt
@@ -0,0 +1,127 @@
+DeviceProfile:
+ 1 dp = 2.0 px
+ isTablet:true
+ isPhone:false
+ transposeLayoutWithOrientation:false
+ isGestureMode:false
+ isLandscape:true
+ isMultiWindowMode:false
+ isTwoPanels:false
+ windowX: 0.0px (0.0dp)
+ windowY: 0.0px (0.0dp)
+ widthPx: 2560.0px (1280.0dp)
+ heightPx: 1600.0px (800.0dp)
+ availableWidthPx: 2560.0px (1280.0dp)
+ availableHeightPx: 1496.0px (748.0dp)
+ mInsets.left: 0.0px (0.0dp)
+ mInsets.top: 104.0px (52.0dp)
+ mInsets.right: 0.0px (0.0dp)
+ mInsets.bottom: 0.0px (0.0dp)
+ aspectRatio:1.6
+ isResponsiveGrid:false
+ isScalableGrid:true
+ inv.numRows: 5
+ inv.numColumns: 6
+ inv.numSearchContainerColumns: 3
+ minCellSize: PointF(120.0, 104.0)dp
+ cellWidthPx: 240.0px (120.0dp)
+ cellHeightPx: 208.0px (104.0dp)
+ getCellSize().x: 240.0px (120.0dp)
+ getCellSize().y: 208.0px (104.0dp)
+ cellLayoutBorderSpacePx Horizontal: 128.0px (64.0dp)
+ cellLayoutBorderSpacePx Vertical: 32.0px (16.0dp)
+ cellLayoutPaddingPx.left: 59.0px (29.5dp)
+ cellLayoutPaddingPx.top: 25.0px (12.5dp)
+ cellLayoutPaddingPx.right: 59.0px (29.5dp)
+ cellLayoutPaddingPx.bottom: 59.0px (29.5dp)
+ iconSizePx: 120.0px (60.0dp)
+ iconTextSizePx: 28.0px (14.0dp)
+ iconDrawablePaddingPx: 9.0px (4.5dp)
+ inv.numFolderRows: 3
+ inv.numFolderColumns: 3
+ folderCellWidthPx: 240.0px (120.0dp)
+ folderCellHeightPx: 208.0px (104.0dp)
+ folderChildIconSizePx: 120.0px (60.0dp)
+ folderChildTextSizePx: 28.0px (14.0dp)
+ folderChildDrawablePaddingPx: 11.0px (5.5dp)
+ folderCellLayoutBorderSpacePx.x: 0.0px (0.0dp)
+ folderCellLayoutBorderSpacePx.y: 0.0px (0.0dp)
+ folderContentPaddingLeftRight: 0.0px (0.0dp)
+ folderTopPadding: 48.0px (24.0dp)
+ folderFooterHeight: 112.0px (56.0dp)
+ bottomSheetTopPadding: 104.0px (52.0dp)
+ bottomSheetOpenDuration: 500
+ bottomSheetCloseDuration: 500
+ bottomSheetWorkspaceScale: 0.97
+ bottomSheetDepth: 0.0
+ allAppsShiftRange: 1496.0px (748.0dp)
+ allAppsTopPadding: 104.0px (52.0dp)
+ allAppsOpenDuration: 500
+ allAppsCloseDuration: 500
+ allAppsIconSizePx: 120.0px (60.0dp)
+ allAppsIconTextSizePx: 28.0px (14.0dp)
+ allAppsIconDrawablePaddingPx: 9.0px (4.5dp)
+ allAppsCellHeightPx: 284.0px (142.0dp)
+ allAppsCellWidthPx: 252.0px (126.0dp)
+ allAppsBorderSpacePxX: 32.0px (16.0dp)
+ allAppsBorderSpacePxY: 32.0px (16.0dp)
+ numShownAllAppsColumns: 6
+ allAppsLeftRightPadding: 32.0px (16.0dp)
+ allAppsLeftRightMargin: 412.0px (206.0dp)
+ hotseatBarSizePx: 200.0px (100.0dp)
+ inv.hotseatColumnSpan: 4
+ hotseatCellHeightPx: 135.0px (67.5dp)
+ hotseatBarBottomSpacePx: 80.0px (40.0dp)
+ mHotseatBarEdgePaddingPx: 0.0px (0.0dp)
+ mHotseatBarWorkspaceSpacePx: 0.0px (0.0dp)
+ hotseatBarEndOffset: 0.0px (0.0dp)
+ hotseatQsbSpace: 0.0px (0.0dp)
+ hotseatQsbHeight: 0.0px (0.0dp)
+ springLoadedHotseatBarTopMarginPx: 128.0px (64.0dp)
+ getHotseatLayoutPadding(context).top: 0.0px (0.0dp)
+ getHotseatLayoutPadding(context).bottom: 65.0px (32.5dp)
+ getHotseatLayoutPadding(context).left: 668.0px (334.0dp)
+ getHotseatLayoutPadding(context).right: 668.0px (334.0dp)
+ numShownHotseatIcons: 6
+ hotseatBorderSpace: 100.0px (50.0dp)
+ isQsbInline: false
+ hotseatQsbWidth: 1224.0px (612.0dp)
+ isTaskbarPresent:false
+ isTaskbarPresentInApps:true
+ taskbarHeight: 0.0px (0.0dp)
+ stashedTaskbarHeight: 0.0px (0.0dp)
+ taskbarBottomMargin: 0.0px (0.0dp)
+ taskbarIconSize: 0.0px (0.0dp)
+ desiredWorkspaceHorizontalMarginPx: 240.0px (120.0dp)
+ workspacePadding.left: 181.0px (90.5dp)
+ workspacePadding.top: 0.0px (0.0dp)
+ workspacePadding.right: 181.0px (90.5dp)
+ workspacePadding.bottom: 244.0px (122.0dp)
+ iconScale: 1.0px (0.5dp)
+ cellScaleToFit : 1.0px (0.5dp)
+ extraSpace: 80.0px (40.0dp)
+ unscaled extraSpace: 80.0px (40.0dp)
+ maxEmptySpace: 200.0px (100.0dp)
+ workspaceTopPadding: 25.0px (12.5dp)
+ workspaceBottomPadding: 55.0px (27.5dp)
+ overviewTaskMarginPx: 0.0px (0.0dp)
+ overviewTaskIconSizePx: 0.0px (0.0dp)
+ overviewTaskIconDrawableSizePx: 0.0px (0.0dp)
+ overviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)
+ overviewTaskThumbnailTopMarginPx: 0.0px (0.0dp)
+ overviewActionsTopMarginPx: 0.0px (0.0dp)
+ overviewActionsHeight: 0.0px (0.0dp)
+ overviewActionsClaimedSpaceBelow: 0.0px (0.0dp)
+ overviewActionsButtonSpacing: 0.0px (0.0dp)
+ overviewPageSpacing: 0.0px (0.0dp)
+ overviewRowSpacing: 0.0px (0.0dp)
+ overviewGridSideMargin: 0.0px (0.0dp)
+ dropTargetBarTopMarginPx: 0.0px (0.0dp)
+ dropTargetBarSizePx: 144.0px (72.0dp)
+ dropTargetBarBottomMarginPx: 64.0px (32.0dp)
+ getCellLayoutSpringLoadShrunkTop(): 312.0px (156.0dp)
+ getCellLayoutSpringLoadShrunkBottom(): 1272.0px (636.0dp)
+ workspaceSpringLoadedMinNextPageVisiblePx: 48.0px (24.0dp)
+ getWorkspaceSpringLoadScale(): 0.76677316px (0.38338658dp)
+ getCellLayoutHeight(): 1252.0px (626.0dp)
+ getCellLayoutWidth(): 2198.0px (1099.0dp)
diff --git a/tests/assets/dumpTests/DeviceProfileDumpTest/tabletPortrait.txt b/tests/assets/dumpTests/DeviceProfileDumpTest/tabletPortrait.txt
new file mode 100644
index 0000000..2b241a1
--- /dev/null
+++ b/tests/assets/dumpTests/DeviceProfileDumpTest/tabletPortrait.txt
@@ -0,0 +1,127 @@
+DeviceProfile:
+ 1 dp = 2.0 px
+ isTablet:true
+ isPhone:false
+ transposeLayoutWithOrientation:false
+ isGestureMode:true
+ isLandscape:false
+ isMultiWindowMode:false
+ isTwoPanels:false
+ windowX: 0.0px (0.0dp)
+ windowY: 0.0px (0.0dp)
+ widthPx: 1600.0px (800.0dp)
+ heightPx: 2560.0px (1280.0dp)
+ availableWidthPx: 1600.0px (800.0dp)
+ availableHeightPx: 2456.0px (1228.0dp)
+ mInsets.left: 0.0px (0.0dp)
+ mInsets.top: 104.0px (52.0dp)
+ mInsets.right: 0.0px (0.0dp)
+ mInsets.bottom: 0.0px (0.0dp)
+ aspectRatio:1.6
+ isResponsiveGrid:false
+ isScalableGrid:true
+ inv.numRows: 5
+ inv.numColumns: 6
+ inv.numSearchContainerColumns: 3
+ minCellSize: PointF(102.0, 120.0)dp
+ cellWidthPx: 204.0px (102.0dp)
+ cellHeightPx: 240.0px (120.0dp)
+ getCellSize().x: 204.0px (102.0dp)
+ getCellSize().y: 240.0px (120.0dp)
+ cellLayoutBorderSpacePx Horizontal: 32.0px (16.0dp)
+ cellLayoutBorderSpacePx Vertical: 128.0px (64.0dp)
+ cellLayoutPaddingPx.left: 72.0px (36.0dp)
+ cellLayoutPaddingPx.top: 72.0px (36.0dp)
+ cellLayoutPaddingPx.right: 72.0px (36.0dp)
+ cellLayoutPaddingPx.bottom: 72.0px (36.0dp)
+ iconSizePx: 120.0px (60.0dp)
+ iconTextSizePx: 28.0px (14.0dp)
+ iconDrawablePaddingPx: 9.0px (4.5dp)
+ inv.numFolderRows: 3
+ inv.numFolderColumns: 3
+ folderCellWidthPx: 204.0px (102.0dp)
+ folderCellHeightPx: 240.0px (120.0dp)
+ folderChildIconSizePx: 120.0px (60.0dp)
+ folderChildTextSizePx: 28.0px (14.0dp)
+ folderChildDrawablePaddingPx: 22.0px (11.0dp)
+ folderCellLayoutBorderSpacePx.x: 0.0px (0.0dp)
+ folderCellLayoutBorderSpacePx.y: 0.0px (0.0dp)
+ folderContentPaddingLeftRight: 0.0px (0.0dp)
+ folderTopPadding: 48.0px (24.0dp)
+ folderFooterHeight: 112.0px (56.0dp)
+ bottomSheetTopPadding: 704.0px (352.0dp)
+ bottomSheetOpenDuration: 500
+ bottomSheetCloseDuration: 500
+ bottomSheetWorkspaceScale: 0.97
+ bottomSheetDepth: 0.0
+ allAppsShiftRange: 1810.0px (905.0dp)
+ allAppsTopPadding: 750.0px (375.0dp)
+ allAppsOpenDuration: 500
+ allAppsCloseDuration: 500
+ allAppsIconSizePx: 120.0px (60.0dp)
+ allAppsIconTextSizePx: 28.0px (14.0dp)
+ allAppsIconDrawablePaddingPx: 9.0px (4.5dp)
+ allAppsCellHeightPx: 316.0px (158.0dp)
+ allAppsCellWidthPx: 192.0px (96.0dp)
+ allAppsBorderSpacePxX: 16.0px (8.0dp)
+ allAppsBorderSpacePxY: 32.0px (16.0dp)
+ numShownAllAppsColumns: 6
+ allAppsLeftRightPadding: 32.0px (16.0dp)
+ allAppsLeftRightMargin: 152.0px (76.0dp)
+ hotseatBarSizePx: 272.0px (136.0dp)
+ inv.hotseatColumnSpan: 6
+ hotseatCellHeightPx: 135.0px (67.5dp)
+ hotseatBarBottomSpacePx: 152.0px (76.0dp)
+ mHotseatBarEdgePaddingPx: 0.0px (0.0dp)
+ mHotseatBarWorkspaceSpacePx: 0.0px (0.0dp)
+ hotseatBarEndOffset: 0.0px (0.0dp)
+ hotseatQsbSpace: 0.0px (0.0dp)
+ hotseatQsbHeight: 0.0px (0.0dp)
+ springLoadedHotseatBarTopMarginPx: 216.0px (108.0dp)
+ getHotseatLayoutPadding(context).top: 0.0px (0.0dp)
+ getHotseatLayoutPadding(context).bottom: 137.0px (68.5dp)
+ getHotseatLayoutPadding(context).left: 150.0px (75.0dp)
+ getHotseatLayoutPadding(context).right: 150.0px (75.0dp)
+ numShownHotseatIcons: 6
+ hotseatBorderSpace: 116.0px (58.0dp)
+ isQsbInline: false
+ hotseatQsbWidth: 1300.0px (650.0dp)
+ isTaskbarPresent:false
+ isTaskbarPresentInApps:true
+ taskbarHeight: 0.0px (0.0dp)
+ stashedTaskbarHeight: 0.0px (0.0dp)
+ taskbarBottomMargin: 0.0px (0.0dp)
+ taskbarIconSize: 0.0px (0.0dp)
+ desiredWorkspaceHorizontalMarginPx: 108.0px (54.0dp)
+ workspacePadding.left: 36.0px (18.0dp)
+ workspacePadding.top: 132.0px (66.0dp)
+ workspacePadding.right: 36.0px (18.0dp)
+ workspacePadding.bottom: 468.0px (234.0dp)
+ iconScale: 1.0px (0.5dp)
+ cellScaleToFit : 1.0px (0.5dp)
+ extraSpace: 424.0px (212.0dp)
+ unscaled extraSpace: 424.0px (212.0dp)
+ maxEmptySpace: 19998.0px (9999.0dp)
+ workspaceTopPadding: 204.0px (102.0dp)
+ workspaceBottomPadding: 220.0px (110.0dp)
+ overviewTaskMarginPx: 0.0px (0.0dp)
+ overviewTaskIconSizePx: 0.0px (0.0dp)
+ overviewTaskIconDrawableSizePx: 0.0px (0.0dp)
+ overviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)
+ overviewTaskThumbnailTopMarginPx: 0.0px (0.0dp)
+ overviewActionsTopMarginPx: 0.0px (0.0dp)
+ overviewActionsHeight: 0.0px (0.0dp)
+ overviewActionsClaimedSpaceBelow: 0.0px (0.0dp)
+ overviewActionsButtonSpacing: 0.0px (0.0dp)
+ overviewPageSpacing: 0.0px (0.0dp)
+ overviewRowSpacing: 0.0px (0.0dp)
+ overviewGridSideMargin: 0.0px (0.0dp)
+ dropTargetBarTopMarginPx: 220.0px (110.0dp)
+ dropTargetBarSizePx: 144.0px (72.0dp)
+ dropTargetBarBottomMarginPx: 96.0px (48.0dp)
+ getCellLayoutSpringLoadShrunkTop(): 564.0px (282.0dp)
+ getCellLayoutSpringLoadShrunkBottom(): 2072.0px (1036.0dp)
+ workspaceSpringLoadedMinNextPageVisiblePx: 48.0px (24.0dp)
+ getWorkspaceSpringLoadScale(): 0.8125px (0.40625dp)
+ getCellLayoutHeight(): 1856.0px (928.0dp)
+ getCellLayoutWidth(): 1528.0px (764.0dp)
diff --git a/tests/assets/dumpTests/DeviceProfileDumpTest/tabletPortrait3Button.txt b/tests/assets/dumpTests/DeviceProfileDumpTest/tabletPortrait3Button.txt
new file mode 100644
index 0000000..6d38d27
--- /dev/null
+++ b/tests/assets/dumpTests/DeviceProfileDumpTest/tabletPortrait3Button.txt
@@ -0,0 +1,127 @@
+DeviceProfile:
+ 1 dp = 2.0 px
+ isTablet:true
+ isPhone:false
+ transposeLayoutWithOrientation:false
+ isGestureMode:false
+ isLandscape:false
+ isMultiWindowMode:false
+ isTwoPanels:false
+ windowX: 0.0px (0.0dp)
+ windowY: 0.0px (0.0dp)
+ widthPx: 1600.0px (800.0dp)
+ heightPx: 2560.0px (1280.0dp)
+ availableWidthPx: 1600.0px (800.0dp)
+ availableHeightPx: 2456.0px (1228.0dp)
+ mInsets.left: 0.0px (0.0dp)
+ mInsets.top: 104.0px (52.0dp)
+ mInsets.right: 0.0px (0.0dp)
+ mInsets.bottom: 0.0px (0.0dp)
+ aspectRatio:1.6
+ isResponsiveGrid:false
+ isScalableGrid:true
+ inv.numRows: 5
+ inv.numColumns: 6
+ inv.numSearchContainerColumns: 3
+ minCellSize: PointF(102.0, 120.0)dp
+ cellWidthPx: 204.0px (102.0dp)
+ cellHeightPx: 240.0px (120.0dp)
+ getCellSize().x: 204.0px (102.0dp)
+ getCellSize().y: 240.0px (120.0dp)
+ cellLayoutBorderSpacePx Horizontal: 32.0px (16.0dp)
+ cellLayoutBorderSpacePx Vertical: 128.0px (64.0dp)
+ cellLayoutPaddingPx.left: 72.0px (36.0dp)
+ cellLayoutPaddingPx.top: 72.0px (36.0dp)
+ cellLayoutPaddingPx.right: 72.0px (36.0dp)
+ cellLayoutPaddingPx.bottom: 72.0px (36.0dp)
+ iconSizePx: 120.0px (60.0dp)
+ iconTextSizePx: 28.0px (14.0dp)
+ iconDrawablePaddingPx: 9.0px (4.5dp)
+ inv.numFolderRows: 3
+ inv.numFolderColumns: 3
+ folderCellWidthPx: 204.0px (102.0dp)
+ folderCellHeightPx: 240.0px (120.0dp)
+ folderChildIconSizePx: 120.0px (60.0dp)
+ folderChildTextSizePx: 28.0px (14.0dp)
+ folderChildDrawablePaddingPx: 22.0px (11.0dp)
+ folderCellLayoutBorderSpacePx.x: 0.0px (0.0dp)
+ folderCellLayoutBorderSpacePx.y: 0.0px (0.0dp)
+ folderContentPaddingLeftRight: 0.0px (0.0dp)
+ folderTopPadding: 48.0px (24.0dp)
+ folderFooterHeight: 112.0px (56.0dp)
+ bottomSheetTopPadding: 704.0px (352.0dp)
+ bottomSheetOpenDuration: 500
+ bottomSheetCloseDuration: 500
+ bottomSheetWorkspaceScale: 0.97
+ bottomSheetDepth: 0.0
+ allAppsShiftRange: 1810.0px (905.0dp)
+ allAppsTopPadding: 750.0px (375.0dp)
+ allAppsOpenDuration: 500
+ allAppsCloseDuration: 500
+ allAppsIconSizePx: 120.0px (60.0dp)
+ allAppsIconTextSizePx: 28.0px (14.0dp)
+ allAppsIconDrawablePaddingPx: 9.0px (4.5dp)
+ allAppsCellHeightPx: 316.0px (158.0dp)
+ allAppsCellWidthPx: 192.0px (96.0dp)
+ allAppsBorderSpacePxX: 16.0px (8.0dp)
+ allAppsBorderSpacePxY: 32.0px (16.0dp)
+ numShownAllAppsColumns: 6
+ allAppsLeftRightPadding: 32.0px (16.0dp)
+ allAppsLeftRightMargin: 152.0px (76.0dp)
+ hotseatBarSizePx: 272.0px (136.0dp)
+ inv.hotseatColumnSpan: 6
+ hotseatCellHeightPx: 135.0px (67.5dp)
+ hotseatBarBottomSpacePx: 152.0px (76.0dp)
+ mHotseatBarEdgePaddingPx: 0.0px (0.0dp)
+ mHotseatBarWorkspaceSpacePx: 0.0px (0.0dp)
+ hotseatBarEndOffset: 0.0px (0.0dp)
+ hotseatQsbSpace: 0.0px (0.0dp)
+ hotseatQsbHeight: 0.0px (0.0dp)
+ springLoadedHotseatBarTopMarginPx: 216.0px (108.0dp)
+ getHotseatLayoutPadding(context).top: 0.0px (0.0dp)
+ getHotseatLayoutPadding(context).bottom: 137.0px (68.5dp)
+ getHotseatLayoutPadding(context).left: 150.0px (75.0dp)
+ getHotseatLayoutPadding(context).right: 150.0px (75.0dp)
+ numShownHotseatIcons: 6
+ hotseatBorderSpace: 116.0px (58.0dp)
+ isQsbInline: false
+ hotseatQsbWidth: 1300.0px (650.0dp)
+ isTaskbarPresent:false
+ isTaskbarPresentInApps:true
+ taskbarHeight: 0.0px (0.0dp)
+ stashedTaskbarHeight: 0.0px (0.0dp)
+ taskbarBottomMargin: 0.0px (0.0dp)
+ taskbarIconSize: 0.0px (0.0dp)
+ desiredWorkspaceHorizontalMarginPx: 108.0px (54.0dp)
+ workspacePadding.left: 36.0px (18.0dp)
+ workspacePadding.top: 132.0px (66.0dp)
+ workspacePadding.right: 36.0px (18.0dp)
+ workspacePadding.bottom: 468.0px (234.0dp)
+ iconScale: 1.0px (0.5dp)
+ cellScaleToFit : 1.0px (0.5dp)
+ extraSpace: 424.0px (212.0dp)
+ unscaled extraSpace: 424.0px (212.0dp)
+ maxEmptySpace: 19998.0px (9999.0dp)
+ workspaceTopPadding: 204.0px (102.0dp)
+ workspaceBottomPadding: 220.0px (110.0dp)
+ overviewTaskMarginPx: 0.0px (0.0dp)
+ overviewTaskIconSizePx: 0.0px (0.0dp)
+ overviewTaskIconDrawableSizePx: 0.0px (0.0dp)
+ overviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)
+ overviewTaskThumbnailTopMarginPx: 0.0px (0.0dp)
+ overviewActionsTopMarginPx: 0.0px (0.0dp)
+ overviewActionsHeight: 0.0px (0.0dp)
+ overviewActionsClaimedSpaceBelow: 0.0px (0.0dp)
+ overviewActionsButtonSpacing: 0.0px (0.0dp)
+ overviewPageSpacing: 0.0px (0.0dp)
+ overviewRowSpacing: 0.0px (0.0dp)
+ overviewGridSideMargin: 0.0px (0.0dp)
+ dropTargetBarTopMarginPx: 220.0px (110.0dp)
+ dropTargetBarSizePx: 144.0px (72.0dp)
+ dropTargetBarBottomMarginPx: 96.0px (48.0dp)
+ getCellLayoutSpringLoadShrunkTop(): 564.0px (282.0dp)
+ getCellLayoutSpringLoadShrunkBottom(): 2072.0px (1036.0dp)
+ workspaceSpringLoadedMinNextPageVisiblePx: 48.0px (24.0dp)
+ getWorkspaceSpringLoadScale(): 0.8125px (0.40625dp)
+ getCellLayoutHeight(): 1856.0px (928.0dp)
+ getCellLayoutWidth(): 1528.0px (764.0dp)
diff --git a/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelLandscape.txt b/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelLandscape.txt
new file mode 100644
index 0000000..5799de7
--- /dev/null
+++ b/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelLandscape.txt
@@ -0,0 +1,127 @@
+DeviceProfile:
+ 1 dp = 2.625 px
+ isTablet:true
+ isPhone:false
+ transposeLayoutWithOrientation:false
+ isGestureMode:true
+ isLandscape:true
+ isMultiWindowMode:false
+ isTwoPanels:true
+ windowX: 0.0px (0.0dp)
+ windowY: 0.0px (0.0dp)
+ widthPx: 2208.0px (841.1429dp)
+ heightPx: 1840.0px (700.9524dp)
+ availableWidthPx: 2208.0px (841.1429dp)
+ availableHeightPx: 1730.0px (659.0476dp)
+ mInsets.left: 0.0px (0.0dp)
+ mInsets.top: 110.0px (41.904762dp)
+ mInsets.right: 0.0px (0.0dp)
+ mInsets.bottom: 0.0px (0.0dp)
+ aspectRatio:1.2
+ isResponsiveGrid:false
+ isScalableGrid:false
+ inv.numRows: 4
+ inv.numColumns: 4
+ inv.numSearchContainerColumns: 4
+ minCellSize: PointF(0.0, 0.0)dp
+ cellWidthPx: 154.0px (58.666668dp)
+ cellHeightPx: 218.0px (83.04762dp)
+ getCellSize().x: 270.0px (102.85714dp)
+ getCellSize().y: 342.0px (130.28572dp)
+ cellLayoutBorderSpacePx Horizontal: 0.0px (0.0dp)
+ cellLayoutBorderSpacePx Vertical: 0.0px (0.0dp)
+ cellLayoutPaddingPx.left: 0.0px (0.0dp)
+ cellLayoutPaddingPx.top: 0.0px (0.0dp)
+ cellLayoutPaddingPx.right: 0.0px (0.0dp)
+ cellLayoutPaddingPx.bottom: 0.0px (0.0dp)
+ iconSizePx: 141.0px (53.714287dp)
+ iconTextSizePx: 34.0px (12.952381dp)
+ iconDrawablePaddingPx: 13.0px (4.952381dp)
+ inv.numFolderRows: 3
+ inv.numFolderColumns: 4
+ folderCellWidthPx: 189.0px (72.0dp)
+ folderCellHeightPx: 219.0px (83.42857dp)
+ folderChildIconSizePx: 141.0px (53.714287dp)
+ folderChildTextSizePx: 34.0px (12.952381dp)
+ folderChildDrawablePaddingPx: 5.0px (1.9047619dp)
+ folderCellLayoutBorderSpacePx.x: 0.0px (0.0dp)
+ folderCellLayoutBorderSpacePx.y: 0.0px (0.0dp)
+ folderContentPaddingLeftRight: 21.0px (8.0dp)
+ folderTopPadding: 63.0px (24.0dp)
+ folderFooterHeight: 147.0px (56.0dp)
+ bottomSheetTopPadding: 110.0px (41.904762dp)
+ bottomSheetOpenDuration: 500
+ bottomSheetCloseDuration: 500
+ bottomSheetWorkspaceScale: 0.97
+ bottomSheetDepth: 1.0
+ allAppsShiftRange: 1730.0px (659.0476dp)
+ allAppsTopPadding: 110.0px (41.904762dp)
+ allAppsOpenDuration: 500
+ allAppsCloseDuration: 500
+ allAppsIconSizePx: 141.0px (53.714287dp)
+ allAppsIconTextSizePx: 34.0px (12.952381dp)
+ allAppsIconDrawablePaddingPx: 21.0px (8.0dp)
+ allAppsCellHeightPx: 315.0px (120.0dp)
+ allAppsCellWidthPx: 183.0px (69.71429dp)
+ allAppsBorderSpacePxX: 42.0px (16.0dp)
+ allAppsBorderSpacePxY: 42.0px (16.0dp)
+ numShownAllAppsColumns: 8
+ allAppsLeftRightPadding: 42.0px (16.0dp)
+ allAppsLeftRightMargin: 183.0px (69.71429dp)
+ hotseatBarSizePx: 267.0px (101.71429dp)
+ inv.hotseatColumnSpan: 4
+ hotseatCellHeightPx: 159.0px (60.57143dp)
+ hotseatBarBottomSpacePx: 126.0px (48.0dp)
+ mHotseatBarEdgePaddingPx: 0.0px (0.0dp)
+ mHotseatBarWorkspaceSpacePx: 0.0px (0.0dp)
+ hotseatBarEndOffset: 0.0px (0.0dp)
+ hotseatQsbSpace: 0.0px (0.0dp)
+ hotseatQsbHeight: 0.0px (0.0dp)
+ springLoadedHotseatBarTopMarginPx: 116.0px (44.190475dp)
+ getHotseatLayoutPadding(context).top: 0.0px (0.0dp)
+ getHotseatLayoutPadding(context).bottom: 108.0px (41.142857dp)
+ getHotseatLayoutPadding(context).left: 113.0px (43.04762dp)
+ getHotseatLayoutPadding(context).right: 113.0px (43.04762dp)
+ numShownHotseatIcons: 6
+ hotseatBorderSpace: 0.0px (0.0dp)
+ isQsbInline: false
+ hotseatQsbWidth: 0.0px (0.0dp)
+ isTaskbarPresent:false
+ isTaskbarPresentInApps:true
+ taskbarHeight: 0.0px (0.0dp)
+ stashedTaskbarHeight: 0.0px (0.0dp)
+ taskbarBottomMargin: 0.0px (0.0dp)
+ taskbarIconSize: 0.0px (0.0dp)
+ desiredWorkspaceHorizontalMarginPx: 21.0px (8.0dp)
+ workspacePadding.left: 21.0px (8.0dp)
+ workspacePadding.top: 30.0px (11.428572dp)
+ workspacePadding.right: 21.0px (8.0dp)
+ workspacePadding.bottom: 330.0px (125.71429dp)
+ iconScale: 1.0px (0.3809524dp)
+ cellScaleToFit : 1.0px (0.3809524dp)
+ extraSpace: 498.0px (189.71428dp)
+ unscaled extraSpace: 498.0px (189.71428dp)
+ maxEmptySpace: 0.0px (0.0dp)
+ workspaceTopPadding: 0.0px (0.0dp)
+ workspaceBottomPadding: 0.0px (0.0dp)
+ overviewTaskMarginPx: 0.0px (0.0dp)
+ overviewTaskIconSizePx: 0.0px (0.0dp)
+ overviewTaskIconDrawableSizePx: 0.0px (0.0dp)
+ overviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)
+ overviewTaskThumbnailTopMarginPx: 0.0px (0.0dp)
+ overviewActionsTopMarginPx: 0.0px (0.0dp)
+ overviewActionsHeight: 0.0px (0.0dp)
+ overviewActionsClaimedSpaceBelow: 0.0px (0.0dp)
+ overviewActionsButtonSpacing: 0.0px (0.0dp)
+ overviewPageSpacing: 0.0px (0.0dp)
+ overviewRowSpacing: 0.0px (0.0dp)
+ overviewGridSideMargin: 0.0px (0.0dp)
+ dropTargetBarTopMarginPx: 0.0px (0.0dp)
+ dropTargetBarSizePx: 147.0px (56.0dp)
+ dropTargetBarBottomMarginPx: 42.0px (16.0dp)
+ getCellLayoutSpringLoadShrunkTop(): 299.0px (113.90476dp)
+ getCellLayoutSpringLoadShrunkBottom(): 1457.0px (555.0476dp)
+ workspaceSpringLoadedMinNextPageVisiblePx: 63.0px (24.0dp)
+ getWorkspaceSpringLoadScale(): 0.8452555px (0.32200208dp)
+ getCellLayoutHeight(): 1370.0px (521.9048dp)
+ getCellLayoutWidth(): 1083.0px (412.57144dp)
diff --git a/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelLandscape3Button.txt b/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelLandscape3Button.txt
new file mode 100644
index 0000000..b4956ff
--- /dev/null
+++ b/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelLandscape3Button.txt
@@ -0,0 +1,127 @@
+DeviceProfile:
+ 1 dp = 2.625 px
+ isTablet:true
+ isPhone:false
+ transposeLayoutWithOrientation:false
+ isGestureMode:false
+ isLandscape:true
+ isMultiWindowMode:false
+ isTwoPanels:true
+ windowX: 0.0px (0.0dp)
+ windowY: 0.0px (0.0dp)
+ widthPx: 2208.0px (841.1429dp)
+ heightPx: 1840.0px (700.9524dp)
+ availableWidthPx: 2208.0px (841.1429dp)
+ availableHeightPx: 1730.0px (659.0476dp)
+ mInsets.left: 0.0px (0.0dp)
+ mInsets.top: 110.0px (41.904762dp)
+ mInsets.right: 0.0px (0.0dp)
+ mInsets.bottom: 0.0px (0.0dp)
+ aspectRatio:1.2
+ isResponsiveGrid:false
+ isScalableGrid:false
+ inv.numRows: 4
+ inv.numColumns: 4
+ inv.numSearchContainerColumns: 4
+ minCellSize: PointF(0.0, 0.0)dp
+ cellWidthPx: 154.0px (58.666668dp)
+ cellHeightPx: 218.0px (83.04762dp)
+ getCellSize().x: 270.0px (102.85714dp)
+ getCellSize().y: 342.0px (130.28572dp)
+ cellLayoutBorderSpacePx Horizontal: 0.0px (0.0dp)
+ cellLayoutBorderSpacePx Vertical: 0.0px (0.0dp)
+ cellLayoutPaddingPx.left: 0.0px (0.0dp)
+ cellLayoutPaddingPx.top: 0.0px (0.0dp)
+ cellLayoutPaddingPx.right: 0.0px (0.0dp)
+ cellLayoutPaddingPx.bottom: 0.0px (0.0dp)
+ iconSizePx: 141.0px (53.714287dp)
+ iconTextSizePx: 34.0px (12.952381dp)
+ iconDrawablePaddingPx: 13.0px (4.952381dp)
+ inv.numFolderRows: 3
+ inv.numFolderColumns: 4
+ folderCellWidthPx: 189.0px (72.0dp)
+ folderCellHeightPx: 219.0px (83.42857dp)
+ folderChildIconSizePx: 141.0px (53.714287dp)
+ folderChildTextSizePx: 34.0px (12.952381dp)
+ folderChildDrawablePaddingPx: 5.0px (1.9047619dp)
+ folderCellLayoutBorderSpacePx.x: 0.0px (0.0dp)
+ folderCellLayoutBorderSpacePx.y: 0.0px (0.0dp)
+ folderContentPaddingLeftRight: 21.0px (8.0dp)
+ folderTopPadding: 63.0px (24.0dp)
+ folderFooterHeight: 147.0px (56.0dp)
+ bottomSheetTopPadding: 110.0px (41.904762dp)
+ bottomSheetOpenDuration: 500
+ bottomSheetCloseDuration: 500
+ bottomSheetWorkspaceScale: 0.97
+ bottomSheetDepth: 1.0
+ allAppsShiftRange: 1730.0px (659.0476dp)
+ allAppsTopPadding: 110.0px (41.904762dp)
+ allAppsOpenDuration: 500
+ allAppsCloseDuration: 500
+ allAppsIconSizePx: 141.0px (53.714287dp)
+ allAppsIconTextSizePx: 34.0px (12.952381dp)
+ allAppsIconDrawablePaddingPx: 21.0px (8.0dp)
+ allAppsCellHeightPx: 315.0px (120.0dp)
+ allAppsCellWidthPx: 183.0px (69.71429dp)
+ allAppsBorderSpacePxX: 42.0px (16.0dp)
+ allAppsBorderSpacePxY: 42.0px (16.0dp)
+ numShownAllAppsColumns: 8
+ allAppsLeftRightPadding: 42.0px (16.0dp)
+ allAppsLeftRightMargin: 183.0px (69.71429dp)
+ hotseatBarSizePx: 267.0px (101.71429dp)
+ inv.hotseatColumnSpan: 4
+ hotseatCellHeightPx: 159.0px (60.57143dp)
+ hotseatBarBottomSpacePx: 126.0px (48.0dp)
+ mHotseatBarEdgePaddingPx: 0.0px (0.0dp)
+ mHotseatBarWorkspaceSpacePx: 0.0px (0.0dp)
+ hotseatBarEndOffset: 0.0px (0.0dp)
+ hotseatQsbSpace: 0.0px (0.0dp)
+ hotseatQsbHeight: 0.0px (0.0dp)
+ springLoadedHotseatBarTopMarginPx: 116.0px (44.190475dp)
+ getHotseatLayoutPadding(context).top: 0.0px (0.0dp)
+ getHotseatLayoutPadding(context).bottom: 108.0px (41.142857dp)
+ getHotseatLayoutPadding(context).left: 113.0px (43.04762dp)
+ getHotseatLayoutPadding(context).right: 113.0px (43.04762dp)
+ numShownHotseatIcons: 6
+ hotseatBorderSpace: 0.0px (0.0dp)
+ isQsbInline: false
+ hotseatQsbWidth: 0.0px (0.0dp)
+ isTaskbarPresent:false
+ isTaskbarPresentInApps:true
+ taskbarHeight: 0.0px (0.0dp)
+ stashedTaskbarHeight: 0.0px (0.0dp)
+ taskbarBottomMargin: 0.0px (0.0dp)
+ taskbarIconSize: 0.0px (0.0dp)
+ desiredWorkspaceHorizontalMarginPx: 21.0px (8.0dp)
+ workspacePadding.left: 21.0px (8.0dp)
+ workspacePadding.top: 30.0px (11.428572dp)
+ workspacePadding.right: 21.0px (8.0dp)
+ workspacePadding.bottom: 330.0px (125.71429dp)
+ iconScale: 1.0px (0.3809524dp)
+ cellScaleToFit : 1.0px (0.3809524dp)
+ extraSpace: 498.0px (189.71428dp)
+ unscaled extraSpace: 498.0px (189.71428dp)
+ maxEmptySpace: 0.0px (0.0dp)
+ workspaceTopPadding: 0.0px (0.0dp)
+ workspaceBottomPadding: 0.0px (0.0dp)
+ overviewTaskMarginPx: 0.0px (0.0dp)
+ overviewTaskIconSizePx: 0.0px (0.0dp)
+ overviewTaskIconDrawableSizePx: 0.0px (0.0dp)
+ overviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)
+ overviewTaskThumbnailTopMarginPx: 0.0px (0.0dp)
+ overviewActionsTopMarginPx: 0.0px (0.0dp)
+ overviewActionsHeight: 0.0px (0.0dp)
+ overviewActionsClaimedSpaceBelow: 0.0px (0.0dp)
+ overviewActionsButtonSpacing: 0.0px (0.0dp)
+ overviewPageSpacing: 0.0px (0.0dp)
+ overviewRowSpacing: 0.0px (0.0dp)
+ overviewGridSideMargin: 0.0px (0.0dp)
+ dropTargetBarTopMarginPx: 0.0px (0.0dp)
+ dropTargetBarSizePx: 147.0px (56.0dp)
+ dropTargetBarBottomMarginPx: 42.0px (16.0dp)
+ getCellLayoutSpringLoadShrunkTop(): 299.0px (113.90476dp)
+ getCellLayoutSpringLoadShrunkBottom(): 1457.0px (555.0476dp)
+ workspaceSpringLoadedMinNextPageVisiblePx: 63.0px (24.0dp)
+ getWorkspaceSpringLoadScale(): 0.8452555px (0.32200208dp)
+ getCellLayoutHeight(): 1370.0px (521.9048dp)
+ getCellLayoutWidth(): 1083.0px (412.57144dp)
diff --git a/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelPortrait.txt b/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelPortrait.txt
new file mode 100644
index 0000000..15afb61
--- /dev/null
+++ b/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelPortrait.txt
@@ -0,0 +1,127 @@
+DeviceProfile:
+ 1 dp = 2.625 px
+ isTablet:true
+ isPhone:false
+ transposeLayoutWithOrientation:false
+ isGestureMode:true
+ isLandscape:false
+ isMultiWindowMode:false
+ isTwoPanels:true
+ windowX: 0.0px (0.0dp)
+ windowY: 0.0px (0.0dp)
+ widthPx: 1840.0px (700.9524dp)
+ heightPx: 2208.0px (841.1429dp)
+ availableWidthPx: 1840.0px (700.9524dp)
+ availableHeightPx: 2075.0px (790.4762dp)
+ mInsets.left: 0.0px (0.0dp)
+ mInsets.top: 133.0px (50.666668dp)
+ mInsets.right: 0.0px (0.0dp)
+ mInsets.bottom: 0.0px (0.0dp)
+ aspectRatio:1.2
+ isResponsiveGrid:false
+ isScalableGrid:false
+ inv.numRows: 4
+ inv.numColumns: 4
+ inv.numSearchContainerColumns: 4
+ minCellSize: PointF(0.0, 0.0)dp
+ cellWidthPx: 154.0px (58.666668dp)
+ cellHeightPx: 218.0px (83.04762dp)
+ getCellSize().x: 224.0px (85.333336dp)
+ getCellSize().y: 430.0px (163.80952dp)
+ cellLayoutBorderSpacePx Horizontal: 0.0px (0.0dp)
+ cellLayoutBorderSpacePx Vertical: 0.0px (0.0dp)
+ cellLayoutPaddingPx.left: 0.0px (0.0dp)
+ cellLayoutPaddingPx.top: 0.0px (0.0dp)
+ cellLayoutPaddingPx.right: 0.0px (0.0dp)
+ cellLayoutPaddingPx.bottom: 0.0px (0.0dp)
+ iconSizePx: 141.0px (53.714287dp)
+ iconTextSizePx: 34.0px (12.952381dp)
+ iconDrawablePaddingPx: 13.0px (4.952381dp)
+ inv.numFolderRows: 3
+ inv.numFolderColumns: 4
+ folderCellWidthPx: 189.0px (72.0dp)
+ folderCellHeightPx: 219.0px (83.42857dp)
+ folderChildIconSizePx: 141.0px (53.714287dp)
+ folderChildTextSizePx: 34.0px (12.952381dp)
+ folderChildDrawablePaddingPx: 5.0px (1.9047619dp)
+ folderCellLayoutBorderSpacePx.x: 0.0px (0.0dp)
+ folderCellLayoutBorderSpacePx.y: 0.0px (0.0dp)
+ folderContentPaddingLeftRight: 21.0px (8.0dp)
+ folderTopPadding: 63.0px (24.0dp)
+ folderFooterHeight: 147.0px (56.0dp)
+ bottomSheetTopPadding: 133.0px (50.666668dp)
+ bottomSheetOpenDuration: 500
+ bottomSheetCloseDuration: 500
+ bottomSheetWorkspaceScale: 0.97
+ bottomSheetDepth: 1.0
+ allAppsShiftRange: 1826.0px (695.619dp)
+ allAppsTopPadding: 382.0px (145.5238dp)
+ allAppsOpenDuration: 500
+ allAppsCloseDuration: 500
+ allAppsIconSizePx: 141.0px (53.714287dp)
+ allAppsIconTextSizePx: 34.0px (12.952381dp)
+ allAppsIconDrawablePaddingPx: 21.0px (8.0dp)
+ allAppsCellHeightPx: 315.0px (120.0dp)
+ allAppsCellWidthPx: 183.0px (69.71429dp)
+ allAppsBorderSpacePxX: 42.0px (16.0dp)
+ allAppsBorderSpacePxY: 42.0px (16.0dp)
+ numShownAllAppsColumns: 8
+ allAppsLeftRightPadding: 42.0px (16.0dp)
+ allAppsLeftRightMargin: 1.0px (0.3809524dp)
+ hotseatBarSizePx: 267.0px (101.71429dp)
+ inv.hotseatColumnSpan: 4
+ hotseatCellHeightPx: 159.0px (60.57143dp)
+ hotseatBarBottomSpacePx: 126.0px (48.0dp)
+ mHotseatBarEdgePaddingPx: 0.0px (0.0dp)
+ mHotseatBarWorkspaceSpacePx: 0.0px (0.0dp)
+ hotseatBarEndOffset: 0.0px (0.0dp)
+ hotseatQsbSpace: 0.0px (0.0dp)
+ hotseatQsbHeight: 0.0px (0.0dp)
+ springLoadedHotseatBarTopMarginPx: 171.0px (65.14286dp)
+ getHotseatLayoutPadding(context).top: 0.0px (0.0dp)
+ getHotseatLayoutPadding(context).bottom: 108.0px (41.142857dp)
+ getHotseatLayoutPadding(context).left: 98.0px (37.333332dp)
+ getHotseatLayoutPadding(context).right: 98.0px (37.333332dp)
+ numShownHotseatIcons: 6
+ hotseatBorderSpace: 0.0px (0.0dp)
+ isQsbInline: false
+ hotseatQsbWidth: 0.0px (0.0dp)
+ isTaskbarPresent:false
+ isTaskbarPresentInApps:true
+ taskbarHeight: 0.0px (0.0dp)
+ stashedTaskbarHeight: 0.0px (0.0dp)
+ taskbarBottomMargin: 0.0px (0.0dp)
+ taskbarIconSize: 0.0px (0.0dp)
+ desiredWorkspaceHorizontalMarginPx: 21.0px (8.0dp)
+ workspacePadding.left: 21.0px (8.0dp)
+ workspacePadding.top: 24.0px (9.142858dp)
+ workspacePadding.right: 21.0px (8.0dp)
+ workspacePadding.bottom: 330.0px (125.71429dp)
+ iconScale: 1.0px (0.3809524dp)
+ cellScaleToFit : 1.0px (0.3809524dp)
+ extraSpace: 849.0px (323.42856dp)
+ unscaled extraSpace: 849.0px (323.42856dp)
+ maxEmptySpace: 0.0px (0.0dp)
+ workspaceTopPadding: 0.0px (0.0dp)
+ workspaceBottomPadding: 0.0px (0.0dp)
+ overviewTaskMarginPx: 0.0px (0.0dp)
+ overviewTaskIconSizePx: 0.0px (0.0dp)
+ overviewTaskIconDrawableSizePx: 0.0px (0.0dp)
+ overviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)
+ overviewTaskThumbnailTopMarginPx: 0.0px (0.0dp)
+ overviewActionsTopMarginPx: 0.0px (0.0dp)
+ overviewActionsHeight: 0.0px (0.0dp)
+ overviewActionsClaimedSpaceBelow: 0.0px (0.0dp)
+ overviewActionsButtonSpacing: 0.0px (0.0dp)
+ overviewPageSpacing: 0.0px (0.0dp)
+ overviewRowSpacing: 0.0px (0.0dp)
+ overviewGridSideMargin: 0.0px (0.0dp)
+ dropTargetBarTopMarginPx: 168.0px (64.0dp)
+ dropTargetBarSizePx: 147.0px (56.0dp)
+ dropTargetBarBottomMarginPx: 42.0px (16.0dp)
+ getCellLayoutSpringLoadShrunkTop(): 490.0px (186.66667dp)
+ getCellLayoutSpringLoadShrunkBottom(): 1770.0px (674.2857dp)
+ workspaceSpringLoadedMinNextPageVisiblePx: 63.0px (24.0dp)
+ getWorkspaceSpringLoadScale(): 0.7437536px (0.2833347dp)
+ getCellLayoutHeight(): 1721.0px (655.619dp)
+ getCellLayoutWidth(): 899.0px (342.4762dp)
diff --git a/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelPortrait3Button.txt b/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelPortrait3Button.txt
new file mode 100644
index 0000000..6cbed1f
--- /dev/null
+++ b/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelPortrait3Button.txt
@@ -0,0 +1,127 @@
+DeviceProfile:
+ 1 dp = 2.625 px
+ isTablet:true
+ isPhone:false
+ transposeLayoutWithOrientation:false
+ isGestureMode:false
+ isLandscape:false
+ isMultiWindowMode:false
+ isTwoPanels:true
+ windowX: 0.0px (0.0dp)
+ windowY: 0.0px (0.0dp)
+ widthPx: 1840.0px (700.9524dp)
+ heightPx: 2208.0px (841.1429dp)
+ availableWidthPx: 1840.0px (700.9524dp)
+ availableHeightPx: 2075.0px (790.4762dp)
+ mInsets.left: 0.0px (0.0dp)
+ mInsets.top: 133.0px (50.666668dp)
+ mInsets.right: 0.0px (0.0dp)
+ mInsets.bottom: 0.0px (0.0dp)
+ aspectRatio:1.2
+ isResponsiveGrid:false
+ isScalableGrid:false
+ inv.numRows: 4
+ inv.numColumns: 4
+ inv.numSearchContainerColumns: 4
+ minCellSize: PointF(0.0, 0.0)dp
+ cellWidthPx: 154.0px (58.666668dp)
+ cellHeightPx: 218.0px (83.04762dp)
+ getCellSize().x: 224.0px (85.333336dp)
+ getCellSize().y: 430.0px (163.80952dp)
+ cellLayoutBorderSpacePx Horizontal: 0.0px (0.0dp)
+ cellLayoutBorderSpacePx Vertical: 0.0px (0.0dp)
+ cellLayoutPaddingPx.left: 0.0px (0.0dp)
+ cellLayoutPaddingPx.top: 0.0px (0.0dp)
+ cellLayoutPaddingPx.right: 0.0px (0.0dp)
+ cellLayoutPaddingPx.bottom: 0.0px (0.0dp)
+ iconSizePx: 141.0px (53.714287dp)
+ iconTextSizePx: 34.0px (12.952381dp)
+ iconDrawablePaddingPx: 13.0px (4.952381dp)
+ inv.numFolderRows: 3
+ inv.numFolderColumns: 4
+ folderCellWidthPx: 189.0px (72.0dp)
+ folderCellHeightPx: 219.0px (83.42857dp)
+ folderChildIconSizePx: 141.0px (53.714287dp)
+ folderChildTextSizePx: 34.0px (12.952381dp)
+ folderChildDrawablePaddingPx: 5.0px (1.9047619dp)
+ folderCellLayoutBorderSpacePx.x: 0.0px (0.0dp)
+ folderCellLayoutBorderSpacePx.y: 0.0px (0.0dp)
+ folderContentPaddingLeftRight: 21.0px (8.0dp)
+ folderTopPadding: 63.0px (24.0dp)
+ folderFooterHeight: 147.0px (56.0dp)
+ bottomSheetTopPadding: 133.0px (50.666668dp)
+ bottomSheetOpenDuration: 500
+ bottomSheetCloseDuration: 500
+ bottomSheetWorkspaceScale: 0.97
+ bottomSheetDepth: 1.0
+ allAppsShiftRange: 1826.0px (695.619dp)
+ allAppsTopPadding: 382.0px (145.5238dp)
+ allAppsOpenDuration: 500
+ allAppsCloseDuration: 500
+ allAppsIconSizePx: 141.0px (53.714287dp)
+ allAppsIconTextSizePx: 34.0px (12.952381dp)
+ allAppsIconDrawablePaddingPx: 21.0px (8.0dp)
+ allAppsCellHeightPx: 315.0px (120.0dp)
+ allAppsCellWidthPx: 183.0px (69.71429dp)
+ allAppsBorderSpacePxX: 42.0px (16.0dp)
+ allAppsBorderSpacePxY: 42.0px (16.0dp)
+ numShownAllAppsColumns: 8
+ allAppsLeftRightPadding: 42.0px (16.0dp)
+ allAppsLeftRightMargin: 1.0px (0.3809524dp)
+ hotseatBarSizePx: 267.0px (101.71429dp)
+ inv.hotseatColumnSpan: 4
+ hotseatCellHeightPx: 159.0px (60.57143dp)
+ hotseatBarBottomSpacePx: 126.0px (48.0dp)
+ mHotseatBarEdgePaddingPx: 0.0px (0.0dp)
+ mHotseatBarWorkspaceSpacePx: 0.0px (0.0dp)
+ hotseatBarEndOffset: 0.0px (0.0dp)
+ hotseatQsbSpace: 0.0px (0.0dp)
+ hotseatQsbHeight: 0.0px (0.0dp)
+ springLoadedHotseatBarTopMarginPx: 171.0px (65.14286dp)
+ getHotseatLayoutPadding(context).top: 0.0px (0.0dp)
+ getHotseatLayoutPadding(context).bottom: 108.0px (41.142857dp)
+ getHotseatLayoutPadding(context).left: 98.0px (37.333332dp)
+ getHotseatLayoutPadding(context).right: 98.0px (37.333332dp)
+ numShownHotseatIcons: 6
+ hotseatBorderSpace: 0.0px (0.0dp)
+ isQsbInline: false
+ hotseatQsbWidth: 0.0px (0.0dp)
+ isTaskbarPresent:false
+ isTaskbarPresentInApps:true
+ taskbarHeight: 0.0px (0.0dp)
+ stashedTaskbarHeight: 0.0px (0.0dp)
+ taskbarBottomMargin: 0.0px (0.0dp)
+ taskbarIconSize: 0.0px (0.0dp)
+ desiredWorkspaceHorizontalMarginPx: 21.0px (8.0dp)
+ workspacePadding.left: 21.0px (8.0dp)
+ workspacePadding.top: 24.0px (9.142858dp)
+ workspacePadding.right: 21.0px (8.0dp)
+ workspacePadding.bottom: 330.0px (125.71429dp)
+ iconScale: 1.0px (0.3809524dp)
+ cellScaleToFit : 1.0px (0.3809524dp)
+ extraSpace: 849.0px (323.42856dp)
+ unscaled extraSpace: 849.0px (323.42856dp)
+ maxEmptySpace: 0.0px (0.0dp)
+ workspaceTopPadding: 0.0px (0.0dp)
+ workspaceBottomPadding: 0.0px (0.0dp)
+ overviewTaskMarginPx: 0.0px (0.0dp)
+ overviewTaskIconSizePx: 0.0px (0.0dp)
+ overviewTaskIconDrawableSizePx: 0.0px (0.0dp)
+ overviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)
+ overviewTaskThumbnailTopMarginPx: 0.0px (0.0dp)
+ overviewActionsTopMarginPx: 0.0px (0.0dp)
+ overviewActionsHeight: 0.0px (0.0dp)
+ overviewActionsClaimedSpaceBelow: 0.0px (0.0dp)
+ overviewActionsButtonSpacing: 0.0px (0.0dp)
+ overviewPageSpacing: 0.0px (0.0dp)
+ overviewRowSpacing: 0.0px (0.0dp)
+ overviewGridSideMargin: 0.0px (0.0dp)
+ dropTargetBarTopMarginPx: 168.0px (64.0dp)
+ dropTargetBarSizePx: 147.0px (56.0dp)
+ dropTargetBarBottomMarginPx: 42.0px (16.0dp)
+ getCellLayoutSpringLoadShrunkTop(): 490.0px (186.66667dp)
+ getCellLayoutSpringLoadShrunkBottom(): 1770.0px (674.2857dp)
+ workspaceSpringLoadedMinNextPageVisiblePx: 63.0px (24.0dp)
+ getWorkspaceSpringLoadScale(): 0.7437536px (0.2833347dp)
+ getCellLayoutHeight(): 1721.0px (655.619dp)
+ getCellLayoutWidth(): 899.0px (342.4762dp)
diff --git a/tests/res/xml/invalid_hotseat_file_case_1.xml b/tests/res/xml/invalid_hotseat_file_case_1.xml
index fcbc5ea..aaaf8bb 100644
--- a/tests/res/xml/invalid_hotseat_file_case_1.xml
+++ b/tests/res/xml/invalid_hotseat_file_case_1.xml
@@ -19,12 +19,14 @@
launcher:specType="height"
launcher:maxAvailableSize="847dp">
<hotseatQsbSpace launcher:ofAvailableSpace="1" />
+ <edgePadding launcher:fixedSize="36dp" />
</hotseatSpec>
<hotseatSpec
launcher:specType="height"
launcher:maxAvailableSize="9999dp">
<hotseatQsbSpace launcher:fixedSize="36dp" />
+ <edgePadding launcher:fixedSize="36dp" />
</hotseatSpec>
</hotseatSpecs>
\ No newline at end of file
diff --git a/tests/res/xml/valid_hotseat_file.xml b/tests/res/xml/valid_hotseat_file.xml
index c7f52e8..f698bd1 100644
--- a/tests/res/xml/valid_hotseat_file.xml
+++ b/tests/res/xml/valid_hotseat_file.xml
@@ -16,15 +16,17 @@
<hotseatSpecs xmlns:launcher="http://schemas.android.com/apk/res-auto">
<hotseatSpec
- launcher:specType="height"
- launcher:maxAvailableSize="847dp">
+ launcher:maxAvailableSize="847dp"
+ launcher:specType="height">
<hotseatQsbSpace launcher:fixedSize="24dp" />
+ <edgePadding launcher:fixedSize="48dp" />
</hotseatSpec>
<hotseatSpec
- launcher:specType="height"
- launcher:maxAvailableSize="9999dp">
+ launcher:maxAvailableSize="9999dp"
+ launcher:specType="height">
<hotseatQsbSpace launcher:fixedSize="36dp" />
+ <edgePadding launcher:fixedSize="48dp" />
</hotseatSpec>
</hotseatSpecs>
\ No newline at end of file
diff --git a/tests/res/xml/valid_hotseat_land_file.xml b/tests/res/xml/valid_hotseat_land_file.xml
new file mode 100644
index 0000000..fc4a836
--- /dev/null
+++ b/tests/res/xml/valid_hotseat_land_file.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ 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.
+ -->
+<hotseatSpecs xmlns:launcher="http://schemas.android.com/apk/res-auto">
+
+ <hotseatSpec
+ launcher:maxAvailableSize="743dp"
+ launcher:specType="width">
+ <hotseatQsbSpace launcher:fixedSize="0dp" />
+ <edgePadding launcher:fixedSize="48dp" />
+ </hotseatSpec>
+
+ <hotseatSpec
+ launcher:maxAvailableSize="9999dp"
+ launcher:specType="width">
+ <hotseatQsbSpace launcher:fixedSize="0dp" />
+ <edgePadding launcher:fixedSize="64dp" />
+ </hotseatSpec>
+
+</hotseatSpecs>
\ No newline at end of file
diff --git a/tests/shared/com/android/launcher3/testing/shared/TestProtocol.java b/tests/shared/com/android/launcher3/testing/shared/TestProtocol.java
index cdf8f08..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";
@@ -120,7 +122,6 @@
"get-activities-created-count";
public static final String REQUEST_GET_ACTIVITIES = "get-activities";
public static final String REQUEST_HAS_TIS = "has-touch-interaction-service";
- public static final String REQUEST_IS_TRACKPAD_GESTURE_ENABLED = "is-trackpad-gesture-enabled";
public static final String REQUEST_TASKBAR_ALL_APPS_TOP_PADDING =
"taskbar-all-apps-top-padding";
public static final String REQUEST_ALL_APPS_TOP_PADDING = "all-apps-top-padding";
diff --git a/tests/src/com/android/launcher3/AbstractDeviceProfileTest.kt b/tests/src/com/android/launcher3/AbstractDeviceProfileTest.kt
index dd79ca8..ed8e324 100644
--- a/tests/src/com/android/launcher3/AbstractDeviceProfileTest.kt
+++ b/tests/src/com/android/launcher3/AbstractDeviceProfileTest.kt
@@ -26,6 +26,7 @@
import com.android.launcher3.util.DisplayController
import com.android.launcher3.util.NavigationMode
import com.android.launcher3.util.WindowBounds
+import com.android.launcher3.util.rule.TestStabilityRule
import com.android.launcher3.util.window.CachedDisplayInfo
import com.android.launcher3.util.window.WindowManagerProxy
import java.io.BufferedReader
@@ -36,6 +37,7 @@
import kotlin.math.min
import org.junit.After
import org.junit.Before
+import org.junit.Rule
import org.mockito.ArgumentMatchers
import org.mockito.Mockito.mock
import org.mockito.Mockito.`when` as whenever
@@ -54,6 +56,8 @@
private lateinit var originalDisplayController: DisplayController
private lateinit var originalWindowManagerProxy: WindowManagerProxy
+ @Rule @JvmField val testStabilityRule = TestStabilityRule()
+
@Before
open fun setUp() {
val appContext: Context = ApplicationProvider.getApplicationContext()
diff --git a/tests/src/com/android/launcher3/allapps/OopTaplOpenCloseAllApps.java b/tests/src/com/android/launcher3/allapps/OopTaplOpenCloseAllApps.java
new file mode 100644
index 0000000..7d6b7f9
--- /dev/null
+++ b/tests/src/com/android/launcher3/allapps/OopTaplOpenCloseAllApps.java
@@ -0,0 +1,187 @@
+/*
+ * 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.allapps;
+
+import static com.android.launcher3.ui.TaplTestsLauncher3.expectFail;
+import static com.android.launcher3.ui.TaplTestsLauncher3.initialize;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
+
+import com.android.launcher3.LauncherState;
+import com.android.launcher3.tapl.AllApps;
+import com.android.launcher3.ui.AbstractLauncherUiTest;
+import com.android.launcher3.ui.PortraitLandscapeRunner.PortraitLandscape;
+
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Test that we can open and close the all apps in multiple situations.
+ * The test runs in Out of process (Oop) and in process.
+ */
+public class OopTaplOpenCloseAllApps extends AbstractLauncherUiTest {
+
+ /**
+ * Calls static method initialize
+ */
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ initialize(this);
+ }
+
+ /**
+ * Make sure we can go home after pressing the context menu on an Icon on the AllApps.
+ */
+ @Test
+ public void testPressHomeOnAllAppsContextMenu() {
+ final AllApps allApps = mLauncher.getWorkspace().switchToAllApps();
+ allApps.freeze();
+ try {
+ allApps.getAppIcon("TestActivity7").openMenu();
+ } finally {
+ allApps.unfreeze();
+ }
+ mLauncher.goHome();
+ }
+
+ /**
+ * Make sure we can open AllApps from the Workspace.
+ */
+ @Test
+ @PortraitLandscape
+ public void testWorkspaceSwitchToAllApps() {
+ assertNotNull("switchToAllApps() returned null",
+ mLauncher.getWorkspace().switchToAllApps());
+ assertTrue("Launcher internal state is not All Apps",
+ isInState(() -> LauncherState.ALL_APPS));
+ }
+
+ /**
+ * Make sure we can go to Workspace from AllApps
+ */
+ @Test
+ @PortraitLandscape
+ public void testAllAppsSwitchToWorkspace() {
+ assertNotNull("switchToWorkspace() returned null",
+ mLauncher.getWorkspace().switchToAllApps()
+ .switchToWorkspace(/* swipeDown= */ true));
+ assertTrue("Launcher internal state is not Workspace",
+ isInState(() -> LauncherState.NORMAL));
+ }
+
+ /**
+ * Make sure the swipe up gesture can take us back to the workspace from AllApps
+ */
+ @Test
+ @PortraitLandscape
+ public void testAllAppsSwipeUpToWorkspace() {
+ assertNotNull("testAllAppsSwipeUpToWorkspace() returned null",
+ mLauncher.getWorkspace().switchToAllApps()
+ .switchToWorkspace(/* swipeDown= */ false));
+ assertTrue("Launcher internal state is not Workspace",
+ isInState(() -> LauncherState.NORMAL));
+ }
+
+ /**
+ * Make sure we can go to the Workspace from AllApps on tablets by tapping on the background.
+ */
+ @Test
+ @PortraitLandscape
+ public void testAllAppsDeadzoneForTablet() {
+ assumeTrue(mLauncher.isTablet());
+
+ mLauncher.getWorkspace().switchToAllApps().dismissByTappingOutsideForTablet(
+ true /* tapRight */);
+ mLauncher.getWorkspace().switchToAllApps().dismissByTappingOutsideForTablet(
+ false /* tapRight */);
+ }
+
+ /**
+ * Make sure that AllApps closes when pressing the home button
+ */
+ @Test
+ @PortraitLandscape
+ public void testAllAppsFromHome() {
+ // Test opening all apps
+ assertNotNull("switchToAllApps() returned null",
+ mLauncher.getWorkspace().switchToAllApps());
+
+ runAllAppsTest(mLauncher.getAllApps());
+
+ // Testing pressHome.
+ assertTrue("Launcher internal state is not All Apps",
+ isInState(() -> LauncherState.ALL_APPS));
+ assertNotNull("pressHome returned null", mLauncher.goHome());
+ assertTrue("Launcher internal state is not Home",
+ isInState(() -> LauncherState.NORMAL));
+ assertNotNull("getHome returned null", mLauncher.getWorkspace());
+ }
+
+ /**
+ * Makes sure the state of AllApps is correct.
+ */
+ public void runAllAppsTest(AllApps allApps) {
+ allApps.freeze();
+ try {
+ assertNotNull("allApps parameter is null", allApps);
+
+ assertTrue(
+ "Launcher internal state is not All Apps",
+ isInState(() -> LauncherState.ALL_APPS));
+
+ // Test flinging forward and backward.
+ executeOnLauncher(launcher -> assertEquals(
+ "All Apps started in already scrolled state", 0,
+ getAllAppsScroll(launcher)));
+
+ allApps.flingForward();
+ assertTrue("Launcher internal state is not All Apps",
+ isInState(() -> LauncherState.ALL_APPS));
+ final Integer flingForwardY = getFromLauncher(
+ launcher -> getAllAppsScroll(launcher));
+ executeOnLauncher(
+ launcher -> assertTrue("flingForward() didn't scroll App Apps",
+ flingForwardY > 0));
+
+ allApps.flingBackward();
+ assertTrue(
+ "Launcher internal state is not All Apps",
+ isInState(() -> LauncherState.ALL_APPS));
+ final Integer flingBackwardY = getFromLauncher(
+ launcher -> getAllAppsScroll(launcher));
+ executeOnLauncher(launcher -> assertTrue("flingBackward() didn't scroll App Apps",
+ flingBackwardY < flingForwardY));
+
+ // Test scrolling down to YouTube.
+ assertNotNull("All apps: can't find YouTube", allApps.getAppIcon("YouTube"));
+ // Test scrolling up to Camera.
+ assertNotNull("All apps: can't find Camera", allApps.getAppIcon("Camera"));
+ // Test failing to find a non-existing app.
+ final AllApps allAppsFinal = allApps;
+ expectFail("All apps: could find a non-existing app",
+ () -> allAppsFinal.getAppIcon("NO APP"));
+
+ assertTrue(
+ "Launcher internal state is not All Apps",
+ isInState(() -> LauncherState.ALL_APPS));
+ } finally {
+ allApps.unfreeze();
+ }
+ }
+}
diff --git a/tests/src/com/android/launcher3/nonquickstep/DeviceProfileDumpTest.kt b/tests/src/com/android/launcher3/nonquickstep/DeviceProfileDumpTest.kt
index 270672f..9b67310 100644
--- a/tests/src/com/android/launcher3/nonquickstep/DeviceProfileDumpTest.kt
+++ b/tests/src/com/android/launcher3/nonquickstep/DeviceProfileDumpTest.kt
@@ -15,14 +15,14 @@
*/
package com.android.launcher3.nonquickstep
+import android.content.Context
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
+import androidx.test.platform.app.InstrumentationRegistry
import com.android.launcher3.AbstractDeviceProfileTest
import com.android.launcher3.DeviceProfile
import com.android.launcher3.InvariantDeviceProfile
import com.google.common.truth.Truth.assertThat
-import java.io.PrintWriter
-import java.io.StringWriter
import org.junit.Test
import org.junit.runner.RunWith
@@ -30,142 +30,14 @@
@SmallTest
@RunWith(AndroidJUnit4::class)
class DeviceProfileDumpTest : AbstractDeviceProfileTest() {
-
+ private val testContext: Context = InstrumentationRegistry.getInstrumentation().context
+ private val folderName: String = "DeviceProfileDumpTest"
@Test
fun phonePortrait3Button() {
initializeVarsForPhone(deviceSpecs["phone"]!!, isGestureMode = false)
val dp = getDeviceProfileForGrid("5_by_5")
- assertThat(dump(dp))
- .isEqualTo(
- "DeviceProfile:\n" +
- "\t1 dp = 2.625 px\n" +
- "\tisTablet:false\n" +
- "\tisPhone:true\n" +
- "\ttransposeLayoutWithOrientation:true\n" +
- "\tisGestureMode:false\n" +
- "\tisLandscape:false\n" +
- "\tisMultiWindowMode:false\n" +
- "\tisTwoPanels:false\n" +
- "\twindowX: 0.0px (0.0dp)\n" +
- "\twindowY: 0.0px (0.0dp)\n" +
- "\twidthPx: 1080.0px (411.42856dp)\n" +
- "\theightPx: 2400.0px (914.2857dp)\n" +
- "\tavailableWidthPx: 1080.0px (411.42856dp)\n" +
- "\tavailableHeightPx: 2156.0px (821.3333dp)\n" +
- "\tmInsets.left: 0.0px (0.0dp)\n" +
- "\tmInsets.top: 118.0px (44.95238dp)\n" +
- "\tmInsets.right: 0.0px (0.0dp)\n" +
- "\tmInsets.bottom: 126.0px (48.0dp)\n" +
- "\taspectRatio:2.2222223\n" +
- "\tisResponsiveGrid:false\n" +
- "\tisScalableGrid:false\n" +
- "\tinv.numRows: 5\n" +
- "\tinv.numColumns: 5\n" +
- "\tinv.numSearchContainerColumns: 5\n" +
- "\tminCellSize: PointF(0.0, 0.0)dp\n" +
- "\tcellWidthPx: 159.0px (60.57143dp)\n" +
- "\tcellHeightPx: 229.0px (87.2381dp)\n" +
- "\tgetCellSize().x: 207.0px (78.85714dp)\n" +
- "\tgetCellSize().y: 379.0px (144.38095dp)\n" +
- "\tcellLayoutBorderSpacePx Horizontal: 0.0px (0.0dp)\n" +
- "\tcellLayoutBorderSpacePx Vertical: 0.0px (0.0dp)\n" +
- "\tcellLayoutPaddingPx.left: 21.0px (8.0dp)\n" +
- "\tcellLayoutPaddingPx.top: 28.0px (10.666667dp)\n" +
- "\tcellLayoutPaddingPx.right: 21.0px (8.0dp)\n" +
- "\tcellLayoutPaddingPx.bottom: 28.0px (10.666667dp)\n" +
- "\ticonSizePx: 147.0px (56.0dp)\n" +
- "\ticonTextSizePx: 38.0px (14.476191dp)\n" +
- "\ticonDrawablePaddingPx: 12.0px (4.571429dp)\n" +
- "\tinv.numFolderRows: 4\n" +
- "\tinv.numFolderColumns: 4\n" +
- "\tfolderCellWidthPx: 195.0px (74.28571dp)\n" +
- "\tfolderCellHeightPx: 230.0px (87.61905dp)\n" +
- "\tfolderChildIconSizePx: 147.0px (56.0dp)\n" +
- "\tfolderChildTextSizePx: 38.0px (14.476191dp)\n" +
- "\tfolderChildDrawablePaddingPx: 4.0px (1.5238096dp)\n" +
- "\tfolderCellLayoutBorderSpacePx.x: 0.0px (0.0dp)\n" +
- "\tfolderCellLayoutBorderSpacePx.y: 0.0px (0.0dp)\n" +
- "\tfolderContentPaddingLeftRight: 21.0px (8.0dp)\n" +
- "\tfolderTopPadding: 63.0px (24.0dp)\n" +
- "\tfolderFooterHeight: 147.0px (56.0dp)\n" +
- "\tbottomSheetTopPadding: 146.0px (55.61905dp)\n" +
- "\tbottomSheetOpenDuration: 267\n" +
- "\tbottomSheetCloseDuration: 267\n" +
- "\tbottomSheetWorkspaceScale: 1.0\n" +
- "\tbottomSheetDepth: 0.0\n" +
- "\tallAppsShiftRange: 788.0px (300.1905dp)\n" +
- "\tallAppsTopPadding: 0.0px (0.0dp)\n" +
- "\tallAppsOpenDuration: 600\n" +
- "\tallAppsCloseDuration: 300\n" +
- "\tallAppsIconSizePx: 147.0px (56.0dp)\n" +
- "\tallAppsIconTextSizePx: 38.0px (14.476191dp)\n" +
- "\tallAppsIconDrawablePaddingPx: 21.0px (8.0dp)\n" +
- "\tallAppsCellHeightPx: 315.0px (120.0dp)\n" +
- "\tallAppsCellWidthPx: 189.0px (72.0dp)\n" +
- "\tallAppsBorderSpacePxX: 42.0px (16.0dp)\n" +
- "\tallAppsBorderSpacePxY: 42.0px (16.0dp)\n" +
- "\tnumShownAllAppsColumns: 5\n" +
- "\tallAppsLeftRightPadding: 0.0px (0.0dp)\n" +
- "\tallAppsLeftRightMargin: 0.0px (0.0dp)\n" +
- "\thotseatBarSizePx: 294.0px (112.0dp)\n" +
- "\tinv.hotseatColumnSpan: 5\n" +
- "\thotseatCellHeightPx: 166.0px (63.238094dp)\n" +
- "\thotseatBarBottomSpacePx: 147.0px (56.0dp)\n" +
- "\thotseatBarSidePaddingStartPx: 0.0px (0.0dp)\n" +
- "\thotseatBarSidePaddingEndPx: 0.0px (0.0dp)\n" +
- "\thotseatBarEndOffset: 0.0px (0.0dp)\n" +
- "\thotseatQsbSpace: 0.0px (0.0dp)\n" +
- "\thotseatQsbHeight: 0.0px (0.0dp)\n" +
- "\tspringLoadedHotseatBarTopMarginPx: 200.0px (76.190475dp)\n" +
- "\tgetHotseatLayoutPadding(context).top: 0.0px (0.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).bottom: 128.0px (48.761906dp)\n" +
- "\tgetHotseatLayoutPadding(context).left: 21.0px (8.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).right: 21.0px (8.0dp)\n" +
- "\tnumShownHotseatIcons: 5\n" +
- "\thotseatBorderSpace: 0.0px (0.0dp)\n" +
- "\tisQsbInline: false\n" +
- "\thotseatQsbWidth: 0.0px (0.0dp)\n" +
- "\tisTaskbarPresent:false\n" +
- "\tisTaskbarPresentInApps:false\n" +
- "\ttaskbarHeight: 0.0px (0.0dp)\n" +
- "\tstashedTaskbarHeight: 0.0px (0.0dp)\n" +
- "\ttaskbarBottomMargin: 0.0px (0.0dp)\n" +
- "\ttaskbarIconSize: 0.0px (0.0dp)\n" +
- "\tdesiredWorkspaceHorizontalMarginPx: 21.0px (8.0dp)\n" +
- "\tworkspacePadding.left: 0.0px (0.0dp)\n" +
- "\tworkspacePadding.top: 0.0px (0.0dp)\n" +
- "\tworkspacePadding.right: 0.0px (0.0dp)\n" +
- "\tworkspacePadding.bottom: 203.0px (77.333336dp)\n" +
- "\ticonScale: 1.0px (0.3809524dp)\n" +
- "\tcellScaleToFit : 1.0px (0.3809524dp)\n" +
- "\textraSpace: 752.0px (286.4762dp)\n" +
- "\tunscaled extraSpace: 752.0px (286.4762dp)\n" +
- "\tmaxEmptySpace: 0.0px (0.0dp)\n" +
- "\tworkspaceTopPadding: 0.0px (0.0dp)\n" +
- "\tworkspaceBottomPadding: 0.0px (0.0dp)\n" +
- "\toverviewTaskMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconSizePx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconDrawableSizePx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)\n" +
- "\toverviewTaskThumbnailTopMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewActionsTopMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewActionsHeight: 0.0px (0.0dp)\n" +
- "\toverviewActionsClaimedSpaceBelow: 126.0px (48.0dp)\n" +
- "\toverviewActionsButtonSpacing: 0.0px (0.0dp)\n" +
- "\toverviewPageSpacing: 0.0px (0.0dp)\n" +
- "\toverviewRowSpacing: 0.0px (0.0dp)\n" +
- "\toverviewGridSideMargin: 0.0px (0.0dp)\n" +
- "\tdropTargetBarTopMarginPx: 84.0px (32.0dp)\n" +
- "\tdropTargetBarSizePx: 147.0px (56.0dp)\n" +
- "\tdropTargetBarBottomMarginPx: 42.0px (16.0dp)\n" +
- "\tgetCellLayoutSpringLoadShrunkTop(): 391.0px (148.95238dp)\n" +
- "\tgetCellLayoutSpringLoadShrunkBottom(): 1906.0px (726.0952dp)\n" +
- "\tworkspaceSpringLoadedMinNextPageVisiblePx: 63.0px (24.0dp)\n" +
- "\tgetWorkspaceSpringLoadScale(): 0.77572966px (0.29551607dp)\n" +
- "\tgetCellLayoutHeight(): 1953.0px (744.0dp)\n" +
- "\tgetCellLayoutWidth(): 1080.0px (411.42856dp)\n"
- )
+ assertDump(dp, "phonePortrait3Button")
}
@Test
@@ -173,136 +45,7 @@
initializeVarsForPhone(deviceSpecs["phone"]!!)
val dp = getDeviceProfileForGrid("5_by_5")
- assertThat(dump(dp))
- .isEqualTo(
- "DeviceProfile:\n" +
- "\t1 dp = 2.625 px\n" +
- "\tisTablet:false\n" +
- "\tisPhone:true\n" +
- "\ttransposeLayoutWithOrientation:true\n" +
- "\tisGestureMode:true\n" +
- "\tisLandscape:false\n" +
- "\tisMultiWindowMode:false\n" +
- "\tisTwoPanels:false\n" +
- "\twindowX: 0.0px (0.0dp)\n" +
- "\twindowY: 0.0px (0.0dp)\n" +
- "\twidthPx: 1080.0px (411.42856dp)\n" +
- "\theightPx: 2400.0px (914.2857dp)\n" +
- "\tavailableWidthPx: 1080.0px (411.42856dp)\n" +
- "\tavailableHeightPx: 2219.0px (845.3333dp)\n" +
- "\tmInsets.left: 0.0px (0.0dp)\n" +
- "\tmInsets.top: 118.0px (44.95238dp)\n" +
- "\tmInsets.right: 0.0px (0.0dp)\n" +
- "\tmInsets.bottom: 63.0px (24.0dp)\n" +
- "\taspectRatio:2.2222223\n" +
- "\tisResponsiveGrid:false\n" +
- "\tisScalableGrid:false\n" +
- "\tinv.numRows: 5\n" +
- "\tinv.numColumns: 5\n" +
- "\tinv.numSearchContainerColumns: 5\n" +
- "\tminCellSize: PointF(0.0, 0.0)dp\n" +
- "\tcellWidthPx: 159.0px (60.57143dp)\n" +
- "\tcellHeightPx: 229.0px (87.2381dp)\n" +
- "\tgetCellSize().x: 207.0px (78.85714dp)\n" +
- "\tgetCellSize().y: 383.0px (145.90475dp)\n" +
- "\tcellLayoutBorderSpacePx Horizontal: 0.0px (0.0dp)\n" +
- "\tcellLayoutBorderSpacePx Vertical: 0.0px (0.0dp)\n" +
- "\tcellLayoutPaddingPx.left: 21.0px (8.0dp)\n" +
- "\tcellLayoutPaddingPx.top: 28.0px (10.666667dp)\n" +
- "\tcellLayoutPaddingPx.right: 21.0px (8.0dp)\n" +
- "\tcellLayoutPaddingPx.bottom: 28.0px (10.666667dp)\n" +
- "\ticonSizePx: 147.0px (56.0dp)\n" +
- "\ticonTextSizePx: 38.0px (14.476191dp)\n" +
- "\ticonDrawablePaddingPx: 12.0px (4.571429dp)\n" +
- "\tinv.numFolderRows: 4\n" +
- "\tinv.numFolderColumns: 4\n" +
- "\tfolderCellWidthPx: 195.0px (74.28571dp)\n" +
- "\tfolderCellHeightPx: 230.0px (87.61905dp)\n" +
- "\tfolderChildIconSizePx: 147.0px (56.0dp)\n" +
- "\tfolderChildTextSizePx: 38.0px (14.476191dp)\n" +
- "\tfolderChildDrawablePaddingPx: 4.0px (1.5238096dp)\n" +
- "\tfolderCellLayoutBorderSpacePx.x: 0.0px (0.0dp)\n" +
- "\tfolderCellLayoutBorderSpacePx.y: 0.0px (0.0dp)\n" +
- "\tfolderContentPaddingLeftRight: 21.0px (8.0dp)\n" +
- "\tfolderTopPadding: 63.0px (24.0dp)\n" +
- "\tfolderFooterHeight: 147.0px (56.0dp)\n" +
- "\tbottomSheetTopPadding: 146.0px (55.61905dp)\n" +
- "\tbottomSheetOpenDuration: 267\n" +
- "\tbottomSheetCloseDuration: 267\n" +
- "\tbottomSheetWorkspaceScale: 1.0\n" +
- "\tbottomSheetDepth: 0.0\n" +
- "\tallAppsShiftRange: 788.0px (300.1905dp)\n" +
- "\tallAppsTopPadding: 0.0px (0.0dp)\n" +
- "\tallAppsOpenDuration: 600\n" +
- "\tallAppsCloseDuration: 300\n" +
- "\tallAppsIconSizePx: 147.0px (56.0dp)\n" +
- "\tallAppsIconTextSizePx: 38.0px (14.476191dp)\n" +
- "\tallAppsIconDrawablePaddingPx: 21.0px (8.0dp)\n" +
- "\tallAppsCellHeightPx: 315.0px (120.0dp)\n" +
- "\tallAppsCellWidthPx: 189.0px (72.0dp)\n" +
- "\tallAppsBorderSpacePxX: 42.0px (16.0dp)\n" +
- "\tallAppsBorderSpacePxY: 42.0px (16.0dp)\n" +
- "\tnumShownAllAppsColumns: 5\n" +
- "\tallAppsLeftRightPadding: 0.0px (0.0dp)\n" +
- "\tallAppsLeftRightMargin: 0.0px (0.0dp)\n" +
- "\thotseatBarSizePx: 273.0px (104.0dp)\n" +
- "\tinv.hotseatColumnSpan: 5\n" +
- "\thotseatCellHeightPx: 166.0px (63.238094dp)\n" +
- "\thotseatBarBottomSpacePx: 126.0px (48.0dp)\n" +
- "\thotseatBarSidePaddingStartPx: 0.0px (0.0dp)\n" +
- "\thotseatBarSidePaddingEndPx: 0.0px (0.0dp)\n" +
- "\thotseatBarEndOffset: 0.0px (0.0dp)\n" +
- "\thotseatQsbSpace: 0.0px (0.0dp)\n" +
- "\thotseatQsbHeight: 0.0px (0.0dp)\n" +
- "\tspringLoadedHotseatBarTopMarginPx: 200.0px (76.190475dp)\n" +
- "\tgetHotseatLayoutPadding(context).top: 0.0px (0.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).bottom: 107.0px (40.761906dp)\n" +
- "\tgetHotseatLayoutPadding(context).left: 21.0px (8.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).right: 21.0px (8.0dp)\n" +
- "\tnumShownHotseatIcons: 5\n" +
- "\thotseatBorderSpace: 0.0px (0.0dp)\n" +
- "\tisQsbInline: false\n" +
- "\thotseatQsbWidth: 0.0px (0.0dp)\n" +
- "\tisTaskbarPresent:false\n" +
- "\tisTaskbarPresentInApps:false\n" +
- "\ttaskbarHeight: 0.0px (0.0dp)\n" +
- "\tstashedTaskbarHeight: 0.0px (0.0dp)\n" +
- "\ttaskbarBottomMargin: 0.0px (0.0dp)\n" +
- "\ttaskbarIconSize: 0.0px (0.0dp)\n" +
- "\tdesiredWorkspaceHorizontalMarginPx: 21.0px (8.0dp)\n" +
- "\tworkspacePadding.left: 0.0px (0.0dp)\n" +
- "\tworkspacePadding.top: 0.0px (0.0dp)\n" +
- "\tworkspacePadding.right: 0.0px (0.0dp)\n" +
- "\tworkspacePadding.bottom: 245.0px (93.333336dp)\n" +
- "\ticonScale: 1.0px (0.3809524dp)\n" +
- "\tcellScaleToFit : 1.0px (0.3809524dp)\n" +
- "\textraSpace: 773.0px (294.4762dp)\n" +
- "\tunscaled extraSpace: 773.0px (294.4762dp)\n" +
- "\tmaxEmptySpace: 0.0px (0.0dp)\n" +
- "\tworkspaceTopPadding: 0.0px (0.0dp)\n" +
- "\tworkspaceBottomPadding: 0.0px (0.0dp)\n" +
- "\toverviewTaskMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconSizePx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconDrawableSizePx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)\n" +
- "\toverviewTaskThumbnailTopMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewActionsTopMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewActionsHeight: 0.0px (0.0dp)\n" +
- "\toverviewActionsClaimedSpaceBelow: 63.0px (24.0dp)\n" +
- "\toverviewActionsButtonSpacing: 0.0px (0.0dp)\n" +
- "\toverviewPageSpacing: 0.0px (0.0dp)\n" +
- "\toverviewRowSpacing: 0.0px (0.0dp)\n" +
- "\toverviewGridSideMargin: 0.0px (0.0dp)\n" +
- "\tdropTargetBarTopMarginPx: 84.0px (32.0dp)\n" +
- "\tdropTargetBarSizePx: 147.0px (56.0dp)\n" +
- "\tdropTargetBarBottomMarginPx: 42.0px (16.0dp)\n" +
- "\tgetCellLayoutSpringLoadShrunkTop(): 391.0px (148.95238dp)\n" +
- "\tgetCellLayoutSpringLoadShrunkBottom(): 1927.0px (734.0952dp)\n" +
- "\tworkspaceSpringLoadedMinNextPageVisiblePx: 63.0px (24.0dp)\n" +
- "\tgetWorkspaceSpringLoadScale(): 0.7781155px (0.29642496dp)\n" +
- "\tgetCellLayoutHeight(): 1974.0px (752.0dp)\n" +
- "\tgetCellLayoutWidth(): 1080.0px (411.42856dp)\n"
- )
+ assertDump(dp, "phonePortrait")
}
@Test
@@ -310,136 +53,7 @@
initializeVarsForPhone(deviceSpecs["phone"]!!, isVerticalBar = true, isGestureMode = false)
val dp = getDeviceProfileForGrid("5_by_5")
- assertThat(dump(dp))
- .isEqualTo(
- "DeviceProfile:\n" +
- "\t1 dp = 2.625 px\n" +
- "\tisTablet:false\n" +
- "\tisPhone:true\n" +
- "\ttransposeLayoutWithOrientation:true\n" +
- "\tisGestureMode:false\n" +
- "\tisLandscape:true\n" +
- "\tisMultiWindowMode:false\n" +
- "\tisTwoPanels:false\n" +
- "\twindowX: 0.0px (0.0dp)\n" +
- "\twindowY: 0.0px (0.0dp)\n" +
- "\twidthPx: 2400.0px (914.2857dp)\n" +
- "\theightPx: 1080.0px (411.42856dp)\n" +
- "\tavailableWidthPx: 2156.0px (821.3333dp)\n" +
- "\tavailableHeightPx: 1006.0px (383.2381dp)\n" +
- "\tmInsets.left: 118.0px (44.95238dp)\n" +
- "\tmInsets.top: 74.0px (28.190475dp)\n" +
- "\tmInsets.right: 126.0px (48.0dp)\n" +
- "\tmInsets.bottom: 0.0px (0.0dp)\n" +
- "\taspectRatio:2.2222223\n" +
- "\tisResponsiveGrid:false\n" +
- "\tisScalableGrid:false\n" +
- "\tinv.numRows: 5\n" +
- "\tinv.numColumns: 5\n" +
- "\tinv.numSearchContainerColumns: 5\n" +
- "\tminCellSize: PointF(0.0, 0.0)dp\n" +
- "\tcellWidthPx: 152.0px (57.904762dp)\n" +
- "\tcellHeightPx: 166.0px (63.238094dp)\n" +
- "\tgetCellSize().x: 368.0px (140.19048dp)\n" +
- "\tgetCellSize().y: 193.0px (73.52381dp)\n" +
- "\tcellLayoutBorderSpacePx Horizontal: 0.0px (0.0dp)\n" +
- "\tcellLayoutBorderSpacePx Vertical: 0.0px (0.0dp)\n" +
- "\tcellLayoutPaddingPx.left: 53.0px (20.190475dp)\n" +
- "\tcellLayoutPaddingPx.top: 0.0px (0.0dp)\n" +
- "\tcellLayoutPaddingPx.right: 53.0px (20.190475dp)\n" +
- "\tcellLayoutPaddingPx.bottom: 40.0px (15.238095dp)\n" +
- "\ticonSizePx: 147.0px (56.0dp)\n" +
- "\ticonTextSizePx: 0.0px (0.0dp)\n" +
- "\ticonDrawablePaddingPx: 0.0px (0.0dp)\n" +
- "\tinv.numFolderRows: 4\n" +
- "\tinv.numFolderColumns: 4\n" +
- "\tfolderCellWidthPx: 173.0px (65.90476dp)\n" +
- "\tfolderCellHeightPx: 205.0px (78.09524dp)\n" +
- "\tfolderChildIconSizePx: 131.0px (49.904762dp)\n" +
- "\tfolderChildTextSizePx: 34.0px (12.952381dp)\n" +
- "\tfolderChildDrawablePaddingPx: 4.0px (1.5238096dp)\n" +
- "\tfolderCellLayoutBorderSpacePx.x: 0.0px (0.0dp)\n" +
- "\tfolderCellLayoutBorderSpacePx.y: 0.0px (0.0dp)\n" +
- "\tfolderContentPaddingLeftRight: 21.0px (8.0dp)\n" +
- "\tfolderTopPadding: 56.0px (21.333334dp)\n" +
- "\tfolderFooterHeight: 131.0px (49.904762dp)\n" +
- "\tbottomSheetTopPadding: 114.0px (43.42857dp)\n" +
- "\tbottomSheetOpenDuration: 267\n" +
- "\tbottomSheetCloseDuration: 267\n" +
- "\tbottomSheetWorkspaceScale: 1.0\n" +
- "\tbottomSheetDepth: 0.0\n" +
- "\tallAppsShiftRange: 788.0px (300.1905dp)\n" +
- "\tallAppsTopPadding: 0.0px (0.0dp)\n" +
- "\tallAppsOpenDuration: 600\n" +
- "\tallAppsCloseDuration: 300\n" +
- "\tallAppsIconSizePx: 147.0px (56.0dp)\n" +
- "\tallAppsIconTextSizePx: 38.0px (14.476191dp)\n" +
- "\tallAppsIconDrawablePaddingPx: 21.0px (8.0dp)\n" +
- "\tallAppsCellHeightPx: 321.0px (122.28571dp)\n" +
- "\tallAppsCellWidthPx: 189.0px (72.0dp)\n" +
- "\tallAppsBorderSpacePxX: 42.0px (16.0dp)\n" +
- "\tallAppsBorderSpacePxY: 42.0px (16.0dp)\n" +
- "\tnumShownAllAppsColumns: 5\n" +
- "\tallAppsLeftRightPadding: 0.0px (0.0dp)\n" +
- "\tallAppsLeftRightMargin: 0.0px (0.0dp)\n" +
- "\thotseatBarSizePx: 252.0px (96.0dp)\n" +
- "\tinv.hotseatColumnSpan: 5\n" +
- "\thotseatCellHeightPx: 166.0px (63.238094dp)\n" +
- "\thotseatBarBottomSpacePx: 126.0px (48.0dp)\n" +
- "\thotseatBarSidePaddingStartPx: 63.0px (24.0dp)\n" +
- "\thotseatBarSidePaddingEndPx: 42.0px (16.0dp)\n" +
- "\thotseatBarEndOffset: 0.0px (0.0dp)\n" +
- "\thotseatQsbSpace: 0.0px (0.0dp)\n" +
- "\thotseatQsbHeight: 0.0px (0.0dp)\n" +
- "\tspringLoadedHotseatBarTopMarginPx: 118.0px (44.95238dp)\n" +
- "\tgetHotseatLayoutPadding(context).top: 64.0px (24.380953dp)\n" +
- "\tgetHotseatLayoutPadding(context).bottom: 49.0px (18.666666dp)\n" +
- "\tgetHotseatLayoutPadding(context).left: 42.0px (16.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).right: 189.0px (72.0dp)\n" +
- "\tnumShownHotseatIcons: 5\n" +
- "\thotseatBorderSpace: 0.0px (0.0dp)\n" +
- "\tisQsbInline: false\n" +
- "\thotseatQsbWidth: 0.0px (0.0dp)\n" +
- "\tisTaskbarPresent:false\n" +
- "\tisTaskbarPresentInApps:false\n" +
- "\ttaskbarHeight: 0.0px (0.0dp)\n" +
- "\tstashedTaskbarHeight: 0.0px (0.0dp)\n" +
- "\ttaskbarBottomMargin: 0.0px (0.0dp)\n" +
- "\ttaskbarIconSize: 0.0px (0.0dp)\n" +
- "\tdesiredWorkspaceHorizontalMarginPx: 0.0px (0.0dp)\n" +
- "\tworkspacePadding.left: 10.0px (3.8095238dp)\n" +
- "\tworkspacePadding.top: 0.0px (0.0dp)\n" +
- "\tworkspacePadding.right: 199.0px (75.809525dp)\n" +
- "\tworkspacePadding.bottom: 0.0px (0.0dp)\n" +
- "\ticonScale: 1.0px (0.3809524dp)\n" +
- "\tcellScaleToFit : 1.0px (0.3809524dp)\n" +
- "\textraSpace: 136.0px (51.809525dp)\n" +
- "\tunscaled extraSpace: 136.0px (51.809525dp)\n" +
- "\tmaxEmptySpace: 0.0px (0.0dp)\n" +
- "\tworkspaceTopPadding: 0.0px (0.0dp)\n" +
- "\tworkspaceBottomPadding: 0.0px (0.0dp)\n" +
- "\toverviewTaskMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconSizePx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconDrawableSizePx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)\n" +
- "\toverviewTaskThumbnailTopMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewActionsTopMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewActionsHeight: 0.0px (0.0dp)\n" +
- "\toverviewActionsClaimedSpaceBelow: 0.0px (0.0dp)\n" +
- "\toverviewActionsButtonSpacing: 0.0px (0.0dp)\n" +
- "\toverviewPageSpacing: 0.0px (0.0dp)\n" +
- "\toverviewRowSpacing: 0.0px (0.0dp)\n" +
- "\toverviewGridSideMargin: 0.0px (0.0dp)\n" +
- "\tdropTargetBarTopMarginPx: 16.0px (6.095238dp)\n" +
- "\tdropTargetBarSizePx: 95.0px (36.190475dp)\n" +
- "\tdropTargetBarBottomMarginPx: 16.0px (6.095238dp)\n" +
- "\tgetCellLayoutSpringLoadShrunkTop(): 201.0px (76.57143dp)\n" +
- "\tgetCellLayoutSpringLoadShrunkBottom(): 1008.0px (384.0dp)\n" +
- "\tworkspaceSpringLoadedMinNextPageVisiblePx: 63.0px (24.0dp)\n" +
- "\tgetWorkspaceSpringLoadScale(): 0.8021869px (0.305595dp)\n" +
- "\tgetCellLayoutHeight(): 1006.0px (383.2381dp)\n" +
- "\tgetCellLayoutWidth(): 1947.0px (741.7143dp)\n"
- )
+ assertDump(dp, "phoneVerticalBar3Button")
}
@Test
@@ -447,136 +61,7 @@
initializeVarsForPhone(deviceSpecs["phone"]!!, isVerticalBar = true)
val dp = getDeviceProfileForGrid("5_by_5")
- assertThat(dump(dp))
- .isEqualTo(
- "DeviceProfile:\n" +
- "\t1 dp = 2.625 px\n" +
- "\tisTablet:false\n" +
- "\tisPhone:true\n" +
- "\ttransposeLayoutWithOrientation:true\n" +
- "\tisGestureMode:true\n" +
- "\tisLandscape:true\n" +
- "\tisMultiWindowMode:false\n" +
- "\tisTwoPanels:false\n" +
- "\twindowX: 0.0px (0.0dp)\n" +
- "\twindowY: 0.0px (0.0dp)\n" +
- "\twidthPx: 2400.0px (914.2857dp)\n" +
- "\theightPx: 1080.0px (411.42856dp)\n" +
- "\tavailableWidthPx: 2282.0px (869.3333dp)\n" +
- "\tavailableHeightPx: 943.0px (359.2381dp)\n" +
- "\tmInsets.left: 118.0px (44.95238dp)\n" +
- "\tmInsets.top: 74.0px (28.190475dp)\n" +
- "\tmInsets.right: 0.0px (0.0dp)\n" +
- "\tmInsets.bottom: 63.0px (24.0dp)\n" +
- "\taspectRatio:2.2222223\n" +
- "\tisResponsiveGrid:false\n" +
- "\tisScalableGrid:false\n" +
- "\tinv.numRows: 5\n" +
- "\tinv.numColumns: 5\n" +
- "\tinv.numSearchContainerColumns: 5\n" +
- "\tminCellSize: PointF(0.0, 0.0)dp\n" +
- "\tcellWidthPx: 152.0px (57.904762dp)\n" +
- "\tcellHeightPx: 166.0px (63.238094dp)\n" +
- "\tgetCellSize().x: 393.0px (149.71428dp)\n" +
- "\tgetCellSize().y: 180.0px (68.57143dp)\n" +
- "\tcellLayoutBorderSpacePx Horizontal: 0.0px (0.0dp)\n" +
- "\tcellLayoutBorderSpacePx Vertical: 0.0px (0.0dp)\n" +
- "\tcellLayoutPaddingPx.left: 53.0px (20.190475dp)\n" +
- "\tcellLayoutPaddingPx.top: 0.0px (0.0dp)\n" +
- "\tcellLayoutPaddingPx.right: 53.0px (20.190475dp)\n" +
- "\tcellLayoutPaddingPx.bottom: 40.0px (15.238095dp)\n" +
- "\ticonSizePx: 147.0px (56.0dp)\n" +
- "\ticonTextSizePx: 0.0px (0.0dp)\n" +
- "\ticonDrawablePaddingPx: 0.0px (0.0dp)\n" +
- "\tinv.numFolderRows: 4\n" +
- "\tinv.numFolderColumns: 4\n" +
- "\tfolderCellWidthPx: 163.0px (62.095238dp)\n" +
- "\tfolderCellHeightPx: 192.0px (73.14286dp)\n" +
- "\tfolderChildIconSizePx: 123.0px (46.857143dp)\n" +
- "\tfolderChildTextSizePx: 32.0px (12.190476dp)\n" +
- "\tfolderChildDrawablePaddingPx: 3.0px (1.1428572dp)\n" +
- "\tfolderCellLayoutBorderSpacePx.x: 0.0px (0.0dp)\n" +
- "\tfolderCellLayoutBorderSpacePx.y: 0.0px (0.0dp)\n" +
- "\tfolderContentPaddingLeftRight: 21.0px (8.0dp)\n" +
- "\tfolderTopPadding: 53.0px (20.190475dp)\n" +
- "\tfolderFooterHeight: 123.0px (46.857143dp)\n" +
- "\tbottomSheetTopPadding: 114.0px (43.42857dp)\n" +
- "\tbottomSheetOpenDuration: 267\n" +
- "\tbottomSheetCloseDuration: 267\n" +
- "\tbottomSheetWorkspaceScale: 1.0\n" +
- "\tbottomSheetDepth: 0.0\n" +
- "\tallAppsShiftRange: 788.0px (300.1905dp)\n" +
- "\tallAppsTopPadding: 0.0px (0.0dp)\n" +
- "\tallAppsOpenDuration: 600\n" +
- "\tallAppsCloseDuration: 300\n" +
- "\tallAppsIconSizePx: 147.0px (56.0dp)\n" +
- "\tallAppsIconTextSizePx: 38.0px (14.476191dp)\n" +
- "\tallAppsIconDrawablePaddingPx: 21.0px (8.0dp)\n" +
- "\tallAppsCellHeightPx: 321.0px (122.28571dp)\n" +
- "\tallAppsCellWidthPx: 189.0px (72.0dp)\n" +
- "\tallAppsBorderSpacePxX: 42.0px (16.0dp)\n" +
- "\tallAppsBorderSpacePxY: 42.0px (16.0dp)\n" +
- "\tnumShownAllAppsColumns: 5\n" +
- "\tallAppsLeftRightPadding: 0.0px (0.0dp)\n" +
- "\tallAppsLeftRightMargin: 0.0px (0.0dp)\n" +
- "\thotseatBarSizePx: 252.0px (96.0dp)\n" +
- "\tinv.hotseatColumnSpan: 5\n" +
- "\thotseatCellHeightPx: 166.0px (63.238094dp)\n" +
- "\thotseatBarBottomSpacePx: 126.0px (48.0dp)\n" +
- "\thotseatBarSidePaddingStartPx: 63.0px (24.0dp)\n" +
- "\thotseatBarSidePaddingEndPx: 42.0px (16.0dp)\n" +
- "\thotseatBarEndOffset: 0.0px (0.0dp)\n" +
- "\thotseatQsbSpace: 0.0px (0.0dp)\n" +
- "\thotseatQsbHeight: 0.0px (0.0dp)\n" +
- "\tspringLoadedHotseatBarTopMarginPx: 118.0px (44.95238dp)\n" +
- "\tgetHotseatLayoutPadding(context).top: 64.0px (24.380953dp)\n" +
- "\tgetHotseatLayoutPadding(context).bottom: 112.0px (42.666668dp)\n" +
- "\tgetHotseatLayoutPadding(context).left: 42.0px (16.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).right: 63.0px (24.0dp)\n" +
- "\tnumShownHotseatIcons: 5\n" +
- "\thotseatBorderSpace: 0.0px (0.0dp)\n" +
- "\tisQsbInline: false\n" +
- "\thotseatQsbWidth: 0.0px (0.0dp)\n" +
- "\tisTaskbarPresent:false\n" +
- "\tisTaskbarPresentInApps:false\n" +
- "\ttaskbarHeight: 0.0px (0.0dp)\n" +
- "\tstashedTaskbarHeight: 0.0px (0.0dp)\n" +
- "\ttaskbarBottomMargin: 0.0px (0.0dp)\n" +
- "\ttaskbarIconSize: 0.0px (0.0dp)\n" +
- "\tdesiredWorkspaceHorizontalMarginPx: 0.0px (0.0dp)\n" +
- "\tworkspacePadding.left: 10.0px (3.8095238dp)\n" +
- "\tworkspacePadding.top: 0.0px (0.0dp)\n" +
- "\tworkspacePadding.right: 199.0px (75.809525dp)\n" +
- "\tworkspacePadding.bottom: 0.0px (0.0dp)\n" +
- "\ticonScale: 1.0px (0.3809524dp)\n" +
- "\tcellScaleToFit : 1.0px (0.3809524dp)\n" +
- "\textraSpace: 73.0px (27.809525dp)\n" +
- "\tunscaled extraSpace: 73.0px (27.809525dp)\n" +
- "\tmaxEmptySpace: 0.0px (0.0dp)\n" +
- "\tworkspaceTopPadding: 0.0px (0.0dp)\n" +
- "\tworkspaceBottomPadding: 0.0px (0.0dp)\n" +
- "\toverviewTaskMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconSizePx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconDrawableSizePx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)\n" +
- "\toverviewTaskThumbnailTopMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewActionsTopMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewActionsHeight: 0.0px (0.0dp)\n" +
- "\toverviewActionsClaimedSpaceBelow: 63.0px (24.0dp)\n" +
- "\toverviewActionsButtonSpacing: 0.0px (0.0dp)\n" +
- "\toverviewPageSpacing: 0.0px (0.0dp)\n" +
- "\toverviewRowSpacing: 0.0px (0.0dp)\n" +
- "\toverviewGridSideMargin: 0.0px (0.0dp)\n" +
- "\tdropTargetBarTopMarginPx: 16.0px (6.095238dp)\n" +
- "\tdropTargetBarSizePx: 95.0px (36.190475dp)\n" +
- "\tdropTargetBarBottomMarginPx: 16.0px (6.095238dp)\n" +
- "\tgetCellLayoutSpringLoadShrunkTop(): 201.0px (76.57143dp)\n" +
- "\tgetCellLayoutSpringLoadShrunkBottom(): 952.0px (362.66666dp)\n" +
- "\tworkspaceSpringLoadedMinNextPageVisiblePx: 63.0px (24.0dp)\n" +
- "\tgetWorkspaceSpringLoadScale(): 0.79639447px (0.30338836dp)\n" +
- "\tgetCellLayoutHeight(): 943.0px (359.2381dp)\n" +
- "\tgetCellLayoutWidth(): 2073.0px (789.7143dp)\n"
- )
+ assertDump(dp, "phoneVerticalBar")
}
@Test
@@ -585,136 +70,7 @@
val dp = getDeviceProfileForGrid("6_by_5")
dp.isTaskbarPresentInApps = true
- assertThat(dump(dp))
- .isEqualTo(
- "DeviceProfile:\n" +
- "\t1 dp = 2.0 px\n" +
- "\tisTablet:true\n" +
- "\tisPhone:false\n" +
- "\ttransposeLayoutWithOrientation:false\n" +
- "\tisGestureMode:false\n" +
- "\tisLandscape:true\n" +
- "\tisMultiWindowMode:false\n" +
- "\tisTwoPanels:false\n" +
- "\twindowX: 0.0px (0.0dp)\n" +
- "\twindowY: 0.0px (0.0dp)\n" +
- "\twidthPx: 2560.0px (1280.0dp)\n" +
- "\theightPx: 1600.0px (800.0dp)\n" +
- "\tavailableWidthPx: 2560.0px (1280.0dp)\n" +
- "\tavailableHeightPx: 1496.0px (748.0dp)\n" +
- "\tmInsets.left: 0.0px (0.0dp)\n" +
- "\tmInsets.top: 104.0px (52.0dp)\n" +
- "\tmInsets.right: 0.0px (0.0dp)\n" +
- "\tmInsets.bottom: 0.0px (0.0dp)\n" +
- "\taspectRatio:1.6\n" +
- "\tisResponsiveGrid:false\n" +
- "\tisScalableGrid:true\n" +
- "\tinv.numRows: 5\n" +
- "\tinv.numColumns: 6\n" +
- "\tinv.numSearchContainerColumns: 3\n" +
- "\tminCellSize: PointF(120.0, 104.0)dp\n" +
- "\tcellWidthPx: 240.0px (120.0dp)\n" +
- "\tcellHeightPx: 208.0px (104.0dp)\n" +
- "\tgetCellSize().x: 240.0px (120.0dp)\n" +
- "\tgetCellSize().y: 208.0px (104.0dp)\n" +
- "\tcellLayoutBorderSpacePx Horizontal: 128.0px (64.0dp)\n" +
- "\tcellLayoutBorderSpacePx Vertical: 32.0px (16.0dp)\n" +
- "\tcellLayoutPaddingPx.left: 59.0px (29.5dp)\n" +
- "\tcellLayoutPaddingPx.top: 25.0px (12.5dp)\n" +
- "\tcellLayoutPaddingPx.right: 59.0px (29.5dp)\n" +
- "\tcellLayoutPaddingPx.bottom: 59.0px (29.5dp)\n" +
- "\ticonSizePx: 120.0px (60.0dp)\n" +
- "\ticonTextSizePx: 28.0px (14.0dp)\n" +
- "\ticonDrawablePaddingPx: 9.0px (4.5dp)\n" +
- "\tinv.numFolderRows: 3\n" +
- "\tinv.numFolderColumns: 3\n" +
- "\tfolderCellWidthPx: 240.0px (120.0dp)\n" +
- "\tfolderCellHeightPx: 208.0px (104.0dp)\n" +
- "\tfolderChildIconSizePx: 120.0px (60.0dp)\n" +
- "\tfolderChildTextSizePx: 28.0px (14.0dp)\n" +
- "\tfolderChildDrawablePaddingPx: 11.0px (5.5dp)\n" +
- "\tfolderCellLayoutBorderSpacePx.x: 0.0px (0.0dp)\n" +
- "\tfolderCellLayoutBorderSpacePx.y: 0.0px (0.0dp)\n" +
- "\tfolderContentPaddingLeftRight: 0.0px (0.0dp)\n" +
- "\tfolderTopPadding: 48.0px (24.0dp)\n" +
- "\tfolderFooterHeight: 112.0px (56.0dp)\n" +
- "\tbottomSheetTopPadding: 104.0px (52.0dp)\n" +
- "\tbottomSheetOpenDuration: 500\n" +
- "\tbottomSheetCloseDuration: 500\n" +
- "\tbottomSheetWorkspaceScale: 0.97\n" +
- "\tbottomSheetDepth: 0.0\n" +
- "\tallAppsShiftRange: 1496.0px (748.0dp)\n" +
- "\tallAppsTopPadding: 104.0px (52.0dp)\n" +
- "\tallAppsOpenDuration: 500\n" +
- "\tallAppsCloseDuration: 500\n" +
- "\tallAppsIconSizePx: 120.0px (60.0dp)\n" +
- "\tallAppsIconTextSizePx: 28.0px (14.0dp)\n" +
- "\tallAppsIconDrawablePaddingPx: 9.0px (4.5dp)\n" +
- "\tallAppsCellHeightPx: 284.0px (142.0dp)\n" +
- "\tallAppsCellWidthPx: 252.0px (126.0dp)\n" +
- "\tallAppsBorderSpacePxX: 32.0px (16.0dp)\n" +
- "\tallAppsBorderSpacePxY: 32.0px (16.0dp)\n" +
- "\tnumShownAllAppsColumns: 6\n" +
- "\tallAppsLeftRightPadding: 32.0px (16.0dp)\n" +
- "\tallAppsLeftRightMargin: 412.0px (206.0dp)\n" +
- "\thotseatBarSizePx: 200.0px (100.0dp)\n" +
- "\tinv.hotseatColumnSpan: 4\n" +
- "\thotseatCellHeightPx: 135.0px (67.5dp)\n" +
- "\thotseatBarBottomSpacePx: 80.0px (40.0dp)\n" +
- "\thotseatBarSidePaddingStartPx: 0.0px (0.0dp)\n" +
- "\thotseatBarSidePaddingEndPx: 0.0px (0.0dp)\n" +
- "\thotseatBarEndOffset: 0.0px (0.0dp)\n" +
- "\thotseatQsbSpace: 0.0px (0.0dp)\n" +
- "\thotseatQsbHeight: 0.0px (0.0dp)\n" +
- "\tspringLoadedHotseatBarTopMarginPx: 128.0px (64.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).top: 0.0px (0.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).bottom: 65.0px (32.5dp)\n" +
- "\tgetHotseatLayoutPadding(context).left: 668.0px (334.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).right: 668.0px (334.0dp)\n" +
- "\tnumShownHotseatIcons: 6\n" +
- "\thotseatBorderSpace: 100.0px (50.0dp)\n" +
- "\tisQsbInline: false\n" +
- "\thotseatQsbWidth: 1224.0px (612.0dp)\n" +
- "\tisTaskbarPresent:false\n" +
- "\tisTaskbarPresentInApps:true\n" +
- "\ttaskbarHeight: 0.0px (0.0dp)\n" +
- "\tstashedTaskbarHeight: 0.0px (0.0dp)\n" +
- "\ttaskbarBottomMargin: 0.0px (0.0dp)\n" +
- "\ttaskbarIconSize: 0.0px (0.0dp)\n" +
- "\tdesiredWorkspaceHorizontalMarginPx: 240.0px (120.0dp)\n" +
- "\tworkspacePadding.left: 181.0px (90.5dp)\n" +
- "\tworkspacePadding.top: 0.0px (0.0dp)\n" +
- "\tworkspacePadding.right: 181.0px (90.5dp)\n" +
- "\tworkspacePadding.bottom: 244.0px (122.0dp)\n" +
- "\ticonScale: 1.0px (0.5dp)\n" +
- "\tcellScaleToFit : 1.0px (0.5dp)\n" +
- "\textraSpace: 80.0px (40.0dp)\n" +
- "\tunscaled extraSpace: 80.0px (40.0dp)\n" +
- "\tmaxEmptySpace: 200.0px (100.0dp)\n" +
- "\tworkspaceTopPadding: 25.0px (12.5dp)\n" +
- "\tworkspaceBottomPadding: 55.0px (27.5dp)\n" +
- "\toverviewTaskMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconSizePx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconDrawableSizePx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)\n" +
- "\toverviewTaskThumbnailTopMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewActionsTopMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewActionsHeight: 0.0px (0.0dp)\n" +
- "\toverviewActionsClaimedSpaceBelow: 0.0px (0.0dp)\n" +
- "\toverviewActionsButtonSpacing: 0.0px (0.0dp)\n" +
- "\toverviewPageSpacing: 0.0px (0.0dp)\n" +
- "\toverviewRowSpacing: 0.0px (0.0dp)\n" +
- "\toverviewGridSideMargin: 0.0px (0.0dp)\n" +
- "\tdropTargetBarTopMarginPx: 0.0px (0.0dp)\n" +
- "\tdropTargetBarSizePx: 144.0px (72.0dp)\n" +
- "\tdropTargetBarBottomMarginPx: 64.0px (32.0dp)\n" +
- "\tgetCellLayoutSpringLoadShrunkTop(): 312.0px (156.0dp)\n" +
- "\tgetCellLayoutSpringLoadShrunkBottom(): 1272.0px (636.0dp)\n" +
- "\tworkspaceSpringLoadedMinNextPageVisiblePx: 48.0px (24.0dp)\n" +
- "\tgetWorkspaceSpringLoadScale(): 0.76677316px (0.38338658dp)\n" +
- "\tgetCellLayoutHeight(): 1252.0px (626.0dp)\n" +
- "\tgetCellLayoutWidth(): 2198.0px (1099.0dp)\n"
- )
+ assertDump(dp, "tabletLandscape3Button")
}
@Test
@@ -723,136 +79,7 @@
val dp = getDeviceProfileForGrid("6_by_5")
dp.isTaskbarPresentInApps = true
- assertThat(dump(dp))
- .isEqualTo(
- "DeviceProfile:\n" +
- "\t1 dp = 2.0 px\n" +
- "\tisTablet:true\n" +
- "\tisPhone:false\n" +
- "\ttransposeLayoutWithOrientation:false\n" +
- "\tisGestureMode:true\n" +
- "\tisLandscape:true\n" +
- "\tisMultiWindowMode:false\n" +
- "\tisTwoPanels:false\n" +
- "\twindowX: 0.0px (0.0dp)\n" +
- "\twindowY: 0.0px (0.0dp)\n" +
- "\twidthPx: 2560.0px (1280.0dp)\n" +
- "\theightPx: 1600.0px (800.0dp)\n" +
- "\tavailableWidthPx: 2560.0px (1280.0dp)\n" +
- "\tavailableHeightPx: 1496.0px (748.0dp)\n" +
- "\tmInsets.left: 0.0px (0.0dp)\n" +
- "\tmInsets.top: 104.0px (52.0dp)\n" +
- "\tmInsets.right: 0.0px (0.0dp)\n" +
- "\tmInsets.bottom: 0.0px (0.0dp)\n" +
- "\taspectRatio:1.6\n" +
- "\tisResponsiveGrid:false\n" +
- "\tisScalableGrid:true\n" +
- "\tinv.numRows: 5\n" +
- "\tinv.numColumns: 6\n" +
- "\tinv.numSearchContainerColumns: 3\n" +
- "\tminCellSize: PointF(120.0, 104.0)dp\n" +
- "\tcellWidthPx: 240.0px (120.0dp)\n" +
- "\tcellHeightPx: 208.0px (104.0dp)\n" +
- "\tgetCellSize().x: 240.0px (120.0dp)\n" +
- "\tgetCellSize().y: 208.0px (104.0dp)\n" +
- "\tcellLayoutBorderSpacePx Horizontal: 128.0px (64.0dp)\n" +
- "\tcellLayoutBorderSpacePx Vertical: 32.0px (16.0dp)\n" +
- "\tcellLayoutPaddingPx.left: 59.0px (29.5dp)\n" +
- "\tcellLayoutPaddingPx.top: 25.0px (12.5dp)\n" +
- "\tcellLayoutPaddingPx.right: 59.0px (29.5dp)\n" +
- "\tcellLayoutPaddingPx.bottom: 59.0px (29.5dp)\n" +
- "\ticonSizePx: 120.0px (60.0dp)\n" +
- "\ticonTextSizePx: 28.0px (14.0dp)\n" +
- "\ticonDrawablePaddingPx: 9.0px (4.5dp)\n" +
- "\tinv.numFolderRows: 3\n" +
- "\tinv.numFolderColumns: 3\n" +
- "\tfolderCellWidthPx: 240.0px (120.0dp)\n" +
- "\tfolderCellHeightPx: 208.0px (104.0dp)\n" +
- "\tfolderChildIconSizePx: 120.0px (60.0dp)\n" +
- "\tfolderChildTextSizePx: 28.0px (14.0dp)\n" +
- "\tfolderChildDrawablePaddingPx: 11.0px (5.5dp)\n" +
- "\tfolderCellLayoutBorderSpacePx.x: 0.0px (0.0dp)\n" +
- "\tfolderCellLayoutBorderSpacePx.y: 0.0px (0.0dp)\n" +
- "\tfolderContentPaddingLeftRight: 0.0px (0.0dp)\n" +
- "\tfolderTopPadding: 48.0px (24.0dp)\n" +
- "\tfolderFooterHeight: 112.0px (56.0dp)\n" +
- "\tbottomSheetTopPadding: 104.0px (52.0dp)\n" +
- "\tbottomSheetOpenDuration: 500\n" +
- "\tbottomSheetCloseDuration: 500\n" +
- "\tbottomSheetWorkspaceScale: 0.97\n" +
- "\tbottomSheetDepth: 0.0\n" +
- "\tallAppsShiftRange: 1496.0px (748.0dp)\n" +
- "\tallAppsTopPadding: 104.0px (52.0dp)\n" +
- "\tallAppsOpenDuration: 500\n" +
- "\tallAppsCloseDuration: 500\n" +
- "\tallAppsIconSizePx: 120.0px (60.0dp)\n" +
- "\tallAppsIconTextSizePx: 28.0px (14.0dp)\n" +
- "\tallAppsIconDrawablePaddingPx: 9.0px (4.5dp)\n" +
- "\tallAppsCellHeightPx: 284.0px (142.0dp)\n" +
- "\tallAppsCellWidthPx: 252.0px (126.0dp)\n" +
- "\tallAppsBorderSpacePxX: 32.0px (16.0dp)\n" +
- "\tallAppsBorderSpacePxY: 32.0px (16.0dp)\n" +
- "\tnumShownAllAppsColumns: 6\n" +
- "\tallAppsLeftRightPadding: 32.0px (16.0dp)\n" +
- "\tallAppsLeftRightMargin: 412.0px (206.0dp)\n" +
- "\thotseatBarSizePx: 200.0px (100.0dp)\n" +
- "\tinv.hotseatColumnSpan: 4\n" +
- "\thotseatCellHeightPx: 135.0px (67.5dp)\n" +
- "\thotseatBarBottomSpacePx: 80.0px (40.0dp)\n" +
- "\thotseatBarSidePaddingStartPx: 0.0px (0.0dp)\n" +
- "\thotseatBarSidePaddingEndPx: 0.0px (0.0dp)\n" +
- "\thotseatBarEndOffset: 0.0px (0.0dp)\n" +
- "\thotseatQsbSpace: 0.0px (0.0dp)\n" +
- "\thotseatQsbHeight: 0.0px (0.0dp)\n" +
- "\tspringLoadedHotseatBarTopMarginPx: 128.0px (64.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).top: 0.0px (0.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).bottom: 65.0px (32.5dp)\n" +
- "\tgetHotseatLayoutPadding(context).left: 668.0px (334.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).right: 668.0px (334.0dp)\n" +
- "\tnumShownHotseatIcons: 6\n" +
- "\thotseatBorderSpace: 100.0px (50.0dp)\n" +
- "\tisQsbInline: false\n" +
- "\thotseatQsbWidth: 1224.0px (612.0dp)\n" +
- "\tisTaskbarPresent:false\n" +
- "\tisTaskbarPresentInApps:true\n" +
- "\ttaskbarHeight: 0.0px (0.0dp)\n" +
- "\tstashedTaskbarHeight: 0.0px (0.0dp)\n" +
- "\ttaskbarBottomMargin: 0.0px (0.0dp)\n" +
- "\ttaskbarIconSize: 0.0px (0.0dp)\n" +
- "\tdesiredWorkspaceHorizontalMarginPx: 240.0px (120.0dp)\n" +
- "\tworkspacePadding.left: 181.0px (90.5dp)\n" +
- "\tworkspacePadding.top: 0.0px (0.0dp)\n" +
- "\tworkspacePadding.right: 181.0px (90.5dp)\n" +
- "\tworkspacePadding.bottom: 244.0px (122.0dp)\n" +
- "\ticonScale: 1.0px (0.5dp)\n" +
- "\tcellScaleToFit : 1.0px (0.5dp)\n" +
- "\textraSpace: 80.0px (40.0dp)\n" +
- "\tunscaled extraSpace: 80.0px (40.0dp)\n" +
- "\tmaxEmptySpace: 200.0px (100.0dp)\n" +
- "\tworkspaceTopPadding: 25.0px (12.5dp)\n" +
- "\tworkspaceBottomPadding: 55.0px (27.5dp)\n" +
- "\toverviewTaskMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconSizePx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconDrawableSizePx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)\n" +
- "\toverviewTaskThumbnailTopMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewActionsTopMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewActionsHeight: 0.0px (0.0dp)\n" +
- "\toverviewActionsClaimedSpaceBelow: 0.0px (0.0dp)\n" +
- "\toverviewActionsButtonSpacing: 0.0px (0.0dp)\n" +
- "\toverviewPageSpacing: 0.0px (0.0dp)\n" +
- "\toverviewRowSpacing: 0.0px (0.0dp)\n" +
- "\toverviewGridSideMargin: 0.0px (0.0dp)\n" +
- "\tdropTargetBarTopMarginPx: 0.0px (0.0dp)\n" +
- "\tdropTargetBarSizePx: 144.0px (72.0dp)\n" +
- "\tdropTargetBarBottomMarginPx: 64.0px (32.0dp)\n" +
- "\tgetCellLayoutSpringLoadShrunkTop(): 312.0px (156.0dp)\n" +
- "\tgetCellLayoutSpringLoadShrunkBottom(): 1272.0px (636.0dp)\n" +
- "\tworkspaceSpringLoadedMinNextPageVisiblePx: 48.0px (24.0dp)\n" +
- "\tgetWorkspaceSpringLoadScale(): 0.76677316px (0.38338658dp)\n" +
- "\tgetCellLayoutHeight(): 1252.0px (626.0dp)\n" +
- "\tgetCellLayoutWidth(): 2198.0px (1099.0dp)\n"
- )
+ assertDump(dp, "tabletLandscape")
}
@Test
@@ -861,136 +88,7 @@
val dp = getDeviceProfileForGrid("6_by_5")
dp.isTaskbarPresentInApps = true
- assertThat(dump(dp))
- .isEqualTo(
- "DeviceProfile:\n" +
- "\t1 dp = 2.0 px\n" +
- "\tisTablet:true\n" +
- "\tisPhone:false\n" +
- "\ttransposeLayoutWithOrientation:false\n" +
- "\tisGestureMode:false\n" +
- "\tisLandscape:false\n" +
- "\tisMultiWindowMode:false\n" +
- "\tisTwoPanels:false\n" +
- "\twindowX: 0.0px (0.0dp)\n" +
- "\twindowY: 0.0px (0.0dp)\n" +
- "\twidthPx: 1600.0px (800.0dp)\n" +
- "\theightPx: 2560.0px (1280.0dp)\n" +
- "\tavailableWidthPx: 1600.0px (800.0dp)\n" +
- "\tavailableHeightPx: 2456.0px (1228.0dp)\n" +
- "\tmInsets.left: 0.0px (0.0dp)\n" +
- "\tmInsets.top: 104.0px (52.0dp)\n" +
- "\tmInsets.right: 0.0px (0.0dp)\n" +
- "\tmInsets.bottom: 0.0px (0.0dp)\n" +
- "\taspectRatio:1.6\n" +
- "\tisResponsiveGrid:false\n" +
- "\tisScalableGrid:true\n" +
- "\tinv.numRows: 5\n" +
- "\tinv.numColumns: 6\n" +
- "\tinv.numSearchContainerColumns: 3\n" +
- "\tminCellSize: PointF(102.0, 120.0)dp\n" +
- "\tcellWidthPx: 204.0px (102.0dp)\n" +
- "\tcellHeightPx: 240.0px (120.0dp)\n" +
- "\tgetCellSize().x: 204.0px (102.0dp)\n" +
- "\tgetCellSize().y: 240.0px (120.0dp)\n" +
- "\tcellLayoutBorderSpacePx Horizontal: 32.0px (16.0dp)\n" +
- "\tcellLayoutBorderSpacePx Vertical: 128.0px (64.0dp)\n" +
- "\tcellLayoutPaddingPx.left: 72.0px (36.0dp)\n" +
- "\tcellLayoutPaddingPx.top: 72.0px (36.0dp)\n" +
- "\tcellLayoutPaddingPx.right: 72.0px (36.0dp)\n" +
- "\tcellLayoutPaddingPx.bottom: 72.0px (36.0dp)\n" +
- "\ticonSizePx: 120.0px (60.0dp)\n" +
- "\ticonTextSizePx: 28.0px (14.0dp)\n" +
- "\ticonDrawablePaddingPx: 9.0px (4.5dp)\n" +
- "\tinv.numFolderRows: 3\n" +
- "\tinv.numFolderColumns: 3\n" +
- "\tfolderCellWidthPx: 204.0px (102.0dp)\n" +
- "\tfolderCellHeightPx: 240.0px (120.0dp)\n" +
- "\tfolderChildIconSizePx: 120.0px (60.0dp)\n" +
- "\tfolderChildTextSizePx: 28.0px (14.0dp)\n" +
- "\tfolderChildDrawablePaddingPx: 22.0px (11.0dp)\n" +
- "\tfolderCellLayoutBorderSpacePx.x: 0.0px (0.0dp)\n" +
- "\tfolderCellLayoutBorderSpacePx.y: 0.0px (0.0dp)\n" +
- "\tfolderContentPaddingLeftRight: 0.0px (0.0dp)\n" +
- "\tfolderTopPadding: 48.0px (24.0dp)\n" +
- "\tfolderFooterHeight: 112.0px (56.0dp)\n" +
- "\tbottomSheetTopPadding: 704.0px (352.0dp)\n" +
- "\tbottomSheetOpenDuration: 500\n" +
- "\tbottomSheetCloseDuration: 500\n" +
- "\tbottomSheetWorkspaceScale: 0.97\n" +
- "\tbottomSheetDepth: 0.0\n" +
- "\tallAppsShiftRange: 1810.0px (905.0dp)\n" +
- "\tallAppsTopPadding: 750.0px (375.0dp)\n" +
- "\tallAppsOpenDuration: 500\n" +
- "\tallAppsCloseDuration: 500\n" +
- "\tallAppsIconSizePx: 120.0px (60.0dp)\n" +
- "\tallAppsIconTextSizePx: 28.0px (14.0dp)\n" +
- "\tallAppsIconDrawablePaddingPx: 9.0px (4.5dp)\n" +
- "\tallAppsCellHeightPx: 316.0px (158.0dp)\n" +
- "\tallAppsCellWidthPx: 192.0px (96.0dp)\n" +
- "\tallAppsBorderSpacePxX: 16.0px (8.0dp)\n" +
- "\tallAppsBorderSpacePxY: 32.0px (16.0dp)\n" +
- "\tnumShownAllAppsColumns: 6\n" +
- "\tallAppsLeftRightPadding: 32.0px (16.0dp)\n" +
- "\tallAppsLeftRightMargin: 152.0px (76.0dp)\n" +
- "\thotseatBarSizePx: 272.0px (136.0dp)\n" +
- "\tinv.hotseatColumnSpan: 6\n" +
- "\thotseatCellHeightPx: 135.0px (67.5dp)\n" +
- "\thotseatBarBottomSpacePx: 152.0px (76.0dp)\n" +
- "\thotseatBarSidePaddingStartPx: 0.0px (0.0dp)\n" +
- "\thotseatBarSidePaddingEndPx: 0.0px (0.0dp)\n" +
- "\thotseatBarEndOffset: 0.0px (0.0dp)\n" +
- "\thotseatQsbSpace: 0.0px (0.0dp)\n" +
- "\thotseatQsbHeight: 0.0px (0.0dp)\n" +
- "\tspringLoadedHotseatBarTopMarginPx: 216.0px (108.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).top: 0.0px (0.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).bottom: 137.0px (68.5dp)\n" +
- "\tgetHotseatLayoutPadding(context).left: 150.0px (75.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).right: 150.0px (75.0dp)\n" +
- "\tnumShownHotseatIcons: 6\n" +
- "\thotseatBorderSpace: 116.0px (58.0dp)\n" +
- "\tisQsbInline: false\n" +
- "\thotseatQsbWidth: 1300.0px (650.0dp)\n" +
- "\tisTaskbarPresent:false\n" +
- "\tisTaskbarPresentInApps:true\n" +
- "\ttaskbarHeight: 0.0px (0.0dp)\n" +
- "\tstashedTaskbarHeight: 0.0px (0.0dp)\n" +
- "\ttaskbarBottomMargin: 0.0px (0.0dp)\n" +
- "\ttaskbarIconSize: 0.0px (0.0dp)\n" +
- "\tdesiredWorkspaceHorizontalMarginPx: 108.0px (54.0dp)\n" +
- "\tworkspacePadding.left: 36.0px (18.0dp)\n" +
- "\tworkspacePadding.top: 132.0px (66.0dp)\n" +
- "\tworkspacePadding.right: 36.0px (18.0dp)\n" +
- "\tworkspacePadding.bottom: 468.0px (234.0dp)\n" +
- "\ticonScale: 1.0px (0.5dp)\n" +
- "\tcellScaleToFit : 1.0px (0.5dp)\n" +
- "\textraSpace: 424.0px (212.0dp)\n" +
- "\tunscaled extraSpace: 424.0px (212.0dp)\n" +
- "\tmaxEmptySpace: 19998.0px (9999.0dp)\n" +
- "\tworkspaceTopPadding: 204.0px (102.0dp)\n" +
- "\tworkspaceBottomPadding: 220.0px (110.0dp)\n" +
- "\toverviewTaskMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconSizePx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconDrawableSizePx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)\n" +
- "\toverviewTaskThumbnailTopMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewActionsTopMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewActionsHeight: 0.0px (0.0dp)\n" +
- "\toverviewActionsClaimedSpaceBelow: 0.0px (0.0dp)\n" +
- "\toverviewActionsButtonSpacing: 0.0px (0.0dp)\n" +
- "\toverviewPageSpacing: 0.0px (0.0dp)\n" +
- "\toverviewRowSpacing: 0.0px (0.0dp)\n" +
- "\toverviewGridSideMargin: 0.0px (0.0dp)\n" +
- "\tdropTargetBarTopMarginPx: 220.0px (110.0dp)\n" +
- "\tdropTargetBarSizePx: 144.0px (72.0dp)\n" +
- "\tdropTargetBarBottomMarginPx: 96.0px (48.0dp)\n" +
- "\tgetCellLayoutSpringLoadShrunkTop(): 564.0px (282.0dp)\n" +
- "\tgetCellLayoutSpringLoadShrunkBottom(): 2072.0px (1036.0dp)\n" +
- "\tworkspaceSpringLoadedMinNextPageVisiblePx: 48.0px (24.0dp)\n" +
- "\tgetWorkspaceSpringLoadScale(): 0.8125px (0.40625dp)\n" +
- "\tgetCellLayoutHeight(): 1856.0px (928.0dp)\n" +
- "\tgetCellLayoutWidth(): 1528.0px (764.0dp)\n"
- )
+ assertDump(dp, "tabletPortrait3Button")
}
@Test
@@ -999,136 +97,7 @@
val dp = getDeviceProfileForGrid("6_by_5")
dp.isTaskbarPresentInApps = true
- assertThat(dump(dp))
- .isEqualTo(
- "DeviceProfile:\n" +
- "\t1 dp = 2.0 px\n" +
- "\tisTablet:true\n" +
- "\tisPhone:false\n" +
- "\ttransposeLayoutWithOrientation:false\n" +
- "\tisGestureMode:true\n" +
- "\tisLandscape:false\n" +
- "\tisMultiWindowMode:false\n" +
- "\tisTwoPanels:false\n" +
- "\twindowX: 0.0px (0.0dp)\n" +
- "\twindowY: 0.0px (0.0dp)\n" +
- "\twidthPx: 1600.0px (800.0dp)\n" +
- "\theightPx: 2560.0px (1280.0dp)\n" +
- "\tavailableWidthPx: 1600.0px (800.0dp)\n" +
- "\tavailableHeightPx: 2456.0px (1228.0dp)\n" +
- "\tmInsets.left: 0.0px (0.0dp)\n" +
- "\tmInsets.top: 104.0px (52.0dp)\n" +
- "\tmInsets.right: 0.0px (0.0dp)\n" +
- "\tmInsets.bottom: 0.0px (0.0dp)\n" +
- "\taspectRatio:1.6\n" +
- "\tisResponsiveGrid:false\n" +
- "\tisScalableGrid:true\n" +
- "\tinv.numRows: 5\n" +
- "\tinv.numColumns: 6\n" +
- "\tinv.numSearchContainerColumns: 3\n" +
- "\tminCellSize: PointF(102.0, 120.0)dp\n" +
- "\tcellWidthPx: 204.0px (102.0dp)\n" +
- "\tcellHeightPx: 240.0px (120.0dp)\n" +
- "\tgetCellSize().x: 204.0px (102.0dp)\n" +
- "\tgetCellSize().y: 240.0px (120.0dp)\n" +
- "\tcellLayoutBorderSpacePx Horizontal: 32.0px (16.0dp)\n" +
- "\tcellLayoutBorderSpacePx Vertical: 128.0px (64.0dp)\n" +
- "\tcellLayoutPaddingPx.left: 72.0px (36.0dp)\n" +
- "\tcellLayoutPaddingPx.top: 72.0px (36.0dp)\n" +
- "\tcellLayoutPaddingPx.right: 72.0px (36.0dp)\n" +
- "\tcellLayoutPaddingPx.bottom: 72.0px (36.0dp)\n" +
- "\ticonSizePx: 120.0px (60.0dp)\n" +
- "\ticonTextSizePx: 28.0px (14.0dp)\n" +
- "\ticonDrawablePaddingPx: 9.0px (4.5dp)\n" +
- "\tinv.numFolderRows: 3\n" +
- "\tinv.numFolderColumns: 3\n" +
- "\tfolderCellWidthPx: 204.0px (102.0dp)\n" +
- "\tfolderCellHeightPx: 240.0px (120.0dp)\n" +
- "\tfolderChildIconSizePx: 120.0px (60.0dp)\n" +
- "\tfolderChildTextSizePx: 28.0px (14.0dp)\n" +
- "\tfolderChildDrawablePaddingPx: 22.0px (11.0dp)\n" +
- "\tfolderCellLayoutBorderSpacePx.x: 0.0px (0.0dp)\n" +
- "\tfolderCellLayoutBorderSpacePx.y: 0.0px (0.0dp)\n" +
- "\tfolderContentPaddingLeftRight: 0.0px (0.0dp)\n" +
- "\tfolderTopPadding: 48.0px (24.0dp)\n" +
- "\tfolderFooterHeight: 112.0px (56.0dp)\n" +
- "\tbottomSheetTopPadding: 704.0px (352.0dp)\n" +
- "\tbottomSheetOpenDuration: 500\n" +
- "\tbottomSheetCloseDuration: 500\n" +
- "\tbottomSheetWorkspaceScale: 0.97\n" +
- "\tbottomSheetDepth: 0.0\n" +
- "\tallAppsShiftRange: 1810.0px (905.0dp)\n" +
- "\tallAppsTopPadding: 750.0px (375.0dp)\n" +
- "\tallAppsOpenDuration: 500\n" +
- "\tallAppsCloseDuration: 500\n" +
- "\tallAppsIconSizePx: 120.0px (60.0dp)\n" +
- "\tallAppsIconTextSizePx: 28.0px (14.0dp)\n" +
- "\tallAppsIconDrawablePaddingPx: 9.0px (4.5dp)\n" +
- "\tallAppsCellHeightPx: 316.0px (158.0dp)\n" +
- "\tallAppsCellWidthPx: 192.0px (96.0dp)\n" +
- "\tallAppsBorderSpacePxX: 16.0px (8.0dp)\n" +
- "\tallAppsBorderSpacePxY: 32.0px (16.0dp)\n" +
- "\tnumShownAllAppsColumns: 6\n" +
- "\tallAppsLeftRightPadding: 32.0px (16.0dp)\n" +
- "\tallAppsLeftRightMargin: 152.0px (76.0dp)\n" +
- "\thotseatBarSizePx: 272.0px (136.0dp)\n" +
- "\tinv.hotseatColumnSpan: 6\n" +
- "\thotseatCellHeightPx: 135.0px (67.5dp)\n" +
- "\thotseatBarBottomSpacePx: 152.0px (76.0dp)\n" +
- "\thotseatBarSidePaddingStartPx: 0.0px (0.0dp)\n" +
- "\thotseatBarSidePaddingEndPx: 0.0px (0.0dp)\n" +
- "\thotseatBarEndOffset: 0.0px (0.0dp)\n" +
- "\thotseatQsbSpace: 0.0px (0.0dp)\n" +
- "\thotseatQsbHeight: 0.0px (0.0dp)\n" +
- "\tspringLoadedHotseatBarTopMarginPx: 216.0px (108.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).top: 0.0px (0.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).bottom: 137.0px (68.5dp)\n" +
- "\tgetHotseatLayoutPadding(context).left: 150.0px (75.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).right: 150.0px (75.0dp)\n" +
- "\tnumShownHotseatIcons: 6\n" +
- "\thotseatBorderSpace: 116.0px (58.0dp)\n" +
- "\tisQsbInline: false\n" +
- "\thotseatQsbWidth: 1300.0px (650.0dp)\n" +
- "\tisTaskbarPresent:false\n" +
- "\tisTaskbarPresentInApps:true\n" +
- "\ttaskbarHeight: 0.0px (0.0dp)\n" +
- "\tstashedTaskbarHeight: 0.0px (0.0dp)\n" +
- "\ttaskbarBottomMargin: 0.0px (0.0dp)\n" +
- "\ttaskbarIconSize: 0.0px (0.0dp)\n" +
- "\tdesiredWorkspaceHorizontalMarginPx: 108.0px (54.0dp)\n" +
- "\tworkspacePadding.left: 36.0px (18.0dp)\n" +
- "\tworkspacePadding.top: 132.0px (66.0dp)\n" +
- "\tworkspacePadding.right: 36.0px (18.0dp)\n" +
- "\tworkspacePadding.bottom: 468.0px (234.0dp)\n" +
- "\ticonScale: 1.0px (0.5dp)\n" +
- "\tcellScaleToFit : 1.0px (0.5dp)\n" +
- "\textraSpace: 424.0px (212.0dp)\n" +
- "\tunscaled extraSpace: 424.0px (212.0dp)\n" +
- "\tmaxEmptySpace: 19998.0px (9999.0dp)\n" +
- "\tworkspaceTopPadding: 204.0px (102.0dp)\n" +
- "\tworkspaceBottomPadding: 220.0px (110.0dp)\n" +
- "\toverviewTaskMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconSizePx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconDrawableSizePx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)\n" +
- "\toverviewTaskThumbnailTopMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewActionsTopMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewActionsHeight: 0.0px (0.0dp)\n" +
- "\toverviewActionsClaimedSpaceBelow: 0.0px (0.0dp)\n" +
- "\toverviewActionsButtonSpacing: 0.0px (0.0dp)\n" +
- "\toverviewPageSpacing: 0.0px (0.0dp)\n" +
- "\toverviewRowSpacing: 0.0px (0.0dp)\n" +
- "\toverviewGridSideMargin: 0.0px (0.0dp)\n" +
- "\tdropTargetBarTopMarginPx: 220.0px (110.0dp)\n" +
- "\tdropTargetBarSizePx: 144.0px (72.0dp)\n" +
- "\tdropTargetBarBottomMarginPx: 96.0px (48.0dp)\n" +
- "\tgetCellLayoutSpringLoadShrunkTop(): 564.0px (282.0dp)\n" +
- "\tgetCellLayoutSpringLoadShrunkBottom(): 2072.0px (1036.0dp)\n" +
- "\tworkspaceSpringLoadedMinNextPageVisiblePx: 48.0px (24.0dp)\n" +
- "\tgetWorkspaceSpringLoadScale(): 0.8125px (0.40625dp)\n" +
- "\tgetCellLayoutHeight(): 1856.0px (928.0dp)\n" +
- "\tgetCellLayoutWidth(): 1528.0px (764.0dp)\n"
- )
+ assertDump(dp, "tabletPortrait")
}
@Test
@@ -1142,136 +111,7 @@
val dp = getDeviceProfileForGrid("4_by_4")
dp.isTaskbarPresentInApps = true
- assertThat(dump(dp))
- .isEqualTo(
- "DeviceProfile:\n" +
- "\t1 dp = 2.625 px\n" +
- "\tisTablet:true\n" +
- "\tisPhone:false\n" +
- "\ttransposeLayoutWithOrientation:false\n" +
- "\tisGestureMode:false\n" +
- "\tisLandscape:true\n" +
- "\tisMultiWindowMode:false\n" +
- "\tisTwoPanels:true\n" +
- "\twindowX: 0.0px (0.0dp)\n" +
- "\twindowY: 0.0px (0.0dp)\n" +
- "\twidthPx: 2208.0px (841.1429dp)\n" +
- "\theightPx: 1840.0px (700.9524dp)\n" +
- "\tavailableWidthPx: 2208.0px (841.1429dp)\n" +
- "\tavailableHeightPx: 1730.0px (659.0476dp)\n" +
- "\tmInsets.left: 0.0px (0.0dp)\n" +
- "\tmInsets.top: 110.0px (41.904762dp)\n" +
- "\tmInsets.right: 0.0px (0.0dp)\n" +
- "\tmInsets.bottom: 0.0px (0.0dp)\n" +
- "\taspectRatio:1.2\n" +
- "\tisResponsiveGrid:false\n" +
- "\tisScalableGrid:false\n" +
- "\tinv.numRows: 4\n" +
- "\tinv.numColumns: 4\n" +
- "\tinv.numSearchContainerColumns: 4\n" +
- "\tminCellSize: PointF(0.0, 0.0)dp\n" +
- "\tcellWidthPx: 154.0px (58.666668dp)\n" +
- "\tcellHeightPx: 218.0px (83.04762dp)\n" +
- "\tgetCellSize().x: 270.0px (102.85714dp)\n" +
- "\tgetCellSize().y: 342.0px (130.28572dp)\n" +
- "\tcellLayoutBorderSpacePx Horizontal: 0.0px (0.0dp)\n" +
- "\tcellLayoutBorderSpacePx Vertical: 0.0px (0.0dp)\n" +
- "\tcellLayoutPaddingPx.left: 0.0px (0.0dp)\n" +
- "\tcellLayoutPaddingPx.top: 0.0px (0.0dp)\n" +
- "\tcellLayoutPaddingPx.right: 0.0px (0.0dp)\n" +
- "\tcellLayoutPaddingPx.bottom: 0.0px (0.0dp)\n" +
- "\ticonSizePx: 141.0px (53.714287dp)\n" +
- "\ticonTextSizePx: 34.0px (12.952381dp)\n" +
- "\ticonDrawablePaddingPx: 13.0px (4.952381dp)\n" +
- "\tinv.numFolderRows: 3\n" +
- "\tinv.numFolderColumns: 4\n" +
- "\tfolderCellWidthPx: 189.0px (72.0dp)\n" +
- "\tfolderCellHeightPx: 219.0px (83.42857dp)\n" +
- "\tfolderChildIconSizePx: 141.0px (53.714287dp)\n" +
- "\tfolderChildTextSizePx: 34.0px (12.952381dp)\n" +
- "\tfolderChildDrawablePaddingPx: 5.0px (1.9047619dp)\n" +
- "\tfolderCellLayoutBorderSpacePx.x: 0.0px (0.0dp)\n" +
- "\tfolderCellLayoutBorderSpacePx.y: 0.0px (0.0dp)\n" +
- "\tfolderContentPaddingLeftRight: 21.0px (8.0dp)\n" +
- "\tfolderTopPadding: 63.0px (24.0dp)\n" +
- "\tfolderFooterHeight: 147.0px (56.0dp)\n" +
- "\tbottomSheetTopPadding: 110.0px (41.904762dp)\n" +
- "\tbottomSheetOpenDuration: 500\n" +
- "\tbottomSheetCloseDuration: 500\n" +
- "\tbottomSheetWorkspaceScale: 0.97\n" +
- "\tbottomSheetDepth: 1.0\n" +
- "\tallAppsShiftRange: 1730.0px (659.0476dp)\n" +
- "\tallAppsTopPadding: 110.0px (41.904762dp)\n" +
- "\tallAppsOpenDuration: 500\n" +
- "\tallAppsCloseDuration: 500\n" +
- "\tallAppsIconSizePx: 141.0px (53.714287dp)\n" +
- "\tallAppsIconTextSizePx: 34.0px (12.952381dp)\n" +
- "\tallAppsIconDrawablePaddingPx: 21.0px (8.0dp)\n" +
- "\tallAppsCellHeightPx: 315.0px (120.0dp)\n" +
- "\tallAppsCellWidthPx: 183.0px (69.71429dp)\n" +
- "\tallAppsBorderSpacePxX: 42.0px (16.0dp)\n" +
- "\tallAppsBorderSpacePxY: 42.0px (16.0dp)\n" +
- "\tnumShownAllAppsColumns: 8\n" +
- "\tallAppsLeftRightPadding: 42.0px (16.0dp)\n" +
- "\tallAppsLeftRightMargin: 183.0px (69.71429dp)\n" +
- "\thotseatBarSizePx: 267.0px (101.71429dp)\n" +
- "\tinv.hotseatColumnSpan: 4\n" +
- "\thotseatCellHeightPx: 159.0px (60.57143dp)\n" +
- "\thotseatBarBottomSpacePx: 126.0px (48.0dp)\n" +
- "\thotseatBarSidePaddingStartPx: 0.0px (0.0dp)\n" +
- "\thotseatBarSidePaddingEndPx: 0.0px (0.0dp)\n" +
- "\thotseatBarEndOffset: 0.0px (0.0dp)\n" +
- "\thotseatQsbSpace: 0.0px (0.0dp)\n" +
- "\thotseatQsbHeight: 0.0px (0.0dp)\n" +
- "\tspringLoadedHotseatBarTopMarginPx: 116.0px (44.190475dp)\n" +
- "\tgetHotseatLayoutPadding(context).top: 0.0px (0.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).bottom: 108.0px (41.142857dp)\n" +
- "\tgetHotseatLayoutPadding(context).left: 113.0px (43.04762dp)\n" +
- "\tgetHotseatLayoutPadding(context).right: 113.0px (43.04762dp)\n" +
- "\tnumShownHotseatIcons: 6\n" +
- "\thotseatBorderSpace: 0.0px (0.0dp)\n" +
- "\tisQsbInline: false\n" +
- "\thotseatQsbWidth: 0.0px (0.0dp)\n" +
- "\tisTaskbarPresent:false\n" +
- "\tisTaskbarPresentInApps:true\n" +
- "\ttaskbarHeight: 0.0px (0.0dp)\n" +
- "\tstashedTaskbarHeight: 0.0px (0.0dp)\n" +
- "\ttaskbarBottomMargin: 0.0px (0.0dp)\n" +
- "\ttaskbarIconSize: 0.0px (0.0dp)\n" +
- "\tdesiredWorkspaceHorizontalMarginPx: 21.0px (8.0dp)\n" +
- "\tworkspacePadding.left: 21.0px (8.0dp)\n" +
- "\tworkspacePadding.top: 30.0px (11.428572dp)\n" +
- "\tworkspacePadding.right: 21.0px (8.0dp)\n" +
- "\tworkspacePadding.bottom: 330.0px (125.71429dp)\n" +
- "\ticonScale: 1.0px (0.3809524dp)\n" +
- "\tcellScaleToFit : 1.0px (0.3809524dp)\n" +
- "\textraSpace: 498.0px (189.71428dp)\n" +
- "\tunscaled extraSpace: 498.0px (189.71428dp)\n" +
- "\tmaxEmptySpace: 0.0px (0.0dp)\n" +
- "\tworkspaceTopPadding: 0.0px (0.0dp)\n" +
- "\tworkspaceBottomPadding: 0.0px (0.0dp)\n" +
- "\toverviewTaskMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconSizePx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconDrawableSizePx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)\n" +
- "\toverviewTaskThumbnailTopMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewActionsTopMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewActionsHeight: 0.0px (0.0dp)\n" +
- "\toverviewActionsClaimedSpaceBelow: 0.0px (0.0dp)\n" +
- "\toverviewActionsButtonSpacing: 0.0px (0.0dp)\n" +
- "\toverviewPageSpacing: 0.0px (0.0dp)\n" +
- "\toverviewRowSpacing: 0.0px (0.0dp)\n" +
- "\toverviewGridSideMargin: 0.0px (0.0dp)\n" +
- "\tdropTargetBarTopMarginPx: 0.0px (0.0dp)\n" +
- "\tdropTargetBarSizePx: 147.0px (56.0dp)\n" +
- "\tdropTargetBarBottomMarginPx: 42.0px (16.0dp)\n" +
- "\tgetCellLayoutSpringLoadShrunkTop(): 299.0px (113.90476dp)\n" +
- "\tgetCellLayoutSpringLoadShrunkBottom(): 1457.0px (555.0476dp)\n" +
- "\tworkspaceSpringLoadedMinNextPageVisiblePx: 63.0px (24.0dp)\n" +
- "\tgetWorkspaceSpringLoadScale(): 0.8452555px (0.32200208dp)\n" +
- "\tgetCellLayoutHeight(): 1370.0px (521.9048dp)\n" +
- "\tgetCellLayoutWidth(): 1083.0px (412.57144dp)\n"
- )
+ assertDump(dp, "twoPanelLandscape3Button")
}
@Test
@@ -1284,136 +124,7 @@
val dp = getDeviceProfileForGrid("4_by_4")
dp.isTaskbarPresentInApps = true
- assertThat(dump(dp))
- .isEqualTo(
- "DeviceProfile:\n" +
- "\t1 dp = 2.625 px\n" +
- "\tisTablet:true\n" +
- "\tisPhone:false\n" +
- "\ttransposeLayoutWithOrientation:false\n" +
- "\tisGestureMode:true\n" +
- "\tisLandscape:true\n" +
- "\tisMultiWindowMode:false\n" +
- "\tisTwoPanels:true\n" +
- "\twindowX: 0.0px (0.0dp)\n" +
- "\twindowY: 0.0px (0.0dp)\n" +
- "\twidthPx: 2208.0px (841.1429dp)\n" +
- "\theightPx: 1840.0px (700.9524dp)\n" +
- "\tavailableWidthPx: 2208.0px (841.1429dp)\n" +
- "\tavailableHeightPx: 1730.0px (659.0476dp)\n" +
- "\tmInsets.left: 0.0px (0.0dp)\n" +
- "\tmInsets.top: 110.0px (41.904762dp)\n" +
- "\tmInsets.right: 0.0px (0.0dp)\n" +
- "\tmInsets.bottom: 0.0px (0.0dp)\n" +
- "\taspectRatio:1.2\n" +
- "\tisResponsiveGrid:false\n" +
- "\tisScalableGrid:false\n" +
- "\tinv.numRows: 4\n" +
- "\tinv.numColumns: 4\n" +
- "\tinv.numSearchContainerColumns: 4\n" +
- "\tminCellSize: PointF(0.0, 0.0)dp\n" +
- "\tcellWidthPx: 154.0px (58.666668dp)\n" +
- "\tcellHeightPx: 218.0px (83.04762dp)\n" +
- "\tgetCellSize().x: 270.0px (102.85714dp)\n" +
- "\tgetCellSize().y: 342.0px (130.28572dp)\n" +
- "\tcellLayoutBorderSpacePx Horizontal: 0.0px (0.0dp)\n" +
- "\tcellLayoutBorderSpacePx Vertical: 0.0px (0.0dp)\n" +
- "\tcellLayoutPaddingPx.left: 0.0px (0.0dp)\n" +
- "\tcellLayoutPaddingPx.top: 0.0px (0.0dp)\n" +
- "\tcellLayoutPaddingPx.right: 0.0px (0.0dp)\n" +
- "\tcellLayoutPaddingPx.bottom: 0.0px (0.0dp)\n" +
- "\ticonSizePx: 141.0px (53.714287dp)\n" +
- "\ticonTextSizePx: 34.0px (12.952381dp)\n" +
- "\ticonDrawablePaddingPx: 13.0px (4.952381dp)\n" +
- "\tinv.numFolderRows: 3\n" +
- "\tinv.numFolderColumns: 4\n" +
- "\tfolderCellWidthPx: 189.0px (72.0dp)\n" +
- "\tfolderCellHeightPx: 219.0px (83.42857dp)\n" +
- "\tfolderChildIconSizePx: 141.0px (53.714287dp)\n" +
- "\tfolderChildTextSizePx: 34.0px (12.952381dp)\n" +
- "\tfolderChildDrawablePaddingPx: 5.0px (1.9047619dp)\n" +
- "\tfolderCellLayoutBorderSpacePx.x: 0.0px (0.0dp)\n" +
- "\tfolderCellLayoutBorderSpacePx.y: 0.0px (0.0dp)\n" +
- "\tfolderContentPaddingLeftRight: 21.0px (8.0dp)\n" +
- "\tfolderTopPadding: 63.0px (24.0dp)\n" +
- "\tfolderFooterHeight: 147.0px (56.0dp)\n" +
- "\tbottomSheetTopPadding: 110.0px (41.904762dp)\n" +
- "\tbottomSheetOpenDuration: 500\n" +
- "\tbottomSheetCloseDuration: 500\n" +
- "\tbottomSheetWorkspaceScale: 0.97\n" +
- "\tbottomSheetDepth: 1.0\n" +
- "\tallAppsShiftRange: 1730.0px (659.0476dp)\n" +
- "\tallAppsTopPadding: 110.0px (41.904762dp)\n" +
- "\tallAppsOpenDuration: 500\n" +
- "\tallAppsCloseDuration: 500\n" +
- "\tallAppsIconSizePx: 141.0px (53.714287dp)\n" +
- "\tallAppsIconTextSizePx: 34.0px (12.952381dp)\n" +
- "\tallAppsIconDrawablePaddingPx: 21.0px (8.0dp)\n" +
- "\tallAppsCellHeightPx: 315.0px (120.0dp)\n" +
- "\tallAppsCellWidthPx: 183.0px (69.71429dp)\n" +
- "\tallAppsBorderSpacePxX: 42.0px (16.0dp)\n" +
- "\tallAppsBorderSpacePxY: 42.0px (16.0dp)\n" +
- "\tnumShownAllAppsColumns: 8\n" +
- "\tallAppsLeftRightPadding: 42.0px (16.0dp)\n" +
- "\tallAppsLeftRightMargin: 183.0px (69.71429dp)\n" +
- "\thotseatBarSizePx: 267.0px (101.71429dp)\n" +
- "\tinv.hotseatColumnSpan: 4\n" +
- "\thotseatCellHeightPx: 159.0px (60.57143dp)\n" +
- "\thotseatBarBottomSpacePx: 126.0px (48.0dp)\n" +
- "\thotseatBarSidePaddingStartPx: 0.0px (0.0dp)\n" +
- "\thotseatBarSidePaddingEndPx: 0.0px (0.0dp)\n" +
- "\thotseatBarEndOffset: 0.0px (0.0dp)\n" +
- "\thotseatQsbSpace: 0.0px (0.0dp)\n" +
- "\thotseatQsbHeight: 0.0px (0.0dp)\n" +
- "\tspringLoadedHotseatBarTopMarginPx: 116.0px (44.190475dp)\n" +
- "\tgetHotseatLayoutPadding(context).top: 0.0px (0.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).bottom: 108.0px (41.142857dp)\n" +
- "\tgetHotseatLayoutPadding(context).left: 113.0px (43.04762dp)\n" +
- "\tgetHotseatLayoutPadding(context).right: 113.0px (43.04762dp)\n" +
- "\tnumShownHotseatIcons: 6\n" +
- "\thotseatBorderSpace: 0.0px (0.0dp)\n" +
- "\tisQsbInline: false\n" +
- "\thotseatQsbWidth: 0.0px (0.0dp)\n" +
- "\tisTaskbarPresent:false\n" +
- "\tisTaskbarPresentInApps:true\n" +
- "\ttaskbarHeight: 0.0px (0.0dp)\n" +
- "\tstashedTaskbarHeight: 0.0px (0.0dp)\n" +
- "\ttaskbarBottomMargin: 0.0px (0.0dp)\n" +
- "\ttaskbarIconSize: 0.0px (0.0dp)\n" +
- "\tdesiredWorkspaceHorizontalMarginPx: 21.0px (8.0dp)\n" +
- "\tworkspacePadding.left: 21.0px (8.0dp)\n" +
- "\tworkspacePadding.top: 30.0px (11.428572dp)\n" +
- "\tworkspacePadding.right: 21.0px (8.0dp)\n" +
- "\tworkspacePadding.bottom: 330.0px (125.71429dp)\n" +
- "\ticonScale: 1.0px (0.3809524dp)\n" +
- "\tcellScaleToFit : 1.0px (0.3809524dp)\n" +
- "\textraSpace: 498.0px (189.71428dp)\n" +
- "\tunscaled extraSpace: 498.0px (189.71428dp)\n" +
- "\tmaxEmptySpace: 0.0px (0.0dp)\n" +
- "\tworkspaceTopPadding: 0.0px (0.0dp)\n" +
- "\tworkspaceBottomPadding: 0.0px (0.0dp)\n" +
- "\toverviewTaskMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconSizePx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconDrawableSizePx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)\n" +
- "\toverviewTaskThumbnailTopMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewActionsTopMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewActionsHeight: 0.0px (0.0dp)\n" +
- "\toverviewActionsClaimedSpaceBelow: 0.0px (0.0dp)\n" +
- "\toverviewActionsButtonSpacing: 0.0px (0.0dp)\n" +
- "\toverviewPageSpacing: 0.0px (0.0dp)\n" +
- "\toverviewRowSpacing: 0.0px (0.0dp)\n" +
- "\toverviewGridSideMargin: 0.0px (0.0dp)\n" +
- "\tdropTargetBarTopMarginPx: 0.0px (0.0dp)\n" +
- "\tdropTargetBarSizePx: 147.0px (56.0dp)\n" +
- "\tdropTargetBarBottomMarginPx: 42.0px (16.0dp)\n" +
- "\tgetCellLayoutSpringLoadShrunkTop(): 299.0px (113.90476dp)\n" +
- "\tgetCellLayoutSpringLoadShrunkBottom(): 1457.0px (555.0476dp)\n" +
- "\tworkspaceSpringLoadedMinNextPageVisiblePx: 63.0px (24.0dp)\n" +
- "\tgetWorkspaceSpringLoadScale(): 0.8452555px (0.32200208dp)\n" +
- "\tgetCellLayoutHeight(): 1370.0px (521.9048dp)\n" +
- "\tgetCellLayoutWidth(): 1083.0px (412.57144dp)\n"
- )
+ assertDump(dp, "twoPanelLandscape")
}
@Test
@@ -1426,136 +137,7 @@
val dp = getDeviceProfileForGrid("4_by_4")
dp.isTaskbarPresentInApps = true
- assertThat(dump(dp))
- .isEqualTo(
- "DeviceProfile:\n" +
- "\t1 dp = 2.625 px\n" +
- "\tisTablet:true\n" +
- "\tisPhone:false\n" +
- "\ttransposeLayoutWithOrientation:false\n" +
- "\tisGestureMode:false\n" +
- "\tisLandscape:false\n" +
- "\tisMultiWindowMode:false\n" +
- "\tisTwoPanels:true\n" +
- "\twindowX: 0.0px (0.0dp)\n" +
- "\twindowY: 0.0px (0.0dp)\n" +
- "\twidthPx: 1840.0px (700.9524dp)\n" +
- "\theightPx: 2208.0px (841.1429dp)\n" +
- "\tavailableWidthPx: 1840.0px (700.9524dp)\n" +
- "\tavailableHeightPx: 2075.0px (790.4762dp)\n" +
- "\tmInsets.left: 0.0px (0.0dp)\n" +
- "\tmInsets.top: 133.0px (50.666668dp)\n" +
- "\tmInsets.right: 0.0px (0.0dp)\n" +
- "\tmInsets.bottom: 0.0px (0.0dp)\n" +
- "\taspectRatio:1.2\n" +
- "\tisResponsiveGrid:false\n" +
- "\tisScalableGrid:false\n" +
- "\tinv.numRows: 4\n" +
- "\tinv.numColumns: 4\n" +
- "\tinv.numSearchContainerColumns: 4\n" +
- "\tminCellSize: PointF(0.0, 0.0)dp\n" +
- "\tcellWidthPx: 154.0px (58.666668dp)\n" +
- "\tcellHeightPx: 218.0px (83.04762dp)\n" +
- "\tgetCellSize().x: 224.0px (85.333336dp)\n" +
- "\tgetCellSize().y: 430.0px (163.80952dp)\n" +
- "\tcellLayoutBorderSpacePx Horizontal: 0.0px (0.0dp)\n" +
- "\tcellLayoutBorderSpacePx Vertical: 0.0px (0.0dp)\n" +
- "\tcellLayoutPaddingPx.left: 0.0px (0.0dp)\n" +
- "\tcellLayoutPaddingPx.top: 0.0px (0.0dp)\n" +
- "\tcellLayoutPaddingPx.right: 0.0px (0.0dp)\n" +
- "\tcellLayoutPaddingPx.bottom: 0.0px (0.0dp)\n" +
- "\ticonSizePx: 141.0px (53.714287dp)\n" +
- "\ticonTextSizePx: 34.0px (12.952381dp)\n" +
- "\ticonDrawablePaddingPx: 13.0px (4.952381dp)\n" +
- "\tinv.numFolderRows: 3\n" +
- "\tinv.numFolderColumns: 4\n" +
- "\tfolderCellWidthPx: 189.0px (72.0dp)\n" +
- "\tfolderCellHeightPx: 219.0px (83.42857dp)\n" +
- "\tfolderChildIconSizePx: 141.0px (53.714287dp)\n" +
- "\tfolderChildTextSizePx: 34.0px (12.952381dp)\n" +
- "\tfolderChildDrawablePaddingPx: 5.0px (1.9047619dp)\n" +
- "\tfolderCellLayoutBorderSpacePx.x: 0.0px (0.0dp)\n" +
- "\tfolderCellLayoutBorderSpacePx.y: 0.0px (0.0dp)\n" +
- "\tfolderContentPaddingLeftRight: 21.0px (8.0dp)\n" +
- "\tfolderTopPadding: 63.0px (24.0dp)\n" +
- "\tfolderFooterHeight: 147.0px (56.0dp)\n" +
- "\tbottomSheetTopPadding: 133.0px (50.666668dp)\n" +
- "\tbottomSheetOpenDuration: 500\n" +
- "\tbottomSheetCloseDuration: 500\n" +
- "\tbottomSheetWorkspaceScale: 0.97\n" +
- "\tbottomSheetDepth: 1.0\n" +
- "\tallAppsShiftRange: 1826.0px (695.619dp)\n" +
- "\tallAppsTopPadding: 382.0px (145.5238dp)\n" +
- "\tallAppsOpenDuration: 500\n" +
- "\tallAppsCloseDuration: 500\n" +
- "\tallAppsIconSizePx: 141.0px (53.714287dp)\n" +
- "\tallAppsIconTextSizePx: 34.0px (12.952381dp)\n" +
- "\tallAppsIconDrawablePaddingPx: 21.0px (8.0dp)\n" +
- "\tallAppsCellHeightPx: 315.0px (120.0dp)\n" +
- "\tallAppsCellWidthPx: 183.0px (69.71429dp)\n" +
- "\tallAppsBorderSpacePxX: 42.0px (16.0dp)\n" +
- "\tallAppsBorderSpacePxY: 42.0px (16.0dp)\n" +
- "\tnumShownAllAppsColumns: 8\n" +
- "\tallAppsLeftRightPadding: 42.0px (16.0dp)\n" +
- "\tallAppsLeftRightMargin: 1.0px (0.3809524dp)\n" +
- "\thotseatBarSizePx: 267.0px (101.71429dp)\n" +
- "\tinv.hotseatColumnSpan: 4\n" +
- "\thotseatCellHeightPx: 159.0px (60.57143dp)\n" +
- "\thotseatBarBottomSpacePx: 126.0px (48.0dp)\n" +
- "\thotseatBarSidePaddingStartPx: 0.0px (0.0dp)\n" +
- "\thotseatBarSidePaddingEndPx: 0.0px (0.0dp)\n" +
- "\thotseatBarEndOffset: 0.0px (0.0dp)\n" +
- "\thotseatQsbSpace: 0.0px (0.0dp)\n" +
- "\thotseatQsbHeight: 0.0px (0.0dp)\n" +
- "\tspringLoadedHotseatBarTopMarginPx: 171.0px (65.14286dp)\n" +
- "\tgetHotseatLayoutPadding(context).top: 0.0px (0.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).bottom: 108.0px (41.142857dp)\n" +
- "\tgetHotseatLayoutPadding(context).left: 98.0px (37.333332dp)\n" +
- "\tgetHotseatLayoutPadding(context).right: 98.0px (37.333332dp)\n" +
- "\tnumShownHotseatIcons: 6\n" +
- "\thotseatBorderSpace: 0.0px (0.0dp)\n" +
- "\tisQsbInline: false\n" +
- "\thotseatQsbWidth: 0.0px (0.0dp)\n" +
- "\tisTaskbarPresent:false\n" +
- "\tisTaskbarPresentInApps:true\n" +
- "\ttaskbarHeight: 0.0px (0.0dp)\n" +
- "\tstashedTaskbarHeight: 0.0px (0.0dp)\n" +
- "\ttaskbarBottomMargin: 0.0px (0.0dp)\n" +
- "\ttaskbarIconSize: 0.0px (0.0dp)\n" +
- "\tdesiredWorkspaceHorizontalMarginPx: 21.0px (8.0dp)\n" +
- "\tworkspacePadding.left: 21.0px (8.0dp)\n" +
- "\tworkspacePadding.top: 24.0px (9.142858dp)\n" +
- "\tworkspacePadding.right: 21.0px (8.0dp)\n" +
- "\tworkspacePadding.bottom: 330.0px (125.71429dp)\n" +
- "\ticonScale: 1.0px (0.3809524dp)\n" +
- "\tcellScaleToFit : 1.0px (0.3809524dp)\n" +
- "\textraSpace: 849.0px (323.42856dp)\n" +
- "\tunscaled extraSpace: 849.0px (323.42856dp)\n" +
- "\tmaxEmptySpace: 0.0px (0.0dp)\n" +
- "\tworkspaceTopPadding: 0.0px (0.0dp)\n" +
- "\tworkspaceBottomPadding: 0.0px (0.0dp)\n" +
- "\toverviewTaskMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconSizePx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconDrawableSizePx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)\n" +
- "\toverviewTaskThumbnailTopMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewActionsTopMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewActionsHeight: 0.0px (0.0dp)\n" +
- "\toverviewActionsClaimedSpaceBelow: 0.0px (0.0dp)\n" +
- "\toverviewActionsButtonSpacing: 0.0px (0.0dp)\n" +
- "\toverviewPageSpacing: 0.0px (0.0dp)\n" +
- "\toverviewRowSpacing: 0.0px (0.0dp)\n" +
- "\toverviewGridSideMargin: 0.0px (0.0dp)\n" +
- "\tdropTargetBarTopMarginPx: 168.0px (64.0dp)\n" +
- "\tdropTargetBarSizePx: 147.0px (56.0dp)\n" +
- "\tdropTargetBarBottomMarginPx: 42.0px (16.0dp)\n" +
- "\tgetCellLayoutSpringLoadShrunkTop(): 490.0px (186.66667dp)\n" +
- "\tgetCellLayoutSpringLoadShrunkBottom(): 1770.0px (674.2857dp)\n" +
- "\tworkspaceSpringLoadedMinNextPageVisiblePx: 63.0px (24.0dp)\n" +
- "\tgetWorkspaceSpringLoadScale(): 0.7437536px (0.2833347dp)\n" +
- "\tgetCellLayoutHeight(): 1721.0px (655.619dp)\n" +
- "\tgetCellLayoutWidth(): 899.0px (342.4762dp)\n"
- )
+ assertDump(dp, "twoPanelPortrait3Button")
}
@Test
@@ -1564,147 +146,17 @@
val dp = getDeviceProfileForGrid("4_by_4")
dp.isTaskbarPresentInApps = true
- assertThat(dump(dp))
- .isEqualTo(
- "DeviceProfile:\n" +
- "\t1 dp = 2.625 px\n" +
- "\tisTablet:true\n" +
- "\tisPhone:false\n" +
- "\ttransposeLayoutWithOrientation:false\n" +
- "\tisGestureMode:true\n" +
- "\tisLandscape:false\n" +
- "\tisMultiWindowMode:false\n" +
- "\tisTwoPanels:true\n" +
- "\twindowX: 0.0px (0.0dp)\n" +
- "\twindowY: 0.0px (0.0dp)\n" +
- "\twidthPx: 1840.0px (700.9524dp)\n" +
- "\theightPx: 2208.0px (841.1429dp)\n" +
- "\tavailableWidthPx: 1840.0px (700.9524dp)\n" +
- "\tavailableHeightPx: 2075.0px (790.4762dp)\n" +
- "\tmInsets.left: 0.0px (0.0dp)\n" +
- "\tmInsets.top: 133.0px (50.666668dp)\n" +
- "\tmInsets.right: 0.0px (0.0dp)\n" +
- "\tmInsets.bottom: 0.0px (0.0dp)\n" +
- "\taspectRatio:1.2\n" +
- "\tisResponsiveGrid:false\n" +
- "\tisScalableGrid:false\n" +
- "\tinv.numRows: 4\n" +
- "\tinv.numColumns: 4\n" +
- "\tinv.numSearchContainerColumns: 4\n" +
- "\tminCellSize: PointF(0.0, 0.0)dp\n" +
- "\tcellWidthPx: 154.0px (58.666668dp)\n" +
- "\tcellHeightPx: 218.0px (83.04762dp)\n" +
- "\tgetCellSize().x: 224.0px (85.333336dp)\n" +
- "\tgetCellSize().y: 430.0px (163.80952dp)\n" +
- "\tcellLayoutBorderSpacePx Horizontal: 0.0px (0.0dp)\n" +
- "\tcellLayoutBorderSpacePx Vertical: 0.0px (0.0dp)\n" +
- "\tcellLayoutPaddingPx.left: 0.0px (0.0dp)\n" +
- "\tcellLayoutPaddingPx.top: 0.0px (0.0dp)\n" +
- "\tcellLayoutPaddingPx.right: 0.0px (0.0dp)\n" +
- "\tcellLayoutPaddingPx.bottom: 0.0px (0.0dp)\n" +
- "\ticonSizePx: 141.0px (53.714287dp)\n" +
- "\ticonTextSizePx: 34.0px (12.952381dp)\n" +
- "\ticonDrawablePaddingPx: 13.0px (4.952381dp)\n" +
- "\tinv.numFolderRows: 3\n" +
- "\tinv.numFolderColumns: 4\n" +
- "\tfolderCellWidthPx: 189.0px (72.0dp)\n" +
- "\tfolderCellHeightPx: 219.0px (83.42857dp)\n" +
- "\tfolderChildIconSizePx: 141.0px (53.714287dp)\n" +
- "\tfolderChildTextSizePx: 34.0px (12.952381dp)\n" +
- "\tfolderChildDrawablePaddingPx: 5.0px (1.9047619dp)\n" +
- "\tfolderCellLayoutBorderSpacePx.x: 0.0px (0.0dp)\n" +
- "\tfolderCellLayoutBorderSpacePx.y: 0.0px (0.0dp)\n" +
- "\tfolderContentPaddingLeftRight: 21.0px (8.0dp)\n" +
- "\tfolderTopPadding: 63.0px (24.0dp)\n" +
- "\tfolderFooterHeight: 147.0px (56.0dp)\n" +
- "\tbottomSheetTopPadding: 133.0px (50.666668dp)\n" +
- "\tbottomSheetOpenDuration: 500\n" +
- "\tbottomSheetCloseDuration: 500\n" +
- "\tbottomSheetWorkspaceScale: 0.97\n" +
- "\tbottomSheetDepth: 1.0\n" +
- "\tallAppsShiftRange: 1826.0px (695.619dp)\n" +
- "\tallAppsTopPadding: 382.0px (145.5238dp)\n" +
- "\tallAppsOpenDuration: 500\n" +
- "\tallAppsCloseDuration: 500\n" +
- "\tallAppsIconSizePx: 141.0px (53.714287dp)\n" +
- "\tallAppsIconTextSizePx: 34.0px (12.952381dp)\n" +
- "\tallAppsIconDrawablePaddingPx: 21.0px (8.0dp)\n" +
- "\tallAppsCellHeightPx: 315.0px (120.0dp)\n" +
- "\tallAppsCellWidthPx: 183.0px (69.71429dp)\n" +
- "\tallAppsBorderSpacePxX: 42.0px (16.0dp)\n" +
- "\tallAppsBorderSpacePxY: 42.0px (16.0dp)\n" +
- "\tnumShownAllAppsColumns: 8\n" +
- "\tallAppsLeftRightPadding: 42.0px (16.0dp)\n" +
- "\tallAppsLeftRightMargin: 1.0px (0.3809524dp)\n" +
- "\thotseatBarSizePx: 267.0px (101.71429dp)\n" +
- "\tinv.hotseatColumnSpan: 4\n" +
- "\thotseatCellHeightPx: 159.0px (60.57143dp)\n" +
- "\thotseatBarBottomSpacePx: 126.0px (48.0dp)\n" +
- "\thotseatBarSidePaddingStartPx: 0.0px (0.0dp)\n" +
- "\thotseatBarSidePaddingEndPx: 0.0px (0.0dp)\n" +
- "\thotseatBarEndOffset: 0.0px (0.0dp)\n" +
- "\thotseatQsbSpace: 0.0px (0.0dp)\n" +
- "\thotseatQsbHeight: 0.0px (0.0dp)\n" +
- "\tspringLoadedHotseatBarTopMarginPx: 171.0px (65.14286dp)\n" +
- "\tgetHotseatLayoutPadding(context).top: 0.0px (0.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).bottom: 108.0px (41.142857dp)\n" +
- "\tgetHotseatLayoutPadding(context).left: 98.0px (37.333332dp)\n" +
- "\tgetHotseatLayoutPadding(context).right: 98.0px (37.333332dp)\n" +
- "\tnumShownHotseatIcons: 6\n" +
- "\thotseatBorderSpace: 0.0px (0.0dp)\n" +
- "\tisQsbInline: false\n" +
- "\thotseatQsbWidth: 0.0px (0.0dp)\n" +
- "\tisTaskbarPresent:false\n" +
- "\tisTaskbarPresentInApps:true\n" +
- "\ttaskbarHeight: 0.0px (0.0dp)\n" +
- "\tstashedTaskbarHeight: 0.0px (0.0dp)\n" +
- "\ttaskbarBottomMargin: 0.0px (0.0dp)\n" +
- "\ttaskbarIconSize: 0.0px (0.0dp)\n" +
- "\tdesiredWorkspaceHorizontalMarginPx: 21.0px (8.0dp)\n" +
- "\tworkspacePadding.left: 21.0px (8.0dp)\n" +
- "\tworkspacePadding.top: 24.0px (9.142858dp)\n" +
- "\tworkspacePadding.right: 21.0px (8.0dp)\n" +
- "\tworkspacePadding.bottom: 330.0px (125.71429dp)\n" +
- "\ticonScale: 1.0px (0.3809524dp)\n" +
- "\tcellScaleToFit : 1.0px (0.3809524dp)\n" +
- "\textraSpace: 849.0px (323.42856dp)\n" +
- "\tunscaled extraSpace: 849.0px (323.42856dp)\n" +
- "\tmaxEmptySpace: 0.0px (0.0dp)\n" +
- "\tworkspaceTopPadding: 0.0px (0.0dp)\n" +
- "\tworkspaceBottomPadding: 0.0px (0.0dp)\n" +
- "\toverviewTaskMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconSizePx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconDrawableSizePx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)\n" +
- "\toverviewTaskThumbnailTopMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewActionsTopMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewActionsHeight: 0.0px (0.0dp)\n" +
- "\toverviewActionsClaimedSpaceBelow: 0.0px (0.0dp)\n" +
- "\toverviewActionsButtonSpacing: 0.0px (0.0dp)\n" +
- "\toverviewPageSpacing: 0.0px (0.0dp)\n" +
- "\toverviewRowSpacing: 0.0px (0.0dp)\n" +
- "\toverviewGridSideMargin: 0.0px (0.0dp)\n" +
- "\tdropTargetBarTopMarginPx: 168.0px (64.0dp)\n" +
- "\tdropTargetBarSizePx: 147.0px (56.0dp)\n" +
- "\tdropTargetBarBottomMarginPx: 42.0px (16.0dp)\n" +
- "\tgetCellLayoutSpringLoadShrunkTop(): 490.0px (186.66667dp)\n" +
- "\tgetCellLayoutSpringLoadShrunkBottom(): 1770.0px (674.2857dp)\n" +
- "\tworkspaceSpringLoadedMinNextPageVisiblePx: 63.0px (24.0dp)\n" +
- "\tgetWorkspaceSpringLoadScale(): 0.7437536px (0.2833347dp)\n" +
- "\tgetCellLayoutHeight(): 1721.0px (655.619dp)\n" +
- "\tgetCellLayoutWidth(): 899.0px (342.4762dp)\n"
- )
+ assertDump(dp, "twoPanelPortrait")
}
private fun getDeviceProfileForGrid(gridName: String): DeviceProfile {
return InvariantDeviceProfile(context, gridName).getDeviceProfile(context)
}
- private fun dump(dp: DeviceProfile): String {
- val stringWriter = StringWriter()
- val printWriter = PrintWriter(stringWriter)
- dp.dump(context, "", printWriter)
- printWriter.flush()
- return stringWriter.toString()
+ private fun assertDump(dp: DeviceProfile, filename: String) {
+ val dump = dump(context!!, dp, "${folderName}_$filename.txt")
+ val expected = readDumpFromAssets(testContext, "$folderName/$filename.txt")
+
+ assertThat(dump).isEqualTo(expected)
}
}
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/responsive/CalculatedHotseatSpecTest.kt b/tests/src/com/android/launcher3/responsive/CalculatedHotseatSpecTest.kt
index 0ecf7ba..5865036 100644
--- a/tests/src/com/android/launcher3/responsive/CalculatedHotseatSpecTest.kt
+++ b/tests/src/com/android/launcher3/responsive/CalculatedHotseatSpecTest.kt
@@ -50,6 +50,7 @@
assertThat(heightSpec.availableSpace).isEqualTo(availableHeight)
assertThat(heightSpec.hotseatQsbSpace).isEqualTo(95)
+ assertThat(heightSpec.edgePadding).isEqualTo(126)
}
/**
@@ -71,5 +72,27 @@
assertThat(heightSpec.availableSpace).isEqualTo(availableHeight)
assertThat(heightSpec.hotseatQsbSpace).isEqualTo(81)
+ assertThat(heightSpec.edgePadding).isEqualTo(162)
+ }
+
+ /**
+ * This test tests:
+ * - (width spec) gets the correct breakpoint from the XML - skips the first breakpoint
+ */
+ @Test
+ fun normalPhoneLandscape_returnsSecondBreakpointSpec() {
+ val deviceSpec = deviceSpecs["phone"]!!
+ initializeVarsForPhone(deviceSpec, isVerticalBar = true)
+
+ // Hotseat uses the whole device width
+ val availableWidth = deviceSpec.naturalSize.second
+
+ val hotseatSpecs =
+ HotseatSpecs.create(TestResourceHelper(context!!, TestR.xml.valid_hotseat_land_file))
+ val widthSpec = hotseatSpecs.getCalculatedWidthSpec(availableWidth)
+
+ assertThat(widthSpec.availableSpace).isEqualTo(availableWidth)
+ assertThat(widthSpec.hotseatQsbSpace).isEqualTo(0)
+ assertThat(widthSpec.edgePadding).isEqualTo(168)
}
}
diff --git a/tests/src/com/android/launcher3/responsive/HotseatSpecsTest.kt b/tests/src/com/android/launcher3/responsive/HotseatSpecsTest.kt
index c764e47..f650e91 100644
--- a/tests/src/com/android/launcher3/responsive/HotseatSpecsTest.kt
+++ b/tests/src/com/android/launcher3/responsive/HotseatSpecsTest.kt
@@ -23,7 +23,6 @@
import com.android.launcher3.AbstractDeviceProfileTest
import com.android.launcher3.tests.R as TestR
import com.android.launcher3.util.TestResourceHelper
-import com.android.systemui.util.dpToPx
import com.google.common.truth.Truth.assertThat
import org.junit.Before
import org.junit.Test
@@ -43,25 +42,55 @@
fun parseValidFile() {
val hotseatSpecs =
HotseatSpecs.create(TestResourceHelper(context!!, TestR.xml.valid_hotseat_file))
- assertThat(hotseatSpecs.specs.size).isEqualTo(2)
- val expectedSpecs =
+ val expectedHeightSpecs =
listOf(
HotseatSpec(
maxAvailableSize = 847.dpToPx(),
specType = ResponsiveSpec.SpecType.HEIGHT,
- hotseatQsbSpace = SizeSpec(24f.dpToPx())
+ hotseatQsbSpace = SizeSpec(24f.dpToPx()),
+ edgePadding = SizeSpec(48f.dpToPx())
),
HotseatSpec(
maxAvailableSize = 9999.dpToPx(),
specType = ResponsiveSpec.SpecType.HEIGHT,
- hotseatQsbSpace = SizeSpec(36f.dpToPx())
+ hotseatQsbSpace = SizeSpec(36f.dpToPx()),
+ edgePadding = SizeSpec(48f.dpToPx())
),
)
- assertThat(hotseatSpecs.specs.size).isEqualTo(expectedSpecs.size)
- assertThat(hotseatSpecs.specs[0]).isEqualTo(expectedSpecs[0])
- assertThat(hotseatSpecs.specs[1]).isEqualTo(expectedSpecs[1])
+ assertThat(hotseatSpecs.heightSpecs.size).isEqualTo(expectedHeightSpecs.size)
+ assertThat(hotseatSpecs.heightSpecs[0]).isEqualTo(expectedHeightSpecs[0])
+ assertThat(hotseatSpecs.heightSpecs[1]).isEqualTo(expectedHeightSpecs[1])
+
+ assertThat(hotseatSpecs.widthSpecs.size).isEqualTo(0)
+ }
+
+ @Test
+ fun parseValidLandscapeFile() {
+ val hotseatSpecs =
+ HotseatSpecs.create(TestResourceHelper(context!!, TestR.xml.valid_hotseat_land_file))
+ assertThat(hotseatSpecs.heightSpecs.size).isEqualTo(0)
+
+ val expectedWidthSpecs =
+ listOf(
+ HotseatSpec(
+ maxAvailableSize = 743.dpToPx(),
+ specType = ResponsiveSpec.SpecType.WIDTH,
+ hotseatQsbSpace = SizeSpec(0f),
+ edgePadding = SizeSpec(48f.dpToPx())
+ ),
+ HotseatSpec(
+ maxAvailableSize = 9999.dpToPx(),
+ specType = ResponsiveSpec.SpecType.WIDTH,
+ hotseatQsbSpace = SizeSpec(0f),
+ edgePadding = SizeSpec(64f.dpToPx())
+ ),
+ )
+
+ assertThat(hotseatSpecs.widthSpecs.size).isEqualTo(expectedWidthSpecs.size)
+ assertThat(hotseatSpecs.widthSpecs[0]).isEqualTo(expectedWidthSpecs[0])
+ assertThat(hotseatSpecs.widthSpecs[1]).isEqualTo(expectedWidthSpecs[1])
}
@Test(expected = IllegalStateException::class)
diff --git a/tests/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncherTest.java b/tests/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncherTest.java
index 7e9d9da..c7431f2 100644
--- a/tests/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncherTest.java
+++ b/tests/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncherTest.java
@@ -184,7 +184,7 @@
mStartPoint = icon.getVisibleCenter();
mEndPoint = new Point(mStartPoint.x, mStartPoint.y);
mLauncher.sendPointer(mDownTime, mDownTime, ACTION_DOWN, mStartPoint,
- LauncherInstrumentation.GestureScope.INSIDE);
+ LauncherInstrumentation.GestureScope.DONT_EXPECT_PILFER);
assertThat(findObjectByResourceName("popup_container")).isNotNull();
return appName;
}
@@ -206,7 +206,7 @@
mStartPoint = icon.getVisibleCenter();
mEndPoint = new Point(mStartPoint.x, mStartPoint.y);
mLauncher.sendPointer(mDownTime, mDownTime, ACTION_DOWN, mStartPoint,
- LauncherInstrumentation.GestureScope.INSIDE);
+ LauncherInstrumentation.GestureScope.DONT_EXPECT_PILFER);
assertThat(findObjectByResourceName("popup_container")).isNotNull();
return appName;
}
@@ -214,12 +214,12 @@
private void moveAppToCenterOfScreen() {
mEndPoint.set(mDevice.getDisplayWidth() / 2, mDevice.getDisplayHeight() / 2);
mLauncher.movePointer(mDownTime, SystemClock.uptimeMillis(), DRAG_TIME_MS, true,
- mStartPoint, mEndPoint, LauncherInstrumentation.GestureScope.INSIDE);
+ mStartPoint, mEndPoint, LauncherInstrumentation.GestureScope.DONT_EXPECT_PILFER);
}
private void dropApp() {
mLauncher.sendPointer(mDownTime, SystemClock.uptimeMillis(), MotionEvent.ACTION_UP,
- mEndPoint, LauncherInstrumentation.GestureScope.INSIDE);
+ mEndPoint, LauncherInstrumentation.GestureScope.DONT_EXPECT_PILFER);
}
private void removeAppByName(String appName) {
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/PortraitLandscapeRunner.java b/tests/src/com/android/launcher3/ui/PortraitLandscapeRunner.java
index f0875f8..ad11268 100644
--- a/tests/src/com/android/launcher3/ui/PortraitLandscapeRunner.java
+++ b/tests/src/com/android/launcher3/ui/PortraitLandscapeRunner.java
@@ -1,9 +1,12 @@
package com.android.launcher3.ui;
+import static com.android.launcher3.util.rule.TestStabilityRule.PLATFORM_PRESUBMIT;
+
import android.util.Log;
import android.view.Surface;
import com.android.launcher3.tapl.TestHelpers;
+import com.android.launcher3.util.rule.TestStabilityRule;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
@@ -30,8 +33,12 @@
@Override
public Statement apply(Statement base, Description description) {
- if (!TestHelpers.isInLauncherProcess() ||
- description.getAnnotation(PortraitLandscape.class) == null) {
+ if (!TestHelpers.isInLauncherProcess()
+ || description.getAnnotation(PortraitLandscape.class) == null
+ // If running in presubmit, don't run in both orientations.
+ // It's important to keep presubmits fast even if we will occasionally miss
+ // regressions in presubmit.
+ || TestStabilityRule.getRunFlavor() == PLATFORM_PRESUBMIT) {
return base;
}
diff --git a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
index c462f59..0316f84 100644
--- a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
+++ b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
@@ -29,7 +29,6 @@
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeFalse;
-import static org.junit.Assume.assumeTrue;
import android.content.Intent;
import android.graphics.Point;
@@ -157,107 +156,6 @@
mLauncher.goHome();
}
- @Test
- public void testPressHomeOnAllAppsContextMenu() throws Exception {
- final AllApps allApps = mLauncher.getWorkspace().switchToAllApps();
- allApps.freeze();
- try {
- allApps.getAppIcon("TestActivity7").openMenu();
- } finally {
- allApps.unfreeze();
- }
- mLauncher.goHome();
- }
-
- public static void runAllAppsTest(AbstractLauncherUiTest test, AllApps allApps) {
- allApps.freeze();
- try {
- assertNotNull("allApps parameter is null", allApps);
-
- assertTrue(
- "Launcher internal state is not All Apps",
- test.isInState(() -> LauncherState.ALL_APPS));
-
- // Test flinging forward and backward.
- test.executeOnLauncher(launcher -> assertEquals(
- "All Apps started in already scrolled state", 0,
- test.getAllAppsScroll(launcher)));
-
- allApps.flingForward();
- assertTrue("Launcher internal state is not All Apps",
- test.isInState(() -> LauncherState.ALL_APPS));
- final Integer flingForwardY = test.getFromLauncher(
- launcher -> test.getAllAppsScroll(launcher));
- test.executeOnLauncher(
- launcher -> assertTrue("flingForward() didn't scroll App Apps",
- flingForwardY > 0));
-
- allApps.flingBackward();
- assertTrue(
- "Launcher internal state is not All Apps",
- test.isInState(() -> LauncherState.ALL_APPS));
- final Integer flingBackwardY = test.getFromLauncher(
- launcher -> test.getAllAppsScroll(launcher));
- test.executeOnLauncher(launcher -> assertTrue("flingBackward() didn't scroll App Apps",
- flingBackwardY < flingForwardY));
-
- // Test scrolling down to YouTube.
- assertNotNull("All apps: can't find YouTube", allApps.getAppIcon("YouTube"));
- // Test scrolling up to Camera.
- assertNotNull("All apps: can't find Camera", allApps.getAppIcon("Camera"));
- // Test failing to find a non-existing app.
- final AllApps allAppsFinal = allApps;
- expectFail("All apps: could find a non-existing app",
- () -> allAppsFinal.getAppIcon("NO APP"));
-
- assertTrue(
- "Launcher internal state is not All Apps",
- test.isInState(() -> LauncherState.ALL_APPS));
- } finally {
- allApps.unfreeze();
- }
- }
-
- @Test
- @PortraitLandscape
- public void testWorkspaceSwitchToAllApps() {
- assertNotNull("switchToAllApps() returned null",
- mLauncher.getWorkspace().switchToAllApps());
- assertTrue("Launcher internal state is not All Apps",
- isInState(() -> LauncherState.ALL_APPS));
- }
-
- @Test
- @PortraitLandscape
- public void testAllAppsSwitchToWorkspace() {
- assertNotNull("switchToWorkspace() returned null",
- mLauncher.getWorkspace().switchToAllApps()
- .switchToWorkspace(/* swipeDown= */ true));
- assertTrue("Launcher internal state is not Workspace",
- isInState(() -> LauncherState.NORMAL));
- }
-
- @Test
- @PortraitLandscape
- public void testAllAppsSwipeUpToWorkspace() {
- assertNotNull("testAllAppsSwipeUpToWorkspace() returned null",
- mLauncher.getWorkspace().switchToAllApps()
- .switchToWorkspace(/* swipeDown= */ false));
- assertTrue("Launcher internal state is not Workspace",
- isInState(() -> LauncherState.NORMAL));
- }
-
- @Test
- @PortraitLandscape
- public void testAllAppsDeadzoneForTablet() throws Exception {
- assumeTrue(mLauncher.isTablet());
-
- mLauncher.getWorkspace().switchToAllApps().dismissByTappingOutsideForTablet(
- true /* tapRight */);
- mLauncher.getWorkspace().switchToAllApps().dismissByTappingOutsideForTablet(
- false /* tapRight */);
- }
-
@PlatinumTest(focusArea = "launcher")
@Test
public void testWorkspace() throws Exception {
@@ -622,7 +520,6 @@
* Adds three icons to the workspace and removes one of them by dragging to uninstall.
*/
@Test
- @ScreenRecord // b/241821721
@PlatinumTest(focusArea = "launcher")
public void uninstallWorkspaceIcon() throws IOException {
Point[] gridPositions = getCornersAndCenterPositions();
@@ -645,10 +542,6 @@
mLauncher.getWorkspace().verifyWorkspaceAppIconIsGone(
DUMMY_APP_NAME + " was expected to disappear after uninstall.", DUMMY_APP_NAME);
- // Debug for b/288944469 I want to test if we are not waiting enough after removing
- // the icon to request the list of icons again, since the items are not removed
- // immediately. This should reduce the flake rate
- SystemClock.sleep(500);
Map<String, Point> finalPositions =
mLauncher.getWorkspace().getWorkspaceIconsPositions();
assertThat(finalPositions).doesNotContainKey(DUMMY_APP_NAME);
@@ -734,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/WorkProfileTest.java b/tests/src/com/android/launcher3/ui/WorkProfileTest.java
index 5b9adcd..ac710fd 100644
--- a/tests/src/com/android/launcher3/ui/WorkProfileTest.java
+++ b/tests/src/com/android/launcher3/ui/WorkProfileTest.java
@@ -19,8 +19,6 @@
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.allapps.AllAppsStore.DEFER_UPDATES_TEST;
import static com.android.launcher3.util.TestUtil.installDummyAppForUser;
-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.assertTrue;
@@ -39,7 +37,6 @@
import com.android.launcher3.allapps.WorkProfileManager;
import com.android.launcher3.tapl.LauncherInstrumentation;
import com.android.launcher3.util.TestUtil;
-import com.android.launcher3.util.rule.TestStabilityRule.Stability;
import org.junit.After;
import org.junit.Before;
@@ -103,8 +100,6 @@
}
private void waitForWorkTabSetup() {
- // Added for b/243688989 flake to determine if we really are in allApps or not at this point
- mLauncher.getAllApps();
waitForLauncherCondition("Work tab not setup", launcher -> {
if (launcher.getAppsView().getContentView() instanceof AllAppsPagedView) {
launcher.getAppsView().getAppsStore().enableDeferUpdates(DEFER_UPDATES_TEST);
@@ -115,7 +110,6 @@
}
@Test
- @Stability(flavors = LOCAL | PLATFORM_POSTSUBMIT) // b/243688989
public void workTabExists() {
assumeTrue(mWorkProfileSetupSuccessful);
waitForWorkTabSetup();
@@ -176,7 +170,6 @@
}
@Test
- @Stability(flavors = LOCAL | PLATFORM_POSTSUBMIT) // b/243688989
public void testEdu() {
assumeTrue(mWorkProfileSetupSuccessful);
waitForWorkTabSetup();
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/widget/RequestPinItemTest.java b/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java
index a6b5369..5c753f9 100644
--- a/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java
+++ b/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java
@@ -48,7 +48,6 @@
import com.android.launcher3.util.LauncherBindableItemsContainer.ItemOperator;
import com.android.launcher3.util.Wait;
import com.android.launcher3.util.Wait.Condition;
-import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord;
import com.android.launcher3.util.rule.ShellCommandRule;
import org.junit.Before;
@@ -85,7 +84,6 @@
public void testEmpty() throws Throwable { /* needed while the broken tests are being fixed */ }
@Test
- @ScreenRecord // b/215673732
public void testPinWidgetNoConfig() throws Throwable {
runTest("pinWidgetNoConfig", true, (info, view) -> info instanceof LauncherAppWidgetInfo &&
((LauncherAppWidgetInfo) info).appWidgetId == mAppWidgetId &&
@@ -94,7 +92,6 @@
}
@Test
- @ScreenRecord // b/215673732
public void testPinWidgetNoConfig_customPreview() throws Throwable {
// Command to set custom preview
Intent command = RequestPinItemActivity.getCommandIntent(
@@ -108,7 +105,6 @@
}
@Test
- @ScreenRecord // b/215673732
public void testPinWidgetWithConfig() throws Throwable {
runTest("pinWidgetWithConfig", true,
(info, view) -> info instanceof LauncherAppWidgetInfo &&
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/FailureWatcher.java b/tests/src/com/android/launcher3/util/rule/FailureWatcher.java
index f2ae9d3..62d70ad 100644
--- a/tests/src/com/android/launcher3/util/rule/FailureWatcher.java
+++ b/tests/src/com/android/launcher3/util/rule/FailureWatcher.java
@@ -103,7 +103,8 @@
if (viewCaptureDataSupplier != null) {
out.putNextEntry(new ZipEntry("FS/data/misc/wmtrace/failed_test.vc"));
- viewCaptureDataSupplier.get().writeTo(out);
+ final ExportedData exportedData = viewCaptureDataSupplier.get();
+ if (exportedData != null) exportedData.writeTo(out);
out.closeEntry();
}
} catch (Exception ignored) {
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/src/com/android/launcher3/util/rule/ViewCaptureRule.kt b/tests/src/com/android/launcher3/util/rule/ViewCaptureRule.kt
index 0f08eef..ccbae4f 100644
--- a/tests/src/com/android/launcher3/util/rule/ViewCaptureRule.kt
+++ b/tests/src/com/android/launcher3/util/rule/ViewCaptureRule.kt
@@ -20,6 +20,7 @@
import android.media.permission.SafeCloseable
import android.os.Bundle
import androidx.test.core.app.ApplicationProvider
+import androidx.test.platform.app.InstrumentationRegistry
import com.android.app.viewcapture.SimpleViewCapture
import com.android.app.viewcapture.ViewCapture.MAIN_EXECUTOR
import com.android.app.viewcapture.data.ExportedData
@@ -50,6 +51,13 @@
private set
override fun apply(base: Statement, description: Description): Statement {
+ // Skip view capture collection in Launcher3 tests to avoid hidden API check exception.
+ if (
+ "com.android.launcher3.tests" ==
+ InstrumentationRegistry.getInstrumentation().context.packageName
+ )
+ return base
+
return object : Statement() {
override fun evaluate() {
viewCaptureData = null
diff --git a/tests/tapl/com/android/launcher3/tapl/AddToHomeScreenPrompt.java b/tests/tapl/com/android/launcher3/tapl/AddToHomeScreenPrompt.java
index 10afe13..425c3c0 100644
--- a/tests/tapl/com/android/launcher3/tapl/AddToHomeScreenPrompt.java
+++ b/tests/tapl/com/android/launcher3/tapl/AddToHomeScreenPrompt.java
@@ -45,8 +45,8 @@
mLauncher.clickObject(
mLauncher.waitForObjectInContainer(
mWidgetCell.getParent().getParent().getParent().getParent(),
- By.text(ADD_AUTOMATICALLY)),
- LauncherInstrumentation.GestureScope.OUTSIDE_WITHOUT_PILFER);
+ By.text(ADD_AUTOMATICALLY))
+ );
mLauncher.waitUntilLauncherObjectGone(getSelector());
}
}
diff --git a/tests/tapl/com/android/launcher3/tapl/Background.java b/tests/tapl/com/android/launcher3/tapl/Background.java
index ebcca00..677f204 100644
--- a/tests/tapl/com/android/launcher3/tapl/Background.java
+++ b/tests/tapl/com/android/launcher3/tapl/Background.java
@@ -66,10 +66,6 @@
}
- protected boolean zeroButtonToOverviewGestureStartsInLauncher() {
- return mLauncher.isTablet();
- }
-
protected boolean zeroButtonToOverviewGestureStateTransitionWhileHolding() {
return false;
}
@@ -146,12 +142,9 @@
final int centerX = mLauncher.getDevice().getDisplayWidth() / 2;
final int startY = getSwipeStartY();
final Point start = new Point(centerX, startY);
- final LauncherInstrumentation.GestureScope gestureScope =
- zeroButtonToOverviewGestureStartsInLauncher()
- ? LauncherInstrumentation.GestureScope.INSIDE_TO_OUTSIDE
- : LauncherInstrumentation.GestureScope.OUTSIDE_WITH_PILFER;
- mLauncher.sendPointer(downTime, downTime, MotionEvent.ACTION_DOWN, start, gestureScope);
+ mLauncher.sendPointer(downTime, downTime, MotionEvent.ACTION_DOWN, start,
+ LauncherInstrumentation.GestureScope.EXPECT_PILFER);
if (!mLauncher.isLauncher3()) {
mLauncher.expectEvent(TestProtocol.SEQUENCE_PILFER,
@@ -167,10 +160,6 @@
final Point start = new Point(centerX, startY);
final Point end =
new Point(centerX, startY - swipeHeight - mLauncher.getTouchSlop());
- final LauncherInstrumentation.GestureScope gestureScope =
- zeroButtonToOverviewGestureStartsInLauncher()
- ? LauncherInstrumentation.GestureScope.INSIDE_TO_OUTSIDE
- : LauncherInstrumentation.GestureScope.OUTSIDE_WITH_PILFER;
mLauncher.movePointer(
downTime,
@@ -178,7 +167,7 @@
ZERO_BUTTON_SWIPE_UP_GESTURE_DURATION,
start,
end,
- gestureScope);
+ LauncherInstrumentation.GestureScope.EXPECT_PILFER);
}
private void sendUpPointerToEnterOverviewToLauncher(long downTime) {
@@ -189,13 +178,9 @@
final Point end =
new Point(centerX, startY - swipeHeight - mLauncher.getTouchSlop());
- final LauncherInstrumentation.GestureScope gestureScope =
- zeroButtonToOverviewGestureStartsInLauncher()
- ? LauncherInstrumentation.GestureScope.INSIDE
- : LauncherInstrumentation.GestureScope.OUTSIDE_WITHOUT_PILFER;
-
mLauncher.sendPointer(downTime, SystemClock.uptimeMillis(),
- MotionEvent.ACTION_UP, end, gestureScope);
+ MotionEvent.ACTION_UP, end,
+ LauncherInstrumentation.GestureScope.DONT_EXPECT_PILFER);
}
/**
@@ -227,7 +212,6 @@
LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
"want to quick switch to the previous app")) {
verifyActiveContainer();
- final boolean launcherWasVisible = mLauncher.isLauncherVisible();
if (mLauncher.getNavigationModel() == NavigationModel.ZERO_BUTTON
|| mLauncher.getTrackpadGestureType() == TrackpadGestureType.FOUR_FINGER) {
final int startX;
@@ -249,13 +233,10 @@
endY = startY;
}
- LauncherInstrumentation.GestureScope gestureScope =
- launcherWasVisible
- ? LauncherInstrumentation.GestureScope.INSIDE_TO_OUTSIDE
- : LauncherInstrumentation.GestureScope.OUTSIDE_WITH_PILFER;
mLauncher.executeAndWaitForEvent(
() -> mLauncher.linearGesture(
- startX, startY, endX, endY, 20, false, gestureScope),
+ startX, startY, endX, endY, 20, false,
+ LauncherInstrumentation.GestureScope.EXPECT_PILFER),
event -> event.getEventType() == TYPE_WINDOW_STATE_CHANGED,
() -> "Quick switch gesture didn't change window state", "swiping");
} else {
diff --git a/tests/tapl/com/android/launcher3/tapl/Home.java b/tests/tapl/com/android/launcher3/tapl/Home.java
index ee9dd1a..252435b 100644
--- a/tests/tapl/com/android/launcher3/tapl/Home.java
+++ b/tests/tapl/com/android/launcher3/tapl/Home.java
@@ -59,11 +59,6 @@
}
@Override
- protected boolean zeroButtonToOverviewGestureStartsInLauncher() {
- return true;
- }
-
- @Override
protected boolean zeroButtonToOverviewGestureStateTransitionWhileHolding() {
return true;
}
diff --git a/tests/tapl/com/android/launcher3/tapl/HomeAllApps.java b/tests/tapl/com/android/launcher3/tapl/HomeAllApps.java
index 33c6334..2951901 100644
--- a/tests/tapl/com/android/launcher3/tapl/HomeAllApps.java
+++ b/tests/tapl/com/android/launcher3/tapl/HomeAllApps.java
@@ -60,8 +60,8 @@
endY,
5 /* steps */,
NORMAL_STATE_ORDINAL,
- swipeDown ? LauncherInstrumentation.GestureScope.INSIDE
- : LauncherInstrumentation.GestureScope.OUTSIDE_WITH_PILFER);
+ swipeDown ? LauncherInstrumentation.GestureScope.DONT_EXPECT_PILFER
+ : LauncherInstrumentation.GestureScope.EXPECT_PILFER);
try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer(
"swiped to workspace")) {
diff --git a/tests/tapl/com/android/launcher3/tapl/Launchable.java b/tests/tapl/com/android/launcher3/tapl/Launchable.java
index 48e327f..3450ea7 100644
--- a/tests/tapl/com/android/launcher3/tapl/Launchable.java
+++ b/tests/tapl/com/android/launcher3/tapl/Launchable.java
@@ -16,10 +16,14 @@
package com.android.launcher3.tapl;
+import static android.view.accessibility.AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED;
+
import static com.android.launcher3.testing.shared.TestProtocol.SPRING_LOADED_STATE_ORDINAL;
+import android.app.UiAutomation;
import android.graphics.Point;
import android.view.MotionEvent;
+import android.view.accessibility.AccessibilityEvent;
import androidx.test.uiautomator.By;
import androidx.test.uiautomator.BySelector;
@@ -83,12 +87,18 @@
* fired when the click is executed.
*/
public LaunchedAppState launchIntoSplitScreen() {
- try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer(
- "want to launch split tasks from " + launchableType())) {
+ try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
+ LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer(
+ "want to launch split tasks from " + launchableType())) {
LauncherInstrumentation.log("Launchable.launch before click "
- + mObject.getVisibleCenter() + " in " + mLauncher.getVisibleBounds(mObject));
-
- mLauncher.clickLauncherObject(mObject);
+ + mObject.getVisibleCenter() + " in " + mLauncher.getVisibleBounds(
+ mObject));
+ mLauncher.executeAndWaitForLauncherEvent(
+ () -> mLauncher.clickLauncherObject(mObject),
+ accessibilityEvent ->
+ accessibilityEvent.getEventType() == TYPE_WINDOW_STATE_CHANGED,
+ () -> "Unable to click object to launch split",
+ "Click launcher object to launch split");
try (LauncherInstrumentation.Closable c2 = mLauncher.addContextLayer("clicked")) {
mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, OverviewTask.SPLIT_START_EVENT);
@@ -152,7 +162,7 @@
downTime,
MotionEvent.ACTION_DOWN,
iconCenter,
- LauncherInstrumentation.GestureScope.INSIDE);
+ LauncherInstrumentation.GestureScope.DONT_EXPECT_PILFER);
LauncherInstrumentation.log("movePointerForStartDrag: sent down");
expectLongClickEvents.run();
waitForLongPressConfirmation();
@@ -165,7 +175,7 @@
downTime,
downTime,
/* slowDown= */ true,
- LauncherInstrumentation.GestureScope.INSIDE);
+ LauncherInstrumentation.GestureScope.DONT_EXPECT_PILFER);
}
private int getStartDragThreshold() {
diff --git a/tests/tapl/com/android/launcher3/tapl/LaunchedAppState.java b/tests/tapl/com/android/launcher3/tapl/LaunchedAppState.java
index 230be06..30417c0 100644
--- a/tests/tapl/com/android/launcher3/tapl/LaunchedAppState.java
+++ b/tests/tapl/com/android/launcher3/tapl/LaunchedAppState.java
@@ -128,13 +128,13 @@
mLauncher.getRealDisplaySize().x / 2, unstashTargetY);
mLauncher.sendPointer(downTime, downTime, MotionEvent.ACTION_DOWN, unstashTarget,
- LauncherInstrumentation.GestureScope.OUTSIDE_WITH_PILFER);
+ LauncherInstrumentation.GestureScope.EXPECT_PILFER);
LauncherInstrumentation.log("showTaskbar: sent down");
try (LauncherInstrumentation.Closable c2 = mLauncher.addContextLayer("pressed down")) {
mLauncher.waitForSystemLauncherObject(TASKBAR_RES_ID);
mLauncher.sendPointer(downTime, downTime, MotionEvent.ACTION_UP, unstashTarget,
- LauncherInstrumentation.GestureScope.OUTSIDE_WITH_PILFER);
+ LauncherInstrumentation.GestureScope.EXPECT_PILFER);
return new Taskbar(mLauncher);
}
@@ -183,7 +183,7 @@
downTime,
SystemClock.uptimeMillis(),
/* slowDown= */ false,
- LauncherInstrumentation.GestureScope.INSIDE);
+ LauncherInstrumentation.GestureScope.DONT_EXPECT_PILFER);
try (LauncherInstrumentation.Closable c3 = launcher.addContextLayer(
"moved pointer to drop point")) {
@@ -194,7 +194,7 @@
SystemClock.uptimeMillis(),
MotionEvent.ACTION_UP,
endPoint,
- LauncherInstrumentation.GestureScope.INSIDE);
+ LauncherInstrumentation.GestureScope.DONT_EXPECT_PILFER);
LauncherInstrumentation.log("SplitscreenDragSource.dragToSplitscreen: "
+ "after drop");
@@ -326,7 +326,7 @@
null, InputDevice.SOURCE_MOUSE);
mLauncher.sendPointer(downTime, downTime, MotionEvent.ACTION_DOWN,
new Point(stashedTaskbarHintArea.x, stashedTaskbarHintArea.y),
- LauncherInstrumentation.GestureScope.OUTSIDE_WITHOUT_PILFER,
+ LauncherInstrumentation.GestureScope.DONT_EXPECT_PILFER,
InputDevice.SOURCE_MOUSE);
mLauncher.sendPointer(downTime, downTime, MotionEvent.ACTION_BUTTON_PRESS,
new Point(stashedTaskbarHintArea.x, stashedTaskbarHintArea.y),
@@ -336,7 +336,7 @@
null, InputDevice.SOURCE_MOUSE);
mLauncher.sendPointer(downTime, downTime, MotionEvent.ACTION_UP,
new Point(stashedTaskbarHintArea.x, stashedTaskbarHintArea.y),
- LauncherInstrumentation.GestureScope.OUTSIDE_WITHOUT_PILFER,
+ LauncherInstrumentation.GestureScope.DONT_EXPECT_PILFER,
InputDevice.SOURCE_MOUSE);
return mLauncher.getWorkspace();
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index e6fc244..872fe6f 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -21,7 +21,6 @@
import static android.content.pm.PackageManager.MATCH_ALL;
import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
import static android.view.MotionEvent.AXIS_GESTURE_SWIPE_FINGER_COUNT;
-
import static com.android.launcher3.tapl.Folder.FOLDER_CONTENT_RES_ID;
import static com.android.launcher3.tapl.TestHelpers.getOverviewPackageName;
import static com.android.launcher3.testing.shared.TestProtocol.NORMAL_STATE_ORDINAL;
@@ -29,12 +28,14 @@
import android.app.ActivityManager;
import android.app.Instrumentation;
import android.app.UiAutomation;
+import android.app.UiModeManager;
import android.content.ComponentName;
import android.content.ContentProviderClient;
import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.pm.ProviderInfo;
+import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Insets;
import android.graphics.Point;
@@ -102,12 +103,6 @@
static final Pattern EVENT_PILFER_POINTERS = Pattern.compile("pilferPointers");
static final Pattern EVENT_START = Pattern.compile("start:");
- static final Pattern EVENT_HOVER_ENTER_TIS = getTouchEventPatternTIS("ACTION_HOVER_ENTER");
- static final Pattern EVENT_HOVER_EXIT_TIS = getTouchEventPatternTIS("ACTION_HOVER_EXIT");
- static final Pattern EVENT_BUTTON_PRESS_TIS = getTouchEventPatternTIS("ACTION_BUTTON_PRESS");
- static final Pattern EVENT_BUTTON_RELEASE_TIS =
- getTouchEventPatternTIS("ACTION_BUTTON_RELEASE");
-
private static final Pattern EVENT_KEY_BACK_DOWN =
getKeyEventPattern("ACTION_DOWN", "KEYCODE_BACK");
private static final Pattern EVENT_KEY_BACK_UP =
@@ -127,12 +122,10 @@
public enum NavigationModel {ZERO_BUTTON, THREE_BUTTON}
- // Where the gesture happens: outside of Launcher, inside or from inside to outside and
- // whether the gesture recognition triggers pilfer.
+ // Defines whether the gesture recognition triggers pilfer.
public enum GestureScope {
- OUTSIDE_WITHOUT_PILFER, OUTSIDE_WITH_PILFER, INSIDE, INSIDE_TO_OUTSIDE,
- INSIDE_TO_OUTSIDE_WITH_KEYCODE, // For gestures that will trigger a keycode from TIS.
- OUTSIDE_WITH_KEYCODE,
+ DONT_EXPECT_PILFER,
+ EXPECT_PILFER,
}
public enum TrackpadGestureType {
@@ -181,6 +174,8 @@
static final long DEFAULT_POLL_INTERVAL = 1000;
private static final String SYSTEMUI_PACKAGE = "com.android.systemui";
private static final String ANDROID_PACKAGE = "android";
+ private static final String ASSISTANT_PACKAGE = "com.google.android.googlequicksearchbox";
+ private static final String ASSISTANT_GO_HOME_RES_ID = "home_icon";
private static WeakReference<VisibleContainer> sActiveContainer = new WeakReference<>(null);
@@ -204,28 +199,6 @@
private TrackpadGestureType mTrackpadGestureType = TrackpadGestureType.NONE;
private int mPointerCount = 0;
- private static Pattern getTouchEventPatternWithPointerCount(String prefix, String action,
- int pointerCount) {
- return Pattern.compile(
- prefix + ": MotionEvent.*?action=" + action + ".*?id\\[0\\]=0"
- + ".*?toolType\\[0\\]=TOOL_TYPE_FINGER.*?buttonState=0.*?pointerCount="
- + pointerCount);
- }
-
- private static Pattern getTouchEventPatternWithPointerCount(String action, int pointerCount) {
- return getTouchEventPatternWithPointerCount("Touch event", action, pointerCount);
- }
-
- private static Pattern getTouchEventPatternTIS(String action) {
- return getTouchEventPatternWithPointerCount("TouchInteractionService.onInputEvent", action,
- 1);
- }
-
- private static Pattern getTouchEventPatternTIS(String action, int pointerCount) {
- return getTouchEventPatternWithPointerCount("TouchInteractionService.onInputEvent", action,
- pointerCount);
- }
-
private static Pattern getKeyEventPattern(String action, String keyCode) {
return Pattern.compile("Key event: KeyEvent.*action=" + action + ".*keyCode=" + keyCode);
}
@@ -368,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);
@@ -973,8 +951,8 @@
GestureScope gestureScope = gestureStartFromLauncher
// Without the navigation bar layer, the gesture scope on tablets remains inside the
// launcher process.
- ? (isTablet() ? GestureScope.INSIDE : GestureScope.INSIDE_TO_OUTSIDE)
- : GestureScope.OUTSIDE_WITH_PILFER;
+ ? (isTablet() ? GestureScope.DONT_EXPECT_PILFER : GestureScope.EXPECT_PILFER)
+ : GestureScope.EXPECT_PILFER;
linearGesture(
displaySize.x / 2, displaySize.y - 1,
displaySize.x / 2, 0,
@@ -1046,8 +1024,7 @@
displaySize.x / 2, startY,
displaySize.x / 2, endY,
ZERO_BUTTON_STEPS_FROM_BACKGROUND_TO_HOME, NORMAL_STATE_ORDINAL,
- gestureStartFromLauncher ? GestureScope.INSIDE_TO_OUTSIDE
- : GestureScope.OUTSIDE_WITH_PILFER);
+ GestureScope.EXPECT_PILFER);
}
} else {
log("Hierarchy before clicking home:");
@@ -1055,7 +1032,7 @@
action = "clicking home button";
runToState(
- waitForNavigationUiObject("home")::click,
+ getHomeButton()::click,
NORMAL_STATE_ORDINAL,
!hasLauncherObject(WORKSPACE_RES_ID)
&& (hasLauncherObject(APPS_RES_ID)
@@ -1082,15 +1059,12 @@
if (getNavigationModel() == NavigationModel.ZERO_BUTTON
|| isThreeFingerTrackpadGesture) {
final Point displaySize = getRealDisplaySize();
- final GestureScope gestureScope =
- launcherVisible ? GestureScope.INSIDE_TO_OUTSIDE_WITH_KEYCODE
- : GestureScope.OUTSIDE_WITH_KEYCODE;
// TODO(b/225505986): change startY and endY back to displaySize.y / 2 once the
// issue is solved.
int startX = isThreeFingerTrackpadGesture ? displaySize.x / 4 : 0;
int endX = isThreeFingerTrackpadGesture ? displaySize.x * 3 / 4 : displaySize.x / 2;
linearGesture(startX, displaySize.y / 4, endX, displaySize.y / 4,
- 10, false, gestureScope);
+ 10, false, GestureScope.DONT_EXPECT_PILFER);
} else {
waitForNavigationUiObject("back").click();
}
@@ -1239,6 +1213,28 @@
}
@NonNull
+ private UiObject2 getHomeButton() {
+ UiModeManager uiManager =
+ (UiModeManager) getContext().getSystemService(Context.UI_MODE_SERVICE);
+ if (uiManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_CAR) {
+ return waitForAssistantHomeButton();
+ } else {
+ return waitForNavigationUiObject("home");
+ }
+ }
+
+ /* Assistant Home button is present when system is in car mode. */
+ @NonNull
+ UiObject2 waitForAssistantHomeButton() {
+ final UiObject2 object = mDevice.wait(
+ Until.findObject(By.res(ASSISTANT_PACKAGE, ASSISTANT_GO_HOME_RES_ID)),
+ WAIT_TIME_MS);
+ assertNotNull(
+ "Can't find an assistant UI object with id: " + ASSISTANT_GO_HOME_RES_ID, object);
+ return object;
+ }
+
+ @NonNull
UiObject2 waitForNavigationUiObject(String resId) {
String resPackage = getNavigationButtonResPackage();
final UiObject2 object = mDevice.wait(
@@ -1500,15 +1496,17 @@
* animations because in some scenarios there is a playing animations when the click is
* attempted.
*/
- void clickObject(UiObject2 uiObject, GestureScope gestureScope) {
+ void clickObject(UiObject2 uiObject) {
final long clickTime = SystemClock.uptimeMillis();
final Point center = uiObject.getVisibleCenter();
- sendPointer(clickTime, clickTime, MotionEvent.ACTION_DOWN, center, gestureScope);
- sendPointer(clickTime, clickTime, MotionEvent.ACTION_UP, center, gestureScope);
+ sendPointer(clickTime, clickTime, MotionEvent.ACTION_DOWN, center,
+ GestureScope.DONT_EXPECT_PILFER);
+ sendPointer(clickTime, clickTime, MotionEvent.ACTION_UP, center,
+ GestureScope.DONT_EXPECT_PILFER);
}
void clickLauncherObject(UiObject2 object) {
- clickObject(object, GestureScope.INSIDE);
+ clickObject(object);
}
void scrollToLastVisibleRow(
@@ -1601,7 +1599,8 @@
executeAndWaitForLauncherEvent(
() -> linearGesture(
- startX, startY, endX, endY, steps, slowDown, GestureScope.INSIDE),
+ startX, startY, endX, endY, steps, slowDown,
+ GestureScope.DONT_EXPECT_PILFER),
event -> TestProtocol.SCROLL_FINISHED_MESSAGE.equals(event.getClassName()),
() -> "Didn't receive a scroll end message: " + startX + ", " + startY
+ ", " + endX + ", " + endY,
@@ -1721,11 +1720,6 @@
TestProtocol.TEST_INFO_RESPONSE_FIELD);
}
- boolean isTrackpadGestureEnabled() {
- return getTestInfo(TestProtocol.REQUEST_IS_TRACKPAD_GESTURE_ENABLED).getBoolean(
- TestProtocol.TEST_INFO_RESPONSE_FIELD);
- }
-
boolean isGridOnlyOverviewEnabled() {
return getTestInfo(TestProtocol.REQUEST_FLAG_ENABLE_GRID_ONLY_OVERVIEW).getBoolean(
TestProtocol.TEST_INFO_RESPONSE_FIELD);
@@ -1743,7 +1737,6 @@
int pointerCount = mPointerCount;
boolean isTrackpadGesture = mTrackpadGestureType != TrackpadGestureType.NONE;
- boolean isTwoFingerTrackpadGesture = mTrackpadGestureType == TrackpadGestureType.TWO_FINGER;
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
if (isTrackpadGesture) {
@@ -1752,59 +1745,18 @@
}
break;
case MotionEvent.ACTION_UP:
- if (hasTIS
- && (gestureScope == GestureScope.OUTSIDE_WITH_PILFER
- || gestureScope == GestureScope.INSIDE_TO_OUTSIDE)) {
+ if (hasTIS && gestureScope == GestureScope.EXPECT_PILFER) {
expectEvent(TestProtocol.SEQUENCE_PILFER, EVENT_PILFER_POINTERS);
}
break;
- case MotionEvent.ACTION_HOVER_ENTER:
- expectEvent(TestProtocol.SEQUENCE_TIS, EVENT_HOVER_ENTER_TIS);
- break;
- case MotionEvent.ACTION_HOVER_EXIT:
- expectEvent(TestProtocol.SEQUENCE_TIS, EVENT_HOVER_EXIT_TIS);
- break;
case MotionEvent.ACTION_POINTER_DOWN:
mPointerCount++;
- if (gestureScope != GestureScope.OUTSIDE_WITH_PILFER
- && gestureScope != GestureScope.OUTSIDE_WITHOUT_PILFER
- && gestureScope != GestureScope.OUTSIDE_WITH_KEYCODE
- && (!isTrackpadGesture || isTwoFingerTrackpadGesture)) {
- expectEvent(TestProtocol.SEQUENCE_MAIN, getTouchEventPatternWithPointerCount(
- "ACTION_POINTER_DOWN", mPointerCount));
- }
- if (hasTIS && (isTrackpadGestureEnabled()
- || getNavigationModel() != NavigationModel.THREE_BUTTON)) {
- expectEvent(TestProtocol.SEQUENCE_TIS, getTouchEventPatternTIS(
- "ACTION_POINTER_DOWN", mPointerCount));
- }
pointerCount = mPointerCount;
break;
case MotionEvent.ACTION_POINTER_UP:
- if (gestureScope != GestureScope.OUTSIDE_WITH_PILFER
- && gestureScope != GestureScope.OUTSIDE_WITHOUT_PILFER
- && gestureScope != GestureScope.OUTSIDE_WITH_KEYCODE
- && (!isTrackpadGesture || isTwoFingerTrackpadGesture)) {
- expectEvent(TestProtocol.SEQUENCE_MAIN, getTouchEventPatternWithPointerCount(
- "ACTION_POINTER_UP", mPointerCount));
- }
// When the gesture is handled outside, it's cancelled within launcher.
- if (hasTIS && (isTrackpadGestureEnabled()
- || getNavigationModel() != NavigationModel.THREE_BUTTON)) {
- if (gestureScope != GestureScope.INSIDE_TO_OUTSIDE_WITH_KEYCODE
- && gestureScope != GestureScope.OUTSIDE_WITH_KEYCODE) {
- expectEvent(TestProtocol.SEQUENCE_TIS, getTouchEventPatternTIS(
- "ACTION_POINTER_UP", mPointerCount));
- }
- }
mPointerCount--;
break;
- case MotionEvent.ACTION_BUTTON_PRESS:
- expectEvent(TestProtocol.SEQUENCE_TIS, EVENT_BUTTON_PRESS_TIS);
- break;
- case MotionEvent.ACTION_BUTTON_RELEASE:
- expectEvent(TestProtocol.SEQUENCE_TIS, EVENT_BUTTON_RELEASE_TIS);
- break;
}
final MotionEvent event = isTrackpadGesture
@@ -1883,11 +1835,12 @@
@NonNull final UiObject2 target, @NonNull String resName, Pattern longClickEvent) {
final Point targetCenter = target.getVisibleCenter();
final long downTime = SystemClock.uptimeMillis();
- sendPointer(downTime, downTime, MotionEvent.ACTION_DOWN, targetCenter, GestureScope.INSIDE);
+ sendPointer(downTime, downTime, MotionEvent.ACTION_DOWN, targetCenter,
+ GestureScope.DONT_EXPECT_PILFER);
expectEvent(TestProtocol.SEQUENCE_MAIN, longClickEvent);
final UiObject2 result = waitForLauncherObject(resName);
sendPointer(downTime, SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, targetCenter,
- GestureScope.INSIDE);
+ GestureScope.DONT_EXPECT_PILFER);
return result;
}
@@ -2163,14 +2116,18 @@
? 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);
sendPointer(downTime, downTime, MotionEvent.ACTION_DOWN, tapTarget,
- LauncherInstrumentation.GestureScope.INSIDE);
+ LauncherInstrumentation.GestureScope.DONT_EXPECT_PILFER);
sendPointer(downTime, downTime, MotionEvent.ACTION_UP, tapTarget,
- LauncherInstrumentation.GestureScope.INSIDE);
+ LauncherInstrumentation.GestureScope.DONT_EXPECT_PILFER);
}
}
diff --git a/tests/tapl/com/android/launcher3/tapl/OverviewTask.java b/tests/tapl/com/android/launcher3/tapl/OverviewTask.java
index 39b93b4..e4cfc52 100644
--- a/tests/tapl/com/android/launcher3/tapl/OverviewTask.java
+++ b/tests/tapl/com/android/launcher3/tapl/OverviewTask.java
@@ -124,7 +124,7 @@
final int centerY = taskBounds.centerY();
mLauncher.executeAndWaitForLauncherEvent(
() -> mLauncher.linearGesture(centerX, centerY, centerX, 0, 10, false,
- LauncherInstrumentation.GestureScope.INSIDE),
+ LauncherInstrumentation.GestureScope.DONT_EXPECT_PILFER),
event -> TestProtocol.DISMISS_ANIMATION_ENDS_MESSAGE.equals(event.getClassName()),
() -> "Didn't receive a dismiss animation ends message: " + centerX + ", "
+ centerY, "swiping to dismiss");
diff --git a/tests/tapl/com/android/launcher3/tapl/OverviewTaskMenu.java b/tests/tapl/com/android/launcher3/tapl/OverviewTaskMenu.java
index 7c29a6c..859e504 100644
--- a/tests/tapl/com/android/launcher3/tapl/OverviewTaskMenu.java
+++ b/tests/tapl/com/android/launcher3/tapl/OverviewTaskMenu.java
@@ -16,6 +16,8 @@
package com.android.launcher3.tapl;
+import static android.view.accessibility.AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED;
+
import androidx.annotation.NonNull;
import androidx.test.uiautomator.By;
import androidx.test.uiautomator.UiObject2;
@@ -50,15 +52,23 @@
}
}
- /** Taps the app info item from the overview task menu and returns the LaunchedAppState
- * representing the App info settings page. */
+ /**
+ * Taps the app info item from the overview task menu and returns the LaunchedAppState
+ * representing the App info settings page.
+ */
@NonNull
public LaunchedAppState tapAppInfoMenuItem() {
try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
"before tapping the app info menu item")) {
- mLauncher.clickLauncherObject(
- mLauncher.findObjectInContainer(mMenu, By.text("App info")));
+
+ mLauncher.executeAndWaitForLauncherEvent(
+ () -> mLauncher.clickLauncherObject(
+ mLauncher.findObjectInContainer(mMenu, By.text("App info"))),
+ accessibilityEvent ->
+ accessibilityEvent.getEventType() == TYPE_WINDOW_STATE_CHANGED,
+ () -> "Unable to start Settings by clicking App Info",
+ "Tap the app info menu item");
try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer(
"tapped app info menu item")) {
diff --git a/tests/tapl/com/android/launcher3/tapl/SearchResultFromQsb.java b/tests/tapl/com/android/launcher3/tapl/SearchResultFromQsb.java
index d02e747..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");
}
}
@@ -91,7 +96,7 @@
* Taps outside bottom sheet to dismiss and return to workspace. Available on tablets only.
* @param tapRight Tap on the right of bottom sheet if true, or left otherwise.
*/
- public Workspace dismissByTappingOutsideForTablet(boolean tapRight) {
+ public void dismissByTappingOutsideForTablet(boolean tapRight) {
try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
"want to tap outside AllApps bottom sheet on the "
@@ -101,8 +106,12 @@
mLauncher.touchOutsideContainer(allAppsBottomSheet, tapRight);
try (LauncherInstrumentation.Closable tapped = mLauncher.addContextLayer(
"tapped outside AllApps bottom sheet")) {
- return mLauncher.getWorkspace();
+ verifyVisibleContainerOnDismiss();
}
}
}
+
+ protected void verifyVisibleContainerOnDismiss() {
+ mLauncher.getWorkspace();
+ }
}
diff --git a/tests/tapl/com/android/launcher3/tapl/SearchResultFromTaskbarQsb.java b/tests/tapl/com/android/launcher3/tapl/SearchResultFromTaskbarQsb.java
index 6c6ab05..00291a3 100644
--- a/tests/tapl/com/android/launcher3/tapl/SearchResultFromTaskbarQsb.java
+++ b/tests/tapl/com/android/launcher3/tapl/SearchResultFromTaskbarQsb.java
@@ -45,4 +45,9 @@
protected TaskbarSearchWebSuggestion createWebSuggestion(UiObject2 webSuggestion) {
return new TaskbarSearchWebSuggestion(mLauncher, webSuggestion);
}
+
+ @Override
+ protected void verifyVisibleContainerOnDismiss() {
+ mLauncher.getLaunchedAppState().assertTaskbarVisible();
+ }
}
diff --git a/tests/tapl/com/android/launcher3/tapl/Taskbar.java b/tests/tapl/com/android/launcher3/tapl/Taskbar.java
index 051630e..4293ee8 100644
--- a/tests/tapl/com/android/launcher3/tapl/Taskbar.java
+++ b/tests/tapl/com/android/launcher3/tapl/Taskbar.java
@@ -76,13 +76,13 @@
mLauncher.getRealDisplaySize().x - 1, mLauncher.getRealDisplaySize().y - 1);
mLauncher.sendPointer(downTime, downTime, MotionEvent.ACTION_DOWN, stashTarget,
- LauncherInstrumentation.GestureScope.INSIDE);
+ LauncherInstrumentation.GestureScope.DONT_EXPECT_PILFER);
LauncherInstrumentation.log("hideTaskbar: sent down");
try (LauncherInstrumentation.Closable c2 = mLauncher.addContextLayer("pressed down")) {
mLauncher.waitUntilSystemLauncherObjectGone(TASKBAR_RES_ID);
mLauncher.sendPointer(downTime, downTime, MotionEvent.ACTION_UP, stashTarget,
- LauncherInstrumentation.GestureScope.INSIDE);
+ LauncherInstrumentation.GestureScope.DONT_EXPECT_PILFER);
}
} finally {
mLauncher.getTestInfo(REQUEST_DISABLE_MANUAL_TASKBAR_STASHING);
@@ -92,7 +92,7 @@
/**
* Opens the Taskbar all apps page.
*/
- public AllAppsFromTaskbar openAllApps() {
+ public TaskbarAllApps openAllApps() {
try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
"want to open taskbar all apps");
LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) {
@@ -101,7 +101,15 @@
mLauncher.waitForSystemLauncherObject(TASKBAR_RES_ID),
getAllAppsButtonSelector()));
- return new AllAppsFromTaskbar(mLauncher);
+ return getAllApps();
+ }
+ }
+
+ /** Returns {@link TaskbarAllApps} if it is open, otherwise fails. */
+ public TaskbarAllApps getAllApps() {
+ try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
+ "want to get taskbar all apps object")) {
+ return new TaskbarAllApps(mLauncher);
}
}
@@ -147,9 +155,9 @@
mLauncher.getRealDisplaySize().y - 1);
mLauncher.sendPointer(downTime, downTime, MotionEvent.ACTION_DOWN, tapTarget,
- LauncherInstrumentation.GestureScope.INSIDE);
+ LauncherInstrumentation.GestureScope.DONT_EXPECT_PILFER);
mLauncher.sendPointer(downTime, downTime, MotionEvent.ACTION_UP, tapTarget,
- LauncherInstrumentation.GestureScope.INSIDE);
+ LauncherInstrumentation.GestureScope.DONT_EXPECT_PILFER);
}
}
}
diff --git a/tests/tapl/com/android/launcher3/tapl/AllAppsFromTaskbar.java b/tests/tapl/com/android/launcher3/tapl/TaskbarAllApps.java
similarity index 94%
rename from tests/tapl/com/android/launcher3/tapl/AllAppsFromTaskbar.java
rename to tests/tapl/com/android/launcher3/tapl/TaskbarAllApps.java
index 0e0291f..63185f9 100644
--- a/tests/tapl/com/android/launcher3/tapl/AllAppsFromTaskbar.java
+++ b/tests/tapl/com/android/launcher3/tapl/TaskbarAllApps.java
@@ -23,9 +23,9 @@
/**
* Operations on AllApps opened from the Taskbar.
*/
-public class AllAppsFromTaskbar extends AllApps {
+public class TaskbarAllApps extends AllApps {
- AllAppsFromTaskbar(LauncherInstrumentation launcher) {
+ TaskbarAllApps(LauncherInstrumentation launcher) {
super(launcher);
}
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;
+ }
+ }
+ }
}
diff --git a/tests/tapl/com/android/launcher3/tapl/Workspace.java b/tests/tapl/com/android/launcher3/tapl/Workspace.java
index 8604988..cf48ebc 100644
--- a/tests/tapl/com/android/launcher3/tapl/Workspace.java
+++ b/tests/tapl/com/android/launcher3/tapl/Workspace.java
@@ -27,6 +27,7 @@
import android.graphics.Point;
import android.graphics.Rect;
import android.os.SystemClock;
+import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
@@ -104,7 +105,8 @@
windowCornerRadius,
startY - swipeHeight - mLauncher.getTouchSlop(),
12,
- ALL_APPS_STATE_ORDINAL, LauncherInstrumentation.GestureScope.INSIDE);
+ ALL_APPS_STATE_ORDINAL,
+ LauncherInstrumentation.GestureScope.DONT_EXPECT_PILFER);
try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer(
"swiped to all apps")) {
@@ -285,6 +287,10 @@
final UiObject2 workspace = verifyActiveContainer();
List<UiObject2> workspaceIcons =
mLauncher.waitForObjectsInContainer(workspace, AppIcon.getAnyAppIconSelector());
+ Log.d("b/288944469", "List size = " + workspaceIcons.size());
+ for (int i = 0; i < workspaceIcons.size(); i++) {
+ Log.d("b/288944469", "index = " + i + " tesxt = " + workspaceIcons.get(i).getText());
+ }
return workspaceIcons.stream()
.collect(
Collectors.toMap(
@@ -386,7 +392,7 @@
Until.hasObject(installerAlert), LauncherInstrumentation.WAIT_TIME_MS));
final UiObject2 ok = device.findObject(By.text("OK"));
assertNotNull("OK button is not shown", ok);
- launcher.clickObject(ok, LauncherInstrumentation.GestureScope.OUTSIDE_WITHOUT_PILFER);
+ launcher.clickObject(ok);
assertTrue("Uninstall alert is not dismissed after clicking OK", device.wait(
Until.gone(installerAlert), LauncherInstrumentation.WAIT_TIME_MS));
@@ -453,7 +459,7 @@
launcher.runToState(
() -> launcher.sendPointer(
downTime, SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, dest,
- LauncherInstrumentation.GestureScope.INSIDE),
+ LauncherInstrumentation.GestureScope.DONT_EXPECT_PILFER),
NORMAL_STATE_ORDINAL,
"sending UP event");
if (expectedEvents != null) {
@@ -542,7 +548,7 @@
executeAndWaitForPageScroll(launcher,
() -> launcher.movePointer(finalDragStart, screenEdge, DEFAULT_DRAG_STEPS,
true, downTime, downTime, true,
- LauncherInstrumentation.GestureScope.INSIDE));
+ LauncherInstrumentation.GestureScope.DONT_EXPECT_PILFER));
targetDest.x += displayX * (targetDest.x > 0 ? -1 : 1);
dragStart = screenEdge;
}
@@ -551,7 +557,7 @@
// we just have to put move the icon to the destination and drop it
launcher.movePointer(dragStart, targetDest, DEFAULT_DRAG_STEPS, isDecelerating,
downTime, SystemClock.uptimeMillis(), false,
- LauncherInstrumentation.GestureScope.INSIDE);
+ LauncherInstrumentation.GestureScope.DONT_EXPECT_PILFER);
dropDraggedIcon(launcher, targetDest, downTime, expectDropEvents);
}
}
@@ -584,7 +590,7 @@
// we just have to put move the icon to the destination and drop it
launcher.movePointer(dragStart, targetDest, DEFAULT_DRAG_STEPS, isDecelerating,
downTime, SystemClock.uptimeMillis(), false,
- LauncherInstrumentation.GestureScope.INSIDE);
+ LauncherInstrumentation.GestureScope.DONT_EXPECT_PILFER);
dropDraggedIcon(launcher, targetDest, downTime, expectDropEvents);
}
}
@@ -621,7 +627,7 @@
executeAndWaitForPageScroll(launcher,
() -> launcher.movePointer(finalDragStart, screenEdge, DEFAULT_DRAG_STEPS,
true, downTime, downTime, true,
- LauncherInstrumentation.GestureScope.INSIDE));
+ LauncherInstrumentation.GestureScope.DONT_EXPECT_PILFER));
currentPage = Workspace.geCurrentPage(launcher);
currentPosition = screenEdge;
}
@@ -650,7 +656,7 @@
launcher.movePointer(dragStart, targetDest, DEFAULT_DRAG_STEPS, true,
downTime, SystemClock.uptimeMillis(), false,
- LauncherInstrumentation.GestureScope.INSIDE);
+ LauncherInstrumentation.GestureScope.DONT_EXPECT_PILFER);
dropDraggedIcon(launcher, targetDest, downTime, expectDropEvents);
}