Merge "Add launch assistant method." into tm-qpr-dev
diff --git a/go/src/com/android/launcher3/model/WidgetsModel.java b/go/src/com/android/launcher3/model/WidgetsModel.java
index 1aa5d03..9a000d6 100644
--- a/go/src/com/android/launcher3/model/WidgetsModel.java
+++ b/go/src/com/android/launcher3/model/WidgetsModel.java
@@ -41,8 +41,10 @@
*/
public class WidgetsModel {
- // True is the widget support is disabled.
+ // True if the widget support is disabled.
public static final boolean GO_DISABLE_WIDGETS = true;
+ // True if the shortcut support is disabled.
+ public static final boolean GO_DISABLE_SHORTCUTS = true;
public static final boolean GO_DISABLE_NOTIFICATION_DOTS = true;
private static final ArrayList<WidgetsListBaseEntry> EMPTY_WIDGET_LIST = new ArrayList<>();
diff --git a/quickstep/src/com/android/launcher3/appprediction/AppsDividerView.java b/quickstep/src/com/android/launcher3/appprediction/AppsDividerView.java
index f42b39f..e8374b8 100644
--- a/quickstep/src/com/android/launcher3/appprediction/AppsDividerView.java
+++ b/quickstep/src/com/android/launcher3/appprediction/AppsDividerView.java
@@ -35,6 +35,7 @@
import com.android.launcher3.R;
import com.android.launcher3.allapps.FloatingHeaderRow;
import com.android.launcher3.allapps.FloatingHeaderView;
+import com.android.launcher3.util.OnboardingPrefs;
import com.android.launcher3.util.Themes;
import com.android.launcher3.views.ActivityContext;
@@ -92,8 +93,10 @@
? R.color.all_apps_label_text_dark
: R.color.all_apps_label_text);
- mShowAllAppsLabel = !ActivityContext.lookupContext(
- getContext()).getOnboardingPrefs().hasReachedMaxCount(ALL_APPS_VISITED_COUNT);
+ OnboardingPrefs<?> onboardingPrefs = ActivityContext.lookupContext(
+ getContext()).getOnboardingPrefs();
+ mShowAllAppsLabel = onboardingPrefs == null || !onboardingPrefs.hasReachedMaxCount(
+ ALL_APPS_VISITED_COUNT);
}
public void setup(FloatingHeaderView parent, FloatingHeaderRow[] rows, boolean tabsHidden) {
@@ -216,8 +219,8 @@
CharSequence allAppsLabelText = getResources().getText(R.string.all_apps_label);
mAllAppsLabelLayout = StaticLayout.Builder.obtain(
- allAppsLabelText, 0, allAppsLabelText.length(), mPaint,
- Math.round(mPaint.measureText(allAppsLabelText.toString())))
+ allAppsLabelText, 0, allAppsLabelText.length(), mPaint,
+ Math.round(mPaint.measureText(allAppsLabelText.toString())))
.setAlignment(Layout.Alignment.ALIGN_CENTER)
.setMaxLines(1)
.setIncludePad(true)
diff --git a/quickstep/src/com/android/launcher3/statehandlers/BackButtonAlphaHandler.java b/quickstep/src/com/android/launcher3/statehandlers/BackButtonAlphaHandler.java
index 8c11081..d33859b 100644
--- a/quickstep/src/com/android/launcher3/statehandlers/BackButtonAlphaHandler.java
+++ b/quickstep/src/com/android/launcher3/statehandlers/BackButtonAlphaHandler.java
@@ -17,7 +17,7 @@
package com.android.launcher3.statehandlers;
import static com.android.launcher3.anim.Interpolators.LINEAR;
-import static com.android.launcher3.util.DisplayController.NavigationMode.TWO_BUTTONS;
+import static com.android.launcher3.util.NavigationMode.TWO_BUTTONS;
import static com.android.quickstep.AnimatedFloat.VALUE;
import com.android.launcher3.LauncherState;
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index 3b1e677..8697b69 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -80,7 +80,7 @@
import com.android.launcher3.testing.shared.TestProtocol;
import com.android.launcher3.touch.ItemClickHandler;
import com.android.launcher3.util.DisplayController;
-import com.android.launcher3.util.DisplayController.NavigationMode;
+import com.android.launcher3.util.NavigationMode;
import com.android.launcher3.util.PackageManagerHelper;
import com.android.launcher3.util.SettingsCache;
import com.android.launcher3.util.TraceHelper;
@@ -868,6 +868,10 @@
btv.post(() -> mControllers.taskbarPopupController.showForIcon(btv));
}
+ public boolean isInApp() {
+ return mControllers.taskbarStashController.isInApp();
+ }
+
protected void dumpLogs(String prefix, PrintWriter pw) {
pw.println(prefix + "TaskbarActivityContext:");
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
index 80b3c1d..bc69088 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
@@ -45,6 +45,7 @@
import com.android.launcher3.taskbar.unfold.NonDestroyableScopedUnfoldTransitionProgressProvider;
import com.android.launcher3.uioverrides.QuickstepLauncher;
import com.android.launcher3.util.DisplayController;
+import com.android.launcher3.util.NavigationMode;
import com.android.launcher3.util.SettingsCache;
import com.android.launcher3.util.SimpleBroadcastReceiver;
import com.android.quickstep.RecentsActivity;
@@ -83,7 +84,7 @@
// It's destruction/creation will be managed by the activity.
private final ScopedUnfoldTransitionProgressProvider mUnfoldProgressProvider =
new NonDestroyableScopedUnfoldTransitionProgressProvider();
- private DisplayController.NavigationMode mNavMode;
+ private NavigationMode mNavMode;
private TaskbarActivityContext mTaskbarActivityContext;
private StatefulActivity mActivity;
diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java
index c4837a0..0e62da3 100644
--- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java
@@ -16,8 +16,7 @@
package com.android.launcher3.taskbar.allapps;
import static com.android.launcher3.LauncherState.ALL_APPS;
-import static com.android.launcher3.anim.Interpolators.AGGRESSIVE_EASE;
-import static com.android.systemui.animation.Interpolators.EMPHASIZED_ACCELERATE;
+import static com.android.launcher3.anim.Interpolators.EMPHASIZED;
import android.animation.PropertyValuesHolder;
import android.content.Context;
@@ -60,7 +59,7 @@
if (animate) {
mOpenCloseAnimator.setValues(
PropertyValuesHolder.ofFloat(TRANSLATION_SHIFT, TRANSLATION_SHIFT_OPENED));
- mOpenCloseAnimator.setInterpolator(AGGRESSIVE_EASE);
+ mOpenCloseAnimator.setInterpolator(EMPHASIZED);
mOpenCloseAnimator.setDuration(
ALL_APPS.getTransitionDuration(mActivityContext, true /* isToState */)).start();
} else {
@@ -87,7 +86,7 @@
@Override
protected Interpolator getIdleInterpolator() {
- return EMPHASIZED_ACCELERATE;
+ return EMPHASIZED;
}
@Override
diff --git a/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
index 8782ee6..2e4e739 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
@@ -28,11 +28,10 @@
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_X;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_Y;
import static com.android.launcher3.states.StateAnimationConfig.SKIP_OVERVIEW;
+import static com.android.quickstep.views.FloatingTaskView.PRIMARY_TRANSLATE_OFFSCREEN;
import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_HORIZONTAL_OFFSET;
-import static com.android.quickstep.views.RecentsView.FIRST_FLOATING_TASK_TRANSLATE_OFFSCREEN;
import static com.android.quickstep.views.RecentsView.RECENTS_GRID_PROGRESS;
import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY;
-import static com.android.quickstep.views.RecentsView.SPLIT_INSTRUCTIONS_FADE;
import static com.android.quickstep.views.RecentsView.TASK_SECONDARY_TRANSLATION;
import static com.android.quickstep.views.RecentsView.TASK_THUMBNAIL_SPLASH_ALPHA;
@@ -112,6 +111,7 @@
// TODO (b/238651489): Refactor state management to avoid need for double check
FloatingTaskView floatingTask = mRecentsView.getFirstFloatingTaskView();
if (floatingTask != null) {
+ // We are in split selection state currently, transitioning to another state
DragLayer dragLayer = mLauncher.getDragLayer();
RectF onScreenRectF = new RectF();
Utilities.getBoundsForViewInDragLayer(mLauncher.getDragLayer(), floatingTask,
@@ -127,8 +127,8 @@
);
setter.setFloat(
- mRecentsView,
- FIRST_FLOATING_TASK_TRANSLATE_OFFSCREEN,
+ mRecentsView.getFirstFloatingTaskView(),
+ PRIMARY_TRANSLATE_OFFSCREEN,
mRecentsView.getPagedOrientationHandler()
.getFloatingTaskOffscreenTranslationTarget(
floatingTask,
@@ -140,14 +140,14 @@
ANIM_OVERVIEW_SPLIT_SELECT_FLOATING_TASK_TRANSLATE_OFFSCREEN,
LINEAR
));
- setter.setFloat(
- mRecentsView,
- SPLIT_INSTRUCTIONS_FADE,
- 1,
+ setter.setViewAlpha(
+ mRecentsView.getSplitInstructionsView(),
+ 0,
config.getInterpolator(
ANIM_OVERVIEW_SPLIT_SELECT_INSTRUCTIONS_FADE,
LINEAR
- ));
+ )
+ );
}
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index 0f3ea15..0a99204 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -45,9 +45,9 @@
import static com.android.launcher3.testing.shared.TestProtocol.QUICK_SWITCH_STATE_ORDINAL;
import static com.android.launcher3.util.DisplayController.CHANGE_ACTIVE_SCREEN;
import static com.android.launcher3.util.DisplayController.CHANGE_NAVIGATION_MODE;
-import static com.android.launcher3.util.DisplayController.NavigationMode.TWO_BUTTONS;
import static com.android.launcher3.util.Executors.THREAD_POOL_EXECUTOR;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
+import static com.android.launcher3.util.NavigationMode.TWO_BUTTONS;
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_HOME_KEY;
import android.animation.AnimatorSet;
@@ -64,6 +64,7 @@
import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.IBinder;
+import android.os.SystemProperties;
import android.view.Display;
import android.view.HapticFeedbackConstants;
import android.view.View;
@@ -113,16 +114,18 @@
import com.android.launcher3.uioverrides.touchcontrollers.TwoButtonNavbarTouchController;
import com.android.launcher3.util.ActivityOptionsWrapper;
import com.android.launcher3.util.DisplayController;
-import com.android.launcher3.util.DisplayController.NavigationMode;
import com.android.launcher3.util.IntSet;
+import com.android.launcher3.util.NavigationMode;
import com.android.launcher3.util.ObjectWrapper;
import com.android.launcher3.util.PendingRequestArgs;
import com.android.launcher3.util.PendingSplitSelectInfo;
import com.android.launcher3.util.RunnableList;
+import com.android.launcher3.util.SafeCloseable;
import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
import com.android.launcher3.util.TouchController;
import com.android.launcher3.util.UiThreadHelper;
import com.android.launcher3.util.UiThreadHelper.AsyncCommand;
+import com.android.launcher3.util.ViewCapture;
import com.android.launcher3.widget.LauncherAppWidgetHost;
import com.android.quickstep.OverviewCommandHelper;
import com.android.quickstep.RecentsModel;
@@ -159,6 +162,9 @@
public class QuickstepLauncher extends Launcher {
+ public static final boolean ENABLE_PIP_KEEP_CLEAR_ALGORITHM =
+ SystemProperties.getBoolean("persist.wm.debug.enable_pip_keep_clear_algorithm", false);
+
public static final boolean GO_LOW_RAM_RECENTS_ENABLED = false;
/**
* Reusable command for applying the shelf height on the background thread.
@@ -191,6 +197,8 @@
*/
private PendingSplitSelectInfo mPendingSplitSelectInfo = null;
+ private SafeCloseable mViewCapture;
+
@Override
protected void setupViews() {
super.setupViews();
@@ -349,16 +357,18 @@
*/
private void onStateOrResumeChanging(boolean inTransition) {
LauncherState state = getStateManager().getState();
- boolean started = ((getActivityFlags() & ACTIVITY_STATE_STARTED)) != 0;
- if (started) {
- DeviceProfile profile = getDeviceProfile();
- boolean willUserBeActive =
- (getActivityFlags() & ACTIVITY_STATE_USER_WILL_BE_ACTIVE) != 0;
- boolean visible = (state == NORMAL || state == OVERVIEW)
- && (willUserBeActive || isUserActive())
- && !profile.isVerticalBarLayout();
- UiThreadHelper.runAsyncCommand(this, SET_SHELF_HEIGHT, visible ? 1 : 0,
- profile.hotseatBarSizePx);
+ if (!ENABLE_PIP_KEEP_CLEAR_ALGORITHM) {
+ boolean started = ((getActivityFlags() & ACTIVITY_STATE_STARTED)) != 0;
+ if (started) {
+ DeviceProfile profile = getDeviceProfile();
+ boolean willUserBeActive =
+ (getActivityFlags() & ACTIVITY_STATE_USER_WILL_BE_ACTIVE) != 0;
+ boolean visible = (state == NORMAL || state == OVERVIEW)
+ && (willUserBeActive || isUserActive())
+ && !profile.isVerticalBarLayout();
+ UiThreadHelper.runAsyncCommand(this, SET_SHELF_HEIGHT, visible ? 1 : 0,
+ profile.hotseatBarSizePx);
+ }
}
if (state == NORMAL && !inTransition) {
((RecentsView) getOverviewPanel()).setSwipeDownShouldLaunchApp(false);
@@ -404,6 +414,7 @@
super.onDestroy();
mHotseatPredictionController.destroy();
+ mViewCapture.close();
}
@Override
@@ -503,6 +514,7 @@
}
addMultiWindowModeChangedListener(mDepthController);
initUnfoldTransitionProgressProvider();
+ mViewCapture = ViewCapture.INSTANCE.get(this).startCapture(getWindow());
}
@Override
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
index 9f2efc4..e21f14f 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
@@ -16,14 +16,17 @@
package com.android.launcher3.uioverrides.states;
import static com.android.launcher3.anim.Interpolators.DEACCEL_2;
+import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_ALLAPPS;
import android.content.Context;
+import com.android.launcher3.DeviceProfile;
import com.android.launcher3.DeviceProfile.DeviceProfileListenable;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
import com.android.launcher3.util.Themes;
/**
@@ -41,9 +44,9 @@
@Override
public <DEVICE_PROFILE_CONTEXT extends Context & DeviceProfileListenable>
int getTransitionDuration(DEVICE_PROFILE_CONTEXT context, boolean isToState) {
- return !context.getDeviceProfile().isTablet && isToState
- ? 600
- : isToState ? 500 : 300;
+ return context.getDeviceProfile().isTablet
+ ? 500
+ : isToState ? 600 : 300;
}
@Override
@@ -77,10 +80,23 @@
}
@Override
- protected float getDepthUnchecked(Context context) {
- // The scrim fades in at approximately 50% of the swipe gesture.
- // This means that the depth should be greater than 1, in order to fully zoom out.
- return 2f;
+ protected <DEVICE_PROFILE_CONTEXT extends Context & DeviceProfile.DeviceProfileListenable>
+ float getDepthUnchecked(DEVICE_PROFILE_CONTEXT context) {
+ if (context.getDeviceProfile().isTablet) {
+ // The goal is to set wallpaper to zoom at workspaceContentScale when in AllApps.
+ // When depth is 0, wallpaper zoom is set to maxWallpaperScale.
+ // When depth is 1, wallpaper zoom is set to 1.
+ // For depth to achieve zoom set to maxWallpaperScale * workspaceContentScale:
+ float maxWallpaperScale = context.getResources().getFloat(
+ com.android.internal.R.dimen.config_wallpaperMaxScale);
+ return Utilities.mapToRange(
+ maxWallpaperScale * context.getDeviceProfile().workspaceContentScale,
+ maxWallpaperScale, 1f, 0f, 1f, LINEAR);
+ } else {
+ // The scrim fades in at approximately 50% of the swipe gesture.
+ // This means that the depth should be greater than 1, in order to fully zoom out.
+ return 2f;
+ }
}
@Override
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
index e5cd53a..56ac4c5 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
@@ -45,7 +45,7 @@
import com.android.launcher3.touch.AbstractStateChangeTouchController;
import com.android.launcher3.touch.SingleAxisSwipeDetector;
import com.android.launcher3.util.DisplayController;
-import com.android.launcher3.util.DisplayController.NavigationMode;
+import com.android.launcher3.util.NavigationMode;
import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.TaskUtils;
import com.android.quickstep.views.RecentsView;
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index 6e616f3..81a5c1c 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -33,6 +33,7 @@
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_OVERVIEW_GESTURE;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_QUICKSWITCH_LEFT;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_QUICKSWITCH_RIGHT;
+import static com.android.launcher3.uioverrides.QuickstepLauncher.ENABLE_PIP_KEEP_CLEAR_ALGORITHM;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import static com.android.launcher3.util.SystemUiController.UI_STATE_FULLSCREEN_TASK;
@@ -333,6 +334,14 @@
return ActiveGestureErrorDetector.GestureEvent.STATE_GESTURE_COMPLETED;
} else if (stateFlag == STATE_GESTURE_CANCELLED) {
return ActiveGestureErrorDetector.GestureEvent.STATE_GESTURE_CANCELLED;
+ } else if (stateFlag == STATE_SCREENSHOT_CAPTURED) {
+ return ActiveGestureErrorDetector.GestureEvent.STATE_SCREENSHOT_CAPTURED;
+ } else if (stateFlag == STATE_CAPTURE_SCREENSHOT) {
+ return ActiveGestureErrorDetector.GestureEvent.STATE_CAPTURE_SCREENSHOT;
+ } else if (stateFlag == STATE_HANDLER_INVALIDATED) {
+ return ActiveGestureErrorDetector.GestureEvent.STATE_HANDLER_INVALIDATED;
+ } else if (stateFlag == STATE_LAUNCHER_DRAWN) {
+ return ActiveGestureErrorDetector.GestureEvent.STATE_LAUNCHER_DRAWN;
}
return null;
}
@@ -1221,6 +1230,8 @@
// Let RecentsView handle the scrolling to the task, which we launch in startNewTask()
// or resumeLastTask().
if (mRecentsView != null) {
+ ActiveGestureLog.INSTANCE.trackEvent(ActiveGestureErrorDetector.GestureEvent
+ .SET_ON_PAGE_TRANSITION_END_CALLBACK);
mRecentsView.setOnPageTransitionEndCallback(
() -> mGestureState.setState(STATE_RECENTS_SCROLLING_FINISHED));
} else {
@@ -1461,12 +1472,13 @@
homeToWindowPositionMap.invert(windowToHomePositionMap);
windowToHomePositionMap.mapRect(startRect);
+ final Rect hotseatKeepClearArea = getKeepClearAreaForHotseat();
final Rect destinationBounds = SystemUiProxy.INSTANCE.get(mContext)
.startSwipePipToHome(taskInfo.topActivity,
taskInfo.topActivityInfo,
runningTaskTarget.taskInfo.pictureInPictureParams,
homeRotation,
- mDp.hotseatBarSizePx);
+ hotseatKeepClearArea);
final Rect appBounds = new Rect();
final WindowConfiguration winConfig = taskInfo.configuration.windowConfiguration;
// Adjust the appBounds for TaskBar by using the calculated window crop Rect
@@ -1529,6 +1541,35 @@
return swipePipToHomeAnimator;
}
+ private Rect getKeepClearAreaForHotseat() {
+ Rect keepClearArea;
+ if (!ENABLE_PIP_KEEP_CLEAR_ALGORITHM) {
+ // make the height equal to hotseatBarSizePx only
+ keepClearArea = new Rect(0, 0, 0, mDp.hotseatBarSizePx);
+ return keepClearArea;
+ }
+ // the keep clear area in global screen coordinates, in pixels
+ if (mDp.isPhone) {
+ if (mDp.isSeascape()) {
+ // in seascape the Hotseat is on the left edge of the screen
+ keepClearArea = new Rect(0, 0, mDp.hotseatBarSizePx, mDp.heightPx);
+ } else if (mDp.isLandscape) {
+ // in landscape the Hotseat is on the right edge of the screen
+ keepClearArea = new Rect(mDp.widthPx - mDp.hotseatBarSizePx, 0,
+ mDp.widthPx, mDp.heightPx);
+ } else {
+ // in portrait mode the Hotseat is at the bottom of the screen
+ keepClearArea = new Rect(0, mDp.heightPx - mDp.hotseatBarSizePx,
+ mDp.widthPx, mDp.heightPx);
+ }
+ } else {
+ // large screens have Hotseat always at the bottom of the screen
+ keepClearArea = new Rect(0, mDp.heightPx - mDp.hotseatBarSizePx,
+ mDp.widthPx, mDp.heightPx);
+ }
+ return keepClearArea;
+ }
+
private void startInterceptingTouchesForGesture() {
if (mRecentsAnimationController == null) {
return;
@@ -1668,6 +1709,9 @@
* handler (in case of quick switch).
*/
private void cancelCurrentAnimation() {
+ ActiveGestureLog.INSTANCE.addLog(
+ "AbsSwipeUpHandler.cancelCurrentAnimation",
+ ActiveGestureErrorDetector.GestureEvent.CANCEL_CURRENT_ANIMATION);
mCanceled = true;
mCurrentShift.cancelAnimation();
diff --git a/quickstep/src/com/android/quickstep/BaseActivityInterface.java b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
index 6354282..315a91e 100644
--- a/quickstep/src/com/android/quickstep/BaseActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
@@ -55,7 +55,7 @@
import com.android.launcher3.taskbar.TaskbarUIController;
import com.android.launcher3.touch.PagedOrientationHandler;
import com.android.launcher3.util.DisplayController;
-import com.android.launcher3.util.DisplayController.NavigationMode;
+import com.android.launcher3.util.NavigationMode;
import com.android.launcher3.views.ScrimView;
import com.android.quickstep.util.ActivityInitListener;
import com.android.quickstep.util.AnimatorControllerWithResistance;
diff --git a/quickstep/src/com/android/quickstep/FallbackActivityInterface.java b/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
index ba61574..466abbe 100644
--- a/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
@@ -16,7 +16,7 @@
package com.android.quickstep;
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
-import static com.android.launcher3.util.DisplayController.NavigationMode.NO_BUTTON;
+import static com.android.launcher3.util.NavigationMode.NO_BUTTON;
import static com.android.quickstep.fallback.RecentsState.BACKGROUND_APP;
import static com.android.quickstep.fallback.RecentsState.DEFAULT;
import static com.android.quickstep.fallback.RecentsState.HOME;
diff --git a/quickstep/src/com/android/quickstep/GestureState.java b/quickstep/src/com/android/quickstep/GestureState.java
index bc2f551..38bf1fd 100644
--- a/quickstep/src/com/android/quickstep/GestureState.java
+++ b/quickstep/src/com/android/quickstep/GestureState.java
@@ -189,6 +189,8 @@
return ActiveGestureErrorDetector.GestureEvent.STATE_END_TARGET_ANIMATION_FINISHED;
} else if (stateFlag == STATE_RECENTS_SCROLLING_FINISHED) {
return ActiveGestureErrorDetector.GestureEvent.STATE_RECENTS_SCROLLING_FINISHED;
+ } else if (stateFlag == STATE_RECENTS_ANIMATION_CANCELED) {
+ return ActiveGestureErrorDetector.GestureEvent.STATE_RECENTS_ANIMATION_CANCELED;
}
return null;
}
diff --git a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
index 4ceafeb..1127e2c 100644
--- a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
@@ -45,7 +45,7 @@
import com.android.launcher3.touch.PagedOrientationHandler;
import com.android.launcher3.uioverrides.QuickstepLauncher;
import com.android.launcher3.util.DisplayController;
-import com.android.launcher3.util.DisplayController.NavigationMode;
+import com.android.launcher3.util.NavigationMode;
import com.android.quickstep.GestureState.GestureEndTarget;
import com.android.quickstep.util.ActivityInitListener;
import com.android.quickstep.util.AnimatorControllerWithResistance;
diff --git a/quickstep/src/com/android/quickstep/MultiStateCallback.java b/quickstep/src/com/android/quickstep/MultiStateCallback.java
index 56e7fb5..a68bea2 100644
--- a/quickstep/src/com/android/quickstep/MultiStateCallback.java
+++ b/quickstep/src/com/android/quickstep/MultiStateCallback.java
@@ -116,7 +116,13 @@
if (gestureEvent == null) {
continue;
}
- ActiveGestureLog.INSTANCE.trackEvent(gestureEvent);
+ if (gestureEvent.mLogEvent && gestureEvent.mTrackEvent) {
+ ActiveGestureLog.INSTANCE.addLog(gestureEvent.name(), gestureEvent);
+ } else if (gestureEvent.mLogEvent) {
+ ActiveGestureLog.INSTANCE.addLog(gestureEvent.name());
+ } else if (gestureEvent.mTrackEvent) {
+ ActiveGestureLog.INSTANCE.trackEvent(gestureEvent);
+ }
}
}
diff --git a/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java b/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java
index 47c5dd0..1b05fd2 100644
--- a/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java
+++ b/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java
@@ -34,7 +34,7 @@
import com.android.launcher3.R;
import com.android.launcher3.testing.shared.ResourceUtils;
import com.android.launcher3.util.DisplayController.Info;
-import com.android.launcher3.util.DisplayController.NavigationMode;
+import com.android.launcher3.util.NavigationMode;
import com.android.launcher3.util.window.CachedDisplayInfo;
import java.io.PrintWriter;
diff --git a/quickstep/src/com/android/quickstep/RecentTasksList.java b/quickstep/src/com/android/quickstep/RecentTasksList.java
index 813e687..5a9862c 100644
--- a/quickstep/src/com/android/quickstep/RecentTasksList.java
+++ b/quickstep/src/com/android/quickstep/RecentTasksList.java
@@ -27,9 +27,9 @@
import androidx.annotation.VisibleForTesting;
-import com.android.quickstep.util.GroupTask;
import com.android.launcher3.util.LooperExecutor;
import com.android.launcher3.util.SplitConfigurationOptions;
+import com.android.quickstep.util.GroupTask;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.system.KeyguardManagerCompat;
import com.android.wm.shell.recents.IRecentTasksListener;
@@ -254,8 +254,12 @@
TaskLoadResult allTasks = new TaskLoadResult(requestId, loadKeysOnly, rawTasks.size());
for (GroupedRecentTaskInfo rawTask : rawTasks) {
- ActivityManager.RecentTaskInfo taskInfo1 = rawTask.mTaskInfo1;
- ActivityManager.RecentTaskInfo taskInfo2 = rawTask.mTaskInfo2;
+ if (rawTask.getType() == GroupedRecentTaskInfo.TYPE_FREEFORM) {
+ // TODO: add entry for freeform tasks
+ continue;
+ }
+ ActivityManager.RecentTaskInfo taskInfo1 = rawTask.getTaskInfo1();
+ ActivityManager.RecentTaskInfo taskInfo2 = rawTask.getTaskInfo2();
Task.TaskKey task1Key = new Task.TaskKey(taskInfo1);
Task task1 = loadKeysOnly
? new Task(task1Key)
@@ -272,7 +276,7 @@
task2.setLastSnapshotData(taskInfo2);
}
final SplitConfigurationOptions.SplitBounds launcherSplitBounds =
- convertSplitBounds(rawTask.mSplitBounds);
+ convertSplitBounds(rawTask.getSplitBounds());
allTasks.add(new GroupTask(task1, task2, launcherSplitBounds));
}
@@ -310,8 +314,8 @@
mSysUiProxy.getRecentTasks(Integer.MAX_VALUE, currentUserId);
writer.println(prefix + " rawTasks=[");
for (GroupedRecentTaskInfo task : rawTasks) {
- writer.println(prefix + " t1=" + task.mTaskInfo1.taskId
- + " t2=" + (task.mTaskInfo2 != null ? task.mTaskInfo2.taskId : "-1"));
+ writer.println(prefix + " t1=" + task.getTaskInfo1().taskId
+ + " t2=" + (task.getTaskInfo2() != null ? task.getTaskInfo2().taskId : "-1"));
}
writer.println(prefix + " ]");
}
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationController.java b/quickstep/src/com/android/quickstep/RecentsAnimationController.java
index fefef2f..542c0d4 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationController.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationController.java
@@ -32,6 +32,8 @@
import com.android.launcher3.util.Preconditions;
import com.android.launcher3.util.RunnableList;
+import com.android.quickstep.util.ActiveGestureErrorDetector;
+import com.android.quickstep.util.ActiveGestureLog;
import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
import com.android.systemui.shared.system.RecentsAnimationControllerCompat;
@@ -172,7 +174,12 @@
*/
@UiThread
public void cleanupScreenshot() {
- UI_HELPER_EXECUTOR.execute(() -> mController.cleanupScreenshot());
+ UI_HELPER_EXECUTOR.execute(() -> {
+ ActiveGestureLog.INSTANCE.addLog(
+ "cleanupScreenshot",
+ ActiveGestureErrorDetector.GestureEvent.CLEANUP_SCREENSHOT);
+ mController.cleanupScreenshot();
+ });
}
/**
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
index b6cfbb0..e87fdad 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
@@ -23,9 +23,9 @@
import static com.android.launcher3.util.DisplayController.CHANGE_ALL;
import static com.android.launcher3.util.DisplayController.CHANGE_NAVIGATION_MODE;
import static com.android.launcher3.util.DisplayController.CHANGE_ROTATION;
-import static com.android.launcher3.util.DisplayController.NavigationMode.NO_BUTTON;
-import static com.android.launcher3.util.DisplayController.NavigationMode.THREE_BUTTONS;
-import static com.android.launcher3.util.DisplayController.NavigationMode.TWO_BUTTONS;
+import static com.android.launcher3.util.NavigationMode.NO_BUTTON;
+import static com.android.launcher3.util.NavigationMode.THREE_BUTTONS;
+import static com.android.launcher3.util.NavigationMode.TWO_BUTTONS;
import static com.android.launcher3.util.SettingsCache.ONE_HANDED_ENABLED;
import static com.android.launcher3.util.SettingsCache.ONE_HANDED_SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_CLICKABLE;
@@ -67,7 +67,7 @@
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.DisplayController.DisplayInfoChangeListener;
import com.android.launcher3.util.DisplayController.Info;
-import com.android.launcher3.util.DisplayController.NavigationMode;
+import com.android.launcher3.util.NavigationMode;
import com.android.launcher3.util.SettingsCache;
import com.android.quickstep.TopTaskTracker.CachedTaskInfo;
import com.android.quickstep.util.NavBarPosition;
diff --git a/quickstep/src/com/android/quickstep/RotationTouchHelper.java b/quickstep/src/com/android/quickstep/RotationTouchHelper.java
index 2186a3b..f8b6966 100644
--- a/quickstep/src/com/android/quickstep/RotationTouchHelper.java
+++ b/quickstep/src/com/android/quickstep/RotationTouchHelper.java
@@ -23,8 +23,8 @@
import static com.android.launcher3.util.DisplayController.CHANGE_NAVIGATION_MODE;
import static com.android.launcher3.util.DisplayController.CHANGE_ROTATION;
import static com.android.launcher3.util.DisplayController.CHANGE_SUPPORTED_BOUNDS;
-import static com.android.launcher3.util.DisplayController.NavigationMode.THREE_BUTTONS;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
+import static com.android.launcher3.util.NavigationMode.THREE_BUTTONS;
import android.content.Context;
import android.content.res.Resources;
@@ -35,8 +35,8 @@
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.DisplayController.DisplayInfoChangeListener;
import com.android.launcher3.util.DisplayController.Info;
-import com.android.launcher3.util.DisplayController.NavigationMode;
import com.android.launcher3.util.MainThreadInitializedObject;
+import com.android.launcher3.util.NavigationMode;
import com.android.quickstep.util.RecentsOrientedState;
import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.shared.system.TaskStackChangeListener;
diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java
index 0ec7e62..8e9ff2f 100644
--- a/quickstep/src/com/android/quickstep/SystemUiProxy.java
+++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java
@@ -28,7 +28,7 @@
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
-import android.graphics.Bitmap;
+import android.content.pm.ShortcutInfo;
import android.graphics.Insets;
import android.graphics.Rect;
import android.os.Bundle;
@@ -509,11 +509,12 @@
}
public Rect startSwipePipToHome(ComponentName componentName, ActivityInfo activityInfo,
- PictureInPictureParams pictureInPictureParams, int launcherRotation, int shelfHeight) {
+ PictureInPictureParams pictureInPictureParams, int launcherRotation,
+ Rect hotseatKeepClearArea) {
if (mPip != null) {
try {
return mPip.startSwipePipToHome(componentName, activityInfo,
- pictureInPictureParams, launcherRotation, shelfHeight);
+ pictureInPictureParams, launcherRotation, hotseatKeepClearArea);
} catch (RemoteException e) {
Log.w(TAG, "Failed call startSwipePipToHome", e);
}
@@ -602,7 +603,21 @@
mSplitScreen.startIntentAndTaskWithLegacyTransition(pendingIntent, fillInIntent,
taskId, mainOptions, sideOptions, sidePosition, splitRatio, adapter);
} catch (RemoteException e) {
- Log.w(TAG, "Failed call startTasksWithLegacyTransition");
+ Log.w(TAG, "Failed call startIntentAndTaskWithLegacyTransition");
+ }
+ }
+ }
+
+ public void startShortcutAndTaskWithLegacyTransition(ShortcutInfo shortcutInfo, int taskId,
+ Bundle mainOptions, Bundle sideOptions,
+ @SplitConfigurationOptions.StagePosition int sidePosition, float splitRatio,
+ RemoteAnimationAdapter adapter) {
+ if (mSystemUiProxy != null) {
+ try {
+ mSplitScreen.startShortcutAndTaskWithLegacyTransition(shortcutInfo, taskId,
+ mainOptions, sideOptions, sidePosition, splitRatio, adapter);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed call startShortcutAndTaskWithLegacyTransition");
}
}
}
diff --git a/quickstep/src/com/android/quickstep/TaskAnimationManager.java b/quickstep/src/com/android/quickstep/TaskAnimationManager.java
index 0314761..5fb806d 100644
--- a/quickstep/src/com/android/quickstep/TaskAnimationManager.java
+++ b/quickstep/src/com/android/quickstep/TaskAnimationManager.java
@@ -36,6 +36,8 @@
import com.android.launcher3.Utilities;
import com.android.launcher3.config.FeatureFlags;
import com.android.quickstep.TopTaskTracker.CachedTaskInfo;
+import com.android.quickstep.util.ActiveGestureErrorDetector;
+import com.android.quickstep.util.ActiveGestureLog;
import com.android.quickstep.views.RecentsView;
import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.system.ActivityManagerWrapper;
@@ -136,6 +138,8 @@
// handling this call entirely
return;
}
+ ActiveGestureLog.INSTANCE.addLog("TaskAnimationManager.startRecentsAnimation",
+ ActiveGestureErrorDetector.GestureEvent.START_RECENTS_ANIMATION);
mController = controller;
mTargets = targets;
mLastAppearedTaskTarget = mTargets.findTask(mLastGestureState.getRunningTaskId());
diff --git a/quickstep/src/com/android/quickstep/TaskViewUtils.java b/quickstep/src/com/android/quickstep/TaskViewUtils.java
index a809c9c..556b99e 100644
--- a/quickstep/src/com/android/quickstep/TaskViewUtils.java
+++ b/quickstep/src/com/android/quickstep/TaskViewUtils.java
@@ -43,7 +43,6 @@
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
-import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.annotation.TargetApi;
import android.app.PendingIntent;
@@ -195,10 +194,10 @@
int taskIndex = recentsView.indexOfChild(v);
Context context = v.getContext();
- DeviceProfile dp = BaseActivity.fromContext(context).getDeviceProfile();
+ BaseActivity baseActivity = BaseActivity.fromContext(context);
+ DeviceProfile dp = baseActivity.getDeviceProfile();
boolean showAsGrid = dp.isTablet;
- boolean parallaxCenterAndAdjacentTask =
- taskIndex != recentsView.getCurrentPage() && !showAsGrid;
+ boolean parallaxCenterAndAdjacentTask = taskIndex != recentsView.getCurrentPage();
int taskRectTranslationPrimary = recentsView.getScrollOffset(taskIndex);
int taskRectTranslationSecondary = showAsGrid ? (int) v.getGridTranslationY() : 0;
@@ -368,7 +367,7 @@
});
if (depthController != null) {
- out.setFloat(depthController, DEPTH, BACKGROUND_APP.getDepth(context),
+ out.setFloat(depthController, DEPTH, BACKGROUND_APP.getDepth(baseActivity),
TOUCH_RESPONSE_INTERPOLATOR);
}
}
@@ -602,11 +601,7 @@
if (raController != null) {
raController.setWillFinishToHome(false);
}
- Context context = v.getContext();
- DeviceProfile dp = BaseActivity.fromContext(context).getDeviceProfile();
- launcherAnim = dp.isTablet
- ? ObjectAnimator.ofFloat(recentsView, RecentsView.CONTENT_ALPHA, 0)
- : recentsView.createAdjacentPageAnimForTaskLaunch(taskView);
+ launcherAnim = recentsView.createAdjacentPageAnimForTaskLaunch(taskView);
launcherAnim.setInterpolator(Interpolators.TOUCH_RESPONSE_INTERPOLATOR);
launcherAnim.setDuration(RECENTS_LAUNCH_DURATION);
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index 82be3ec..040c55b 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -82,6 +82,7 @@
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.OnboardingPrefs;
import com.android.launcher3.util.TraceHelper;
+import com.android.launcher3.util.ViewCapture;
import com.android.launcher3.util.WindowBounds;
import com.android.quickstep.inputconsumers.AccessibilityInputConsumer;
import com.android.quickstep.inputconsumers.AssistantInputConsumer;
@@ -461,7 +462,8 @@
mOverviewComponentObserver = new OverviewComponentObserver(this, mDeviceState);
mOverviewCommandHelper = new OverviewCommandHelper(this,
mOverviewComponentObserver, mTaskAnimationManager);
- mResetGestureInputConsumer = new ResetGestureInputConsumer(mTaskAnimationManager);
+ mResetGestureInputConsumer = new ResetGestureInputConsumer(
+ mTaskAnimationManager, mTaskbarManager::getCurrentActivityContext);
mInputConsumer = InputConsumerController.getRecentsAnimationInputConsumer();
mInputConsumer.registerInputConsumer();
onSystemUiFlagsChanged(mDeviceState.getSystemUiStateFlags());
@@ -721,8 +723,10 @@
gestureState.updateRunningTask(taskInfo);
}
// Log initial state for the gesture.
- ActiveGestureLog.INSTANCE.addLog(
- "Current SystemUi state flags= " + mDeviceState.getSystemUiStateString());
+ ActiveGestureLog.INSTANCE.addLog(new CompoundString("Current running task package name=")
+ .append(taskInfo == null ? "no running task" : taskInfo.getPackageName()));
+ ActiveGestureLog.INSTANCE.addLog(new CompoundString("Current SystemUi state flags=")
+ .append(mDeviceState.getSystemUiStateString()));
return gestureState;
}
@@ -1024,12 +1028,27 @@
.append("activity == null, trying to use default input consumer"));
}
- if (activity.getRootView().hasWindowFocus()
- || previousGestureState.isRunningAnimationToLauncher()
- || (ASSISTANT_GIVES_LAUNCHER_FOCUS.get()
- && forceOverviewInputConsumer)
- || (ENABLE_QUICKSTEP_LIVE_TILE.get()
- && gestureState.getActivityInterface().isInLiveTileMode())) {
+ boolean hasWindowFocus = activity.getRootView().hasWindowFocus();
+ boolean isPreviousGestureAnimatingToLauncher =
+ previousGestureState.isRunningAnimationToLauncher();
+ boolean forcingOverviewInputConsumer =
+ ASSISTANT_GIVES_LAUNCHER_FOCUS.get() && forceOverviewInputConsumer;
+ boolean isInLiveTileMode = ENABLE_QUICKSTEP_LIVE_TILE.get()
+ && gestureState.getActivityInterface().isInLiveTileMode();
+ reasonString.append(SUBSTRING_PREFIX)
+ .append(hasWindowFocus
+ ? "activity has window focus"
+ : (isPreviousGestureAnimatingToLauncher
+ ? "previous gesture is still animating to launcher"
+ : (forcingOverviewInputConsumer
+ ? "assistant gives launcher focus and forcing focus"
+ : (isInLiveTileMode
+ ? "device is in live mode"
+ : "all overview focus conditions failed"))));
+ if (hasWindowFocus
+ || isPreviousGestureAnimatingToLauncher
+ || forcingOverviewInputConsumer
+ || isInLiveTileMode) {
reasonString.append(SUBSTRING_PREFIX)
.append("overview should have focus, using OverviewInputConsumer");
return new OverviewInputConsumer(gestureState, activity, mInputMonitorCompat,
@@ -1196,6 +1215,8 @@
createdOverviewActivity.getDeviceProfile().dump(this, "", pw);
}
mTaskbarManager.dumpLogs("", pw);
+
+ ViewCapture.INSTANCE.get(this).dump(pw, fd);
}
}
diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackNavBarTouchController.java b/quickstep/src/com/android/quickstep/fallback/FallbackNavBarTouchController.java
index 3e01ed0..8a87f63 100644
--- a/quickstep/src/com/android/quickstep/fallback/FallbackNavBarTouchController.java
+++ b/quickstep/src/com/android/quickstep/fallback/FallbackNavBarTouchController.java
@@ -22,7 +22,7 @@
import com.android.launcher3.Utilities;
import com.android.launcher3.util.DisplayController;
-import com.android.launcher3.util.DisplayController.NavigationMode;
+import com.android.launcher3.util.NavigationMode;
import com.android.launcher3.util.TouchController;
import com.android.quickstep.RecentsActivity;
import com.android.quickstep.util.NavBarPosition;
diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
index eb739a6..7c96bf8 100644
--- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
+++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
@@ -227,6 +227,11 @@
}
@Override
+ public void onStateTransitionFailed(RecentsState toState) {
+ reset();
+ }
+
+ @Override
public void onStateTransitionComplete(RecentsState finalState) {
if (finalState == HOME) {
// Clean-up logic that occurs when recents is no longer in use/visible.
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/ProgressDelegateInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/ProgressDelegateInputConsumer.java
index 2462394..b9b5e7c 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/ProgressDelegateInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/ProgressDelegateInputConsumer.java
@@ -28,6 +28,8 @@
import android.graphics.Point;
import android.view.MotionEvent;
+import androidx.annotation.Nullable;
+
import com.android.launcher3.anim.AnimatorListeners;
import com.android.launcher3.testing.TestLogging;
import com.android.launcher3.testing.shared.TestProtocol;
@@ -41,6 +43,7 @@
import com.android.quickstep.RecentsAnimationController;
import com.android.quickstep.RecentsAnimationTargets;
import com.android.quickstep.TaskAnimationManager;
+import com.android.quickstep.util.ActiveGestureErrorDetector;
import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.system.InputMonitorCompat;
@@ -99,7 +102,8 @@
mDisplaySize = DisplayController.INSTANCE.get(context).getInfo().currentSize;
// Init states
- mStateCallback = new MultiStateCallback(STATE_NAMES);
+ mStateCallback = new MultiStateCallback(
+ STATE_NAMES, ProgressDelegateInputConsumer::getTrackedEventForState);
mStateCallback.runOnceAtState(STATE_TARGET_RECEIVED | STATE_HANDLER_INVALIDATED,
this::endRemoteAnimation);
mStateCallback.runOnceAtState(STATE_TARGET_RECEIVED | STATE_FLING_FINISHED,
@@ -109,6 +113,14 @@
mSwipeDetector.setDetectableScrollConditions(DIRECTION_POSITIVE, false);
}
+ @Nullable
+ private static ActiveGestureErrorDetector.GestureEvent getTrackedEventForState(int stateFlag) {
+ if (stateFlag == STATE_HANDLER_INVALIDATED) {
+ return ActiveGestureErrorDetector.GestureEvent.STATE_HANDLER_INVALIDATED;
+ }
+ return null;
+ }
+
@Override
public int getType() {
return TYPE_PROGRESS_DELEGATE;
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/ResetGestureInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/ResetGestureInputConsumer.java
index d34b40b..349f4d2 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/ResetGestureInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/ResetGestureInputConsumer.java
@@ -17,18 +17,25 @@
import android.view.MotionEvent;
+import com.android.launcher3.taskbar.TaskbarActivityContext;
import com.android.quickstep.InputConsumer;
import com.android.quickstep.TaskAnimationManager;
+import java.util.function.Supplier;
+
/**
* A NO_OP input consumer which also resets any pending gesture
*/
public class ResetGestureInputConsumer implements InputConsumer {
private final TaskAnimationManager mTaskAnimationManager;
+ private final Supplier<TaskbarActivityContext> mActivityContextSupplier;
- public ResetGestureInputConsumer(TaskAnimationManager taskAnimationManager) {
+ public ResetGestureInputConsumer(
+ TaskAnimationManager taskAnimationManager,
+ Supplier<TaskbarActivityContext> activityContextSupplier) {
mTaskAnimationManager = taskAnimationManager;
+ mActivityContextSupplier = activityContextSupplier;
}
@Override
@@ -40,7 +47,9 @@
public void onMotionEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN
&& mTaskAnimationManager.isRecentsAnimationRunning()) {
- mTaskAnimationManager.finishRunningRecentsAnimation(false /* toHome */);
+ TaskbarActivityContext tac = mActivityContextSupplier.get();
+ mTaskAnimationManager.finishRunningRecentsAnimation(
+ /* toHome= */ tac != null && !tac.isInApp());
}
}
}
diff --git a/quickstep/src/com/android/quickstep/interaction/NavBarGestureHandler.java b/quickstep/src/com/android/quickstep/interaction/NavBarGestureHandler.java
index 4badf30..e7bf7e2 100644
--- a/quickstep/src/com/android/quickstep/interaction/NavBarGestureHandler.java
+++ b/quickstep/src/com/android/quickstep/interaction/NavBarGestureHandler.java
@@ -44,10 +44,10 @@
import androidx.annotation.Nullable;
import com.android.launcher3.R;
-import com.android.launcher3.testing.shared.ResourceUtils;
import com.android.launcher3.anim.Interpolators;
+import com.android.launcher3.testing.shared.ResourceUtils;
import com.android.launcher3.util.DisplayController;
-import com.android.launcher3.util.DisplayController.NavigationMode;
+import com.android.launcher3.util.NavigationMode;
import com.android.quickstep.util.MotionPauseDetector;
import com.android.quickstep.util.NavBarPosition;
import com.android.quickstep.util.TriggerSwipeUpTouchTracker;
diff --git a/quickstep/src/com/android/quickstep/logging/SettingsChangeLogger.java b/quickstep/src/com/android/quickstep/logging/SettingsChangeLogger.java
index 99553e8..2ccdfa3 100644
--- a/quickstep/src/com/android/quickstep/logging/SettingsChangeLogger.java
+++ b/quickstep/src/com/android/quickstep/logging/SettingsChangeLogger.java
@@ -46,8 +46,8 @@
import com.android.launcher3.model.DeviceGridState;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.DisplayController.Info;
-import com.android.launcher3.util.DisplayController.NavigationMode;
import com.android.launcher3.util.MainThreadInitializedObject;
+import com.android.launcher3.util.NavigationMode;
import com.android.launcher3.util.SettingsCache;
import org.xmlpull.v1.XmlPullParser;
diff --git a/quickstep/src/com/android/quickstep/util/ActiveGestureErrorDetector.java b/quickstep/src/com/android/quickstep/util/ActiveGestureErrorDetector.java
index 78075de..693ef10 100644
--- a/quickstep/src/com/android/quickstep/util/ActiveGestureErrorDetector.java
+++ b/quickstep/src/com/android/quickstep/util/ActiveGestureErrorDetector.java
@@ -29,11 +29,36 @@
*/
public class ActiveGestureErrorDetector {
+ /**
+ * Enums associated to gesture navigation events.
+ */
public enum GestureEvent {
MOTION_DOWN, MOTION_UP, SET_END_TARGET, ON_SETTLED_ON_END_TARGET, START_RECENTS_ANIMATION,
- FINISH_RECENTS_ANIMATION, CANCEL_RECENTS_ANIMATION, STATE_GESTURE_STARTED,
- STATE_GESTURE_COMPLETED, STATE_GESTURE_CANCELLED, STATE_END_TARGET_ANIMATION_FINISHED,
- STATE_RECENTS_SCROLLING_FINISHED
+ FINISH_RECENTS_ANIMATION, CANCEL_RECENTS_ANIMATION, SET_ON_PAGE_TRANSITION_END_CALLBACK,
+ CANCEL_CURRENT_ANIMATION, CLEANUP_SCREENSHOT,
+
+ /**
+ * These GestureEvents are specifically associated to state flags that get set in
+ * {@link com.android.quickstep.MultiStateCallback}. If a state flag needs to be tracked
+ * for error detection, an enum should be added here and that state flag-enum pair should
+ * be added to the state flag's container class' {@code getTrackedEventForState} method.
+ */
+ STATE_GESTURE_STARTED, STATE_GESTURE_COMPLETED, STATE_GESTURE_CANCELLED,
+ STATE_END_TARGET_ANIMATION_FINISHED, STATE_RECENTS_SCROLLING_FINISHED,
+ STATE_CAPTURE_SCREENSHOT, STATE_SCREENSHOT_CAPTURED, STATE_HANDLER_INVALIDATED,
+ STATE_RECENTS_ANIMATION_CANCELED, STATE_LAUNCHER_DRAWN(true, false);
+
+ public final boolean mLogEvent;
+ public final boolean mTrackEvent;
+
+ GestureEvent() {
+ this(false, true);
+ }
+
+ GestureEvent(boolean logEvent, boolean trackEvent) {
+ mLogEvent = logEvent;
+ mTrackEvent = trackEvent;
+ }
}
private ActiveGestureErrorDetector() {}
@@ -90,6 +115,14 @@
+ "before/without startRecentsAnimation.",
writer);
break;
+ case CLEANUP_SCREENSHOT:
+ errorDetected |= printErrorIfTrue(
+ !encounteredEvents.contains(GestureEvent.STATE_SCREENSHOT_CAPTURED),
+ /* errorMessage= */ prefix + "\t\trecents activity screenshot was "
+ + "cleaned up before/without STATE_SCREENSHOT_CAPTURED "
+ + "being set.",
+ writer);
+ break;
case STATE_GESTURE_COMPLETED:
errorDetected |= printErrorIfTrue(
!encounteredEvents.contains(GestureEvent.MOTION_UP),
@@ -114,12 +147,40 @@
+ "before/without STATE_GESTURE_STARTED.",
writer);
break;
+ case STATE_SCREENSHOT_CAPTURED:
+ errorDetected |= printErrorIfTrue(
+ !encounteredEvents.contains(GestureEvent.STATE_CAPTURE_SCREENSHOT),
+ /* errorMessage= */ prefix + "\t\tSTATE_SCREENSHOT_CAPTURED set "
+ + "before/without STATE_CAPTURE_SCREENSHOT.",
+ writer);
+ break;
+ case STATE_RECENTS_SCROLLING_FINISHED:
+ errorDetected |= printErrorIfTrue(
+ !encounteredEvents.contains(
+ GestureEvent.SET_ON_PAGE_TRANSITION_END_CALLBACK),
+ /* errorMessage= */ prefix + "\t\tSTATE_RECENTS_SCROLLING_FINISHED "
+ + "set before/without calling "
+ + "setOnPageTransitionEndCallback.",
+ writer);
+ break;
+ case STATE_RECENTS_ANIMATION_CANCELED:
+ errorDetected |= printErrorIfTrue(
+ !encounteredEvents.contains(
+ GestureEvent.START_RECENTS_ANIMATION),
+ /* errorMessage= */ prefix + "\t\tSTATE_RECENTS_ANIMATION_CANCELED "
+ + "set before/without startRecentsAnimation.",
+ writer);
+ break;
case MOTION_DOWN:
case SET_END_TARGET:
case START_RECENTS_ANIMATION:
+ case SET_ON_PAGE_TRANSITION_END_CALLBACK:
+ case CANCEL_CURRENT_ANIMATION:
case STATE_GESTURE_STARTED:
case STATE_END_TARGET_ANIMATION_FINISHED:
- case STATE_RECENTS_SCROLLING_FINISHED:
+ case STATE_CAPTURE_SCREENSHOT:
+ case STATE_HANDLER_INVALIDATED:
+ case STATE_LAUNCHER_DRAWN:
default:
// No-Op
}
@@ -183,6 +244,39 @@
+ "STATE_GESTURE_COMPLETED and STATE_GESTURE_CANCELLED weren't.",
writer);
+ errorDetected |= printErrorIfTrue(
+ /* condition= */ encounteredEvents.contains(
+ GestureEvent.STATE_CAPTURE_SCREENSHOT)
+ && !encounteredEvents.contains(GestureEvent.STATE_SCREENSHOT_CAPTURED),
+ /* errorMessage= */ prefix + "\t\tSTATE_CAPTURE_SCREENSHOT was set, but "
+ + "STATE_SCREENSHOT_CAPTURED wasn't.",
+ writer);
+
+ errorDetected |= printErrorIfTrue(
+ /* condition= */ encounteredEvents.contains(
+ GestureEvent.SET_ON_PAGE_TRANSITION_END_CALLBACK)
+ && !encounteredEvents.contains(
+ GestureEvent.STATE_RECENTS_SCROLLING_FINISHED),
+ /* errorMessage= */ prefix + "\t\tsetOnPageTransitionEndCallback called, but "
+ + "STATE_RECENTS_SCROLLING_FINISHED wasn't set.",
+ writer);
+
+ errorDetected |= printErrorIfTrue(
+ /* condition= */ !encounteredEvents.contains(
+ GestureEvent.CANCEL_CURRENT_ANIMATION)
+ && !encounteredEvents.contains(GestureEvent.STATE_HANDLER_INVALIDATED),
+ /* errorMessage= */ prefix + "\t\tAbsSwipeUpHandler.cancelCurrentAnimation "
+ + "wasn't called and STATE_HANDLER_INVALIDATED wasn't set.",
+ writer);
+
+ errorDetected |= printErrorIfTrue(
+ /* condition= */ encounteredEvents.contains(
+ GestureEvent.STATE_RECENTS_ANIMATION_CANCELED)
+ && !encounteredEvents.contains(GestureEvent.CLEANUP_SCREENSHOT),
+ /* errorMessage= */ prefix + "\t\tSTATE_RECENTS_ANIMATION_CANCELED was set but "
+ + "the task screenshot wasn't cleaned up.",
+ writer);
+
if (!errorDetected) {
writer.println(prefix + "\t\tNo errors detected.");
}
diff --git a/quickstep/src/com/android/quickstep/util/ActiveGestureLog.java b/quickstep/src/com/android/quickstep/util/ActiveGestureLog.java
index 9f08010..40eb31b 100644
--- a/quickstep/src/com/android/quickstep/util/ActiveGestureLog.java
+++ b/quickstep/src/com/android/quickstep/util/ActiveGestureLog.java
@@ -138,14 +138,10 @@
List<EventEntry> lastEventEntries = lastEventLog.eventEntries;
EventEntry lastEntry = lastEventEntries.size() > 0
? lastEventEntries.get(lastEventEntries.size() - 1) : null;
- EventEntry secondLastEntry = lastEventEntries.size() > 1
- ? lastEventEntries.get(lastEventEntries.size() - 2) : null;
// Update the last EventEntry if it's a duplicate
- if (isEntrySame(lastEntry, type, event, compoundString, gestureEvent)
- && isEntrySame(secondLastEntry, type, event, compoundString, gestureEvent)) {
- lastEntry.update(type, event, extras, compoundString, gestureEvent);
- secondLastEntry.duplicateCount++;
+ if (isEntrySame(lastEntry, type, event, extras, compoundString, gestureEvent)) {
+ lastEntry.duplicateCount++;
return;
}
EventEntry eventEntry = new EventEntry();
@@ -223,11 +219,13 @@
EventEntry entry,
int type,
String event,
+ float extras,
CompoundString compoundString,
ActiveGestureErrorDetector.GestureEvent gestureEvent) {
return entry != null
&& entry.type == type
&& entry.event.equals(event)
+ && Float.compare(entry.extras, extras) == 0
&& entry.mCompoundString.equals(compoundString)
&& entry.gestureEvent == gestureEvent;
}
@@ -342,7 +340,7 @@
return false;
}
CompoundString other = (CompoundString) obj;
- return mIsNoOp && other.mIsNoOp && Objects.equals(mSubstrings, other.mSubstrings);
+ return (mIsNoOp == other.mIsNoOp) && Objects.equals(mSubstrings, other.mSubstrings);
}
}
}
diff --git a/quickstep/src/com/android/quickstep/util/LayoutUtils.java b/quickstep/src/com/android/quickstep/util/LayoutUtils.java
index d0856be..f7136a5 100644
--- a/quickstep/src/com/android/quickstep/util/LayoutUtils.java
+++ b/quickstep/src/com/android/quickstep/util/LayoutUtils.java
@@ -23,7 +23,7 @@
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.touch.PagedOrientationHandler;
import com.android.launcher3.util.DisplayController;
-import com.android.launcher3.util.DisplayController.NavigationMode;
+import com.android.launcher3.util.NavigationMode;
import com.android.quickstep.LauncherActivityInterface;
public class LayoutUtils {
diff --git a/quickstep/src/com/android/quickstep/util/NavBarPosition.java b/quickstep/src/com/android/quickstep/util/NavBarPosition.java
index 527a6d2..59c8263 100644
--- a/quickstep/src/com/android/quickstep/util/NavBarPosition.java
+++ b/quickstep/src/com/android/quickstep/util/NavBarPosition.java
@@ -15,12 +15,12 @@
*/
package com.android.quickstep.util;
-import static com.android.launcher3.util.DisplayController.NavigationMode.NO_BUTTON;
+import static com.android.launcher3.util.NavigationMode.NO_BUTTON;
import android.view.Surface;
import com.android.launcher3.util.DisplayController.Info;
-import com.android.launcher3.util.DisplayController.NavigationMode;
+import com.android.launcher3.util.NavigationMode;
/**
* Utility class to check nav bar position.
diff --git a/quickstep/src/com/android/quickstep/util/QuickstepOnboardingPrefs.java b/quickstep/src/com/android/quickstep/util/QuickstepOnboardingPrefs.java
index fc44b99..e928b27 100644
--- a/quickstep/src/com/android/quickstep/util/QuickstepOnboardingPrefs.java
+++ b/quickstep/src/com/android/quickstep/util/QuickstepOnboardingPrefs.java
@@ -21,7 +21,7 @@
import static com.android.launcher3.LauncherState.HINT_STATE;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.OVERVIEW;
-import static com.android.launcher3.util.DisplayController.NavigationMode.NO_BUTTON;
+import static com.android.launcher3.util.NavigationMode.NO_BUTTON;
import android.content.SharedPreferences;
diff --git a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
index 8f32214..7efb1a5 100644
--- a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
+++ b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
@@ -31,16 +31,20 @@
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ShortcutInfo;
import android.os.Handler;
import android.os.IBinder;
import android.os.UserHandle;
import android.text.TextUtils;
+import android.util.Log;
import android.view.RemoteAnimationAdapter;
import android.view.SurfaceControl;
import android.window.TransitionInfo;
import androidx.annotation.Nullable;
+import com.android.launcher3.shortcuts.ShortcutKey;
import com.android.launcher3.statehandlers.DepthController;
import com.android.launcher3.statemanager.StateManager;
import com.android.launcher3.testing.TestLogging;
@@ -66,6 +70,7 @@
* and is in the process of either a) selecting a second app or b) exiting intention to invoke split
*/
public class SplitSelectStateController {
+ private static final String TAG = "SplitSelectStateCtor";
private final Context mContext;
private final Handler mHandler;
@@ -196,7 +201,7 @@
null /* sideOptions */, STAGE_POSITION_BOTTOM_OR_RIGHT, splitRatio,
new RemoteTransitionCompat(animationRunner, MAIN_EXECUTOR,
ActivityThread.currentActivityThread().getApplicationThread()));
- // TODO: handle intent + task with shell transition
+ // TODO(b/237635859): handle intent/shortcut + task with shell transition
} else {
RemoteSplitLaunchAnimationRunner animationRunner =
new RemoteSplitLaunchAnimationRunner(taskId1, taskPendingIntent, taskId2,
@@ -215,9 +220,17 @@
taskIds[1], null /* sideOptions */, STAGE_POSITION_BOTTOM_OR_RIGHT,
splitRatio, adapter);
} else {
- mSystemUiProxy.startIntentAndTaskWithLegacyTransition(taskPendingIntent,
- fillInIntent, taskId2, mainOpts.toBundle(), null /* sideOptions */,
- stagePosition, splitRatio, adapter);
+ final ShortcutInfo shortcutInfo = getShortcutInfo(mInitialTaskIntent,
+ taskPendingIntent.getCreatorUserHandle());
+ if (shortcutInfo != null) {
+ mSystemUiProxy.startShortcutAndTaskWithLegacyTransition(shortcutInfo, taskId2,
+ mainOpts.toBundle(), null /* sideOptions */, stagePosition, splitRatio,
+ adapter);
+ } else {
+ mSystemUiProxy.startIntentAndTaskWithLegacyTransition(taskPendingIntent,
+ fillInIntent, taskId2, mainOpts.toBundle(), null /* sideOptions */,
+ stagePosition, splitRatio, adapter);
+ }
}
}
}
@@ -230,6 +243,28 @@
this.mRecentsAnimationRunning = running;
}
+ @Nullable
+ private ShortcutInfo getShortcutInfo(Intent intent, UserHandle userHandle) {
+ if (intent == null || intent.getPackage() == null) {
+ return null;
+ }
+
+ final String shortcutId = intent.getStringExtra(ShortcutKey.EXTRA_SHORTCUT_ID);
+ if (shortcutId == null) {
+ return null;
+ }
+
+ try {
+ final Context context = mContext.createPackageContextAsUser(
+ intent.getPackage(), 0 /* flags */, userHandle);
+ return new ShortcutInfo.Builder(context, shortcutId).build();
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.w(TAG, "Failed to create a ShortcutInfo for " + intent.getPackage());
+ }
+
+ return null;
+ }
+
/**
* Requires Shell Transitions
*/
diff --git a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
index d37300c..0a49008 100644
--- a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
+++ b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
@@ -102,7 +102,7 @@
private boolean mLayoutValid = false;
private int mOrientationStateId;
private SplitBounds mSplitBounds;
- private boolean mDrawsBelowRecents;
+ private Boolean mDrawsBelowRecents = null;
private boolean mIsGridTask;
private int mTaskRectTranslationX;
private int mTaskRectTranslationY;
@@ -391,7 +391,8 @@
.withWindowCrop(mTmpCropRect)
.withCornerRadius(getCurrentCornerRadius());
- if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
+ // If mDrawsBelowRecents is unset, no reordering will be enforced.
+ if (ENABLE_QUICKSTEP_LIVE_TILE.get() && mDrawsBelowRecents != null) {
// In legacy transitions, the animation leashes remain in same hierarchy in the
// TaskDisplayArea, so we don't want to bump the layer too high otherwise it will
// conflict with layers that WM core positions (ie. the input consumers). For shell
diff --git a/quickstep/src/com/android/quickstep/views/FloatingTaskView.java b/quickstep/src/com/android/quickstep/views/FloatingTaskView.java
index 7a66ea0..c3bf041 100644
--- a/quickstep/src/com/android/quickstep/views/FloatingTaskView.java
+++ b/quickstep/src/com/android/quickstep/views/FloatingTaskView.java
@@ -14,6 +14,7 @@
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
+import android.util.FloatProperty;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
@@ -49,6 +50,29 @@
*/
public class FloatingTaskView extends FrameLayout {
+ public static final FloatProperty<FloatingTaskView> PRIMARY_TRANSLATE_OFFSCREEN =
+ new FloatProperty<FloatingTaskView>("floatingTaskPrimaryTranslateOffscreen") {
+ @Override
+ public void setValue(FloatingTaskView view, float translation) {
+ ((RecentsView) view.mActivity.getOverviewPanel()).getPagedOrientationHandler()
+ .setFloatingTaskPrimaryTranslation(
+ view,
+ translation,
+ view.mActivity.getDeviceProfile()
+ );
+ }
+
+ @Override
+ public Float get(FloatingTaskView view) {
+ return ((RecentsView) view.mActivity.getOverviewPanel())
+ .getPagedOrientationHandler()
+ .getFloatingTaskPrimaryTranslation(
+ view,
+ view.mActivity.getDeviceProfile()
+ );
+ }
+ };
+
private FloatingTaskThumbnailView mThumbnailView;
private SplitPlaceholderView mSplitPlaceholderView;
private RectF mStartingPosition;
diff --git a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
index a870f9c..0bed51d 100644
--- a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
+++ b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
@@ -250,8 +250,7 @@
@Override
public void setOverlayEnabled(boolean overlayEnabled) {
- super.setOverlayEnabled(overlayEnabled);
- mSnapshotView2.setOverlayEnabled(overlayEnabled);
+ // Intentional no-op to prevent setting smart actions overlay on thumbnails
}
@Override
@@ -319,4 +318,10 @@
super.applyThumbnailSplashAlpha();
mSnapshotView2.setSplashAlpha(mTaskThumbnailSplashAlpha);
}
+
+ @Override
+ void setThumbnailVisibility(int visibility) {
+ super.setThumbnailVisibility(visibility);
+ mSnapshotView2.setVisibility(visibility);
+ }
}
diff --git a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
index 6a33d36..de7ccad 100644
--- a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
@@ -120,6 +120,11 @@
}
@Override
+ public void onStateTransitionFailed(LauncherState toState) {
+ reset();
+ }
+
+ @Override
public void onStateTransitionComplete(LauncherState finalState) {
if (finalState == NORMAL || finalState == SPRING_LOADED) {
// Clean-up logic that occurs when recents is no longer in use/visible.
diff --git a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
index 62ec0ef..08a17c4 100644
--- a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
+++ b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
@@ -32,9 +32,9 @@
import com.android.launcher3.Insettable;
import com.android.launcher3.R;
import com.android.launcher3.util.DisplayController;
-import com.android.launcher3.util.DisplayController.NavigationMode;
import com.android.launcher3.util.MultiValueAlpha;
import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
+import com.android.launcher3.util.NavigationMode;
import com.android.quickstep.TaskOverlayFactory.OverlayUICallbacks;
import com.android.quickstep.util.LayoutUtils;
@@ -53,7 +53,9 @@
HIDDEN_NON_ZERO_ROTATION,
HIDDEN_NO_TASKS,
HIDDEN_NO_RECENTS,
- HIDDEN_SPLIT_SCREEN})
+ HIDDEN_SPLIT_SCREEN,
+ HIDDEN_SPLIT_SELECT_ACTIVE
+ })
@Retention(RetentionPolicy.SOURCE)
public @interface ActionsHiddenFlags { }
@@ -61,6 +63,7 @@
public static final int HIDDEN_NO_TASKS = 1 << 1;
public static final int HIDDEN_NO_RECENTS = 1 << 2;
public static final int HIDDEN_SPLIT_SCREEN = 1 << 3;
+ public static final int HIDDEN_SPLIT_SELECT_ACTIVE = 1 << 4;
@IntDef(flag = true, value = {
DISABLED_SCROLLING,
@@ -79,6 +82,11 @@
private static final int INDEX_HIDDEN_FLAGS_ALPHA = 3;
private static final int INDEX_SHARE_TARGET_ALPHA = 4;
+ public @interface SplitButtonDisabledFlags { }
+
+ public static final int FLAG_IS_NOT_TABLET = 1 << 0;
+ public static final int FLAG_SINGLE_TASK = 1 << 1;
+
private MultiValueAlpha mMultiValueAlpha;
private Button mSplitButton;
@@ -88,6 +96,9 @@
@ActionsDisabledFlags
protected int mDisabledFlags;
+ @SplitButtonDisabledFlags
+ private int mSplitButtonDisabledFlags;
+
@Nullable
protected T mCallbacks;
@@ -182,6 +193,20 @@
LayoutUtils.setViewEnabled(this, isEnabled);
}
+ /**
+ * Updates the proper flags to indicate whether the "Split screen" button should be enabled.
+ *
+ * @param flag The flag to update.
+ * @param enable Whether to enable the disable flag: True will cause view to be disabled.
+ */
+ public void updateSplitButtonFlags(@SplitButtonDisabledFlags int flag, boolean enable) {
+ if (enable) {
+ mSplitButtonDisabledFlags |= flag;
+ } else {
+ mSplitButtonDisabledFlags &= ~flag;
+ }
+ }
+
public AlphaProperty getContentAlpha() {
return mMultiValueAlpha.getProperty(INDEX_CONTENT_ALPHA);
}
@@ -263,12 +288,17 @@
0, 0, 0);
}
- public void setSplitButtonVisible(boolean visible) {
+ /**
+ * Shows/hides the "Split" button based on the status of mHiddenFlags.
+ */
+ public void updateSplitButtonVisibility() {
if (mSplitButton == null) {
return;
}
-
- mSplitButton.setVisibility(visible ? VISIBLE : GONE);
- findViewById(R.id.action_split_space).setVisibility(visible ? VISIBLE : GONE);
+ boolean shouldBeVisible = mSplitButtonDisabledFlags == 0
+ // and neither of these flags are active
+ && (mHiddenFlags & (HIDDEN_SPLIT_SCREEN | HIDDEN_SPLIT_SELECT_ACTIVE)) == 0;
+ mSplitButton.setVisibility(shouldBeVisible ? VISIBLE : GONE);
+ findViewById(R.id.action_split_space).setVisibility(shouldBeVisible ? VISIBLE : GONE);
}
}
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 69557a8..f8bf3d8 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -52,10 +52,13 @@
import static com.android.launcher3.util.SystemUiController.UI_STATE_FULLSCREEN_TASK;
import static com.android.quickstep.TaskUtils.checkCurrentOrManagedUserId;
import static com.android.quickstep.views.ClearAllButton.DISMISS_ALPHA;
+import static com.android.quickstep.views.OverviewActionsView.FLAG_IS_NOT_TABLET;
+import static com.android.quickstep.views.OverviewActionsView.FLAG_SINGLE_TASK;
import static com.android.quickstep.views.OverviewActionsView.HIDDEN_NON_ZERO_ROTATION;
import static com.android.quickstep.views.OverviewActionsView.HIDDEN_NO_RECENTS;
import static com.android.quickstep.views.OverviewActionsView.HIDDEN_NO_TASKS;
import static com.android.quickstep.views.OverviewActionsView.HIDDEN_SPLIT_SCREEN;
+import static com.android.quickstep.views.OverviewActionsView.HIDDEN_SPLIT_SELECT_ACTIVE;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -397,39 +400,6 @@
}
};
- public static final FloatProperty<RecentsView> FIRST_FLOATING_TASK_TRANSLATE_OFFSCREEN =
- new FloatProperty<RecentsView>("firstFloatingTaskTranslateOffscreen") {
- @Override
- public void setValue(RecentsView view, float translation) {
- view.getPagedOrientationHandler().setFloatingTaskPrimaryTranslation(
- view.mFirstFloatingTaskView,
- translation,
- view.mActivity.getDeviceProfile()
- );
- }
-
- @Override
- public Float get(RecentsView view) {
- return view.getPagedOrientationHandler().getFloatingTaskPrimaryTranslation(
- view.mFirstFloatingTaskView,
- view.mActivity.getDeviceProfile()
- );
- }
- };
-
- public static final FloatProperty<RecentsView> SPLIT_INSTRUCTIONS_FADE =
- new FloatProperty<RecentsView>("splitInstructionsFade") {
- @Override
- public void setValue(RecentsView view, float fade) {
- view.mSplitInstructionsView.setAlpha(1 - fade);
- }
-
- @Override
- public Float get(RecentsView view) {
- return 1 - view.mSplitInstructionsView.getAlpha();
- }
- };
-
// OverScroll constants
private static final int OVERSCROLL_PAGE_SNAP_ANIMATION_DURATION = 270;
@@ -2827,7 +2797,11 @@
RectF startingTaskRect = new RectF();
if (mSplitHiddenTaskView != null) {
- mSplitHiddenTaskView.setVisibility(INVISIBLE);
+ // Split staging is initiated, hide the original TaskView thumbnail.
+ // Toggled back on in resetFromSplitSelectionState().
+ mSplitHiddenTaskView.setThumbnailVisibility(INVISIBLE);
+ anim.addFloat(mSplitHiddenTaskView, TaskView.ICON_ALPHA, 1, 0,
+ clampToProgress(LINEAR, 0, 0.167f));
mFirstFloatingTaskView = FloatingTaskView.getFloatingTaskView(mActivity,
mSplitHiddenTaskView.getThumbnail(),
mSplitHiddenTaskView.getThumbnail().getThumbnail(),
@@ -2855,6 +2829,8 @@
InteractionJankMonitorWrapper.end(
InteractionJankMonitorWrapper.CUJ_SPLIT_SCREEN_ENTER);
} else {
+ // If transition to split select was interrupted, clean up to prevent glitches
+ resetFromSplitSelectionState();
InteractionJankMonitorWrapper.cancel(
InteractionJankMonitorWrapper.CUJ_SPLIT_SCREEN_ENTER);
}
@@ -3414,11 +3390,11 @@
private void updateCurrentTaskActionsVisibility() {
boolean isCurrentSplit = getCurrentPageTaskView() instanceof GroupedTaskView;
mActionsView.updateHiddenFlags(HIDDEN_SPLIT_SCREEN, isCurrentSplit);
- if (isCurrentSplit) {
- return;
- }
- mActionsView.setSplitButtonVisible(
- mActivity.getDeviceProfile().isTablet && getTaskViewCount() > 1);
+ mActionsView.updateHiddenFlags(HIDDEN_SPLIT_SELECT_ACTIVE, isSplitSelectionActive());
+ mActionsView.updateSplitButtonFlags(FLAG_IS_NOT_TABLET,
+ !mActivity.getDeviceProfile().isTablet);
+ mActionsView.updateSplitButtonFlags(FLAG_SINGLE_TASK, getTaskViewCount() <= 1);
+ mActionsView.updateSplitButtonVisibility();
}
/**
@@ -4222,7 +4198,9 @@
resetTaskVisuals();
mSplitHiddenTaskViewIndex = -1;
if (mSplitHiddenTaskView != null) {
- mSplitHiddenTaskView.setVisibility(VISIBLE);
+ // Toggle thumbnail visibility back on (turned off in
+ // createInitialSplitSelectAnimation()).
+ mSplitHiddenTaskView.setThumbnailVisibility(VISIBLE);
mSplitHiddenTaskView = null;
}
}
@@ -4342,25 +4320,27 @@
int taskIndex = indexOfChild(tv);
int centerTaskIndex = getCurrentPage();
- boolean launchingCenterTask = taskIndex == centerTaskIndex;
float toScale = getMaxScaleForFullScreen();
- RecentsView recentsView = tv.getRecentsView();
+ boolean showAsGrid = showAsGrid();
+ boolean launchingCenterTask = showAsGrid
+ ? tv.isFocusedTask() && isTaskViewFullyVisible(tv)
+ : taskIndex == centerTaskIndex;
if (launchingCenterTask) {
- anim.play(ObjectAnimator.ofFloat(recentsView, RECENTS_SCALE_PROPERTY, toScale));
- anim.play(ObjectAnimator.ofFloat(recentsView, FULLSCREEN_PROGRESS, 1));
- } else {
+ anim.play(ObjectAnimator.ofFloat(this, RECENTS_SCALE_PROPERTY, toScale));
+ anim.play(ObjectAnimator.ofFloat(this, FULLSCREEN_PROGRESS, 1));
+ } else if (!showAsGrid) {
// We are launching an adjacent task, so parallax the center and other adjacent task.
float displacementX = tv.getWidth() * (toScale - 1f);
float primaryTranslation = mIsRtl ? -displacementX : displacementX;
anim.play(ObjectAnimator.ofFloat(getPageAt(centerTaskIndex),
mOrientationHandler.getPrimaryViewTranslate(), primaryTranslation));
- int runningTaskIndex = recentsView.getRunningTaskIndex();
+ int runningTaskIndex = getRunningTaskIndex();
if (ENABLE_QUICKSTEP_LIVE_TILE.get()
&& runningTaskIndex != -1
&& runningTaskIndex != taskIndex
- && recentsView.getRemoteTargetHandles() != null) {
- for (RemoteTargetHandle remoteHandle : recentsView.getRemoteTargetHandles()) {
+ && getRemoteTargetHandles() != null) {
+ for (RemoteTargetHandle remoteHandle : getRemoteTargetHandles()) {
anim.play(ObjectAnimator.ofFloat(
remoteHandle.getTaskViewSimulator().taskPrimaryTranslation,
AnimatedFloat.VALUE,
@@ -4380,7 +4360,7 @@
properties));
}
}
- anim.play(ObjectAnimator.ofFloat(recentsView, TASK_THUMBNAIL_SPLASH_ALPHA, 0, 1));
+ anim.play(ObjectAnimator.ofFloat(this, TASK_THUMBNAIL_SPLASH_ALPHA, 0, 1));
return anim;
}
@@ -5334,6 +5314,11 @@
return mFirstFloatingTaskView;
}
+ @Nullable
+ public SplitInstructionsView getSplitInstructionsView() {
+ return mSplitInstructionsView;
+ }
+
/** Update the current activity locus id to show the enabled state of Overview */
public void updateLocusId() {
String locusId = "Overview";
diff --git a/quickstep/src/com/android/quickstep/views/SplitInstructionsView.java b/quickstep/src/com/android/quickstep/views/SplitInstructionsView.java
index 7d94505..bcaa462 100644
--- a/quickstep/src/com/android/quickstep/views/SplitInstructionsView.java
+++ b/quickstep/src/com/android/quickstep/views/SplitInstructionsView.java
@@ -16,7 +16,7 @@
package com.android.quickstep.views;
-import static com.android.launcher3.util.DisplayController.NavigationMode.THREE_BUTTONS;
+import static com.android.launcher3.util.NavigationMode.THREE_BUTTONS;
import android.content.Context;
import android.util.AttributeSet;
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index 34c2021..a84ea63 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -323,6 +323,19 @@
}
};
+ public static final FloatProperty<TaskView> ICON_ALPHA =
+ new FloatProperty<TaskView>("iconAlpha") {
+ @Override
+ public void setValue(TaskView taskView, float v) {
+ taskView.mIconView.setAlpha(v);
+ }
+
+ @Override
+ public Float get(TaskView taskView) {
+ return taskView.mIconView.getAlpha();
+ }
+ };
+
@Nullable
protected Task mTask;
protected TaskThumbnailView mSnapshotView;
@@ -1488,6 +1501,10 @@
return display != null ? display.getDisplayId() : DEFAULT_DISPLAY;
}
+ void setThumbnailVisibility(int visibility) {
+ mSnapshotView.setVisibility(visibility);
+ }
+
/**
* We update and subsequently draw these in {@link #setFullscreenProgress(float)}.
*/
diff --git a/quickstep/tests/src/com/android/quickstep/DeviceProfileTest.kt b/quickstep/tests/src/com/android/quickstep/DeviceProfileTest.kt
deleted file mode 100644
index 9977207..0000000
--- a/quickstep/tests/src/com/android/quickstep/DeviceProfileTest.kt
+++ /dev/null
@@ -1,1479 +0,0 @@
-/*
- * Copyright (C) 2022 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
-
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.filters.SmallTest
-import com.android.launcher3.DeviceProfileBaseTest
-import com.google.common.truth.Truth.assertThat
-import org.junit.Test
-import org.junit.runner.RunWith
-
-/**
- * Tests for DeviceProfile.
- */
-@SmallTest
-@RunWith(AndroidJUnit4::class)
-class DeviceProfileTest : DeviceProfileBaseTest() {
-
- @Test
- fun phonePortrait3Button() {
- initializeVarsForPhone(isGestureMode = false)
- val dp = newDP()
-
- 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" +
- "\tisScalableGrid:true\n" +
- "\tinv.numRows: 5\n" +
- "\tinv.numColumns: 4\n" +
- "\tinv.numSearchContainerColumns: 4\n" +
- "\tminCellSize: PointF(80.0, 104.0)dp\n" +
- "\tcellWidthPx: 210.0px (80.0dp)\n" +
- "\tcellHeightPx: 272.0px (103.61905dp)\n" +
- "\tgetCellSize().x: 210.0px (80.0dp)\n" +
- "\tgetCellSize().y: 272.0px (103.61905dp)\n" +
- "\tcellLayoutBorderSpacePx Horizontal: 42.0px (16.0dp)\n" +
- "\tcellLayoutBorderSpacePx Vertical: 42.0px (16.0dp)\n" +
- "\tcellLayoutPaddingPx.left: 28.0px (10.666667dp)\n" +
- "\tcellLayoutPaddingPx.top: 28.0px (10.666667dp)\n" +
- "\tcellLayoutPaddingPx.right: 28.0px (10.666667dp)\n" +
- "\tcellLayoutPaddingPx.bottom: 28.0px (10.666667dp)\n" +
- "\ticonSizePx: 157.0px (59.809525dp)\n" +
- "\ticonTextSizePx: 36.0px (13.714286dp)\n" +
- "\ticonDrawablePaddingPx: 17.0px (6.4761906dp)\n" +
- "\tfolderCellWidthPx: 210.0px (80.0dp)\n" +
- "\tfolderCellHeightPx: 247.0px (94.09524dp)\n" +
- "\tfolderChildIconSizePx: 158.0px (60.190475dp)\n" +
- "\tfolderChildTextSizePx: 37.0px (14.095238dp)\n" +
- "\tfolderChildDrawablePaddingPx: 13.0px (4.952381dp)\n" +
- "\tfolderCellLayoutBorderSpacePx Horizontal: 42.0px (16.0dp)\n" +
- "\tfolderCellLayoutBorderSpacePx Vertical: 42.0px (16.0dp)\n" +
- "\tfolderContentPaddingLeftRight: 42.0px (16.0dp)\n" +
- "\tfolderTopPadding: 63.0px (24.0dp)\n" +
- "\tbottomSheetTopPadding: 146.0px (55.61905dp)\n" +
- "\tallAppsShiftRange: 788.0px (300.1905dp)\n" +
- "\tallAppsTopPadding: 0.0px (0.0dp)\n" +
- "\tallAppsIconSizePx: 157.0px (59.809525dp)\n" +
- "\tallAppsIconTextSizePx: 37.0px (14.095238dp)\n" +
- "\tallAppsIconDrawablePaddingPx: 18.0px (6.857143dp)\n" +
- "\tallAppsCellHeightPx: 314.0px (119.61905dp)\n" +
- "\tallAppsCellWidthPx: 210.0px (80.0dp)\n" +
- "\tallAppsBorderSpacePxX: 42.0px (16.0dp)\n" +
- "\tallAppsBorderSpacePxY: 42.0px (16.0dp)\n" +
- "\tnumShownAllAppsColumns: 4\n" +
- "\tallAppsLeftRightPadding: 57.0px (21.714285dp)\n" +
- "\tallAppsLeftRightMargin: 0.0px (0.0dp)\n" +
- "\thotseatBarSizePx: 511.0px (194.66667dp)\n" +
- "\tinv.hotseatColumnSpan: 4\n" +
- "\thotseatCellHeightPx: 177.0px (67.42857dp)\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: 74.0px (28.190475dp)\n" +
- "\thotseatQsbHeight: 165.0px (62.857143dp)\n" +
- "\tspringLoadedHotseatBarTopMarginPx: 200.0px (76.190475dp)\n" +
- "\tgetHotseatLayoutPadding(context).top: 0.0px (0.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).bottom: 334.0px (127.2381dp)\n" +
- "\tgetHotseatLayoutPadding(context).left: 83.0px (31.619047dp)\n" +
- "\tgetHotseatLayoutPadding(context).right: 83.0px (31.619047dp)\n" +
- "\tnumShownHotseatIcons: 4\n" +
- "\thotseatBorderSpace: 95.0px (36.190475dp)\n" +
- "\tisQsbInline: false\n" +
- "\thotseatQsbWidth: 913.0px (347.8095dp)\n" +
- "\tisTaskbarPresent:false\n" +
- "\tisTaskbarPresentInApps:false\n" +
- "\ttaskbarSize: 0.0px (0.0dp)\n" +
- "\tdesiredWorkspaceHorizontalMarginPx: 57.0px (21.714285dp)\n" +
- "\tworkspacePadding.left: 29.0px (11.047619dp)\n" +
- "\tworkspacePadding.top: 67.0px (25.52381dp)\n" +
- "\tworkspacePadding.right: 29.0px (11.047619dp)\n" +
- "\tworkspacePadding.bottom: 504.0px (192.0dp)\n" +
- "\ticonScale: 0.9981516px (0.38024822dp)\n" +
- "\tcellScaleToFit : 0.9981516px (0.38024822dp)\n" +
- "\textraSpace: 211.0px (80.38095dp)\n" +
- "\tunscaled extraSpace: 211.39073px (80.5298dp)\n" +
- "\tmaxEmptySpace: 315.0px (120.0dp)\n" +
- "\tworkspaceTopPadding: 95.0px (36.190475dp)\n" +
- "\tworkspaceBottomPadding: 116.0px (44.190475dp)\n" +
- "\toverviewTaskMarginPx: 42.0px (16.0dp)\n" +
- "\toverviewTaskIconSizePx: 126.0px (48.0dp)\n" +
- "\toverviewTaskIconDrawableSizePx: 116.0px (44.190475dp)\n" +
- "\toverviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)\n" +
- "\toverviewTaskThumbnailTopMarginPx: 168.0px (64.0dp)\n" +
- "\toverviewActionsTopMarginPx: 63.0px (24.0dp)\n" +
- "\toverviewActionsHeight: 126.0px (48.0dp)\n" +
- "\toverviewActionsButtonSpacing: 95.0px (36.190475dp)\n" +
- "\toverviewPageSpacing: 42.0px (16.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(): 1689.0px (643.4286dp)\n" +
- "\tworkspaceSpringLoadedMinNextPageVisiblePx: 63.0px (24.0dp)\n" +
- "\tgetWorkspaceSpringLoadScale(): 0.81892747px (0.31197238dp)\n" +
- "\tgetCellLayoutHeight(): 1585.0px (603.8095dp)\n" +
- "\tgetCellLayoutWidth(): 1022.0px (389.33334dp)\n")
- }
-
- @Test
- fun phonePortrait() {
- initializeVarsForPhone()
- val dp = newDP()
-
- 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" +
- "\tisScalableGrid:true\n" +
- "\tinv.numRows: 5\n" +
- "\tinv.numColumns: 4\n" +
- "\tinv.numSearchContainerColumns: 4\n" +
- "\tminCellSize: PointF(80.0, 104.0)dp\n" +
- "\tcellWidthPx: 210.0px (80.0dp)\n" +
- "\tcellHeightPx: 272.0px (103.61905dp)\n" +
- "\tgetCellSize().x: 210.0px (80.0dp)\n" +
- "\tgetCellSize().y: 272.0px (103.61905dp)\n" +
- "\tcellLayoutBorderSpacePx Horizontal: 42.0px (16.0dp)\n" +
- "\tcellLayoutBorderSpacePx Vertical: 42.0px (16.0dp)\n" +
- "\tcellLayoutPaddingPx.left: 28.0px (10.666667dp)\n" +
- "\tcellLayoutPaddingPx.top: 28.0px (10.666667dp)\n" +
- "\tcellLayoutPaddingPx.right: 28.0px (10.666667dp)\n" +
- "\tcellLayoutPaddingPx.bottom: 28.0px (10.666667dp)\n" +
- "\ticonSizePx: 157.0px (59.809525dp)\n" +
- "\ticonTextSizePx: 36.0px (13.714286dp)\n" +
- "\ticonDrawablePaddingPx: 17.0px (6.4761906dp)\n" +
- "\tfolderCellWidthPx: 210.0px (80.0dp)\n" +
- "\tfolderCellHeightPx: 247.0px (94.09524dp)\n" +
- "\tfolderChildIconSizePx: 158.0px (60.190475dp)\n" +
- "\tfolderChildTextSizePx: 37.0px (14.095238dp)\n" +
- "\tfolderChildDrawablePaddingPx: 13.0px (4.952381dp)\n" +
- "\tfolderCellLayoutBorderSpacePx Horizontal: 42.0px (16.0dp)\n" +
- "\tfolderCellLayoutBorderSpacePx Vertical: 42.0px (16.0dp)\n" +
- "\tfolderContentPaddingLeftRight: 42.0px (16.0dp)\n" +
- "\tfolderTopPadding: 63.0px (24.0dp)\n" +
- "\tbottomSheetTopPadding: 146.0px (55.61905dp)\n" +
- "\tallAppsShiftRange: 788.0px (300.1905dp)\n" +
- "\tallAppsTopPadding: 0.0px (0.0dp)\n" +
- "\tallAppsIconSizePx: 157.0px (59.809525dp)\n" +
- "\tallAppsIconTextSizePx: 37.0px (14.095238dp)\n" +
- "\tallAppsIconDrawablePaddingPx: 18.0px (6.857143dp)\n" +
- "\tallAppsCellHeightPx: 314.0px (119.61905dp)\n" +
- "\tallAppsCellWidthPx: 210.0px (80.0dp)\n" +
- "\tallAppsBorderSpacePxX: 42.0px (16.0dp)\n" +
- "\tallAppsBorderSpacePxY: 42.0px (16.0dp)\n" +
- "\tnumShownAllAppsColumns: 4\n" +
- "\tallAppsLeftRightPadding: 57.0px (21.714285dp)\n" +
- "\tallAppsLeftRightMargin: 0.0px (0.0dp)\n" +
- "\thotseatBarSizePx: 511.0px (194.66667dp)\n" +
- "\tinv.hotseatColumnSpan: 4\n" +
- "\thotseatCellHeightPx: 177.0px (67.42857dp)\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: 95.0px (36.190475dp)\n" +
- "\thotseatQsbHeight: 165.0px (62.857143dp)\n" +
- "\tspringLoadedHotseatBarTopMarginPx: 200.0px (76.190475dp)\n" +
- "\tgetHotseatLayoutPadding(context).top: 0.0px (0.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).bottom: 334.0px (127.2381dp)\n" +
- "\tgetHotseatLayoutPadding(context).left: 83.0px (31.619047dp)\n" +
- "\tgetHotseatLayoutPadding(context).right: 83.0px (31.619047dp)\n" +
- "\tnumShownHotseatIcons: 4\n" +
- "\thotseatBorderSpace: 95.0px (36.190475dp)\n" +
- "\tisQsbInline: false\n" +
- "\thotseatQsbWidth: 913.0px (347.8095dp)\n" +
- "\tisTaskbarPresent:false\n" +
- "\tisTaskbarPresentInApps:false\n" +
- "\ttaskbarSize: 0.0px (0.0dp)\n" +
- "\tdesiredWorkspaceHorizontalMarginPx: 57.0px (21.714285dp)\n" +
- "\tworkspacePadding.left: 29.0px (11.047619dp)\n" +
- "\tworkspacePadding.top: 67.0px (25.52381dp)\n" +
- "\tworkspacePadding.right: 29.0px (11.047619dp)\n" +
- "\tworkspacePadding.bottom: 567.0px (216.0dp)\n" +
- "\ticonScale: 0.9981516px (0.38024822dp)\n" +
- "\tcellScaleToFit : 0.9981516px (0.38024822dp)\n" +
- "\textraSpace: 211.0px (80.38095dp)\n" +
- "\tunscaled extraSpace: 211.39073px (80.5298dp)\n" +
- "\tmaxEmptySpace: 315.0px (120.0dp)\n" +
- "\tworkspaceTopPadding: 95.0px (36.190475dp)\n" +
- "\tworkspaceBottomPadding: 116.0px (44.190475dp)\n" +
- "\toverviewTaskMarginPx: 42.0px (16.0dp)\n" +
- "\toverviewTaskIconSizePx: 126.0px (48.0dp)\n" +
- "\toverviewTaskIconDrawableSizePx: 116.0px (44.190475dp)\n" +
- "\toverviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)\n" +
- "\toverviewTaskThumbnailTopMarginPx: 168.0px (64.0dp)\n" +
- "\toverviewActionsTopMarginPx: 63.0px (24.0dp)\n" +
- "\toverviewActionsHeight: 126.0px (48.0dp)\n" +
- "\toverviewActionsButtonSpacing: 95.0px (36.190475dp)\n" +
- "\toverviewPageSpacing: 42.0px (16.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(): 1689.0px (643.4286dp)\n" +
- "\tworkspaceSpringLoadedMinNextPageVisiblePx: 63.0px (24.0dp)\n" +
- "\tgetWorkspaceSpringLoadScale(): 0.81892747px (0.31197238dp)\n" +
- "\tgetCellLayoutHeight(): 1585.0px (603.8095dp)\n" +
- "\tgetCellLayoutWidth(): 1022.0px (389.33334dp)\n")
- }
-
- @Test
- fun tabletLandscape3Button() {
- initializeVarsForTablet(isLandscape = true, isGestureMode = false)
- val dp = newDP()
- 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" +
- "\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: 32.0px (16.0dp)\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: 14.0px (7.0dp)\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: 16.0px (8.0dp)\n" +
- "\tfolderCellLayoutBorderSpacePx Horizontal: 32.0px (16.0dp)\n" +
- "\tfolderCellLayoutBorderSpacePx Vertical: 32.0px (16.0dp)\n" +
- "\tfolderContentPaddingLeftRight: 32.0px (16.0dp)\n" +
- "\tfolderTopPadding: 48.0px (24.0dp)\n" +
- "\tbottomSheetTopPadding: 104.0px (52.0dp)\n" +
- "\tallAppsShiftRange: 1496.0px (748.0dp)\n" +
- "\tallAppsTopPadding: 104.0px (52.0dp)\n" +
- "\tallAppsIconSizePx: 120.0px (60.0dp)\n" +
- "\tallAppsIconTextSizePx: 28.0px (14.0dp)\n" +
- "\tallAppsIconDrawablePaddingPx: 14.0px (7.0dp)\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: 64.0px (32.0dp)\n" +
- "\tallAppsLeftRightMargin: 380.0px (190.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: 705.0px (352.5dp)\n" +
- "\thotseatQsbSpace: 64.0px (32.0dp)\n" +
- "\thotseatQsbHeight: 126.0px (63.0dp)\n" +
- "\tspringLoadedHotseatBarTopMarginPx: 128.0px (64.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).top: -8.0px (-4.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).bottom: 73.0px (36.5dp)\n" +
- "\tgetHotseatLayoutPadding(context).left: 954.0px (477.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).right: 705.0px (352.5dp)\n" +
- "\tnumShownHotseatIcons: 6\n" +
- "\thotseatBorderSpace: 36.0px (18.0dp)\n" +
- "\tisQsbInline: true\n" +
- "\thotseatQsbWidth: 619.0px (309.5dp)\n" +
- "\tisTaskbarPresent:true\n" +
- "\tisTaskbarPresentInApps:true\n" +
- "\ttaskbarSize: 120.0px (60.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: 237.0px (118.5dp)\n" +
- "\ticonScale: 1.0px (0.5dp)\n" +
- "\tcellScaleToFit : 1.0px (0.5dp)\n" +
- "\textraSpace: 104.0px (52.0dp)\n" +
- "\tunscaled extraSpace: 104.0px (52.0dp)\n" +
- "\tmaxEmptySpace: 200.0px (100.0dp)\n" +
- "\tworkspaceTopPadding: 32.0px (16.0dp)\n" +
- "\tworkspaceBottomPadding: 72.0px (36.0dp)\n" +
- "\toverviewTaskMarginPx: 32.0px (16.0dp)\n" +
- "\toverviewTaskIconSizePx: 96.0px (48.0dp)\n" +
- "\toverviewTaskIconDrawableSizePx: 88.0px (44.0dp)\n" +
- "\toverviewTaskIconDrawableSizeGridPx: 88.0px (44.0dp)\n" +
- "\toverviewTaskThumbnailTopMarginPx: 128.0px (64.0dp)\n" +
- "\toverviewActionsTopMarginPx: 40.0px (20.0dp)\n" +
- "\toverviewActionsHeight: 96.0px (48.0dp)\n" +
- "\toverviewActionsButtonSpacing: 72.0px (36.0dp)\n" +
- "\toverviewPageSpacing: 88.0px (44.0dp)\n" +
- "\toverviewRowSpacing: 72.0px (36.0dp)\n" +
- "\toverviewGridSideMargin: 128.0px (64.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.76250994px (0.38125497dp)\n" +
- "\tgetCellLayoutHeight(): 1259.0px (629.5dp)\n" +
- "\tgetCellLayoutWidth(): 2198.0px (1099.0dp)\n")
- }
-
- @Test
- fun tabletLandscape() {
- initializeVarsForTablet(isLandscape = true)
- val dp = newDP()
- 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" +
- "\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: 32.0px (16.0dp)\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: 14.0px (7.0dp)\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: 16.0px (8.0dp)\n" +
- "\tfolderCellLayoutBorderSpacePx Horizontal: 32.0px (16.0dp)\n" +
- "\tfolderCellLayoutBorderSpacePx Vertical: 32.0px (16.0dp)\n" +
- "\tfolderContentPaddingLeftRight: 32.0px (16.0dp)\n" +
- "\tfolderTopPadding: 48.0px (24.0dp)\n" +
- "\tbottomSheetTopPadding: 104.0px (52.0dp)\n" +
- "\tallAppsShiftRange: 1496.0px (748.0dp)\n" +
- "\tallAppsTopPadding: 104.0px (52.0dp)\n" +
- "\tallAppsIconSizePx: 120.0px (60.0dp)\n" +
- "\tallAppsIconTextSizePx: 28.0px (14.0dp)\n" +
- "\tallAppsIconDrawablePaddingPx: 14.0px (7.0dp)\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: 64.0px (32.0dp)\n" +
- "\tallAppsLeftRightMargin: 380.0px (190.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: 64.0px (32.0dp)\n" +
- "\thotseatQsbHeight: 126.0px (63.0dp)\n" +
- "\tspringLoadedHotseatBarTopMarginPx: 128.0px (64.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).top: -8.0px (-4.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).bottom: 73.0px (36.5dp)\n" +
- "\tgetHotseatLayoutPadding(context).left: 1040.0px (520.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).right: 300.0px (150.0dp)\n" +
- "\tnumShownHotseatIcons: 6\n" +
- "\thotseatBorderSpace: 100.0px (50.0dp)\n" +
- "\tisQsbInline: true\n" +
- "\thotseatQsbWidth: 640.0px (320.0dp)\n" +
- "\tisTaskbarPresent:true\n" +
- "\tisTaskbarPresentInApps:true\n" +
- "\ttaskbarSize: 120.0px (60.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: 237.0px (118.5dp)\n" +
- "\ticonScale: 1.0px (0.5dp)\n" +
- "\tcellScaleToFit : 1.0px (0.5dp)\n" +
- "\textraSpace: 104.0px (52.0dp)\n" +
- "\tunscaled extraSpace: 104.0px (52.0dp)\n" +
- "\tmaxEmptySpace: 200.0px (100.0dp)\n" +
- "\tworkspaceTopPadding: 32.0px (16.0dp)\n" +
- "\tworkspaceBottomPadding: 72.0px (36.0dp)\n" +
- "\toverviewTaskMarginPx: 32.0px (16.0dp)\n" +
- "\toverviewTaskIconSizePx: 96.0px (48.0dp)\n" +
- "\toverviewTaskIconDrawableSizePx: 88.0px (44.0dp)\n" +
- "\toverviewTaskIconDrawableSizeGridPx: 88.0px (44.0dp)\n" +
- "\toverviewTaskThumbnailTopMarginPx: 128.0px (64.0dp)\n" +
- "\toverviewActionsTopMarginPx: 40.0px (20.0dp)\n" +
- "\toverviewActionsHeight: 96.0px (48.0dp)\n" +
- "\toverviewActionsButtonSpacing: 72.0px (36.0dp)\n" +
- "\toverviewPageSpacing: 88.0px (44.0dp)\n" +
- "\toverviewRowSpacing: 72.0px (36.0dp)\n" +
- "\toverviewGridSideMargin: 128.0px (64.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.76250994px (0.38125497dp)\n" +
- "\tgetCellLayoutHeight(): 1259.0px (629.5dp)\n" +
- "\tgetCellLayoutWidth(): 2198.0px (1099.0dp)\n")
- }
-
- @Test
- fun tabletPortrait3Button() {
- initializeVarsForTablet(isGestureMode = false)
- val dp = newDP()
- 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" +
- "\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: 14.0px (7.0dp)\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: 16.0px (8.0dp)\n" +
- "\tfolderCellLayoutBorderSpacePx Horizontal: 32.0px (16.0dp)\n" +
- "\tfolderCellLayoutBorderSpacePx Vertical: 32.0px (16.0dp)\n" +
- "\tfolderContentPaddingLeftRight: 32.0px (16.0dp)\n" +
- "\tfolderTopPadding: 48.0px (24.0dp)\n" +
- "\tbottomSheetTopPadding: 704.0px (352.0dp)\n" +
- "\tallAppsShiftRange: 1936.0px (968.0dp)\n" +
- "\tallAppsTopPadding: 624.0px (312.0dp)\n" +
- "\tallAppsIconSizePx: 120.0px (60.0dp)\n" +
- "\tallAppsIconTextSizePx: 28.0px (14.0dp)\n" +
- "\tallAppsIconDrawablePaddingPx: 14.0px (7.0dp)\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: 56.0px (28.0dp)\n" +
- "\tallAppsLeftRightMargin: 128.0px (64.0dp)\n" +
- "\thotseatBarSizePx: 358.0px (179.0dp)\n" +
- "\tinv.hotseatColumnSpan: 6\n" +
- "\thotseatCellHeightPx: 135.0px (67.5dp)\n" +
- "\thotseatBarBottomSpacePx: 72.0px (36.0dp)\n" +
- "\thotseatBarSidePaddingStartPx: 0.0px (0.0dp)\n" +
- "\thotseatBarSidePaddingEndPx: 0.0px (0.0dp)\n" +
- "\thotseatBarEndOffset: 558.0px (279.0dp)\n" +
- "\thotseatQsbSpace: 64.0px (32.0dp)\n" +
- "\thotseatQsbHeight: 126.0px (63.0dp)\n" +
- "\tspringLoadedHotseatBarTopMarginPx: 216.0px (108.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).top: 158.0px (79.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).bottom: 65.0px (32.5dp)\n" +
- "\tgetHotseatLayoutPadding(context).left: 150.0px (75.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).right: 558.0px (279.0dp)\n" +
- "\tnumShownHotseatIcons: 5\n" +
- "\thotseatBorderSpace: 73.0px (36.5dp)\n" +
- "\tisQsbInline: false\n" +
- "\thotseatQsbWidth: 1300.0px (650.0dp)\n" +
- "\tisTaskbarPresent:true\n" +
- "\tisTaskbarPresentInApps:true\n" +
- "\ttaskbarSize: 120.0px (60.0dp)\n" +
- "\tdesiredWorkspaceHorizontalMarginPx: 108.0px (54.0dp)\n" +
- "\tworkspacePadding.left: 36.0px (18.0dp)\n" +
- "\tworkspacePadding.top: 87.0px (43.5dp)\n" +
- "\tworkspacePadding.right: 36.0px (18.0dp)\n" +
- "\tworkspacePadding.bottom: 513.0px (256.5dp)\n" +
- "\ticonScale: 1.0px (0.5dp)\n" +
- "\tcellScaleToFit : 1.0px (0.5dp)\n" +
- "\textraSpace: 362.0px (181.0dp)\n" +
- "\tunscaled extraSpace: 362.0px (181.0dp)\n" +
- "\tmaxEmptySpace: 19998.0px (9999.0dp)\n" +
- "\tworkspaceTopPadding: 159.0px (79.5dp)\n" +
- "\tworkspaceBottomPadding: 203.0px (101.5dp)\n" +
- "\toverviewTaskMarginPx: 32.0px (16.0dp)\n" +
- "\toverviewTaskIconSizePx: 96.0px (48.0dp)\n" +
- "\toverviewTaskIconDrawableSizePx: 88.0px (44.0dp)\n" +
- "\toverviewTaskIconDrawableSizeGridPx: 88.0px (44.0dp)\n" +
- "\toverviewTaskThumbnailTopMarginPx: 128.0px (64.0dp)\n" +
- "\toverviewActionsTopMarginPx: 48.0px (24.0dp)\n" +
- "\toverviewActionsHeight: 96.0px (48.0dp)\n" +
- "\toverviewActionsButtonSpacing: 72.0px (36.0dp)\n" +
- "\toverviewPageSpacing: 88.0px (44.0dp)\n" +
- "\toverviewRowSpacing: 72.0px (36.0dp)\n" +
- "\toverviewGridSideMargin: 128.0px (64.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(): 1986.0px (993.0dp)\n" +
- "\tworkspaceSpringLoadedMinNextPageVisiblePx: 48.0px (24.0dp)\n" +
- "\tgetWorkspaceSpringLoadScale(): 0.76616377px (0.38308188dp)\n" +
- "\tgetCellLayoutHeight(): 1856.0px (928.0dp)\n" +
- "\tgetCellLayoutWidth(): 1528.0px (764.0dp)\n")
- }
-
- @Test
- fun tabletPortrait() {
- initializeVarsForTablet()
- val dp = newDP()
- 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" +
- "\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: 14.0px (7.0dp)\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: 16.0px (8.0dp)\n" +
- "\tfolderCellLayoutBorderSpacePx Horizontal: 32.0px (16.0dp)\n" +
- "\tfolderCellLayoutBorderSpacePx Vertical: 32.0px (16.0dp)\n" +
- "\tfolderContentPaddingLeftRight: 32.0px (16.0dp)\n" +
- "\tfolderTopPadding: 48.0px (24.0dp)\n" +
- "\tbottomSheetTopPadding: 704.0px (352.0dp)\n" +
- "\tallAppsShiftRange: 1936.0px (968.0dp)\n" +
- "\tallAppsTopPadding: 624.0px (312.0dp)\n" +
- "\tallAppsIconSizePx: 120.0px (60.0dp)\n" +
- "\tallAppsIconTextSizePx: 28.0px (14.0dp)\n" +
- "\tallAppsIconDrawablePaddingPx: 14.0px (7.0dp)\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: 56.0px (28.0dp)\n" +
- "\tallAppsLeftRightMargin: 128.0px (64.0dp)\n" +
- "\thotseatBarSizePx: 358.0px (179.0dp)\n" +
- "\tinv.hotseatColumnSpan: 6\n" +
- "\thotseatCellHeightPx: 135.0px (67.5dp)\n" +
- "\thotseatBarBottomSpacePx: 72.0px (36.0dp)\n" +
- "\thotseatBarSidePaddingStartPx: 0.0px (0.0dp)\n" +
- "\thotseatBarSidePaddingEndPx: 0.0px (0.0dp)\n" +
- "\thotseatBarEndOffset: 0.0px (0.0dp)\n" +
- "\thotseatQsbSpace: 64.0px (32.0dp)\n" +
- "\thotseatQsbHeight: 126.0px (63.0dp)\n" +
- "\tspringLoadedHotseatBarTopMarginPx: 216.0px (108.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).top: 158.0px (79.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).bottom: 65.0px (32.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:true\n" +
- "\tisTaskbarPresentInApps:true\n" +
- "\ttaskbarSize: 120.0px (60.0dp)\n" +
- "\tdesiredWorkspaceHorizontalMarginPx: 108.0px (54.0dp)\n" +
- "\tworkspacePadding.left: 36.0px (18.0dp)\n" +
- "\tworkspacePadding.top: 87.0px (43.5dp)\n" +
- "\tworkspacePadding.right: 36.0px (18.0dp)\n" +
- "\tworkspacePadding.bottom: 513.0px (256.5dp)\n" +
- "\ticonScale: 1.0px (0.5dp)\n" +
- "\tcellScaleToFit : 1.0px (0.5dp)\n" +
- "\textraSpace: 362.0px (181.0dp)\n" +
- "\tunscaled extraSpace: 362.0px (181.0dp)\n" +
- "\tmaxEmptySpace: 19998.0px (9999.0dp)\n" +
- "\tworkspaceTopPadding: 159.0px (79.5dp)\n" +
- "\tworkspaceBottomPadding: 203.0px (101.5dp)\n" +
- "\toverviewTaskMarginPx: 32.0px (16.0dp)\n" +
- "\toverviewTaskIconSizePx: 96.0px (48.0dp)\n" +
- "\toverviewTaskIconDrawableSizePx: 88.0px (44.0dp)\n" +
- "\toverviewTaskIconDrawableSizeGridPx: 88.0px (44.0dp)\n" +
- "\toverviewTaskThumbnailTopMarginPx: 128.0px (64.0dp)\n" +
- "\toverviewActionsTopMarginPx: 48.0px (24.0dp)\n" +
- "\toverviewActionsHeight: 96.0px (48.0dp)\n" +
- "\toverviewActionsButtonSpacing: 72.0px (36.0dp)\n" +
- "\toverviewPageSpacing: 88.0px (44.0dp)\n" +
- "\toverviewRowSpacing: 72.0px (36.0dp)\n" +
- "\toverviewGridSideMargin: 128.0px (64.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(): 1986.0px (993.0dp)\n" +
- "\tworkspaceSpringLoadedMinNextPageVisiblePx: 48.0px (24.0dp)\n" +
- "\tgetWorkspaceSpringLoadScale(): 0.76616377px (0.38308188dp)\n" +
- "\tgetCellLayoutHeight(): 1856.0px (928.0dp)\n" +
- "\tgetCellLayoutWidth(): 1528.0px (764.0dp)\n")
- }
-
- @Test
- fun twoPanelLandscape3Button() {
- initializeVarsForTwoPanel(isLandscape = true, isGestureMode = false)
- val dp = newDP()
- 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" +
- "\tisScalableGrid:true\n" +
- "\tinv.numRows: 4\n" +
- "\tinv.numColumns: 4\n" +
- "\tinv.numSearchContainerColumns: 4\n" +
- "\tminCellSize: PointF(80.0, 102.0)dp\n" +
- "\tcellWidthPx: 210.0px (80.0dp)\n" +
- "\tcellHeightPx: 267.0px (101.71429dp)\n" +
- "\tgetCellSize().x: 210.0px (80.0dp)\n" +
- "\tgetCellSize().y: 267.0px (101.71429dp)\n" +
- "\tcellLayoutBorderSpacePx Horizontal: 52.0px (19.809525dp)\n" +
- "\tcellLayoutBorderSpacePx Vertical: 52.0px (19.809525dp)\n" +
- "\tcellLayoutPaddingPx.left: 26.0px (9.904762dp)\n" +
- "\tcellLayoutPaddingPx.top: 18.0px (6.857143dp)\n" +
- "\tcellLayoutPaddingPx.right: 26.0px (9.904762dp)\n" +
- "\tcellLayoutPaddingPx.bottom: 26.0px (9.904762dp)\n" +
- "\ticonSizePx: 157.0px (59.809525dp)\n" +
- "\ticonTextSizePx: 36.0px (13.714286dp)\n" +
- "\ticonDrawablePaddingPx: 17.0px (6.4761906dp)\n" +
- "\tfolderCellWidthPx: 210.0px (80.0dp)\n" +
- "\tfolderCellHeightPx: 247.0px (94.09524dp)\n" +
- "\tfolderChildIconSizePx: 158.0px (60.190475dp)\n" +
- "\tfolderChildTextSizePx: 37.0px (14.095238dp)\n" +
- "\tfolderChildDrawablePaddingPx: 13.0px (4.952381dp)\n" +
- "\tfolderCellLayoutBorderSpacePx Horizontal: 42.0px (16.0dp)\n" +
- "\tfolderCellLayoutBorderSpacePx Vertical: 42.0px (16.0dp)\n" +
- "\tfolderContentPaddingLeftRight: 42.0px (16.0dp)\n" +
- "\tfolderTopPadding: 63.0px (24.0dp)\n" +
- "\tbottomSheetTopPadding: 110.0px (41.904762dp)\n" +
- "\tallAppsShiftRange: 1730.0px (659.0476dp)\n" +
- "\tallAppsTopPadding: 110.0px (41.904762dp)\n" +
- "\tallAppsIconSizePx: 157.0px (59.809525dp)\n" +
- "\tallAppsIconTextSizePx: 37.0px (14.095238dp)\n" +
- "\tallAppsIconDrawablePaddingPx: 18.0px (6.857143dp)\n" +
- "\tallAppsCellHeightPx: 315.0px (120.0dp)\n" +
- "\tallAppsCellWidthPx: 210.0px (80.0dp)\n" +
- "\tallAppsBorderSpacePxX: 52.0px (19.809525dp)\n" +
- "\tallAppsBorderSpacePxY: 42.0px (16.0dp)\n" +
- "\tnumShownAllAppsColumns: 6\n" +
- "\tallAppsLeftRightPadding: 137.0px (52.190475dp)\n" +
- "\tallAppsLeftRightMargin: 207.0px (78.85714dp)\n" +
- "\thotseatBarSizePx: 417.0px (158.85715dp)\n" +
- "\tinv.hotseatColumnSpan: 6\n" +
- "\thotseatCellHeightPx: 177.0px (67.42857dp)\n" +
- "\thotseatBarBottomSpacePx: 53.0px (20.190475dp)\n" +
- "\thotseatBarSidePaddingStartPx: 0.0px (0.0dp)\n" +
- "\thotseatBarSidePaddingEndPx: 0.0px (0.0dp)\n" +
- "\thotseatBarEndOffset: 744.0px (283.42856dp)\n" +
- "\thotseatQsbSpace: 74.0px (28.190475dp)\n" +
- "\thotseatQsbHeight: 165.0px (62.857143dp)\n" +
- "\tspringLoadedHotseatBarTopMarginPx: 116.0px (44.190475dp)\n" +
- "\tgetHotseatLayoutPadding(context).top: 197.0px (75.04762dp)\n" +
- "\tgetHotseatLayoutPadding(context).bottom: 43.0px (16.380953dp)\n" +
- "\tgetHotseatLayoutPadding(context).left: 106.0px (40.38095dp)\n" +
- "\tgetHotseatLayoutPadding(context).right: 744.0px (283.42856dp)\n" +
- "\tnumShownHotseatIcons: 6\n" +
- "\thotseatBorderSpace: 83.0px (31.619047dp)\n" +
- "\tisQsbInline: false\n" +
- "\thotseatQsbWidth: 1467.0px (558.8571dp)\n" +
- "\tisTaskbarPresent:true\n" +
- "\tisTaskbarPresentInApps:true\n" +
- "\ttaskbarSize: 158.0px (60.190475dp)\n" +
- "\tdesiredWorkspaceHorizontalMarginPx: 79.0px (30.095238dp)\n" +
- "\tworkspacePadding.left: 53.0px (20.190475dp)\n" +
- "\tworkspacePadding.top: 0.0px (0.0dp)\n" +
- "\tworkspacePadding.right: 53.0px (20.190475dp)\n" +
- "\tworkspacePadding.bottom: 461.0px (175.61905dp)\n" +
- "\ticonScale: 0.99864316px (0.3804355dp)\n" +
- "\tcellScaleToFit : 0.99864316px (0.3804355dp)\n" +
- "\textraSpace: 57.0px (21.714285dp)\n" +
- "\tunscaled extraSpace: 57.077446px (21.74379dp)\n" +
- "\tmaxEmptySpace: 131.0px (49.904762dp)\n" +
- "\tworkspaceTopPadding: 18.0px (6.857143dp)\n" +
- "\tworkspaceBottomPadding: 39.0px (14.857142dp)\n" +
- "\toverviewTaskMarginPx: 32.0px (12.190476dp)\n" +
- "\toverviewTaskIconSizePx: 126.0px (48.0dp)\n" +
- "\toverviewTaskIconDrawableSizePx: 116.0px (44.190475dp)\n" +
- "\toverviewTaskIconDrawableSizeGridPx: 116.0px (44.190475dp)\n" +
- "\toverviewTaskThumbnailTopMarginPx: 158.0px (60.190475dp)\n" +
- "\toverviewActionsTopMarginPx: 32.0px (12.190476dp)\n" +
- "\toverviewActionsHeight: 126.0px (48.0dp)\n" +
- "\toverviewActionsButtonSpacing: 95.0px (36.190475dp)\n" +
- "\toverviewPageSpacing: 95.0px (36.190475dp)\n" +
- "\toverviewRowSpacing: 74.0px (28.190475dp)\n" +
- "\toverviewGridSideMargin: 168.0px (64.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(): 1307.0px (497.90475dp)\n" +
- "\tworkspaceSpringLoadedMinNextPageVisiblePx: 63.0px (24.0dp)\n" +
- "\tgetWorkspaceSpringLoadScale(): 0.79432625px (0.30260047dp)\n" +
- "\tgetCellLayoutHeight(): 1269.0px (483.42856dp)\n" +
- "\tgetCellLayoutWidth(): 1051.0px (400.38095dp)\n")
- }
-
- @Test
- fun twoPanelLandscape() {
- initializeVarsForTwoPanel(isLandscape = true)
- val dp = newDP()
- 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" +
- "\tisScalableGrid:true\n" +
- "\tinv.numRows: 4\n" +
- "\tinv.numColumns: 4\n" +
- "\tinv.numSearchContainerColumns: 4\n" +
- "\tminCellSize: PointF(80.0, 102.0)dp\n" +
- "\tcellWidthPx: 210.0px (80.0dp)\n" +
- "\tcellHeightPx: 267.0px (101.71429dp)\n" +
- "\tgetCellSize().x: 210.0px (80.0dp)\n" +
- "\tgetCellSize().y: 267.0px (101.71429dp)\n" +
- "\tcellLayoutBorderSpacePx Horizontal: 52.0px (19.809525dp)\n" +
- "\tcellLayoutBorderSpacePx Vertical: 52.0px (19.809525dp)\n" +
- "\tcellLayoutPaddingPx.left: 26.0px (9.904762dp)\n" +
- "\tcellLayoutPaddingPx.top: 18.0px (6.857143dp)\n" +
- "\tcellLayoutPaddingPx.right: 26.0px (9.904762dp)\n" +
- "\tcellLayoutPaddingPx.bottom: 26.0px (9.904762dp)\n" +
- "\ticonSizePx: 157.0px (59.809525dp)\n" +
- "\ticonTextSizePx: 36.0px (13.714286dp)\n" +
- "\ticonDrawablePaddingPx: 17.0px (6.4761906dp)\n" +
- "\tfolderCellWidthPx: 210.0px (80.0dp)\n" +
- "\tfolderCellHeightPx: 247.0px (94.09524dp)\n" +
- "\tfolderChildIconSizePx: 158.0px (60.190475dp)\n" +
- "\tfolderChildTextSizePx: 37.0px (14.095238dp)\n" +
- "\tfolderChildDrawablePaddingPx: 13.0px (4.952381dp)\n" +
- "\tfolderCellLayoutBorderSpacePx Horizontal: 42.0px (16.0dp)\n" +
- "\tfolderCellLayoutBorderSpacePx Vertical: 42.0px (16.0dp)\n" +
- "\tfolderContentPaddingLeftRight: 42.0px (16.0dp)\n" +
- "\tfolderTopPadding: 63.0px (24.0dp)\n" +
- "\tbottomSheetTopPadding: 110.0px (41.904762dp)\n" +
- "\tallAppsShiftRange: 1730.0px (659.0476dp)\n" +
- "\tallAppsTopPadding: 110.0px (41.904762dp)\n" +
- "\tallAppsIconSizePx: 157.0px (59.809525dp)\n" +
- "\tallAppsIconTextSizePx: 37.0px (14.095238dp)\n" +
- "\tallAppsIconDrawablePaddingPx: 18.0px (6.857143dp)\n" +
- "\tallAppsCellHeightPx: 315.0px (120.0dp)\n" +
- "\tallAppsCellWidthPx: 210.0px (80.0dp)\n" +
- "\tallAppsBorderSpacePxX: 52.0px (19.809525dp)\n" +
- "\tallAppsBorderSpacePxY: 42.0px (16.0dp)\n" +
- "\tnumShownAllAppsColumns: 6\n" +
- "\tallAppsLeftRightPadding: 137.0px (52.190475dp)\n" +
- "\tallAppsLeftRightMargin: 207.0px (78.85714dp)\n" +
- "\thotseatBarSizePx: 417.0px (158.85715dp)\n" +
- "\tinv.hotseatColumnSpan: 6\n" +
- "\thotseatCellHeightPx: 177.0px (67.42857dp)\n" +
- "\thotseatBarBottomSpacePx: 53.0px (20.190475dp)\n" +
- "\thotseatBarSidePaddingStartPx: 0.0px (0.0dp)\n" +
- "\thotseatBarSidePaddingEndPx: 0.0px (0.0dp)\n" +
- "\thotseatBarEndOffset: 0.0px (0.0dp)\n" +
- "\thotseatQsbSpace: 74.0px (28.190475dp)\n" +
- "\thotseatQsbHeight: 165.0px (62.857143dp)\n" +
- "\tspringLoadedHotseatBarTopMarginPx: 116.0px (44.190475dp)\n" +
- "\tgetHotseatLayoutPadding(context).top: 197.0px (75.04762dp)\n" +
- "\tgetHotseatLayoutPadding(context).bottom: 43.0px (16.380953dp)\n" +
- "\tgetHotseatLayoutPadding(context).left: 370.0px (140.95238dp)\n" +
- "\tgetHotseatLayoutPadding(context).right: 370.0px (140.95238dp)\n" +
- "\tnumShownHotseatIcons: 6\n" +
- "\thotseatBorderSpace: 105.0px (40.0dp)\n" +
- "\tisQsbInline: false\n" +
- "\thotseatQsbWidth: 1467.0px (558.8571dp)\n" +
- "\tisTaskbarPresent:true\n" +
- "\tisTaskbarPresentInApps:true\n" +
- "\ttaskbarSize: 158.0px (60.190475dp)\n" +
- "\tdesiredWorkspaceHorizontalMarginPx: 79.0px (30.095238dp)\n" +
- "\tworkspacePadding.left: 53.0px (20.190475dp)\n" +
- "\tworkspacePadding.top: 0.0px (0.0dp)\n" +
- "\tworkspacePadding.right: 53.0px (20.190475dp)\n" +
- "\tworkspacePadding.bottom: 461.0px (175.61905dp)\n" +
- "\ticonScale: 0.99864316px (0.3804355dp)\n" +
- "\tcellScaleToFit : 0.99864316px (0.3804355dp)\n" +
- "\textraSpace: 57.0px (21.714285dp)\n" +
- "\tunscaled extraSpace: 57.077446px (21.74379dp)\n" +
- "\tmaxEmptySpace: 131.0px (49.904762dp)\n" +
- "\tworkspaceTopPadding: 18.0px (6.857143dp)\n" +
- "\tworkspaceBottomPadding: 39.0px (14.857142dp)\n" +
- "\toverviewTaskMarginPx: 32.0px (12.190476dp)\n" +
- "\toverviewTaskIconSizePx: 126.0px (48.0dp)\n" +
- "\toverviewTaskIconDrawableSizePx: 116.0px (44.190475dp)\n" +
- "\toverviewTaskIconDrawableSizeGridPx: 116.0px (44.190475dp)\n" +
- "\toverviewTaskThumbnailTopMarginPx: 158.0px (60.190475dp)\n" +
- "\toverviewActionsTopMarginPx: 32.0px (12.190476dp)\n" +
- "\toverviewActionsHeight: 126.0px (48.0dp)\n" +
- "\toverviewActionsButtonSpacing: 95.0px (36.190475dp)\n" +
- "\toverviewPageSpacing: 95.0px (36.190475dp)\n" +
- "\toverviewRowSpacing: 74.0px (28.190475dp)\n" +
- "\toverviewGridSideMargin: 168.0px (64.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(): 1307.0px (497.90475dp)\n" +
- "\tworkspaceSpringLoadedMinNextPageVisiblePx: 63.0px (24.0dp)\n" +
- "\tgetWorkspaceSpringLoadScale(): 0.79432625px (0.30260047dp)\n" +
- "\tgetCellLayoutHeight(): 1269.0px (483.42856dp)\n" +
- "\tgetCellLayoutWidth(): 1051.0px (400.38095dp)\n")
- }
-
- @Test
- fun twoPanelPortrait3Button() {
- initializeVarsForTwoPanel(isGestureMode = false)
- val dp = newDP()
- 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: 2098.0px (799.2381dp)\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" +
- "\tisScalableGrid:true\n" +
- "\tinv.numRows: 4\n" +
- "\tinv.numColumns: 4\n" +
- "\tinv.numSearchContainerColumns: 4\n" +
- "\tminCellSize: PointF(68.0, 116.0)dp\n" +
- "\tcellWidthPx: 178.0px (67.809525dp)\n" +
- "\tcellHeightPx: 304.0px (115.809525dp)\n" +
- "\tgetCellSize().x: 178.0px (67.809525dp)\n" +
- "\tgetCellSize().y: 304.0px (115.809525dp)\n" +
- "\tcellLayoutBorderSpacePx Horizontal: 42.0px (16.0dp)\n" +
- "\tcellLayoutBorderSpacePx Vertical: 52.0px (19.809525dp)\n" +
- "\tcellLayoutPaddingPx.left: 21.0px (8.0dp)\n" +
- "\tcellLayoutPaddingPx.top: 21.0px (8.0dp)\n" +
- "\tcellLayoutPaddingPx.right: 21.0px (8.0dp)\n" +
- "\tcellLayoutPaddingPx.bottom: 21.0px (8.0dp)\n" +
- "\ticonSizePx: 136.0px (51.809525dp)\n" +
- "\ticonTextSizePx: 31.0px (11.809524dp)\n" +
- "\ticonDrawablePaddingPx: 17.0px (6.4761906dp)\n" +
- "\tfolderCellWidthPx: 210.0px (80.0dp)\n" +
- "\tfolderCellHeightPx: 247.0px (94.09524dp)\n" +
- "\tfolderChildIconSizePx: 158.0px (60.190475dp)\n" +
- "\tfolderChildTextSizePx: 37.0px (14.095238dp)\n" +
- "\tfolderChildDrawablePaddingPx: 13.0px (4.952381dp)\n" +
- "\tfolderCellLayoutBorderSpacePx Horizontal: 42.0px (16.0dp)\n" +
- "\tfolderCellLayoutBorderSpacePx Vertical: 42.0px (16.0dp)\n" +
- "\tfolderContentPaddingLeftRight: 42.0px (16.0dp)\n" +
- "\tfolderTopPadding: 63.0px (24.0dp)\n" +
- "\tbottomSheetTopPadding: 110.0px (41.904762dp)\n" +
- "\tallAppsShiftRange: 2098.0px (799.2381dp)\n" +
- "\tallAppsTopPadding: 110.0px (41.904762dp)\n" +
- "\tallAppsIconSizePx: 136.0px (51.809525dp)\n" +
- "\tallAppsIconTextSizePx: 31.0px (11.809524dp)\n" +
- "\tallAppsIconDrawablePaddingPx: 18.0px (6.857143dp)\n" +
- "\tallAppsCellHeightPx: 345.0px (131.42857dp)\n" +
- "\tallAppsCellWidthPx: 178.0px (67.809525dp)\n" +
- "\tallAppsBorderSpacePxX: 42.0px (16.0dp)\n" +
- "\tallAppsBorderSpacePxY: 73.0px (27.809525dp)\n" +
- "\tnumShownAllAppsColumns: 6\n" +
- "\tallAppsLeftRightPadding: 126.0px (48.0dp)\n" +
- "\tallAppsLeftRightMargin: 155.0px (59.04762dp)\n" +
- "\thotseatBarSizePx: 459.0px (174.85715dp)\n" +
- "\tinv.hotseatColumnSpan: 6\n" +
- "\thotseatCellHeightPx: 153.0px (58.285713dp)\n" +
- "\thotseatBarBottomSpacePx: 95.0px (36.190475dp)\n" +
- "\thotseatBarSidePaddingStartPx: 0.0px (0.0dp)\n" +
- "\thotseatBarSidePaddingEndPx: 0.0px (0.0dp)\n" +
- "\thotseatBarEndOffset: 660.0px (251.42857dp)\n" +
- "\thotseatQsbSpace: 95.0px (36.190475dp)\n" +
- "\thotseatQsbHeight: 165.0px (62.857143dp)\n" +
- "\tspringLoadedHotseatBarTopMarginPx: 171.0px (65.14286dp)\n" +
- "\tgetHotseatLayoutPadding(context).top: 219.0px (83.42857dp)\n" +
- "\tgetHotseatLayoutPadding(context).bottom: 87.0px (33.142857dp)\n" +
- "\tgetHotseatLayoutPadding(context).left: 78.0px (29.714285dp)\n" +
- "\tgetHotseatLayoutPadding(context).right: 660.0px (251.42857dp)\n" +
- "\tnumShownHotseatIcons: 6\n" +
- "\thotseatBorderSpace: 57.0px (21.714285dp)\n" +
- "\tisQsbInline: false\n" +
- "\thotseatQsbWidth: 1236.0px (470.85715dp)\n" +
- "\tisTaskbarPresent:true\n" +
- "\tisTaskbarPresentInApps:true\n" +
- "\ttaskbarSize: 158.0px (60.190475dp)\n" +
- "\tdesiredWorkspaceHorizontalMarginPx: 58.0px (22.095238dp)\n" +
- "\tworkspacePadding.left: 37.0px (14.095238dp)\n" +
- "\tworkspacePadding.top: 68.0px (25.904762dp)\n" +
- "\tworkspacePadding.right: 37.0px (14.095238dp)\n" +
- "\tworkspacePadding.bottom: 615.0px (234.28572dp)\n" +
- "\ticonScale: 0.9978308px (0.38012603dp)\n" +
- "\tcellScaleToFit : 0.9978308px (0.38012603dp)\n" +
- "\textraSpace: 235.0px (89.52381dp)\n" +
- "\tunscaled extraSpace: 235.51086px (89.71842dp)\n" +
- "\tmaxEmptySpace: 236.0px (89.90476dp)\n" +
- "\tworkspaceTopPadding: 89.0px (33.904762dp)\n" +
- "\tworkspaceBottomPadding: 146.0px (55.61905dp)\n" +
- "\toverviewTaskMarginPx: 32.0px (12.190476dp)\n" +
- "\toverviewTaskIconSizePx: 126.0px (48.0dp)\n" +
- "\toverviewTaskIconDrawableSizePx: 116.0px (44.190475dp)\n" +
- "\toverviewTaskIconDrawableSizeGridPx: 116.0px (44.190475dp)\n" +
- "\toverviewTaskThumbnailTopMarginPx: 158.0px (60.190475dp)\n" +
- "\toverviewActionsTopMarginPx: 63.0px (24.0dp)\n" +
- "\toverviewActionsHeight: 126.0px (48.0dp)\n" +
- "\toverviewActionsButtonSpacing: 95.0px (36.190475dp)\n" +
- "\toverviewPageSpacing: 95.0px (36.190475dp)\n" +
- "\toverviewRowSpacing: 74.0px (28.190475dp)\n" +
- "\toverviewGridSideMargin: 168.0px (64.0dp)\n" +
- "\tdropTargetBarTopMarginPx: 168.0px (64.0dp)\n" +
- "\tdropTargetBarSizePx: 147.0px (56.0dp)\n" +
- "\tdropTargetBarBottomMarginPx: 42.0px (16.0dp)\n" +
- "\tgetCellLayoutSpringLoadShrunkTop(): 467.0px (177.90475dp)\n" +
- "\tgetCellLayoutSpringLoadShrunkBottom(): 1578.0px (601.1429dp)\n" +
- "\tworkspaceSpringLoadedMinNextPageVisiblePx: 63.0px (24.0dp)\n" +
- "\tgetWorkspaceSpringLoadScale(): 0.785159px (0.29910818dp)\n" +
- "\tgetCellLayoutHeight(): 1415.0px (539.0476dp)\n" +
- "\tgetCellLayoutWidth(): 883.0px (336.38095dp)\n")
- }
-
- @Test
- fun twoPanelPortrait() {
- initializeVarsForTwoPanel()
- val dp = newDP()
- 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: 2098.0px (799.2381dp)\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" +
- "\tisScalableGrid:true\n" +
- "\tinv.numRows: 4\n" +
- "\tinv.numColumns: 4\n" +
- "\tinv.numSearchContainerColumns: 4\n" +
- "\tminCellSize: PointF(68.0, 116.0)dp\n" +
- "\tcellWidthPx: 178.0px (67.809525dp)\n" +
- "\tcellHeightPx: 304.0px (115.809525dp)\n" +
- "\tgetCellSize().x: 178.0px (67.809525dp)\n" +
- "\tgetCellSize().y: 304.0px (115.809525dp)\n" +
- "\tcellLayoutBorderSpacePx Horizontal: 42.0px (16.0dp)\n" +
- "\tcellLayoutBorderSpacePx Vertical: 52.0px (19.809525dp)\n" +
- "\tcellLayoutPaddingPx.left: 21.0px (8.0dp)\n" +
- "\tcellLayoutPaddingPx.top: 21.0px (8.0dp)\n" +
- "\tcellLayoutPaddingPx.right: 21.0px (8.0dp)\n" +
- "\tcellLayoutPaddingPx.bottom: 21.0px (8.0dp)\n" +
- "\ticonSizePx: 136.0px (51.809525dp)\n" +
- "\ticonTextSizePx: 31.0px (11.809524dp)\n" +
- "\ticonDrawablePaddingPx: 17.0px (6.4761906dp)\n" +
- "\tfolderCellWidthPx: 210.0px (80.0dp)\n" +
- "\tfolderCellHeightPx: 247.0px (94.09524dp)\n" +
- "\tfolderChildIconSizePx: 158.0px (60.190475dp)\n" +
- "\tfolderChildTextSizePx: 37.0px (14.095238dp)\n" +
- "\tfolderChildDrawablePaddingPx: 13.0px (4.952381dp)\n" +
- "\tfolderCellLayoutBorderSpacePx Horizontal: 42.0px (16.0dp)\n" +
- "\tfolderCellLayoutBorderSpacePx Vertical: 42.0px (16.0dp)\n" +
- "\tfolderContentPaddingLeftRight: 42.0px (16.0dp)\n" +
- "\tfolderTopPadding: 63.0px (24.0dp)\n" +
- "\tbottomSheetTopPadding: 110.0px (41.904762dp)\n" +
- "\tallAppsShiftRange: 2098.0px (799.2381dp)\n" +
- "\tallAppsTopPadding: 110.0px (41.904762dp)\n" +
- "\tallAppsIconSizePx: 136.0px (51.809525dp)\n" +
- "\tallAppsIconTextSizePx: 31.0px (11.809524dp)\n" +
- "\tallAppsIconDrawablePaddingPx: 18.0px (6.857143dp)\n" +
- "\tallAppsCellHeightPx: 345.0px (131.42857dp)\n" +
- "\tallAppsCellWidthPx: 178.0px (67.809525dp)\n" +
- "\tallAppsBorderSpacePxX: 42.0px (16.0dp)\n" +
- "\tallAppsBorderSpacePxY: 73.0px (27.809525dp)\n" +
- "\tnumShownAllAppsColumns: 6\n" +
- "\tallAppsLeftRightPadding: 126.0px (48.0dp)\n" +
- "\tallAppsLeftRightMargin: 155.0px (59.04762dp)\n" +
- "\thotseatBarSizePx: 459.0px (174.85715dp)\n" +
- "\tinv.hotseatColumnSpan: 6\n" +
- "\thotseatCellHeightPx: 153.0px (58.285713dp)\n" +
- "\thotseatBarBottomSpacePx: 95.0px (36.190475dp)\n" +
- "\thotseatBarSidePaddingStartPx: 0.0px (0.0dp)\n" +
- "\thotseatBarSidePaddingEndPx: 0.0px (0.0dp)\n" +
- "\thotseatBarEndOffset: 0.0px (0.0dp)\n" +
- "\thotseatQsbSpace: 95.0px (36.190475dp)\n" +
- "\thotseatQsbHeight: 165.0px (62.857143dp)\n" +
- "\tspringLoadedHotseatBarTopMarginPx: 171.0px (65.14286dp)\n" +
- "\tgetHotseatLayoutPadding(context).top: 219.0px (83.42857dp)\n" +
- "\tgetHotseatLayoutPadding(context).bottom: 87.0px (33.142857dp)\n" +
- "\tgetHotseatLayoutPadding(context).left: 302.0px (115.04762dp)\n" +
- "\tgetHotseatLayoutPadding(context).right: 302.0px (115.04762dp)\n" +
- "\tnumShownHotseatIcons: 6\n" +
- "\thotseatBorderSpace: 84.0px (32.0dp)\n" +
- "\tisQsbInline: false\n" +
- "\thotseatQsbWidth: 1236.0px (470.85715dp)\n" +
- "\tisTaskbarPresent:true\n" +
- "\tisTaskbarPresentInApps:true\n" +
- "\ttaskbarSize: 158.0px (60.190475dp)\n" +
- "\tdesiredWorkspaceHorizontalMarginPx: 58.0px (22.095238dp)\n" +
- "\tworkspacePadding.left: 37.0px (14.095238dp)\n" +
- "\tworkspacePadding.top: 68.0px (25.904762dp)\n" +
- "\tworkspacePadding.right: 37.0px (14.095238dp)\n" +
- "\tworkspacePadding.bottom: 615.0px (234.28572dp)\n" +
- "\ticonScale: 0.9978308px (0.38012603dp)\n" +
- "\tcellScaleToFit : 0.9978308px (0.38012603dp)\n" +
- "\textraSpace: 235.0px (89.52381dp)\n" +
- "\tunscaled extraSpace: 235.51086px (89.71842dp)\n" +
- "\tmaxEmptySpace: 236.0px (89.90476dp)\n" +
- "\tworkspaceTopPadding: 89.0px (33.904762dp)\n" +
- "\tworkspaceBottomPadding: 146.0px (55.61905dp)\n" +
- "\toverviewTaskMarginPx: 32.0px (12.190476dp)\n" +
- "\toverviewTaskIconSizePx: 126.0px (48.0dp)\n" +
- "\toverviewTaskIconDrawableSizePx: 116.0px (44.190475dp)\n" +
- "\toverviewTaskIconDrawableSizeGridPx: 116.0px (44.190475dp)\n" +
- "\toverviewTaskThumbnailTopMarginPx: 158.0px (60.190475dp)\n" +
- "\toverviewActionsTopMarginPx: 63.0px (24.0dp)\n" +
- "\toverviewActionsHeight: 126.0px (48.0dp)\n" +
- "\toverviewActionsButtonSpacing: 95.0px (36.190475dp)\n" +
- "\toverviewPageSpacing: 95.0px (36.190475dp)\n" +
- "\toverviewRowSpacing: 74.0px (28.190475dp)\n" +
- "\toverviewGridSideMargin: 168.0px (64.0dp)\n" +
- "\tdropTargetBarTopMarginPx: 168.0px (64.0dp)\n" +
- "\tdropTargetBarSizePx: 147.0px (56.0dp)\n" +
- "\tdropTargetBarBottomMarginPx: 42.0px (16.0dp)\n" +
- "\tgetCellLayoutSpringLoadShrunkTop(): 467.0px (177.90475dp)\n" +
- "\tgetCellLayoutSpringLoadShrunkBottom(): 1578.0px (601.1429dp)\n" +
- "\tworkspaceSpringLoadedMinNextPageVisiblePx: 63.0px (24.0dp)\n" +
- "\tgetWorkspaceSpringLoadScale(): 0.785159px (0.29910818dp)\n" +
- "\tgetCellLayoutHeight(): 1415.0px (539.0476dp)\n" +
- "\tgetCellLayoutWidth(): 883.0px (336.38095dp)\n")
- }
-
- @Test
- fun phoneVerticalBar3Button() {
- initializeVarsForPhone(isVerticalBar = true, isGestureMode = false)
- val dp = newDP()
-
- 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" +
- "\tisScalableGrid:false\n" +
- "\tinv.numRows: 5\n" +
- "\tinv.numColumns: 4\n" +
- "\tinv.numSearchContainerColumns: 4\n" +
- "\tminCellSize: PointF(80.0, 104.0)dp\n" +
- "\tcellWidthPx: 153.0px (58.285713dp)\n" +
- "\tcellHeightPx: 160.0px (60.95238dp)\n" +
- "\tgetCellSize().x: 461.0px (175.61905dp)\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: 142.0px (54.095238dp)\n" +
- "\ticonTextSizePx: 0.0px (0.0dp)\n" +
- "\ticonDrawablePaddingPx: 0.0px (0.0dp)\n" +
- "\tfolderCellWidthPx: 175.0px (66.666664dp)\n" +
- "\tfolderCellHeightPx: 205.0px (78.09524dp)\n" +
- "\tfolderChildIconSizePx: 131.0px (49.904762dp)\n" +
- "\tfolderChildTextSizePx: 34.0px (12.952381dp)\n" +
- "\tfolderChildDrawablePaddingPx: 9.0px (3.4285715dp)\n" +
- "\tfolderCellLayoutBorderSpacePx Horizontal: 42.0px (16.0dp)\n" +
- "\tfolderCellLayoutBorderSpacePx Vertical: 42.0px (16.0dp)\n" +
- "\tfolderContentPaddingLeftRight: 21.0px (8.0dp)\n" +
- "\tfolderTopPadding: 42.0px (16.0dp)\n" +
- "\tbottomSheetTopPadding: 114.0px (43.42857dp)\n" +
- "\tallAppsShiftRange: 788.0px (300.1905dp)\n" +
- "\tallAppsTopPadding: 0.0px (0.0dp)\n" +
- "\tallAppsIconSizePx: 158.0px (60.190475dp)\n" +
- "\tallAppsIconTextSizePx: 37.0px (14.095238dp)\n" +
- "\tallAppsIconDrawablePaddingPx: 21.0px (8.0dp)\n" +
- "\tallAppsCellHeightPx: 329.0px (125.333336dp)\n" +
- "\tallAppsCellWidthPx: 200.0px (76.190475dp)\n" +
- "\tallAppsBorderSpacePxX: 42.0px (16.0dp)\n" +
- "\tallAppsBorderSpacePxY: 42.0px (16.0dp)\n" +
- "\tnumShownAllAppsColumns: 4\n" +
- "\tallAppsLeftRightPadding: 0.0px (0.0dp)\n" +
- "\tallAppsLeftRightMargin: 0.0px (0.0dp)\n" +
- "\thotseatBarSizePx: 247.0px (94.09524dp)\n" +
- "\tinv.hotseatColumnSpan: 4\n" +
- "\thotseatCellHeightPx: 160.0px (60.95238dp)\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: 95.0px (36.190475dp)\n" +
- "\thotseatQsbHeight: 165.0px (62.857143dp)\n" +
- "\tspringLoadedHotseatBarTopMarginPx: 118.0px (44.95238dp)\n" +
- "\tgetHotseatLayoutPadding(context).top: 65.0px (24.761906dp)\n" +
- "\tgetHotseatLayoutPadding(context).bottom: 48.0px (18.285715dp)\n" +
- "\tgetHotseatLayoutPadding(context).left: 42.0px (16.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).right: 189.0px (72.0dp)\n" +
- "\tnumShownHotseatIcons: 4\n" +
- "\thotseatBorderSpace: 0.0px (0.0dp)\n" +
- "\tisQsbInline: false\n" +
- "\thotseatQsbWidth: 1525.0px (580.9524dp)\n" +
- "\tisTaskbarPresent:false\n" +
- "\tisTaskbarPresentInApps:false\n" +
- "\ttaskbarSize: 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: 194.0px (73.90476dp)\n" +
- "\tworkspacePadding.bottom: 0.0px (0.0dp)\n" +
- "\ticonScale: 1.0px (0.3809524dp)\n" +
- "\tcellScaleToFit : 1.0px (0.3809524dp)\n" +
- "\textraSpace: 166.0px (63.238094dp)\n" +
- "\tunscaled extraSpace: 166.0px (63.238094dp)\n" +
- "\tmaxEmptySpace: 184.0px (70.09524dp)\n" +
- "\tworkspaceTopPadding: 0.0px (0.0dp)\n" +
- "\tworkspaceBottomPadding: 0.0px (0.0dp)\n" +
- "\toverviewTaskMarginPx: 42.0px (16.0dp)\n" +
- "\toverviewTaskIconSizePx: 126.0px (48.0dp)\n" +
- "\toverviewTaskIconDrawableSizePx: 116.0px (44.190475dp)\n" +
- "\toverviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)\n" +
- "\toverviewTaskThumbnailTopMarginPx: 168.0px (64.0dp)\n" +
- "\toverviewActionsTopMarginPx: 32.0px (12.190476dp)\n" +
- "\toverviewActionsHeight: 126.0px (48.0dp)\n" +
- "\toverviewActionsButtonSpacing: 95.0px (36.190475dp)\n" +
- "\toverviewPageSpacing: 42.0px (16.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(): 983.0px (374.4762dp)\n" +
- "\tworkspaceSpringLoadedMinNextPageVisiblePx: 63.0px (24.0dp)\n" +
- "\tgetWorkspaceSpringLoadScale(): 0.777336px (0.296128dp)\n" +
- "\tgetCellLayoutHeight(): 1006.0px (383.2381dp)\n" +
- "\tgetCellLayoutWidth(): 1952.0px (743.619dp)\n")
- }
-
- @Test
- fun phoneVerticalBar() {
- initializeVarsForPhone(isVerticalBar = true)
- val dp = newDP()
-
- 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" +
- "\tisScalableGrid:false\n" +
- "\tinv.numRows: 5\n" +
- "\tinv.numColumns: 4\n" +
- "\tinv.numSearchContainerColumns: 4\n" +
- "\tminCellSize: PointF(80.0, 104.0)dp\n" +
- "\tcellWidthPx: 153.0px (58.285713dp)\n" +
- "\tcellHeightPx: 160.0px (60.95238dp)\n" +
- "\tgetCellSize().x: 493.0px (187.80952dp)\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: 142.0px (54.095238dp)\n" +
- "\ticonTextSizePx: 0.0px (0.0dp)\n" +
- "\ticonDrawablePaddingPx: 0.0px (0.0dp)\n" +
- "\tfolderCellWidthPx: 159.0px (60.57143dp)\n" +
- "\tfolderCellHeightPx: 187.0px (71.2381dp)\n" +
- "\tfolderChildIconSizePx: 119.0px (45.333332dp)\n" +
- "\tfolderChildTextSizePx: 31.0px (11.809524dp)\n" +
- "\tfolderChildDrawablePaddingPx: 8.0px (3.047619dp)\n" +
- "\tfolderCellLayoutBorderSpacePx Horizontal: 42.0px (16.0dp)\n" +
- "\tfolderCellLayoutBorderSpacePx Vertical: 42.0px (16.0dp)\n" +
- "\tfolderContentPaddingLeftRight: 21.0px (8.0dp)\n" +
- "\tfolderTopPadding: 42.0px (16.0dp)\n" +
- "\tbottomSheetTopPadding: 114.0px (43.42857dp)\n" +
- "\tallAppsShiftRange: 788.0px (300.1905dp)\n" +
- "\tallAppsTopPadding: 0.0px (0.0dp)\n" +
- "\tallAppsIconSizePx: 158.0px (60.190475dp)\n" +
- "\tallAppsIconTextSizePx: 37.0px (14.095238dp)\n" +
- "\tallAppsIconDrawablePaddingPx: 21.0px (8.0dp)\n" +
- "\tallAppsCellHeightPx: 329.0px (125.333336dp)\n" +
- "\tallAppsCellWidthPx: 200.0px (76.190475dp)\n" +
- "\tallAppsBorderSpacePxX: 42.0px (16.0dp)\n" +
- "\tallAppsBorderSpacePxY: 42.0px (16.0dp)\n" +
- "\tnumShownAllAppsColumns: 4\n" +
- "\tallAppsLeftRightPadding: 0.0px (0.0dp)\n" +
- "\tallAppsLeftRightMargin: 0.0px (0.0dp)\n" +
- "\thotseatBarSizePx: 247.0px (94.09524dp)\n" +
- "\tinv.hotseatColumnSpan: 4\n" +
- "\thotseatCellHeightPx: 160.0px (60.95238dp)\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: 95.0px (36.190475dp)\n" +
- "\thotseatQsbHeight: 165.0px (62.857143dp)\n" +
- "\tspringLoadedHotseatBarTopMarginPx: 118.0px (44.95238dp)\n" +
- "\tgetHotseatLayoutPadding(context).top: 65.0px (24.761906dp)\n" +
- "\tgetHotseatLayoutPadding(context).bottom: 111.0px (42.285713dp)\n" +
- "\tgetHotseatLayoutPadding(context).left: 42.0px (16.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).right: 63.0px (24.0dp)\n" +
- "\tnumShownHotseatIcons: 4\n" +
- "\thotseatBorderSpace: 0.0px (0.0dp)\n" +
- "\tisQsbInline: false\n" +
- "\thotseatQsbWidth: 1621.0px (617.5238dp)\n" +
- "\tisTaskbarPresent:false\n" +
- "\tisTaskbarPresentInApps:false\n" +
- "\ttaskbarSize: 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: 194.0px (73.90476dp)\n" +
- "\tworkspacePadding.bottom: 0.0px (0.0dp)\n" +
- "\ticonScale: 1.0px (0.3809524dp)\n" +
- "\tcellScaleToFit : 1.0px (0.3809524dp)\n" +
- "\textraSpace: 103.0px (39.238094dp)\n" +
- "\tunscaled extraSpace: 103.0px (39.238094dp)\n" +
- "\tmaxEmptySpace: 131.0px (49.904762dp)\n" +
- "\tworkspaceTopPadding: 0.0px (0.0dp)\n" +
- "\tworkspaceBottomPadding: 0.0px (0.0dp)\n" +
- "\toverviewTaskMarginPx: 42.0px (16.0dp)\n" +
- "\toverviewTaskIconSizePx: 126.0px (48.0dp)\n" +
- "\toverviewTaskIconDrawableSizePx: 116.0px (44.190475dp)\n" +
- "\toverviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)\n" +
- "\toverviewTaskThumbnailTopMarginPx: 168.0px (64.0dp)\n" +
- "\toverviewActionsTopMarginPx: 32.0px (12.190476dp)\n" +
- "\toverviewActionsHeight: 126.0px (48.0dp)\n" +
- "\toverviewActionsButtonSpacing: 95.0px (36.190475dp)\n" +
- "\toverviewPageSpacing: 42.0px (16.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(): 927.0px (353.14285dp)\n" +
- "\tworkspaceSpringLoadedMinNextPageVisiblePx: 63.0px (24.0dp)\n" +
- "\tgetWorkspaceSpringLoadScale(): 0.76988333px (0.2932889dp)\n" +
- "\tgetCellLayoutHeight(): 943.0px (359.2381dp)\n" +
- "\tgetCellLayoutWidth(): 2078.0px (791.619dp)\n")
- }
-}
\ No newline at end of file
diff --git a/quickstep/tests/src/com/android/quickstep/OrientationTouchTransformerTest.java b/quickstep/tests/src/com/android/quickstep/OrientationTouchTransformerTest.java
index c822578..9c240f0 100644
--- a/quickstep/tests/src/com/android/quickstep/OrientationTouchTransformerTest.java
+++ b/quickstep/tests/src/com/android/quickstep/OrientationTouchTransformerTest.java
@@ -19,7 +19,7 @@
import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
-import static com.android.launcher3.util.DisplayController.NavigationMode.NO_BUTTON;
+import static com.android.launcher3.util.NavigationMode.NO_BUTTON;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
diff --git a/quickstep/tests/src/com/android/quickstep/RecentTasksListTest.java b/quickstep/tests/src/com/android/quickstep/RecentTasksListTest.java
index 4e49716..262dc37 100644
--- a/quickstep/tests/src/com/android/quickstep/RecentTasksListTest.java
+++ b/quickstep/tests/src/com/android/quickstep/RecentTasksListTest.java
@@ -70,7 +70,7 @@
@Test
public void loadTasksInBackground_onlyKeys_noValidTaskDescription() {
- GroupedRecentTaskInfo recentTaskInfos = new GroupedRecentTaskInfo(
+ GroupedRecentTaskInfo recentTaskInfos = GroupedRecentTaskInfo.forSplitTasks(
new ActivityManager.RecentTaskInfo(), new ActivityManager.RecentTaskInfo(), null);
when(mockSystemUiProxy.getRecentTasks(anyInt(), anyInt()))
.thenReturn(new ArrayList<>(Collections.singletonList(recentTaskInfos)));
@@ -90,8 +90,8 @@
task1.taskDescription = new ActivityManager.TaskDescription(taskDescription);
ActivityManager.RecentTaskInfo task2 = new ActivityManager.RecentTaskInfo();
task2.taskDescription = new ActivityManager.TaskDescription();
- GroupedRecentTaskInfo recentTaskInfos = new GroupedRecentTaskInfo(
- task1, task2, null);
+ GroupedRecentTaskInfo recentTaskInfos = GroupedRecentTaskInfo.forSplitTasks(task1, task2,
+ null);
when(mockSystemUiProxy.getRecentTasks(anyInt(), anyInt()))
.thenReturn(new ArrayList<>(Collections.singletonList(recentTaskInfos)));
diff --git a/quickstep/tests/src/com/android/quickstep/util/TaskViewSimulatorTest.java b/quickstep/tests/src/com/android/quickstep/util/TaskViewSimulatorTest.java
index d43aafa..190b002 100644
--- a/quickstep/tests/src/com/android/quickstep/util/TaskViewSimulatorTest.java
+++ b/quickstep/tests/src/com/android/quickstep/util/TaskViewSimulatorTest.java
@@ -34,6 +34,7 @@
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.DisplayController.Info;
import com.android.launcher3.util.LauncherModelHelper;
+import com.android.launcher3.util.NavigationMode;
import com.android.launcher3.util.ReflectionHelpers;
import com.android.launcher3.util.RotationUtils;
import com.android.launcher3.util.WindowBounds;
@@ -164,6 +165,7 @@
WindowManagerProxy wmProxy = mock(WindowManagerProxy.class);
doReturn(cdi).when(wmProxy).getDisplayInfo(any());
doReturn(wm).when(wmProxy).getRealBounds(any(), any());
+ doReturn(NavigationMode.NO_BUTTON).when(wmProxy).getNavigationMode(any());
ArrayMap<CachedDisplayInfo, WindowBounds[]> perDisplayBoundsCache =
new ArrayMap<>();
diff --git a/res/layout/hotseat.xml b/res/layout/hotseat.xml
index 82b0b8d..95ebd94 100644
--- a/res/layout/hotseat.xml
+++ b/res/layout/hotseat.xml
@@ -21,4 +21,5 @@
android:layout_height="match_parent"
android:theme="@style/HomeScreenElementTheme"
android:importantForAccessibility="no"
+ android:preferKeepClear="true"
launcher:containerType="hotseat" />
\ No newline at end of file
diff --git a/res/layout/user_folder_icon_normalized.xml b/res/layout/user_folder_icon_normalized.xml
index 87bf33d..4dee6e7 100644
--- a/res/layout/user_folder_icon_normalized.xml
+++ b/res/layout/user_folder_icon_normalized.xml
@@ -34,7 +34,8 @@
android:clipChildren="false"
android:orientation="horizontal"
android:paddingLeft="12dp"
- android:paddingRight="12dp" >
+ android:paddingRight="12dp"
+ android:alpha="0">
<com.android.launcher3.folder.FolderNameEditText
android:id="@+id/folder_name"
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index e075559..c234900 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -101,7 +101,7 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"المجلد: <xliff:g id="NAME">%1$s</xliff:g>، <xliff:g id="SIZE">%2$d</xliff:g> عنصر"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"المجلد: <xliff:g id="NAME">%1$s</xliff:g>، <xliff:g id="SIZE">%2$d</xliff:g> عنصر أو أكثر"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"الخلفيات"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"الخلفية والنمط"</string>
+ <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"الخلفية والأسلوب"</string>
<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>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index a9d1127..2e886db 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -226,6 +226,7 @@
<dimen name="drop_target_text_size">16sp</dimen>
<dimen name="drop_target_shadow_elevation">2dp</dimen>
<dimen name="drop_target_bar_margin_horizontal">4dp</dimen>
+ <dimen name="drop_target_button_drawable_size">20dp</dimen>
<dimen name="drop_target_button_drawable_padding">8dp</dimen>
<dimen name="drop_target_button_drawable_horizontal_padding">16dp</dimen>
<dimen name="drop_target_button_drawable_vertical_padding">8dp</dimen>
diff --git a/src/com/android/launcher3/ButtonDropTarget.java b/src/com/android/launcher3/ButtonDropTarget.java
index 3b24df2..5abe3d3 100644
--- a/src/com/android/launcher3/ButtonDropTarget.java
+++ b/src/com/android/launcher3/ButtonDropTarget.java
@@ -91,7 +91,7 @@
Resources resources = getResources();
mDragDistanceThreshold = resources.getDimensionPixelSize(R.dimen.drag_distanceThreshold);
- mDrawableSize = resources.getDimensionPixelSize(R.dimen.drop_target_text_size);
+ mDrawableSize = resources.getDimensionPixelSize(R.dimen.drop_target_button_drawable_size);
mDrawablePadding = resources.getDimensionPixelSize(
R.dimen.drop_target_button_drawable_padding);
}
@@ -374,11 +374,63 @@
hideTooltip();
}
+ /**
+ * Returns if the text will be truncated within the provided availableWidth.
+ */
public boolean isTextTruncated(int availableWidth) {
- availableWidth -= (getPaddingLeft() + getPaddingRight() + mDrawable.getIntrinsicWidth()
- + getCompoundDrawablePadding());
- CharSequence displayedText = TextUtils.ellipsize(mText, getPaint(), availableWidth,
+ availableWidth -= getPaddingLeft() + getPaddingRight();
+ if (mIconVisible) {
+ availableWidth -= mDrawable.getIntrinsicWidth() + getCompoundDrawablePadding();
+ }
+ if (availableWidth <= 0) {
+ return true;
+ }
+ CharSequence firstLine = TextUtils.ellipsize(mText, getPaint(), availableWidth,
TextUtils.TruncateAt.END);
- return !mText.equals(displayedText);
+ if (!mTextMultiLine) {
+ return !TextUtils.equals(mText, firstLine);
+ }
+ if (TextUtils.equals(mText, firstLine)) {
+ // When multi-line is active, if it can display as one line, then text is not truncated.
+ return false;
+ }
+ CharSequence secondLine =
+ TextUtils.ellipsize(mText.subSequence(firstLine.length(), mText.length()),
+ getPaint(), availableWidth, TextUtils.TruncateAt.END);
+ return !(TextUtils.equals(mText.subSequence(0, firstLine.length()), firstLine)
+ && TextUtils.equals(mText.subSequence(firstLine.length(), secondLine.length()),
+ secondLine));
+ }
+
+ /**
+ * Reduce the size of the text until it fits the measured width or reaches a minimum.
+ *
+ * The minimum size is defined by {@code R.dimen.button_drop_target_min_text_size} and
+ * it diminishes by intervals defined by
+ * {@code R.dimen.button_drop_target_resize_text_increment}
+ * This functionality is very similar to the option
+ * {@link TextView#setAutoSizeTextTypeWithDefaults(int)} but can't be used in this view because
+ * the layout width is {@code WRAP_CONTENT}.
+ *
+ * @return The biggest text size in SP that makes the text fit or if the text can't fit returns
+ * the min available value
+ */
+ public float resizeTextToFit() {
+ float minSize = Utilities.pxToSp(getResources()
+ .getDimensionPixelSize(R.dimen.button_drop_target_min_text_size));
+ float step = Utilities.pxToSp(getResources()
+ .getDimensionPixelSize(R.dimen.button_drop_target_resize_text_increment));
+ float textSize = Utilities.pxToSp(getTextSize());
+
+ int availableWidth = getMeasuredWidth();
+ while (textSize > minSize) {
+ if (isTextTruncated(availableWidth)) {
+ textSize -= step;
+ setTextSize(textSize);
+ } else {
+ return textSize;
+ }
+ }
+ return minSize;
}
}
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index a330fb3..0292e04 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -52,6 +52,7 @@
import java.io.PrintWriter;
import java.util.List;
+import java.util.Locale;
@SuppressLint("NewApi")
public class DeviceProfile {
@@ -1037,7 +1038,7 @@
/ getCellLayoutHeight();
scale = Math.min(scale, 1f);
- // Reduce scale if next pages would not be visible after scaling the workspace
+ // Reduce scale if next pages would not be visible after scaling the workspace.
int workspaceWidth = availableWidthPx;
float scaledWorkspaceWidth = workspaceWidth * scale;
float maxAvailableWidth = workspaceWidth - (2 * workspaceSpringLoadedMinNextPageVisiblePx);
@@ -1354,6 +1355,10 @@
return "\t" + name + ": " + value + "px (" + dpiFromPx(value, mMetrics.densityDpi) + "dp)";
}
+ private String dpPointFToString(String name, PointF value) {
+ return String.format(Locale.ENGLISH, "\t%s: PointF(%.1f, %.1f)dp", name, value.x, value.y);
+ }
+
/** Dumps various DeviceProfile variables to the specified writer. */
public void dump(Context context, String prefix, PrintWriter writer) {
writer.println(prefix + "DeviceProfile:");
@@ -1389,7 +1394,7 @@
writer.println(prefix + "\tinv.numSearchContainerColumns: "
+ inv.numSearchContainerColumns);
- writer.println(prefix + "\tminCellSize: " + inv.minCellSize[mTypeIndex] + "dp");
+ writer.println(prefix + dpPointFToString("minCellSize", inv.minCellSize[mTypeIndex]));
writer.println(prefix + pxToDpStr("cellWidthPx", cellWidthPx));
writer.println(prefix + pxToDpStr("cellHeightPx", cellHeightPx));
@@ -1669,7 +1674,7 @@
mTransposeLayoutWithOrientation = !mInfo.isTablet(mWindowBounds);
}
if (mIsGestureMode == null) {
- mIsGestureMode = DisplayController.getNavigationMode(mContext).hasGestures;
+ mIsGestureMode = mInfo.navigationMode.hasGestures;
}
if (mDotRendererCache == null) {
mDotRendererCache = new SparseArray<>();
diff --git a/src/com/android/launcher3/DropTargetBar.java b/src/com/android/launcher3/DropTargetBar.java
index d64cb26..98ecf3a 100644
--- a/src/com/android/launcher3/DropTargetBar.java
+++ b/src/com/android/launcher3/DropTargetBar.java
@@ -151,6 +151,8 @@
int widthSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST);
ButtonDropTarget firstButton = mTempTargets[0];
+ firstButton.setTextSize(TypedValue.COMPLEX_UNIT_PX,
+ mLauncher.getDeviceProfile().dropTargetTextSizePx);
firstButton.setTextVisible(true);
firstButton.setIconVisible(true);
firstButton.measure(widthSpec, heightSpec);
@@ -160,14 +162,16 @@
int horizontalPadding = dp.dropTargetHorizontalPaddingPx;
ButtonDropTarget firstButton = mTempTargets[0];
+ firstButton.setTextSize(TypedValue.COMPLEX_UNIT_PX, dp.dropTargetTextSizePx);
firstButton.setTextVisible(true);
firstButton.setIconVisible(true);
firstButton.setTextMultiLine(false);
- // Reset second button padding in case it was previously changed to multi-line text.
+ // Reset first button padding in case it was previously changed to multi-line text.
firstButton.setPadding(horizontalPadding, verticalPadding, horizontalPadding,
verticalPadding);
ButtonDropTarget secondButton = mTempTargets[1];
+ secondButton.setTextSize(TypedValue.COMPLEX_UNIT_PX, dp.dropTargetTextSizePx);
secondButton.setTextVisible(true);
secondButton.setIconVisible(true);
secondButton.setTextMultiLine(false);
@@ -175,20 +179,14 @@
secondButton.setPadding(horizontalPadding, verticalPadding, horizontalPadding,
verticalPadding);
- float scale = dp.getWorkspaceSpringLoadScale(mLauncher);
- int scaledPanelWidth = (int) (dp.getCellLayoutWidth() * scale);
-
int availableWidth;
if (dp.isTwoPanels) {
- // Both buttons for two panel fit to the width of one Cell Layout (less
- // half of the center gap between the buttons).
- int halfButtonGap = dp.dropTargetGapPx / 2;
- availableWidth = scaledPanelWidth - halfButtonGap / 2;
+ // Each button for two panel fits to half the width of the screen excluding the
+ // center gap between the buttons.
+ availableWidth = (dp.availableWidthPx - dp.dropTargetGapPx) / 2;
} else {
- // Both buttons plus the button gap do not display past the edge of the scaled
- // workspace, less a pre-defined gap from the edge of the workspace.
- availableWidth = scaledPanelWidth - dp.dropTargetGapPx
- - 2 * dp.dropTargetButtonWorkspaceEdgeGapPx;
+ // Both buttons plus the button gap do not display past the edge of the screen.
+ availableWidth = dp.availableWidthPx - dp.dropTargetGapPx;
}
int widthSpec = MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST);
@@ -219,6 +217,15 @@
horizontalPadding, verticalPadding / 2);
}
}
+
+ // If text is still truncated, shrink to fit in measured width and resize both targets.
+ float minTextSize =
+ Math.min(firstButton.resizeTextToFit(), secondButton.resizeTextToFit());
+ if (firstButton.getTextSize() != minTextSize
+ || secondButton.getTextSize() != minTextSize) {
+ firstButton.setTextSize(minTextSize);
+ secondButton.setTextSize(minTextSize);
+ }
}
setMeasuredDimension(width, height);
}
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 4a52d3e..4312c3d 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -195,7 +195,6 @@
import com.android.launcher3.util.TouchController;
import com.android.launcher3.util.TraceHelper;
import com.android.launcher3.util.UiThreadHelper;
-import com.android.launcher3.util.ViewCapture;
import com.android.launcher3.util.ViewOnDrawExecutor;
import com.android.launcher3.views.ActivityContext;
import com.android.launcher3.views.FloatingIconView;
@@ -393,7 +392,6 @@
private LauncherState mPrevLauncherState;
private StringCache mStringCache;
- private ViewCapture mViewCapture;
@Override
@TargetApi(Build.VERSION_CODES.S)
@@ -1488,23 +1486,11 @@
public void onAttachedToWindow() {
super.onAttachedToWindow();
mOverlayManager.onAttachedToWindow();
- if (FeatureFlags.CONTINUOUS_VIEW_TREE_CAPTURE.get()) {
- View root = getDragLayer().getRootView();
- if (mViewCapture != null) {
- mViewCapture.detach();
- }
- mViewCapture = new ViewCapture(getWindow());
- mViewCapture.attach();
- }
}
@Override
public void onDetachedFromWindow() {
super.onDetachedFromWindow();
- if (mViewCapture != null) {
- mViewCapture.detach();
- mViewCapture = null;
- }
mOverlayManager.onDetachedFromWindow();
closeContextMenu();
}
@@ -2985,7 +2971,6 @@
*/
@Override
public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
- SafeCloseable viewDump = mViewCapture == null ? null : mViewCapture.beginDump(writer, fd);
super.dump(prefix, fd, writer, args);
if (args.length > 0 && TextUtils.equals(args[0], "--all")) {
@@ -3026,10 +3011,6 @@
mPopupDataProvider.dump(prefix, writer);
mDeviceProfile.dump(this, prefix, writer);
- if (viewDump != null) {
- viewDump.close();
- }
-
try {
FileLog.flushAll(writer);
} catch (Exception e) {
diff --git a/src/com/android/launcher3/LauncherState.java b/src/com/android/launcher3/LauncherState.java
index 4532ed4..c3b5392 100644
--- a/src/com/android/launcher3/LauncherState.java
+++ b/src/com/android/launcher3/LauncherState.java
@@ -265,7 +265,8 @@
*
* 0 means completely zoomed in, without blurs. 1 is zoomed out, with blurs.
*/
- public final float getDepth(Context context) {
+ public final <DEVICE_PROFILE_CONTEXT extends Context & DeviceProfile.DeviceProfileListenable>
+ float getDepth(DEVICE_PROFILE_CONTEXT context) {
return getDepth(context,
BaseDraggingActivity.fromContext(context).getDeviceProfile().isMultiWindowMode);
}
@@ -275,14 +276,16 @@
*
* @see #getDepth(Context).
*/
- public final float getDepth(Context context, boolean isMultiWindowMode) {
+ public final <DEVICE_PROFILE_CONTEXT extends Context & DeviceProfile.DeviceProfileListenable>
+ float getDepth(DEVICE_PROFILE_CONTEXT context, boolean isMultiWindowMode) {
if (isMultiWindowMode) {
return 0;
}
return getDepthUnchecked(context);
}
- protected float getDepthUnchecked(Context context) {
+ protected <DEVICE_PROFILE_CONTEXT extends Context & DeviceProfile.DeviceProfileListenable>
+ float getDepthUnchecked(DEVICE_PROFILE_CONTEXT context) {
return 0f;
}
diff --git a/src/com/android/launcher3/PendingAddItemInfo.java b/src/com/android/launcher3/PendingAddItemInfo.java
index be994ee..b7a22fc 100644
--- a/src/com/android/launcher3/PendingAddItemInfo.java
+++ b/src/com/android/launcher3/PendingAddItemInfo.java
@@ -18,6 +18,7 @@
import android.content.ComponentName;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.launcher3.model.data.ItemInfo;
@@ -43,6 +44,7 @@
/**
* Returns shallow copy of the object.
*/
+ @NonNull
@Override
public ItemInfo makeShallowCopy() {
PendingAddItemInfo itemInfo = new PendingAddItemInfo();
diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
index ecc9d7e..1cec9d0 100644
--- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java
+++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
@@ -227,7 +227,7 @@
@Override
public void setStateWithAnimation(LauncherState toState,
StateAnimationConfig config, PendingAnimation builder) {
- if (NORMAL.equals(toState) && mLauncher.isInState(ALL_APPS)) {
+ if (mLauncher.isInState(ALL_APPS) && !ALL_APPS.equals(toState)) {
builder.addEndListener(success -> {
// Reset pull back progress and alpha after switching states.
ALL_APPS_PULL_BACK_TRANSLATION.set(this, 0f);
diff --git a/src/com/android/launcher3/anim/AnimationSuccessListener.java b/src/com/android/launcher3/anim/AnimationSuccessListener.java
index a312070..6196df2 100644
--- a/src/com/android/launcher3/anim/AnimationSuccessListener.java
+++ b/src/com/android/launcher3/anim/AnimationSuccessListener.java
@@ -19,6 +19,8 @@
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
+import androidx.annotation.CallSuper;
+
/**
* Extension of {@link AnimatorListenerAdapter} for listening for non-cancelled animations
*/
@@ -27,6 +29,7 @@
protected boolean mCancelled = false;
@Override
+ @CallSuper
public void onAnimationCancel(Animator animation) {
mCancelled = true;
}
diff --git a/src/com/android/launcher3/anim/Interpolators.java b/src/com/android/launcher3/anim/Interpolators.java
index 0a77aa7..12b4223 100644
--- a/src/com/android/launcher3/anim/Interpolators.java
+++ b/src/com/android/launcher3/anim/Interpolators.java
@@ -57,6 +57,10 @@
public static final Interpolator DECELERATED_EASE = new PathInterpolator(0, 0, .2f, 1f);
public static final Interpolator ACCELERATED_EASE = new PathInterpolator(0.4f, 0, 1f, 1f);
+ /**
+ * The default emphasized interpolator. Used for hero / emphasized movement of content.
+ */
+ public static final Interpolator EMPHASIZED = createEmphasizedInterpolator();
public static final Interpolator EMPHASIZED_ACCELERATE = new PathInterpolator(
0.3f, 0f, 0.8f, 0.15f);
public static final Interpolator EMPHASIZED_DECELERATE = new PathInterpolator(
@@ -87,7 +91,6 @@
public static final Interpolator TOUCH_RESPONSE_INTERPOLATOR_ACCEL_DEACCEL =
v -> ACCEL_DEACCEL.getInterpolation(TOUCH_RESPONSE_INTERPOLATOR.getInterpolation(v));
-
/**
* Inversion of ZOOM_OUT, compounded with an ease-out.
*/
@@ -218,4 +221,14 @@
public static Interpolator reverse(Interpolator interpolator) {
return t -> 1 - interpolator.getInterpolation(1 - t);
}
+
+ // Create the default emphasized interpolator
+ private static PathInterpolator createEmphasizedInterpolator() {
+ Path path = new Path();
+ // Doing the same as fast_out_extra_slow_in
+ path.moveTo(0f, 0f);
+ path.cubicTo(0.05f, 0f, 0.133333f, 0.06f, 0.166666f, 0.4f);
+ path.cubicTo(0.208333f, 0.82f, 0.25f, 1f, 1f, 1f);
+ return new PathInterpolator(path);
+ }
}
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index ff40712..a643196 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -65,12 +65,12 @@
*/
public static final BooleanFlag ENABLE_INPUT_CONSUMER_REASON_LOGGING = getDebugFlag(
"ENABLE_INPUT_CONSUMER_REASON_LOGGING",
- false,
+ true,
"Log the reason why an Input Consumer was selected for a gesture.");
public static final BooleanFlag ENABLE_GESTURE_ERROR_DETECTION = getDebugFlag(
"ENABLE_GESTURE_ERROR_DETECTION",
- false,
+ true,
"Analyze gesture events and log detected errors");
// When enabled the promise icon is visible in all apps while installation an app.
@@ -285,6 +285,9 @@
"FOLDABLE_WORKSPACE_REORDER", true,
"In foldables, when reordering the icons and widgets, is now going to use both sides");
+ public static final BooleanFlag SHOW_SEARCH_EDUCARD_QSB = new DeviceFlag(
+ "SHOW_SEARCH_EDUCARD_QSB", false, "Shows Search Educard for QSB entry in OneSearch.");
+
public static void initialize(Context context) {
synchronized (sDebugFlags) {
for (DebugFlag flag : sDebugFlags) {
diff --git a/src/com/android/launcher3/icons/ShortcutCachingLogic.java b/src/com/android/launcher3/icons/ShortcutCachingLogic.java
index 4890ba6..d5a79dd 100644
--- a/src/com/android/launcher3/icons/ShortcutCachingLogic.java
+++ b/src/com/android/launcher3/icons/ShortcutCachingLogic.java
@@ -16,7 +16,7 @@
package com.android.launcher3.icons;
-import static com.android.launcher3.model.WidgetsModel.GO_DISABLE_WIDGETS;
+import static com.android.launcher3.model.WidgetsModel.GO_DISABLE_SHORTCUTS;
import android.content.ComponentName;
import android.content.Context;
@@ -100,7 +100,7 @@
* Launcher specific checks
*/
public static Drawable getIcon(Context context, ShortcutInfo shortcutInfo, int density) {
- if (GO_DISABLE_WIDGETS) {
+ if (GO_DISABLE_SHORTCUTS) {
return null;
}
try {
diff --git a/src/com/android/launcher3/model/BgDataModel.java b/src/com/android/launcher3/model/BgDataModel.java
index de23c4b..ffb0f2f 100644
--- a/src/com/android/launcher3/model/BgDataModel.java
+++ b/src/com/android/launcher3/model/BgDataModel.java
@@ -17,7 +17,7 @@
import static android.content.pm.LauncherApps.ShortcutQuery.FLAG_GET_KEY_FIELDS_ONLY;
-import static com.android.launcher3.model.WidgetsModel.GO_DISABLE_WIDGETS;
+import static com.android.launcher3.model.WidgetsModel.GO_DISABLE_SHORTCUTS;
import static com.android.launcher3.shortcuts.ShortcutRequest.PINNED;
import static java.util.stream.Collectors.groupingBy;
@@ -286,7 +286,7 @@
* shortcuts and unpinning any extra shortcuts.
*/
public synchronized void updateShortcutPinnedState(Context context, UserHandle user) {
- if (GO_DISABLE_WIDGETS) {
+ if (GO_DISABLE_SHORTCUTS) {
return;
}
diff --git a/src/com/android/launcher3/model/ItemInstallQueue.java b/src/com/android/launcher3/model/ItemInstallQueue.java
index 229bb2d..69f9b53 100644
--- a/src/com/android/launcher3/model/ItemInstallQueue.java
+++ b/src/com/android/launcher3/model/ItemInstallQueue.java
@@ -288,6 +288,7 @@
}
@Override
+ @Nullable
public Intent getIntent() {
return intent;
}
diff --git a/src/com/android/launcher3/model/data/AppInfo.java b/src/com/android/launcher3/model/data/AppInfo.java
index 24e7dd3..34972e7 100644
--- a/src/com/android/launcher3/model/data/AppInfo.java
+++ b/src/com/android/launcher3/model/data/AppInfo.java
@@ -29,6 +29,7 @@
import android.os.UserManager;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import com.android.launcher3.LauncherSettings;
@@ -65,6 +66,7 @@
}
@Override
+ @Nullable
public Intent getIntent() {
return intent;
}
diff --git a/src/com/android/launcher3/model/data/FolderInfo.java b/src/com/android/launcher3/model/data/FolderInfo.java
index 8386adb..524b769 100644
--- a/src/com/android/launcher3/model/data/FolderInfo.java
+++ b/src/com/android/launcher3/model/data/FolderInfo.java
@@ -26,6 +26,7 @@
import android.os.Process;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.launcher3.LauncherSettings;
@@ -154,7 +155,7 @@
}
@Override
- public void onAddToDatabase(ContentWriter writer) {
+ public void onAddToDatabase(@NonNull ContentWriter writer) {
super.onAddToDatabase(writer);
writer.put(LauncherSettings.Favorites.TITLE, title)
.put(LauncherSettings.Favorites.OPTIONS, options);
@@ -206,8 +207,9 @@
return String.format("%s; labelState=%s", super.dumpProperties(), getLabelState());
}
+ @NonNull
@Override
- public LauncherAtom.ItemInfo buildProto(FolderInfo fInfo) {
+ public LauncherAtom.ItemInfo buildProto(@Nullable FolderInfo fInfo) {
FolderIcon.Builder folderIcon = FolderIcon.newBuilder()
.setCardinality(contents.size());
if (LabelState.SUGGESTED.equals(getLabelState())) {
@@ -261,6 +263,7 @@
: LabelState.SUGGESTED;
}
+ @NonNull
@Override
public ItemInfo makeShallowCopy() {
FolderInfo folderInfo = new FolderInfo();
@@ -272,6 +275,7 @@
/**
* Returns {@link LauncherAtom.FolderIcon} wrapped as {@link LauncherAtom.ItemInfo} for logging.
*/
+ @NonNull
@Override
public LauncherAtom.ItemInfo buildProto() {
return buildProto(null);
diff --git a/src/com/android/launcher3/model/data/ItemInfo.java b/src/com/android/launcher3/model/data/ItemInfo.java
index 1e8e3ca..466f63f 100644
--- a/src/com/android/launcher3/model/data/ItemInfo.java
+++ b/src/com/android/launcher3/model/data/ItemInfo.java
@@ -42,6 +42,7 @@
import android.os.Process;
import android.os.UserHandle;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.launcher3.LauncherSettings;
@@ -141,30 +142,34 @@
/**
* Title of the item
*/
+ @Nullable
public CharSequence title;
/**
* Content description of the item.
*/
+ @Nullable
public CharSequence contentDescription;
/**
* When the instance is created using {@link #copyFrom}, this field is used to keep track of
* original {@link ComponentName}.
*/
+ @Nullable
private ComponentName mComponentName;
+ @NonNull
public UserHandle user;
public ItemInfo() {
user = Process.myUserHandle();
}
- protected ItemInfo(ItemInfo info) {
+ protected ItemInfo(@NonNull final ItemInfo info) {
copyFrom(info);
}
- public void copyFrom(ItemInfo info) {
+ public void copyFrom(@NonNull final ItemInfo info) {
id = info.id;
title = info.title;
cellX = info.cellX;
@@ -182,6 +187,7 @@
mComponentName = info.getTargetComponent();
}
+ @Nullable
public Intent getIntent() {
return null;
}
@@ -209,7 +215,7 @@
: null;
}
- public void writeToValues(ContentWriter writer) {
+ public void writeToValues(@NonNull final ContentWriter writer) {
writer.put(LauncherSettings.Favorites.ITEM_TYPE, itemType)
.put(LauncherSettings.Favorites.CONTAINER, container)
.put(LauncherSettings.Favorites.SCREEN, screenId)
@@ -220,7 +226,7 @@
.put(LauncherSettings.Favorites.RANK, rank);
}
- public void readFromValues(ContentValues values) {
+ public void readFromValues(@NonNull final ContentValues values) {
itemType = values.getAsInteger(LauncherSettings.Favorites.ITEM_TYPE);
container = values.getAsInteger(LauncherSettings.Favorites.CONTAINER);
screenId = values.getAsInteger(LauncherSettings.Favorites.SCREEN);
@@ -234,7 +240,7 @@
/**
* Write the fields of this item to the DB
*/
- public void onAddToDatabase(ContentWriter writer) {
+ public void onAddToDatabase(@NonNull final ContentWriter writer) {
if (Workspace.EXTRA_EMPTY_SCREEN_IDS.contains(screenId)) {
// We should never persist an item on the extra empty screen.
throw new RuntimeException("Screen id should not be extra empty screen: " + screenId);
@@ -245,10 +251,12 @@
}
@Override
+ @NonNull
public final String toString() {
return getClass().getSimpleName() + "(" + dumpProperties() + ")";
}
+ @NonNull
protected String dumpProperties() {
return "id=" + id
+ " type=" + LauncherSettings.Favorites.itemTypeToString(itemType)
@@ -288,14 +296,17 @@
/**
* Creates {@link LauncherAtom.ItemInfo} with important fields and parent container info.
*/
+ @NonNull
public LauncherAtom.ItemInfo buildProto() {
return buildProto(null);
}
/**
* Creates {@link LauncherAtom.ItemInfo} with important fields and parent container info.
+ * @param fInfo
*/
- public LauncherAtom.ItemInfo buildProto(FolderInfo fInfo) {
+ @NonNull
+ public LauncherAtom.ItemInfo buildProto(@Nullable final FolderInfo fInfo) {
LauncherAtom.ItemInfo.Builder itemBuilder = getDefaultItemInfoBuilder();
Optional<ComponentName> nullableComponent = Optional.ofNullable(getTargetComponent());
switch (itemType) {
@@ -373,6 +384,7 @@
return itemBuilder.build();
}
+ @NonNull
protected LauncherAtom.ItemInfo.Builder getDefaultItemInfoBuilder() {
LauncherAtom.ItemInfo.Builder itemBuilder = LauncherAtom.ItemInfo.newBuilder();
itemBuilder.setIsWork(!Process.myUserHandle().equals(user));
@@ -383,6 +395,7 @@
/**
* Returns {@link ContainerInfo} used when logging this item.
*/
+ @NonNull
public ContainerInfo getContainerInfo() {
switch (container) {
case CONTAINER_HOTSEAT:
@@ -447,6 +460,7 @@
* Returns non-AOSP container wrapped by {@link ExtendedContainers} object. Should be overridden
* by build variants.
*/
+ @NonNull
protected ExtendedContainers getExtendedContainer() {
return ExtendedContainers.getDefaultInstance();
}
@@ -454,6 +468,7 @@
/**
* Returns shallow copy of the object.
*/
+ @NonNull
public ItemInfo makeShallowCopy() {
ItemInfo itemInfo = new ItemInfo();
itemInfo.copyFrom(this);
@@ -463,7 +478,8 @@
/**
* Sets the title of the item and writes to DB model if needed.
*/
- public void setTitle(CharSequence title, ModelWriter modelWriter) {
+ public void setTitle(@Nullable final CharSequence title,
+ @Nullable final ModelWriter modelWriter) {
this.title = title;
}
}
diff --git a/src/com/android/launcher3/model/data/LauncherAppWidgetInfo.java b/src/com/android/launcher3/model/data/LauncherAppWidgetInfo.java
index e57a895..1fbe04f 100644
--- a/src/com/android/launcher3/model/data/LauncherAppWidgetInfo.java
+++ b/src/com/android/launcher3/model/data/LauncherAppWidgetInfo.java
@@ -29,6 +29,7 @@
import android.content.res.Resources;
import android.os.Process;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.launcher3.Launcher;
@@ -191,7 +192,7 @@
}
@Override
- public void onAddToDatabase(ContentWriter writer) {
+ public void onAddToDatabase(@NonNull ContentWriter writer) {
super.onAddToDatabase(writer);
writer.put(LauncherSettings.Favorites.APPWIDGET_ID, appWidgetId)
.put(LauncherSettings.Favorites.APPWIDGET_PROVIDER, providerName.flattenToString())
@@ -283,8 +284,9 @@
}
}
+ @NonNull
@Override
- public LauncherAtom.ItemInfo buildProto(FolderInfo folderInfo) {
+ public LauncherAtom.ItemInfo buildProto(@Nullable FolderInfo folderInfo) {
LauncherAtom.ItemInfo info = super.buildProto(folderInfo);
return info.toBuilder()
.setWidget(info.getWidget().toBuilder().setWidgetFeatures(widgetFeatures))
diff --git a/src/com/android/launcher3/model/data/SearchActionItemInfo.java b/src/com/android/launcher3/model/data/SearchActionItemInfo.java
index e879313..04042ea 100644
--- a/src/com/android/launcher3/model/data/SearchActionItemInfo.java
+++ b/src/com/android/launcher3/model/data/SearchActionItemInfo.java
@@ -24,6 +24,7 @@
import android.os.Process;
import android.os.UserHandle;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.launcher3.LauncherAppState;
@@ -70,7 +71,7 @@
}
@Override
- public void copyFrom(com.android.launcher3.model.data.ItemInfo info) {
+ public void copyFrom(@NonNull com.android.launcher3.model.data.ItemInfo info) {
super.copyFrom(info);
SearchActionItemInfo itemInfo = (SearchActionItemInfo) info;
this.mFallbackPackageName = itemInfo.mFallbackPackageName;
@@ -91,6 +92,7 @@
}
@Override
+ @Nullable
public Intent getIntent() {
return mIntent;
}
@@ -131,8 +133,9 @@
return new SearchActionItemInfo(this);
}
+ @NonNull
@Override
- public ItemInfo buildProto(FolderInfo fInfo) {
+ public ItemInfo buildProto(@Nullable FolderInfo fInfo) {
SearchActionItem.Builder itemBuilder = SearchActionItem.newBuilder()
.setPackageName(mFallbackPackageName);
diff --git a/src/com/android/launcher3/model/data/WorkspaceItemInfo.java b/src/com/android/launcher3/model/data/WorkspaceItemInfo.java
index 2b3da33..1f16474 100644
--- a/src/com/android/launcher3/model/data/WorkspaceItemInfo.java
+++ b/src/com/android/launcher3/model/data/WorkspaceItemInfo.java
@@ -24,6 +24,7 @@
import android.text.TextUtils;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.LauncherSettings.Favorites;
@@ -130,7 +131,7 @@
}
@Override
- public void onAddToDatabase(ContentWriter writer) {
+ public void onAddToDatabase(@NonNull ContentWriter writer) {
super.onAddToDatabase(writer);
writer.put(Favorites.TITLE, title)
.put(Favorites.INTENT, getIntent())
@@ -147,6 +148,7 @@
}
@Override
+ @Nullable
public Intent getIntent() {
return intent;
}
diff --git a/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java b/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java
index 33b2f55..a55f7e3 100644
--- a/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java
+++ b/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java
@@ -73,11 +73,11 @@
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mModel = LauncherAppState.getInstance(this).getModel();
+ mOnboardingPrefs = new OnboardingPrefs<>(this, Utilities.getPrefs(this));
+ mSecondaryDisplayPredictions = SecondaryDisplayPredictions.newInstance(this);
if (getWindow().getDecorView().isAttachedToWindow()) {
initUi();
}
- mOnboardingPrefs = new OnboardingPrefs<>(this, Utilities.getPrefs(this));
- mSecondaryDisplayPredictions = SecondaryDisplayPredictions.newInstance(this);
}
@Override
diff --git a/src/com/android/launcher3/shortcuts/ShortcutRequest.java b/src/com/android/launcher3/shortcuts/ShortcutRequest.java
index 5291ce4..07d3292 100644
--- a/src/com/android/launcher3/shortcuts/ShortcutRequest.java
+++ b/src/com/android/launcher3/shortcuts/ShortcutRequest.java
@@ -16,7 +16,7 @@
package com.android.launcher3.shortcuts;
-import static com.android.launcher3.model.WidgetsModel.GO_DISABLE_WIDGETS;
+import static com.android.launcher3.model.WidgetsModel.GO_DISABLE_SHORTCUTS;
import android.content.ComponentName;
import android.content.Context;
@@ -46,7 +46,7 @@
| ShortcutQuery.FLAG_MATCH_MANIFEST;
public static final int PINNED = ShortcutQuery.FLAG_MATCH_PINNED;
- private final ShortcutQuery mQuery = GO_DISABLE_WIDGETS ? null : new ShortcutQuery();
+ private final ShortcutQuery mQuery = GO_DISABLE_SHORTCUTS ? null : new ShortcutQuery();
private final Context mContext;
private final UserHandle mUserHandle;
@@ -73,7 +73,7 @@
* @return A list of ShortcutInfo's associated with the given package.
*/
public ShortcutRequest forPackage(String packageName, @Nullable List<String> shortcutIds) {
- if (!GO_DISABLE_WIDGETS && packageName != null) {
+ if (!GO_DISABLE_SHORTCUTS && packageName != null) {
mQuery.setPackage(packageName);
mQuery.setShortcutIds(shortcutIds);
}
@@ -81,7 +81,7 @@
}
public ShortcutRequest withContainer(@Nullable ComponentName activity) {
- if (!GO_DISABLE_WIDGETS) {
+ if (!GO_DISABLE_SHORTCUTS) {
if (activity == null) {
mFailed = true;
} else {
@@ -92,7 +92,7 @@
}
public QueryResult query(int flags) {
- if (GO_DISABLE_WIDGETS || mFailed) {
+ if (GO_DISABLE_SHORTCUTS || mFailed) {
return QueryResult.DEFAULT;
}
mQuery.setQueryFlags(flags);
@@ -108,7 +108,7 @@
public static class QueryResult extends ArrayList<ShortcutInfo> {
- static final QueryResult DEFAULT = new QueryResult(GO_DISABLE_WIDGETS);
+ static final QueryResult DEFAULT = new QueryResult(GO_DISABLE_SHORTCUTS);
private final boolean mWasSuccess;
diff --git a/src/com/android/launcher3/statemanager/StateManager.java b/src/com/android/launcher3/statemanager/StateManager.java
index 2aa9dde..54e8e5b 100644
--- a/src/com/android/launcher3/statemanager/StateManager.java
+++ b/src/com/android/launcher3/statemanager/StateManager.java
@@ -342,6 +342,12 @@
public void onAnimationSuccess(Animator animator) {
onStateTransitionEnd(state);
}
+
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ super.onAnimationCancel(animation);
+ onStateTransitionFailed(state);
+ }
};
}
@@ -354,6 +360,12 @@
}
}
+ private void onStateTransitionFailed(STATE_TYPE state) {
+ for (int i = mListeners.size() - 1; i >= 0; i--) {
+ mListeners.get(i).onStateTransitionFailed(state);
+ }
+ }
+
private void onStateTransitionEnd(STATE_TYPE state) {
// Only change the stable states after the transitions have finished
if (state != mCurrentStableState) {
@@ -588,6 +600,11 @@
default void onStateTransitionStart(STATE_TYPE toState) { }
+ /**
+ * If the state transition animation fails (e.g. is canceled by the user), this fires.
+ */
+ default void onStateTransitionFailed(STATE_TYPE toState) { }
+
default void onStateTransitionComplete(STATE_TYPE finalState) { }
}
diff --git a/src/com/android/launcher3/testing/shared/ResourceUtils.java b/src/com/android/launcher3/testing/shared/ResourceUtils.java
index 551aeaf..d0ae258 100644
--- a/src/com/android/launcher3/testing/shared/ResourceUtils.java
+++ b/src/com/android/launcher3/testing/shared/ResourceUtils.java
@@ -36,6 +36,8 @@
public static final String STATUS_BAR_HEIGHT_LANDSCAPE = "status_bar_height_landscape";
public static final String STATUS_BAR_HEIGHT_PORTRAIT = "status_bar_height_portrait";
+ public static final String NAV_BAR_INTERACTION_MODE_RES_NAME = "config_navBarInteractionMode";
+
public static int getNavbarSize(String resName, Resources res) {
return getDimenByName(resName, res, DEFAULT_NAVBAR_VALUE);
}
diff --git a/src/com/android/launcher3/touch/AllAppsSwipeController.java b/src/com/android/launcher3/touch/AllAppsSwipeController.java
index 37b76fb..5279dec 100644
--- a/src/com/android/launcher3/touch/AllAppsSwipeController.java
+++ b/src/com/android/launcher3/touch/AllAppsSwipeController.java
@@ -18,6 +18,7 @@
import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.anim.Interpolators.DECELERATED_EASE;
+import static com.android.launcher3.anim.Interpolators.EMPHASIZED;
import static com.android.launcher3.anim.Interpolators.EMPHASIZED_ACCELERATE;
import static com.android.launcher3.anim.Interpolators.EMPHASIZED_DECELERATE;
import static com.android.launcher3.anim.Interpolators.FINAL_FRAME;
@@ -199,8 +200,10 @@
Interpolators.reverse(ALL_APPS_SCRIM_RESPONDER));
config.setInterpolator(ANIM_ALL_APPS_FADE, FINAL_FRAME);
if (!config.userControlled) {
- config.setInterpolator(ANIM_VERTICAL_PROGRESS, EMPHASIZED_ACCELERATE);
+ config.setInterpolator(ANIM_VERTICAL_PROGRESS, EMPHASIZED);
}
+ config.setInterpolator(ANIM_WORKSPACE_SCALE, EMPHASIZED);
+ config.setInterpolator(ANIM_DEPTH, EMPHASIZED);
} else {
if (config.userControlled) {
config.setInterpolator(ANIM_DEPTH, Interpolators.reverse(BLUR_MANUAL));
@@ -238,8 +241,10 @@
config.setInterpolator(ANIM_ALL_APPS_FADE, INSTANT);
config.setInterpolator(ANIM_SCRIM_FADE, ALL_APPS_SCRIM_RESPONDER);
if (!config.userControlled) {
- config.setInterpolator(ANIM_VERTICAL_PROGRESS, EMPHASIZED_DECELERATE);
+ config.setInterpolator(ANIM_VERTICAL_PROGRESS, EMPHASIZED);
}
+ config.setInterpolator(ANIM_WORKSPACE_SCALE, EMPHASIZED);
+ config.setInterpolator(ANIM_DEPTH, EMPHASIZED);
} else {
config.setInterpolator(ANIM_DEPTH, config.userControlled ? BLUR_MANUAL : BLUR_ATOMIC);
config.setInterpolator(ANIM_WORKSPACE_FADE,
diff --git a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
index dd9f642..07d1839 100644
--- a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
+++ b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
@@ -27,7 +27,7 @@
import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_X;
import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_Y;
import static com.android.launcher3.touch.SingleAxisSwipeDetector.VERTICAL;
-import static com.android.launcher3.util.DisplayController.NavigationMode.THREE_BUTTONS;
+import static com.android.launcher3.util.NavigationMode.THREE_BUTTONS;
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT;
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT;
diff --git a/src/com/android/launcher3/util/DisplayController.java b/src/com/android/launcher3/util/DisplayController.java
index 94f9f25..e57c88d 100644
--- a/src/com/android/launcher3/util/DisplayController.java
+++ b/src/com/android/launcher3/util/DisplayController.java
@@ -19,11 +19,7 @@
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
-import static com.android.launcher3.testing.shared.ResourceUtils.INVALID_RESOURCE_HANDLE;
import static com.android.launcher3.Utilities.dpiFromPx;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_NAVIGATION_MODE_2_BUTTON;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_NAVIGATION_MODE_3_BUTTON;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_NAVIGATION_MODE_GESTURE_BUTTON;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.PackageManagerHelper.getPackageFilter;
import static com.android.launcher3.util.window.WindowManagerProxy.MIN_TABLET_WIDTH;
@@ -46,9 +42,7 @@
import androidx.annotation.AnyThread;
import androidx.annotation.UiThread;
-import com.android.launcher3.testing.shared.ResourceUtils;
import com.android.launcher3.Utilities;
-import com.android.launcher3.logging.StatsLogManager.LauncherEvent;
import com.android.launcher3.util.window.CachedDisplayInfo;
import com.android.launcher3.util.window.WindowManagerProxy;
@@ -56,6 +50,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
+import java.util.Map;
import java.util.Objects;
import java.util.Set;
@@ -81,7 +76,6 @@
| CHANGE_DENSITY | CHANGE_SUPPORTED_BOUNDS | CHANGE_NAVIGATION_MODE;
private static final String ACTION_OVERLAY_CHANGED = "android.intent.action.OVERLAY_CHANGED";
- private static final String NAV_BAR_INTERACTION_MODE_RES_NAME = "config_navBarInteractionMode";
private static final String TARGET_OVERLAY_PACKAGE = "android";
private final Context mContext;
@@ -294,7 +288,7 @@
// Used for testing
public Info(Context displayInfoContext,
WindowManagerProxy wmProxy,
- ArrayMap<CachedDisplayInfo, WindowBounds[]> perDisplayBoundsCache) {
+ Map<CachedDisplayInfo, WindowBounds[]> perDisplayBoundsCache) {
CachedDisplayInfo displayInfo = wmProxy.getDisplayInfo(displayInfoContext);
normalizedDisplayInfo = displayInfo.normalize();
rotation = displayInfo.rotation;
@@ -305,7 +299,7 @@
fontScale = config.fontScale;
densityDpi = config.densityDpi;
mScreenSizeDp = new PortraitSize(config.screenHeightDp, config.screenWidthDp);
- navigationMode = parseNavigationMode(displayInfoContext);
+ navigationMode = wmProxy.getNavigationMode(displayInfoContext);
mPerDisplayBounds.putAll(perDisplayBoundsCache);
WindowBounds[] cachedValue = mPerDisplayBounds.get(normalizedDisplayInfo);
@@ -405,35 +399,4 @@
}
}
- public enum NavigationMode {
- THREE_BUTTONS(false, 0, LAUNCHER_NAVIGATION_MODE_3_BUTTON),
- TWO_BUTTONS(true, 1, LAUNCHER_NAVIGATION_MODE_2_BUTTON),
- NO_BUTTON(true, 2, LAUNCHER_NAVIGATION_MODE_GESTURE_BUTTON);
-
- public final boolean hasGestures;
- public final int resValue;
- public final LauncherEvent launcherEvent;
-
- NavigationMode(boolean hasGestures, int resValue, LauncherEvent launcherEvent) {
- this.hasGestures = hasGestures;
- this.resValue = resValue;
- this.launcherEvent = launcherEvent;
- }
- }
-
- private static NavigationMode parseNavigationMode(Context context) {
- int modeInt = ResourceUtils.getIntegerByName(NAV_BAR_INTERACTION_MODE_RES_NAME,
- context.getResources(), INVALID_RESOURCE_HANDLE);
-
- if (modeInt == INVALID_RESOURCE_HANDLE) {
- Log.e(TAG, "Failed to get system resource ID. Incompatible framework version?");
- } else {
- for (NavigationMode m : NavigationMode.values()) {
- if (m.resValue == modeInt) {
- return m;
- }
- }
- }
- return Utilities.ATLEAST_S ? NavigationMode.NO_BUTTON : NavigationMode.THREE_BUTTONS;
- }
}
diff --git a/src/com/android/launcher3/util/NavigationMode.java b/src/com/android/launcher3/util/NavigationMode.java
new file mode 100644
index 0000000..37dd41c
--- /dev/null
+++ b/src/com/android/launcher3/util/NavigationMode.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 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;
+
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_NAVIGATION_MODE_2_BUTTON;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_NAVIGATION_MODE_3_BUTTON;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_NAVIGATION_MODE_GESTURE_BUTTON;
+
+import com.android.launcher3.logging.StatsLogManager;
+
+/**
+ * Navigation mode used in the device.
+ */
+public enum NavigationMode {
+ THREE_BUTTONS(false, 0, LAUNCHER_NAVIGATION_MODE_3_BUTTON),
+ TWO_BUTTONS(true, 1, LAUNCHER_NAVIGATION_MODE_2_BUTTON),
+ NO_BUTTON(true, 2, LAUNCHER_NAVIGATION_MODE_GESTURE_BUTTON);
+
+ public final boolean hasGestures;
+ public final int resValue;
+ public final StatsLogManager.LauncherEvent launcherEvent;
+
+ NavigationMode(boolean hasGestures, int resValue, StatsLogManager.LauncherEvent launcherEvent) {
+ this.hasGestures = hasGestures;
+ this.resValue = resValue;
+ this.launcherEvent = launcherEvent;
+ }
+}
diff --git a/src/com/android/launcher3/util/OnboardingPrefs.java b/src/com/android/launcher3/util/OnboardingPrefs.java
index f4cf21e..d942b7a 100644
--- a/src/com/android/launcher3/util/OnboardingPrefs.java
+++ b/src/com/android/launcher3/util/OnboardingPrefs.java
@@ -43,13 +43,14 @@
public static final String SEARCH_ONBOARDING_COUNT = "launcher.search_onboarding_count";
public static final String TASKBAR_EDU_SEEN = "launcher.taskbar_edu_seen";
public static final String ALL_APPS_VISITED_COUNT = "launcher.all_apps_visited_count";
+ public static final String QSB_SEARCH_ONBOARDING_CARD_DISMISSED = "launcher.qsb_edu_dismiss";
// When adding a new key, add it here as well, to be able to reset it from Developer Options.
public static final Map<String, String[]> ALL_PREF_KEYS = Map.of(
"All Apps Bounce", new String[] { HOME_BOUNCE_SEEN, HOME_BOUNCE_COUNT },
"Hybrid Hotseat Education", new String[] { HOTSEAT_DISCOVERY_TIP_COUNT,
HOTSEAT_LONGPRESS_TIP_SEEN },
"Search Education", new String[] { SEARCH_KEYBOARD_EDU_SEEN, SEARCH_SNACKBAR_COUNT,
- SEARCH_ONBOARDING_COUNT},
+ SEARCH_ONBOARDING_COUNT, QSB_SEARCH_ONBOARDING_CARD_DISMISSED},
"Taskbar Education", new String[] { TASKBAR_EDU_SEEN },
"All Apps Visited Count", new String[] {ALL_APPS_VISITED_COUNT}
);
@@ -61,7 +62,8 @@
HOME_BOUNCE_SEEN,
HOTSEAT_LONGPRESS_TIP_SEEN,
SEARCH_KEYBOARD_EDU_SEEN,
- TASKBAR_EDU_SEEN
+ TASKBAR_EDU_SEEN,
+ QSB_SEARCH_ONBOARDING_CARD_DISMISSED
})
@Retention(RetentionPolicy.SOURCE)
public @interface EventBoolKey {}
diff --git a/src/com/android/launcher3/util/ShortcutUtil.java b/src/com/android/launcher3/util/ShortcutUtil.java
index 91cf835..79cafa0 100644
--- a/src/com/android/launcher3/util/ShortcutUtil.java
+++ b/src/com/android/launcher3/util/ShortcutUtil.java
@@ -34,7 +34,7 @@
* Returns true when we should show depp shortcuts in shortcut menu for the item.
*/
public static boolean supportsDeepShortcuts(ItemInfo info) {
- return isActive(info) && isApp(info) && !WidgetsModel.GO_DISABLE_WIDGETS;
+ return isActive(info) && isApp(info) && !WidgetsModel.GO_DISABLE_SHORTCUTS;
}
/**
diff --git a/src/com/android/launcher3/util/ViewCapture.java b/src/com/android/launcher3/util/ViewCapture.java
index e368ac3..0cf3ad7 100644
--- a/src/com/android/launcher3/util/ViewCapture.java
+++ b/src/com/android/launcher3/util/ViewCapture.java
@@ -17,18 +17,25 @@
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
+import static com.android.launcher3.util.Executors.createAndStartNewLooper;
import static java.util.stream.Collectors.toList;
+import android.content.Context;
import android.content.res.Resources;
import android.os.Handler;
+import android.os.Looper;
import android.os.Message;
+import android.os.Process;
import android.os.Trace;
import android.text.TextUtils;
import android.util.Base64;
import android.util.Base64OutputStream;
import android.util.Log;
+import android.util.Pair;
+import android.util.SparseArray;
import android.view.View;
+import android.view.View.OnAttachStateChangeListener;
import android.view.ViewGroup;
import android.view.ViewTreeObserver.OnDrawListener;
import android.view.Window;
@@ -36,6 +43,7 @@
import androidx.annotation.UiThread;
import androidx.annotation.WorkerThread;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.view.ViewCaptureData.ExportedData;
import com.android.launcher3.view.ViewCaptureData.FrameData;
import com.android.launcher3.view.ViewCaptureData.ViewNode;
@@ -45,13 +53,14 @@
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.List;
import java.util.concurrent.Future;
import java.util.zip.GZIPOutputStream;
/**
* Utility class for capturing view data every frame
*/
-public class ViewCapture implements OnDrawListener {
+public class ViewCapture {
private static final String TAG = "ViewCapture";
@@ -61,104 +70,27 @@
// Launcher. This allows the first free frames avoid object allocation during view capture.
private static final int INIT_POOL_SIZE = 300;
- private final Window mWindow;
- private final View mRoot;
- private final Resources mResources;
+ public static final MainThreadInitializedObject<ViewCapture> INSTANCE =
+ new MainThreadInitializedObject<>(ViewCapture::new);
- private final Handler mHandler;
- private final ViewRef mViewRef = new ViewRef();
+ private final List<WindowListener> mListeners = new ArrayList<>();
- private int mFrameIndexBg = -1;
- private final long[] mFrameTimesBg = new long[MEMORY_SIZE];
- private final ViewPropertyRef[] mNodesBg = new ViewPropertyRef[MEMORY_SIZE];
+ private final Context mContext;
+ private final LooperExecutor mExecutor;
// Pool used for capturing view tree on the UI thread.
private ViewRef mPool = new ViewRef();
- /**
- * @param window the window for the capture data
- */
- public ViewCapture(Window window) {
- mWindow = window;
- mRoot = mWindow.getDecorView();
- mResources = mRoot.getResources();
- mHandler = new Handler(UI_HELPER_EXECUTOR.getLooper(), this::captureViewPropertiesBg);
- }
-
- /**
- * Attaches the ViewCapture to the root
- */
- public void attach() {
- mHandler.post(this::initPool);
- }
-
- /**
- * Removes a previously attached ViewCapture from the root
- */
- public void detach() {
- mHandler.post(() -> MAIN_EXECUTOR.execute(
- () -> mRoot.getViewTreeObserver().removeOnDrawListener(this)));
- }
-
- @Override
- public void onDraw() {
- Trace.beginSection("view_capture");
- captureViewTree(mRoot, mViewRef);
- Message m = Message.obtain(mHandler);
- m.obj = mViewRef.next;
- mHandler.sendMessage(m);
- Trace.endSection();
- }
-
- /**
- * Captures the View property on the background thread, and transfer all the ViewRef objects
- * back to the pool
- */
- @WorkerThread
- private boolean captureViewPropertiesBg(Message msg) {
- ViewRef start = (ViewRef) msg.obj;
- long time = msg.getWhen();
- if (start == null) {
- return false;
+ private ViewCapture(Context context) {
+ mContext = context;
+ if (FeatureFlags.CONTINUOUS_VIEW_TREE_CAPTURE.get()) {
+ Looper looper = createAndStartNewLooper("ViewCapture",
+ Process.THREAD_PRIORITY_FOREGROUND);
+ mExecutor = new LooperExecutor(looper);
+ mExecutor.execute(this::initPool);
+ } else {
+ mExecutor = UI_HELPER_EXECUTOR;
}
- mFrameIndexBg++;
- if (mFrameIndexBg >= MEMORY_SIZE) {
- mFrameIndexBg = 0;
- }
- mFrameTimesBg[mFrameIndexBg] = time;
-
- ViewPropertyRef recycle = mNodesBg[mFrameIndexBg];
-
- ViewPropertyRef result = null;
- ViewPropertyRef resultEnd = null;
-
- ViewRef current = start;
- ViewRef last = start;
- while (current != null) {
- ViewPropertyRef propertyRef = recycle;
- if (propertyRef == null) {
- propertyRef = new ViewPropertyRef();
- } else {
- recycle = recycle.next;
- propertyRef.next = null;
- }
-
- propertyRef.transfer(current);
- last = current;
- current = current.next;
-
- if (result == null) {
- result = propertyRef;
- resultEnd = result;
- } else {
- resultEnd.next = propertyRef;
- resultEnd = propertyRef;
- }
- }
- mNodesBg[mFrameIndexBg] = result;
- ViewRef end = last;
- MAIN_EXECUTOR.execute(() -> addToPool(start, end));
- return true;
}
@UiThread
@@ -177,36 +109,59 @@
current = current.next;
}
- ViewRef end = current;
- MAIN_EXECUTOR.execute(() -> {
- addToPool(start, end);
- if (mRoot.isAttachedToWindow()) {
- mRoot.getViewTreeObserver().addOnDrawListener(this);
- }
- });
- }
-
- private String getName() {
- String title = mWindow.getAttributes().getTitle().toString();
- return TextUtils.isEmpty(title) ? mWindow.toString() : title;
+ ViewRef finalCurrent = current;
+ MAIN_EXECUTOR.execute(() -> addToPool(start, finalCurrent));
}
/**
- * Starts the dump process which is completed on closing the returned object.
+ * Attaches the ViewCapture to the provided window and returns a handle to detach the listener
*/
- public SafeCloseable beginDump(PrintWriter writer, FileDescriptor out) {
- Future<ExportedData> task = UI_HELPER_EXECUTOR.submit(this::dumpToProto);
+ public SafeCloseable startCapture(Window window) {
+ String title = window.getAttributes().getTitle().toString();
+ String name = TextUtils.isEmpty(title) ? window.toString() : title;
+ return startCapture(window.getDecorView(), name);
+ }
+ /**
+ * Attaches the ViewCapture to the provided window and returns a handle to detach the listener
+ */
+ public SafeCloseable startCapture(View view, String name) {
+ if (!FeatureFlags.CONTINUOUS_VIEW_TREE_CAPTURE.get()) {
+ return () -> { };
+ }
+
+ WindowListener listener = new WindowListener(view, name);
+ mExecutor.execute(() -> MAIN_EXECUTOR.execute(listener::attachToRoot));
+ mListeners.add(listener);
return () -> {
+ mListeners.remove(listener);
+ listener.destroy();
+ };
+ }
+
+ /**
+ * Dumps all the active view captures
+ */
+ public void dump(PrintWriter writer, FileDescriptor out) {
+ if (!FeatureFlags.CONTINUOUS_VIEW_TREE_CAPTURE.get()) {
+ return;
+ }
+ ViewIdProvider idProvider = new ViewIdProvider(mContext.getResources());
+
+ // Collect all the tasks first so that all the tasks are posted on the executor
+ List<Pair<String, Future<ExportedData>>> tasks = mListeners.stream()
+ .map(l -> Pair.create(l.name, mExecutor.submit(() -> l.dumpToProto(idProvider))))
+ .collect(toList());
+
+ tasks.forEach(pair -> {
writer.println();
writer.println(" ContinuousViewCapture:");
- writer.println(" window " + getName() + ":");
- writer.println(" pkg:" + mRoot.getContext().getPackageName());
+ writer.println(" window " + pair.first + ":");
+ writer.println(" pkg:" + mContext.getPackageName());
writer.print(" data:");
writer.flush();
-
try (OutputStream os = new FileOutputStream(out)) {
- ExportedData data = task.get();
+ ExportedData data = pair.second.get();
OutputStream encodedOS = new GZIPOutputStream(new Base64OutputStream(os,
Base64.NO_CLOSE | Base64.NO_PADDING | Base64.NO_WRAP));
data.writeTo(encodedOS);
@@ -217,51 +172,156 @@
}
writer.println();
writer.println("--end--");
- };
+ });
}
- @WorkerThread
- private ExportedData dumpToProto() {
- ExportedData.Builder dataBuilder = ExportedData.newBuilder();
- Resources res = mResources;
- ArrayList<Class> classList = new ArrayList<>();
+ private class WindowListener implements OnDrawListener {
- int size = (mNodesBg[MEMORY_SIZE - 1] == null) ? mFrameIndexBg + 1 : MEMORY_SIZE;
- for (int i = size - 1; i >= 0; i--) {
- int index = (MEMORY_SIZE + mFrameIndexBg - i) % MEMORY_SIZE;
- ViewNode.Builder nodeBuilder = ViewNode.newBuilder();
- mNodesBg[index].toProto(res, classList, nodeBuilder);
- dataBuilder.addFrameData(FrameData.newBuilder()
- .setNode(nodeBuilder)
- .setTimestamp(mFrameTimesBg[index]));
- }
- return dataBuilder
- .addAllClassname(classList.stream().map(Class::getName).collect(toList()))
- .build();
- }
+ private final View mRoot;
+ public final String name;
- private ViewRef captureViewTree(View view, ViewRef start) {
- ViewRef ref;
- if (mPool != null) {
- ref = mPool;
- mPool = mPool.next;
- ref.next = null;
- } else {
- ref = new ViewRef();
+ private final Handler mHandler;
+ private final ViewRef mViewRef = new ViewRef();
+
+ private int mFrameIndexBg = -1;
+ private final long[] mFrameTimesBg = new long[MEMORY_SIZE];
+ private final ViewPropertyRef[] mNodesBg = new ViewPropertyRef[MEMORY_SIZE];
+
+ private boolean mDestroyed = false;
+
+ WindowListener(View view, String name) {
+ mRoot = view;
+ this.name = name;
+ mHandler = new Handler(mExecutor.getLooper(), this::captureViewPropertiesBg);
}
- ref.view = view;
- start.next = ref;
- if (view instanceof ViewGroup) {
- ViewRef result = ref;
- ViewGroup parent = (ViewGroup) view;
- int childCount = ref.childCount = parent.getChildCount();
- for (int i = 0; i < childCount; i++) {
- result = captureViewTree(parent.getChildAt(i), result);
+
+ @Override
+ public void onDraw() {
+ Trace.beginSection("view_capture");
+ captureViewTree(mRoot, mViewRef);
+ Message m = Message.obtain(mHandler);
+ m.obj = mViewRef.next;
+ mHandler.sendMessage(m);
+ Trace.endSection();
+ }
+
+ /**
+ * Captures the View property on the background thread, and transfer all the ViewRef objects
+ * back to the pool
+ */
+ @WorkerThread
+ private boolean captureViewPropertiesBg(Message msg) {
+ ViewRef start = (ViewRef) msg.obj;
+ long time = msg.getWhen();
+ if (start == null) {
+ return false;
}
- return result;
- } else {
- ref.childCount = 0;
- return ref;
+ mFrameIndexBg++;
+ if (mFrameIndexBg >= MEMORY_SIZE) {
+ mFrameIndexBg = 0;
+ }
+ mFrameTimesBg[mFrameIndexBg] = time;
+
+ ViewPropertyRef recycle = mNodesBg[mFrameIndexBg];
+
+ ViewPropertyRef result = null;
+ ViewPropertyRef resultEnd = null;
+
+ ViewRef current = start;
+ ViewRef last = start;
+ while (current != null) {
+ ViewPropertyRef propertyRef = recycle;
+ if (propertyRef == null) {
+ propertyRef = new ViewPropertyRef();
+ } else {
+ recycle = recycle.next;
+ propertyRef.next = null;
+ }
+
+ propertyRef.transfer(current);
+ last = current;
+ current = current.next;
+
+ if (result == null) {
+ result = propertyRef;
+ resultEnd = result;
+ } else {
+ resultEnd.next = propertyRef;
+ resultEnd = propertyRef;
+ }
+ }
+ mNodesBg[mFrameIndexBg] = result;
+ ViewRef end = last;
+ MAIN_EXECUTOR.execute(() -> addToPool(start, end));
+ return true;
+ }
+
+ void attachToRoot() {
+ if (mRoot.isAttachedToWindow()) {
+ mRoot.getViewTreeObserver().addOnDrawListener(this);
+ } else {
+ mRoot.addOnAttachStateChangeListener(new OnAttachStateChangeListener() {
+ @Override
+ public void onViewAttachedToWindow(View v) {
+ if (!mDestroyed) {
+ mRoot.getViewTreeObserver().addOnDrawListener(WindowListener.this);
+ }
+ mRoot.removeOnAttachStateChangeListener(this);
+ }
+
+ @Override
+ public void onViewDetachedFromWindow(View v) { }
+ });
+ }
+ }
+
+ void destroy() {
+ mRoot.getViewTreeObserver().removeOnDrawListener(this);
+ mDestroyed = true;
+ }
+
+ @WorkerThread
+ private ExportedData dumpToProto(ViewIdProvider idProvider) {
+ ExportedData.Builder dataBuilder = ExportedData.newBuilder();
+ ArrayList<Class> classList = new ArrayList<>();
+
+ int size = (mNodesBg[MEMORY_SIZE - 1] == null) ? mFrameIndexBg + 1 : MEMORY_SIZE;
+ for (int i = size - 1; i >= 0; i--) {
+ int index = (MEMORY_SIZE + mFrameIndexBg - i) % MEMORY_SIZE;
+ ViewNode.Builder nodeBuilder = ViewNode.newBuilder();
+ mNodesBg[index].toProto(idProvider, classList, nodeBuilder);
+ dataBuilder.addFrameData(FrameData.newBuilder()
+ .setNode(nodeBuilder)
+ .setTimestamp(mFrameTimesBg[index]));
+ }
+ return dataBuilder
+ .addAllClassname(classList.stream().map(Class::getName).collect(toList()))
+ .build();
+ }
+
+ private ViewRef captureViewTree(View view, ViewRef start) {
+ ViewRef ref;
+ if (mPool != null) {
+ ref = mPool;
+ mPool = mPool.next;
+ ref.next = null;
+ } else {
+ ref = new ViewRef();
+ }
+ ref.view = view;
+ start.next = ref;
+ if (view instanceof ViewGroup) {
+ ViewRef result = ref;
+ ViewGroup parent = (ViewGroup) view;
+ int childCount = ref.childCount = parent.getChildCount();
+ for (int i = 0; i < childCount; i++) {
+ result = captureViewTree(parent.getChildAt(i), result);
+ }
+ return result;
+ } else {
+ ref.childCount = 0;
+ return ref;
+ }
}
}
@@ -318,18 +378,8 @@
* at the end of the iteration.
* @return
*/
- public ViewPropertyRef toProto(Resources res, ArrayList<Class> classList,
+ public ViewPropertyRef toProto(ViewIdProvider idProvider, ArrayList<Class> classList,
ViewNode.Builder outBuilder) {
- String resolvedId;
- if (id >= 0) {
- try {
- resolvedId = res.getResourceTypeName(id) + '/' + res.getResourceEntryName(id);
- } catch (Resources.NotFoundException e) {
- resolvedId = "id/" + "0x" + Integer.toHexString(id).toUpperCase();
- }
- } else {
- resolvedId = "NO_ID";
- }
int classnameIndex = classList.indexOf(clazz);
if (classnameIndex < 0) {
classnameIndex = classList.size();
@@ -338,7 +388,7 @@
outBuilder
.setClassnameIndex(classnameIndex)
.setHashcode(hashCode)
- .setId(resolvedId)
+ .setId(idProvider.getName(id))
.setLeft(left)
.setTop(top)
.setWidth(right - left)
@@ -356,7 +406,7 @@
ViewPropertyRef result = next;
for (int i = 0; (i < childCount) && (result != null); i++) {
ViewNode.Builder childBuilder = ViewNode.newBuilder();
- result = result.toProto(res, classList, childBuilder);
+ result = result.toProto(idProvider, classList, childBuilder);
outBuilder.addChildren(childBuilder);
}
return result;
@@ -368,4 +418,31 @@
public int childCount = 0;
public ViewRef next;
}
+
+ private static final class ViewIdProvider {
+
+ private final SparseArray<String> mNames = new SparseArray<>();
+ private final Resources mRes;
+
+ ViewIdProvider(Resources res) {
+ mRes = res;
+ }
+
+ String getName(int id) {
+ String name = mNames.get(id);
+ if (name == null) {
+ if (id >= 0) {
+ try {
+ name = mRes.getResourceTypeName(id) + '/' + mRes.getResourceEntryName(id);
+ } catch (Resources.NotFoundException e) {
+ name = "id/" + "0x" + Integer.toHexString(id).toUpperCase();
+ }
+ } else {
+ name = "NO_ID";
+ }
+ mNames.put(id, name);
+ }
+ return name;
+ }
+ }
}
diff --git a/src/com/android/launcher3/util/window/WindowManagerProxy.java b/src/com/android/launcher3/util/window/WindowManagerProxy.java
index 582ff8d..fb2ae73 100644
--- a/src/com/android/launcher3/util/window/WindowManagerProxy.java
+++ b/src/com/android/launcher3/util/window/WindowManagerProxy.java
@@ -17,14 +17,15 @@
import static android.view.Display.DEFAULT_DISPLAY;
+import static com.android.launcher3.Utilities.dpiFromPx;
import static com.android.launcher3.testing.shared.ResourceUtils.INVALID_RESOURCE_HANDLE;
import static com.android.launcher3.testing.shared.ResourceUtils.NAVBAR_HEIGHT;
import static com.android.launcher3.testing.shared.ResourceUtils.NAVBAR_HEIGHT_LANDSCAPE;
import static com.android.launcher3.testing.shared.ResourceUtils.NAVBAR_LANDSCAPE_LEFT_RIGHT_SIZE;
+import static com.android.launcher3.testing.shared.ResourceUtils.NAV_BAR_INTERACTION_MODE_RES_NAME;
import static com.android.launcher3.testing.shared.ResourceUtils.STATUS_BAR_HEIGHT;
import static com.android.launcher3.testing.shared.ResourceUtils.STATUS_BAR_HEIGHT_LANDSCAPE;
import static com.android.launcher3.testing.shared.ResourceUtils.STATUS_BAR_HEIGHT_PORTRAIT;
-import static com.android.launcher3.Utilities.dpiFromPx;
import static com.android.launcher3.util.MainThreadInitializedObject.forOverride;
import static com.android.launcher3.util.RotationUtils.deltaRotation;
import static com.android.launcher3.util.RotationUtils.rotateRect;
@@ -40,6 +41,7 @@
import android.hardware.display.DisplayManager;
import android.os.Build;
import android.util.ArrayMap;
+import android.util.Log;
import android.view.Display;
import android.view.DisplayCutout;
import android.view.Surface;
@@ -48,9 +50,10 @@
import android.view.WindowMetrics;
import com.android.launcher3.R;
-import com.android.launcher3.testing.shared.ResourceUtils;
import com.android.launcher3.Utilities;
+import com.android.launcher3.testing.shared.ResourceUtils;
import com.android.launcher3.util.MainThreadInitializedObject;
+import com.android.launcher3.util.NavigationMode;
import com.android.launcher3.util.ResourceBasedOverride;
import com.android.launcher3.util.WindowBounds;
@@ -59,6 +62,7 @@
*/
public class WindowManagerProxy implements ResourceBasedOverride {
+ private static final String TAG = "WindowManagerProxy";
public static final int MIN_TABLET_WIDTH = 600;
public static final MainThreadInitializedObject<WindowManagerProxy> INSTANCE =
@@ -343,4 +347,24 @@
return displayInfoContext.getSystemService(DisplayManager.class).getDisplay(
DEFAULT_DISPLAY);
}
+
+ /**
+ * Returns the current navigation mode from resource.
+ */
+ public NavigationMode getNavigationMode(Context context) {
+ int modeInt = ResourceUtils.getIntegerByName(NAV_BAR_INTERACTION_MODE_RES_NAME,
+ context.getResources(), INVALID_RESOURCE_HANDLE);
+
+ if (modeInt == INVALID_RESOURCE_HANDLE) {
+ Log.e(TAG, "Failed to get system resource ID. Incompatible framework version?");
+ } else {
+ for (NavigationMode m : NavigationMode.values()) {
+ if (m.resValue == modeInt) {
+ return m;
+ }
+ }
+ }
+ return Utilities.ATLEAST_S ? NavigationMode.NO_BUTTON :
+ NavigationMode.THREE_BUTTONS;
+ }
}
diff --git a/src/com/android/launcher3/views/ActivityContext.java b/src/com/android/launcher3/views/ActivityContext.java
index 93078e4..e2dc34f 100644
--- a/src/com/android/launcher3/views/ActivityContext.java
+++ b/src/com/android/launcher3/views/ActivityContext.java
@@ -141,6 +141,7 @@
default void applyOverwritesToLogItem(LauncherAtom.ItemInfo.Builder itemInfoBuilder) { }
/** Onboarding preferences for any onboarding data within this context. */
+ @Nullable
default OnboardingPrefs<?> getOnboardingPrefs() {
return null;
}
diff --git a/src/com/android/launcher3/views/AppLauncher.java b/src/com/android/launcher3/views/AppLauncher.java
index 19e66ab..dc07e45 100644
--- a/src/com/android/launcher3/views/AppLauncher.java
+++ b/src/com/android/launcher3/views/AppLauncher.java
@@ -16,7 +16,7 @@
package com.android.launcher3.views;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_APP_LAUNCH_TAP;
-import static com.android.launcher3.model.WidgetsModel.GO_DISABLE_WIDGETS;
+import static com.android.launcher3.model.WidgetsModel.GO_DISABLE_SHORTCUTS;
import android.app.ActivityOptions;
import android.content.ActivityNotFoundException;
@@ -190,7 +190,7 @@
*/
default void startShortcut(String packageName, String id, Rect sourceBounds,
Bundle startActivityOptions, UserHandle user) {
- if (GO_DISABLE_WIDGETS) {
+ if (GO_DISABLE_SHORTCUTS) {
return;
}
try {
diff --git a/src/com/android/launcher3/widget/PendingAddWidgetInfo.java b/src/com/android/launcher3/widget/PendingAddWidgetInfo.java
index 470a800..ccf4b2e 100644
--- a/src/com/android/launcher3/widget/PendingAddWidgetInfo.java
+++ b/src/com/android/launcher3/widget/PendingAddWidgetInfo.java
@@ -19,6 +19,9 @@
import android.content.Context;
import android.os.Bundle;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.PendingAddItemInfo;
import com.android.launcher3.logger.LauncherAtom;
@@ -66,8 +69,9 @@
return WidgetSizes.getWidgetSizeOptions(context, componentName, spanX, spanY);
}
+ @NonNull
@Override
- public LauncherAtom.ItemInfo buildProto(FolderInfo folderInfo) {
+ public LauncherAtom.ItemInfo buildProto(@Nullable FolderInfo folderInfo) {
LauncherAtom.ItemInfo info = super.buildProto(folderInfo);
return info.toBuilder()
.addItemAttributes(LauncherAppWidgetInfo.getAttribute(sourceContainer))
diff --git a/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java b/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java
index 702f343..13ad7a4 100644
--- a/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java
+++ b/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java
@@ -62,6 +62,8 @@
// True is the widget support is disabled.
public static final boolean GO_DISABLE_WIDGETS = false;
+ // True is the shortcut support is disabled.
+ public static final boolean GO_DISABLE_SHORTCUTS = false;
public static final boolean GO_DISABLE_NOTIFICATION_DOTS = false;
private static final String TAG = "WidgetsModel";
diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/states/AllAppsState.java b/src_ui_overrides/com/android/launcher3/uioverrides/states/AllAppsState.java
index bf35dd8..9daea94 100644
--- a/src_ui_overrides/com/android/launcher3/uioverrides/states/AllAppsState.java
+++ b/src_ui_overrides/com/android/launcher3/uioverrides/states/AllAppsState.java
@@ -32,7 +32,6 @@
public class AllAppsState extends LauncherState {
private static final float PARALLAX_COEFFICIENT = .125f;
- private static final float WORKSPACE_SCALE_FACTOR = 0.97f;
private static final int STATE_FLAGS = FLAG_WORKSPACE_INACCESSIBLE;
@@ -60,7 +59,8 @@
@Override
public ScaleAndTranslation getWorkspaceScaleAndTranslation(Launcher launcher) {
- return new ScaleAndTranslation(WORKSPACE_SCALE_FACTOR, NO_OFFSET, NO_OFFSET);
+ return new ScaleAndTranslation(launcher.getDeviceProfile().workspaceContentScale, NO_OFFSET,
+ NO_OFFSET);
}
@Override
@@ -71,7 +71,7 @@
ScaleAndTranslation overviewScaleAndTranslation = LauncherState.OVERVIEW
.getWorkspaceScaleAndTranslation(launcher);
return new ScaleAndTranslation(
- WORKSPACE_SCALE_FACTOR,
+ launcher.getDeviceProfile().workspaceContentScale,
overviewScaleAndTranslation.translationX,
overviewScaleAndTranslation.translationY);
}
diff --git a/tests/src/com/android/launcher3/celllayout/CellLayoutBoard.java b/tests/src/com/android/launcher3/celllayout/CellLayoutBoard.java
index 3ca05bc..a32ce3c 100644
--- a/tests/src/com/android/launcher3/celllayout/CellLayoutBoard.java
+++ b/tests/src/com/android/launcher3/celllayout/CellLayoutBoard.java
@@ -30,39 +30,117 @@
public class CellLayoutBoard {
+ public static class CellType {
+ // The cells marked by this will be filled by 1x1 widgets and will be ignored when
+ // validating
+ public static final char IGNORE = 'x';
+ // The cells marked by this will be filled by app icons
+ public static final char ICON = 'i';
+ // Empty space
+ public static final char EMPTY = '-';
+ // Widget that will be saved as "main widget" for easier retrieval
+ public static final char MAIN_WIDGET = 'm';
+ // Everything else will be consider a widget
+ }
+
+ public static class WidgetRect {
+ public char mType;
+ public Rect mBounds;
+
+ WidgetRect(char type, Rect bounds) {
+ this.mType = type;
+ this.mBounds = bounds;
+ }
+
+ int getSpanX() {
+ return mBounds.right - mBounds.left + 1;
+ }
+
+ int getSpanY() {
+ return mBounds.top - mBounds.bottom + 1;
+ }
+
+ int getCellX() {
+ return mBounds.left;
+ }
+
+ int getCellY() {
+ return mBounds.bottom;
+ }
+
+ boolean shouldIgnore() {
+ return this.mType == CellType.IGNORE;
+ }
+
+ @Override
+ public String toString() {
+ return "WidgetRect type = " + mType + " bounds = " + mBounds.toString();
+ }
+ }
+
+ public static class IconPoint {
+ public Point coord;
+ public char mType;
+
+ public IconPoint(Point coord, char type) {
+ this.coord = coord;
+ mType = type;
+ }
+
+ public char getType() {
+ return mType;
+ }
+
+ public void setType(char type) {
+ mType = type;
+ }
+
+ public Point getCoord() {
+ return coord;
+ }
+
+ public void setCoord(Point coord) {
+ this.coord = coord;
+ }
+ }
+
static final int INFINITE = 99999;
- char[][] mBoard = new char[30][30];
+ char[][] mWidget = new char[30][30];
- List<TestBoardWidget> mWidgetsRects = new ArrayList<>();
- Map<Character, TestBoardWidget> mWidgetsMap = new HashMap<>();
+ List<WidgetRect> mWidgetsRects = new ArrayList<>();
+ Map<Character, WidgetRect> mWidgetsMap = new HashMap<>();
- List<TestBoardAppIcon> mIconPoints = new ArrayList<>();
- Map<Character, TestBoardAppIcon> mIconsMap = new HashMap<>();
+ List<IconPoint> mIconPoints = new ArrayList<>();
+ Map<Character, IconPoint> mIconsMap = new HashMap<>();
Point mMain = new Point();
CellLayoutBoard() {
- for (int x = 0; x < mBoard.length; x++) {
- for (int y = 0; y < mBoard[0].length; y++) {
- mBoard[x][y] = '-';
+ for (int x = 0; x < mWidget.length; x++) {
+ for (int y = 0; y < mWidget[0].length; y++) {
+ mWidget[x][y] = CellType.EMPTY;
}
}
}
- public List<TestBoardWidget> getWidgets() {
+ public List<WidgetRect> getWidgets() {
return mWidgetsRects;
}
+ public List<IconPoint> getIcons() {
+ return mIconPoints;
+ }
+
public Point getMain() {
return mMain;
}
- public TestBoardWidget getWidgetRect(char c) {
+ public WidgetRect getWidgetRect(char c) {
return mWidgetsMap.get(c);
}
- public static TestBoardWidget getWidgetRect(int x, int y, Set<Point> used, char[][] board) {
+ public static WidgetRect getWidgetRect(int x, int y, Set<Point> used, char[][] board) {
char type = board[x][y];
Queue<Point> search = new ArrayDeque<Point>();
Point current = new Point(x, y);
@@ -91,20 +169,20 @@
}
}
}
- return new TestBoardWidget(type, widgetRect);
+ return new WidgetRect(type, widgetRect);
}
public static boolean isWidget(char type) {
- return type != 'i' && type != '-';
+ return type != CellType.ICON && type != CellType.EMPTY;
}
public static boolean isIcon(char type) {
- return type == 'i';
+ return type == CellType.ICON;
}
- private static List<TestBoardWidget> getRects(char[][] board) {
+ private static List<WidgetRect> getRects(char[][] board) {
Set<Point> used = new HashSet<>();
- List<TestBoardWidget> widgetsRects = new ArrayList<>();
+ List<WidgetRect> widgetsRects = new ArrayList<>();
for (int x = 0; x < board.length; x++) {
for (int y = 0; y < board[0].length; y++) {
if (!used.contains(new Point(x, y)) && isWidget(board[x][y])) {
@@ -115,12 +193,12 @@
return widgetsRects;
}
- private static List<TestBoardAppIcon> getIconPoints(char[][] board) {
- List<TestBoardAppIcon> iconPoints = new ArrayList<>();
+ private static List<IconPoint> getIconPoints(char[][] board) {
+ List<IconPoint> iconPoints = new ArrayList<>();
for (int x = 0; x < board.length; x++) {
for (int y = 0; y < board[0].length; y++) {
if (isIcon(board[x][y])) {
- iconPoints.add(new TestBoardAppIcon(new Point(x, y), board[x][y]));
+ iconPoints.add(new IconPoint(new Point(x, y), board[x][y]));
}
}
}
@@ -135,18 +213,18 @@
String line = lines[y];
for (int x = 0; x < line.length(); x++) {
char c = line.charAt(x);
- if (c == 'm') {
+ if (c == CellType.MAIN_WIDGET) {
board.mMain = new Point(x, y);
}
- if (c != '-') {
- board.mBoard[x][y] = line.charAt(x);
+ if (c != CellType.EMPTY) {
+ board.mWidget[x][y] = line.charAt(x);
}
}
}
- board.mWidgetsRects = getRects(board.mBoard);
+ board.mWidgetsRects = getRects(board.mWidget);
board.mWidgetsRects.forEach(
widgetRect -> board.mWidgetsMap.put(widgetRect.mType, widgetRect));
- board.mIconPoints = getIconPoints(board.mBoard);
+ board.mIconPoints = getIconPoints(board.mWidget);
return board;
}
}
diff --git a/tests/src/com/android/launcher3/celllayout/ReorderWidgets.java b/tests/src/com/android/launcher3/celllayout/ReorderWidgets.java
index 5f5dfea..93fbf97 100644
--- a/tests/src/com/android/launcher3/celllayout/ReorderWidgets.java
+++ b/tests/src/com/android/launcher3/celllayout/ReorderWidgets.java
@@ -15,16 +15,13 @@
*/
package com.android.launcher3.celllayout;
-import static com.android.launcher3.util.WidgetUtils.createWidgetInfo;
-
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import android.graphics.Point;
-import android.graphics.Rect;
import android.util.Log;
import android.view.View;
-import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
@@ -34,13 +31,14 @@
import com.android.launcher3.celllayout.testcases.PushReorderCase;
import com.android.launcher3.celllayout.testcases.ReorderTestCase;
import com.android.launcher3.celllayout.testcases.SimpleReorderCase;
-import com.android.launcher3.model.data.LauncherAppWidgetInfo;
+import com.android.launcher3.tapl.Widget;
+import com.android.launcher3.tapl.WidgetResizeFrame;
import com.android.launcher3.ui.AbstractLauncherUiTest;
import com.android.launcher3.ui.TaplTestsLauncher3;
-import com.android.launcher3.ui.TestViewHelpers;
import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord;
import com.android.launcher3.util.rule.ShellCommandRule;
-import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
+import com.android.launcher3.views.DoubleShadowBubbleTextView;
+import com.android.launcher3.widget.LauncherAppWidgetHostView;
import org.junit.Assume;
import org.junit.Before;
@@ -60,6 +58,8 @@
private static final String TAG = ReorderWidgets.class.getSimpleName();
+ TestWorkspaceBuilder mBoardBuilder;
+
private View getViewAt(int cellX, int cellY) {
return getFromLauncher(l -> l.getWorkspace().getScreenWithId(
l.getWorkspace().getScreenIdForPageIndex(0)).getChildAt(cellX, cellY));
@@ -76,6 +76,7 @@
@Before
public void setup() throws Throwable {
+ mBoardBuilder = new TestWorkspaceBuilder(this);
TaplTestsLauncher3.initialize(this);
clearHomescreen();
}
@@ -86,78 +87,44 @@
private boolean validateBoard(CellLayoutBoard board) {
boolean match = true;
Point cellDimensions = getCellDimensions();
- for (TestBoardWidget widgetRect: board.getWidgets()) {
+ for (CellLayoutBoard.WidgetRect widgetRect: board.getWidgets()) {
if (widgetRect.shouldIgnore()) {
continue;
}
View widget = getViewAt(widgetRect.getCellX(), widgetRect.getCellY());
+ assertTrue("The view selected at " + board + " is not a widget",
+ widget instanceof LauncherAppWidgetHostView);
match &= widgetRect.getSpanX()
== Math.round(widget.getWidth() / (float) cellDimensions.x);
match &= widgetRect.getSpanY()
== Math.round(widget.getHeight() / (float) cellDimensions.y);
if (!match) return match;
}
+ for (CellLayoutBoard.IconPoint iconPoint : board.getIcons()) {
+ View icon = getViewAt(iconPoint.getCoord().x, iconPoint.getCoord().y);
+ assertTrue("The view selected at " + iconPoint.coord + " is not an Icon",
+ icon instanceof DoubleShadowBubbleTextView);
+ }
return match;
}
- /**
- * Fills the given rect in WidgetRect with 1x1 widgets. This is useful to equalize cases.
- */
- private void fillWithWidgets(TestBoardWidget widgetRect) {
- int initX = widgetRect.getCellX();
- int initY = widgetRect.getCellY();
- for (int x = 0; x < widgetRect.getSpanX(); x++) {
- for (int y = 0; y < widgetRect.getSpanY(); y++) {
- int auxX = initX + x;
- int auxY = initY + y;
- try {
- // this widgets are filling, we don't care if we can't place them
- addWidgetInCell(
- new TestBoardWidget('x',
- new Rect(auxX, auxY, auxX, auxY))
- );
- } catch (Exception e) {
- Log.d(TAG, "Unable to place filling widget at " + auxX + "," + auxY);
- }
- }
- }
- }
-
- private void addWidgetInCell(TestBoardWidget widgetRect) {
- LauncherAppWidgetProviderInfo info = TestViewHelpers.findWidgetProvider(this, false);
- LauncherAppWidgetInfo item = createWidgetInfo(info,
- ApplicationProvider.getApplicationContext(), true);
- item.cellX = widgetRect.getCellX();
- item.cellY = widgetRect.getCellY();
-
- item.spanX = widgetRect.getSpanX();
- item.spanY = widgetRect.getSpanY();
- addItemToScreen(item);
- }
-
- private void addCorrespondingWidgetRect(TestBoardWidget widgetRect) {
- if (widgetRect.mType == 'x') {
- fillWithWidgets(widgetRect);
- } else {
- addWidgetInCell(widgetRect);
- }
- }
-
private void runTestCase(ReorderTestCase testCase) {
Point mainWidgetCellPos = testCase.mStart.getMain();
- testCase.mStart.getWidgets().forEach(this::addCorrespondingWidgetRect);
+ mBoardBuilder.buildBoard(testCase.mStart);
- mLauncher.getWorkspace()
- .getWidgetAtCell(mainWidgetCellPos.x, mainWidgetCellPos.y)
- .dragWidgetToWorkspace(testCase.moveMainTo.x, testCase.moveMainTo.y)
- .dismiss(); // dismiss resize frame
+ Widget widget = mLauncher.getWorkspace().getWidgetAtCell(mainWidgetCellPos.x,
+ mainWidgetCellPos.y);
+ assertNotNull(widget);
+ WidgetResizeFrame resizeFrame = widget.dragWidgetToWorkspace(testCase.moveMainTo.x,
+ testCase.moveMainTo.y);
+ resizeFrame.dismiss();
boolean isValid = false;
for (CellLayoutBoard board : testCase.mEnd) {
isValid |= validateBoard(board);
}
- assertTrue("None of the valid boards match with the current state", isValid);
+ assertTrue("Non of the valid boards match with the current state", isValid);
}
/**
diff --git a/tests/src/com/android/launcher3/celllayout/TestWorkspaceBuilder.java b/tests/src/com/android/launcher3/celllayout/TestWorkspaceBuilder.java
new file mode 100644
index 0000000..10e399d
--- /dev/null
+++ b/tests/src/com/android/launcher3/celllayout/TestWorkspaceBuilder.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2022 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.celllayout;
+
+import static com.android.launcher3.util.WidgetUtils.createWidgetInfo;
+
+import android.content.ComponentName;
+import android.graphics.Rect;
+import android.os.Process;
+import android.os.UserHandle;
+import android.util.Log;
+
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.launcher3.LauncherSettings;
+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.ui.AbstractLauncherUiTest;
+import com.android.launcher3.ui.TestViewHelpers;
+import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
+
+public class TestWorkspaceBuilder {
+
+ private static final ComponentName APP_COMPONENT_NAME = new ComponentName(
+ "com.google.android.calculator", "com.android.calculator2.Calculator");
+
+ public AbstractLauncherUiTest mTest;
+
+ private UserHandle mMyUser;
+
+ public TestWorkspaceBuilder(AbstractLauncherUiTest test) {
+ mTest = test;
+ mMyUser = Process.myUserHandle();
+ }
+
+ private static final String TAG = "CellLayoutBoardBuilder";
+
+ /**
+ * Fills the given rect in WidgetRect with 1x1 widgets. This is useful to equalize cases.
+ */
+ private void fillWithWidgets(CellLayoutBoard.WidgetRect widgetRect) {
+ int initX = widgetRect.getCellX();
+ int initY = widgetRect.getCellY();
+ for (int x = initX; x < initX + widgetRect.getSpanX(); x++) {
+ for (int y = initY; y < initY + widgetRect.getSpanY(); y++) {
+ try {
+ // this widgets are filling, we don't care if we can't place them
+ addWidgetInCell(
+ new CellLayoutBoard.WidgetRect(CellLayoutBoard.CellType.IGNORE,
+ new Rect(x, y, x, y))
+ );
+ } catch (Exception e) {
+ Log.d(TAG, "Unable to place filling widget at " + x + "," + y);
+ }
+ }
+ }
+ }
+
+ private void addWidgetInCell(CellLayoutBoard.WidgetRect widgetRect) {
+ LauncherAppWidgetProviderInfo info = TestViewHelpers.findWidgetProvider(mTest, false);
+ LauncherAppWidgetInfo item = createWidgetInfo(info,
+ ApplicationProvider.getApplicationContext(), true);
+
+ item.cellX = widgetRect.getCellX();
+ item.cellY = widgetRect.getCellY();
+ item.spanX = widgetRect.getSpanX();
+ item.spanY = widgetRect.getSpanY();
+ mTest.addItemToScreen(item);
+ }
+
+ private void addIconInCell(CellLayoutBoard.IconPoint iconPoint) {
+ AppInfo appInfo = new AppInfo(APP_COMPONENT_NAME, "test icon", mMyUser,
+ AppInfo.makeLaunchIntent(APP_COMPONENT_NAME));
+
+ appInfo.cellX = iconPoint.getCoord().x;
+ appInfo.cellY = iconPoint.getCoord().y;
+ appInfo.minSpanY = appInfo.minSpanX = appInfo.spanX = appInfo.spanY = 1;
+ appInfo.container = LauncherSettings.Favorites.CONTAINER_DESKTOP;
+ appInfo.componentName = APP_COMPONENT_NAME;
+
+ mTest.addItemToScreen(new WorkspaceItemInfo(appInfo));
+ }
+
+ private void addCorrespondingWidgetRect(CellLayoutBoard.WidgetRect widgetRect) {
+ if (widgetRect.mType == 'x') {
+ fillWithWidgets(widgetRect);
+ } else {
+ addWidgetInCell(widgetRect);
+ }
+ }
+
+ public void buildBoard(CellLayoutBoard board) {
+ board.getWidgets().forEach(this::addCorrespondingWidgetRect);
+ board.getIcons().forEach(this::addIconInCell);
+ }
+}
diff --git a/tests/src/com/android/launcher3/celllayout/testcases/FullReorderCase.java b/tests/src/com/android/launcher3/celllayout/testcases/FullReorderCase.java
index 1326389..94e55cf 100644
--- a/tests/src/com/android/launcher3/celllayout/testcases/FullReorderCase.java
+++ b/tests/src/com/android/launcher3/celllayout/testcases/FullReorderCase.java
@@ -19,6 +19,10 @@
import java.util.Map;
+/**
+ * The grids represent the workspace to be build by TestWorkspaceBuilder, to see what each character
+ * in the board mean refer to {@code CellType}
+ */
public class FullReorderCase {
/** 5x5 Test
diff --git a/tests/src/com/android/launcher3/celllayout/testcases/MoveOutReorderCase.java b/tests/src/com/android/launcher3/celllayout/testcases/MoveOutReorderCase.java
index 1701390..a222d3d 100644
--- a/tests/src/com/android/launcher3/celllayout/testcases/MoveOutReorderCase.java
+++ b/tests/src/com/android/launcher3/celllayout/testcases/MoveOutReorderCase.java
@@ -19,6 +19,10 @@
import java.util.Map;
+/**
+ * The grids represent the workspace to be build by TestWorkspaceBuilder, to see what each character
+ * in the board mean refer to {@code CellType}
+ */
public class MoveOutReorderCase {
/** 5x5 Test
diff --git a/tests/src/com/android/launcher3/celllayout/testcases/PushReorderCase.java b/tests/src/com/android/launcher3/celllayout/testcases/PushReorderCase.java
index bb8d5e9..e16ff42 100644
--- a/tests/src/com/android/launcher3/celllayout/testcases/PushReorderCase.java
+++ b/tests/src/com/android/launcher3/celllayout/testcases/PushReorderCase.java
@@ -19,6 +19,10 @@
import java.util.Map;
+/**
+ * The grids represent the workspace to be build by TestWorkspaceBuilder, to see what each character
+ * in the board mean refer to {@code CellType}
+ */
public class PushReorderCase {
/** 5x5 Test
diff --git a/tests/src/com/android/launcher3/celllayout/testcases/SimpleReorderCase.java b/tests/src/com/android/launcher3/celllayout/testcases/SimpleReorderCase.java
index 30269a0..546c48b 100644
--- a/tests/src/com/android/launcher3/celllayout/testcases/SimpleReorderCase.java
+++ b/tests/src/com/android/launcher3/celllayout/testcases/SimpleReorderCase.java
@@ -19,6 +19,10 @@
import java.util.Map;
+/**
+ * The grids represent the workspace to be build by TestWorkspaceBuilder, to see what each character
+ * in the board mean refer to {@code CellType}
+ */
public class SimpleReorderCase {
/** 5x5 Test
diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
index 304153f..a66b09a 100644
--- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
+++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
@@ -319,7 +319,7 @@
/**
* Adds {@param item} on the homescreen on the 0th screen
*/
- protected void addItemToScreen(ItemInfo item) {
+ public void addItemToScreen(ItemInfo item) {
WidgetUtils.addItemToScreen(item, mTargetContext);
resetLoaderState();