Merge "Avoid IconView's setModalAlpha interfere with setContentAlpha" into main
diff --git a/go/quickstep/src/com/android/quickstep/TaskOverlayFactoryGo.java b/go/quickstep/src/com/android/quickstep/TaskOverlayFactoryGo.java
index 0eb8775..26ca06a 100644
--- a/go/quickstep/src/com/android/quickstep/TaskOverlayFactoryGo.java
+++ b/go/quickstep/src/com/android/quickstep/TaskOverlayFactoryGo.java
@@ -56,7 +56,7 @@
import com.android.quickstep.util.AssistContentRequester;
import com.android.quickstep.util.RecentsOrientedState;
import com.android.quickstep.views.GoOverviewActionsView;
-import com.android.quickstep.views.TaskThumbnailViewDeprecated;
+import com.android.quickstep.views.TaskView.TaskContainer;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.recents.model.ThumbnailData;
@@ -101,8 +101,8 @@
/**
* Create a new overlay instance for the given View
*/
- public TaskOverlayGo createOverlay(TaskThumbnailViewDeprecated thumbnailView) {
- return new TaskOverlayGo(thumbnailView, mContentRequester);
+ public TaskOverlayGo createOverlay(TaskContainer taskContainer) {
+ return new TaskOverlayGo(taskContainer, mContentRequester);
}
/**
@@ -120,9 +120,9 @@
private OverlayDialogGo mDialog;
private ArrowTipView mArrowTipView;
- private TaskOverlayGo(TaskThumbnailViewDeprecated taskThumbnailView,
+ private TaskOverlayGo(TaskContainer taskContainer,
AssistContentRequester assistContentRequester) {
- super(taskThumbnailView);
+ super(taskContainer);
mFactoryContentRequester = assistContentRequester;
mSharedPreferences = LauncherPrefs.getPrefs(mApplicationContext);
}
@@ -148,7 +148,8 @@
// Disable Overview Actions for Work Profile apps
boolean isManagedProfileTask =
UserManager.get(mApplicationContext).isManagedProfile(task.key.userId);
- boolean isAllowedByPolicy = mThumbnailView.isRealSnapshot() && !isManagedProfileTask;
+ boolean isAllowedByPolicy = mTaskContainer.getThumbnailViewDeprecated().isRealSnapshot()
+ && !isManagedProfileTask;
getActionsView().setCallbacks(new OverlayUICallbacksGoImpl(isAllowedByPolicy, task));
mTaskPackageName = task.key.getPackageName();
mSharedPreferences = LauncherPrefs.getPrefs(mApplicationContext);
@@ -162,8 +163,7 @@
int taskId = task.key.id;
mFactoryContentRequester.requestAssistContent(taskId, this::onAssistContentReceived);
- RecentsOrientedState orientedState =
- mThumbnailView.getTaskView().getRecentsView().getPagedViewOrientedState();
+ RecentsOrientedState orientedState = mTaskContainer.getTaskView().getOrientedState();
boolean isInLandscape = orientedState.getDisplayRotation() != ROTATION_0;
// show tooltips in portrait mode only
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
index d0c494c..2b68b52 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
@@ -269,8 +269,8 @@
foundTaskView,
foundTask,
taskContainer.getIconView().getDrawable(),
- taskContainer.getThumbnailView(),
- taskContainer.getThumbnailView().getThumbnail(),
+ taskContainer.getThumbnailViewDeprecated(),
+ taskContainer.getThumbnailViewDeprecated().getThumbnail(),
null /* intent */,
null /* user */,
info);
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index e379b2a..c33e4cc 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -542,16 +542,18 @@
if (mDesktopVisibilityController != null) {
mDesktopVisibilityController.unregisterSystemUiListener();
}
+ mDesktopVisibilityController = null;
if (mSplitSelectStateController != null) {
+ removeBackAnimationCallback(mSplitSelectStateController.getSplitBackHandler());
mSplitSelectStateController.onDestroy();
}
+ mSplitSelectStateController = null;
super.onDestroy();
mHotseatPredictionController.destroy();
mSplitWithKeyboardShortcutController.onDestroy();
if (mViewCapture != null) mViewCapture.close();
- removeBackAnimationCallback(mSplitSelectStateController.getSplitBackHandler());
}
@Override
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
index 1a98db1..93e4fbd 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
@@ -151,7 +151,7 @@
int sysuiFlags = 0;
TaskView tv = mOverviewPanel.getTaskViewAt(0);
if (tv != null) {
- sysuiFlags = tv.getFirstThumbnailView().getSysUiStatusNavFlags();
+ sysuiFlags = tv.getFirstThumbnailViewDeprecated().getSysUiStatusNavFlags();
}
mLauncher.getSystemUiController().updateUiState(UI_STATE_FULLSCREEN_TASK, sysuiFlags);
} else {
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java
index 26b528c..4bc3c16 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java
@@ -252,7 +252,7 @@
mTaskBeingDragged, maxDuration, currentInterpolator);
// Since the thumbnail is what is filling the screen, based the end displacement on it.
- View thumbnailView = mTaskBeingDragged.getFirstThumbnailView();
+ View thumbnailView = mTaskBeingDragged.getFirstThumbnailViewDeprecated();
mTempCords[1] = orientationHandler.getSecondaryDimension(thumbnailView);
dl.getDescendantCoordRelativeToSelf(thumbnailView, mTempCords);
mEndDisplacement = secondaryLayerDimension - mTempCords[1];
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index 10e327d..463222d 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -107,7 +107,6 @@
import com.android.launcher3.dragndrop.DragView;
import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.logging.StatsLogManager.StatsLogger;
-import com.android.launcher3.statehandlers.DesktopVisibilityController;
import com.android.launcher3.statemanager.BaseState;
import com.android.launcher3.taskbar.TaskbarThresholdUtils;
import com.android.launcher3.taskbar.TaskbarUIController;
@@ -926,7 +925,7 @@
TaskView runningTask = mRecentsView.getRunningTaskView();
TaskView centermostTask = mRecentsView.getTaskViewNearestToCenterOfScreen();
int centermostTaskFlags = centermostTask == null ? 0
- : centermostTask.getFirstThumbnailView().getSysUiStatusNavFlags();
+ : centermostTask.getFirstThumbnailViewDeprecated().getSysUiStatusNavFlags();
boolean swipeUpThresholdPassed = windowProgress > 1 - UPDATE_SYSUI_FLAGS_THRESHOLD;
boolean quickswitchThresholdPassed = centermostTask != runningTask;
@@ -1478,7 +1477,7 @@
? SysUiStatsLog.LAUNCHER_UICHANGED__INPUT_TYPE__TRACKPAD
: SysUiStatsLog.LAUNCHER_UICHANGED__INPUT_TYPE__TOUCH);
if (targetTask != null) {
- logger.withItemInfo(targetTask.getItemInfo());
+ logger.withItemInfo(targetTask.getFirstItemInfo());
}
int pageIndex = endTarget == LAST_TASK || mRecentsView == null
@@ -2424,7 +2423,8 @@
RemoteAnimationTarget taskTarget = taskTargetOptional.get();
TaskView taskView = mRecentsView == null
? null : mRecentsView.getTaskViewByTaskId(taskTarget.taskId);
- if (taskView == null || !taskView.getFirstThumbnailView().shouldShowSplashView()) {
+ if (taskView == null
+ || !taskView.getFirstThumbnailViewDeprecated().shouldShowSplashView()) {
ActiveGestureLog.INSTANCE.addLog("Invalid task view splash state");
finishRecentsAnimationOnTasksAppeared(null /* onFinishComplete */);
return;
diff --git a/quickstep/src/com/android/quickstep/DesktopSystemShortcut.kt b/quickstep/src/com/android/quickstep/DesktopSystemShortcut.kt
index fdf4574..50a06fc 100644
--- a/quickstep/src/com/android/quickstep/DesktopSystemShortcut.kt
+++ b/quickstep/src/com/android/quickstep/DesktopSystemShortcut.kt
@@ -29,24 +29,24 @@
/** A menu item, "Desktop", that allows the user to bring the current app into Desktop Windowing. */
class DesktopSystemShortcut(
container: RecentsViewContainer,
- private val mTaskContainer: TaskContainer,
+ private val taskContainer: TaskContainer,
abstractFloatingViewHelper: AbstractFloatingViewHelper
) :
SystemShortcut<RecentsViewContainer>(
R.drawable.ic_caption_desktop_button_foreground,
R.string.recent_task_option_desktop,
container,
- mTaskContainer.itemInfo,
- mTaskContainer.taskView,
+ taskContainer.itemInfo,
+ taskContainer.taskView,
abstractFloatingViewHelper
) {
override fun onClick(view: View) {
dismissTaskMenuView()
- val recentsView = mTarget!!.getOverviewPanel<RecentsView<*, *>>()
- recentsView.moveTaskToDesktop(mTaskContainer) {
+ val recentsView = mTarget.getOverviewPanel<RecentsView<*, *>>()
+ recentsView.moveTaskToDesktop(taskContainer) {
mTarget.statsLogManager
.logger()
- .withItemInfo(mTaskContainer.itemInfo)
+ .withItemInfo(taskContainer.itemInfo)
.log(LauncherEvent.LAUNCHER_SYSTEM_SHORTCUT_DESKTOP_TAP)
}
}
diff --git a/quickstep/src/com/android/quickstep/TaskOverlayFactory.java b/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
index 1a46fb6..b183ae3 100644
--- a/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
+++ b/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
@@ -80,8 +80,9 @@
return shortcuts;
}
- public TaskOverlay createOverlay(TaskThumbnailViewDeprecated thumbnailView) {
- return new TaskOverlay(thumbnailView);
+ /** Creates a {@link TaskOverlay} associated with the provide {@link TaskContainer}. */
+ public TaskOverlay<?> createOverlay(TaskContainer taskContainer) {
+ return new TaskOverlay<>(taskContainer);
}
/**
@@ -124,28 +125,29 @@
public static class TaskOverlay<T extends OverviewActionsView> {
protected final Context mApplicationContext;
- protected final TaskThumbnailViewDeprecated mThumbnailView;
+ protected final TaskContainer mTaskContainer;
private T mActionsView;
protected ImageActionsApi mImageApi;
- protected TaskOverlay(TaskThumbnailViewDeprecated taskThumbnailViewDeprecated) {
- mApplicationContext = taskThumbnailViewDeprecated.getContext().getApplicationContext();
- mThumbnailView = taskThumbnailViewDeprecated;
+ protected TaskOverlay(TaskContainer taskContainer) {
+ mApplicationContext = taskContainer.getTaskView().getContext().getApplicationContext();
+ mTaskContainer = taskContainer;
mImageApi = new ImageActionsApi(
- mApplicationContext, mThumbnailView::getThumbnail);
+ mApplicationContext, mTaskContainer.getThumbnailViewDeprecated()::getThumbnail);
}
protected T getActionsView() {
if (mActionsView == null) {
- mActionsView = BaseActivity.fromContext(mThumbnailView.getContext()).findViewById(
+ mActionsView = BaseActivity.fromContext(
+ mTaskContainer.getThumbnailViewDeprecated().getContext()).findViewById(
R.id.overview_actions_view);
}
return mActionsView;
}
public TaskThumbnailViewDeprecated getThumbnailView() {
- return mThumbnailView;
+ return mTaskContainer.getThumbnailViewDeprecated();
}
/**
@@ -157,7 +159,8 @@
if (thumbnail != null) {
getActionsView().updateDisabledFlags(DISABLED_ROTATED, rotated);
- boolean isAllowedByPolicy = mThumbnailView.isRealSnapshot();
+ boolean isAllowedByPolicy =
+ mTaskContainer.getThumbnailViewDeprecated().isRealSnapshot();
getActionsView().setCallbacks(new OverlayUICallbacksImpl(isAllowedByPolicy, task));
}
}
@@ -168,7 +171,8 @@
* @param callback callback to run, after switching to screenshot
*/
public void endLiveTileMode(@NonNull Runnable callback) {
- RecentsView recentsView = mThumbnailView.getTaskView().getRecentsView();
+ RecentsView recentsView =
+ mTaskContainer.getThumbnailViewDeprecated().getTaskView().getRecentsView();
// Task has already been dismissed
if (recentsView == null) return;
recentsView.switchToScreenshot(
@@ -181,8 +185,8 @@
*/
@SuppressLint("NewApi")
protected void saveScreenshot(Task task) {
- if (mThumbnailView.isRealSnapshot()) {
- mImageApi.saveScreenshot(mThumbnailView.getThumbnail(),
+ if (mTaskContainer.getThumbnailViewDeprecated().isRealSnapshot()) {
+ mImageApi.saveScreenshot(mTaskContainer.getThumbnailViewDeprecated().getThumbnail(),
getTaskSnapshotBounds(), getTaskSnapshotInsets(), task.key);
} else {
showBlockedByPolicyMessage();
@@ -190,14 +194,17 @@
}
protected void enterSplitSelect() {
- RecentsView overviewPanel = mThumbnailView.getTaskView().getRecentsView();
+ RecentsView overviewPanel =
+ mTaskContainer.getThumbnailViewDeprecated().getTaskView().getRecentsView();
// Task has already been dismissed
if (overviewPanel == null) return;
- overviewPanel.initiateSplitSelect(mThumbnailView.getTaskView());
+ overviewPanel.initiateSplitSelect(
+ mTaskContainer.getThumbnailViewDeprecated().getTaskView());
}
protected void saveAppPair() {
- GroupedTaskView taskView = (GroupedTaskView) mThumbnailView.getTaskView();
+ GroupedTaskView taskView =
+ (GroupedTaskView) mTaskContainer.getThumbnailViewDeprecated().getTaskView();
taskView.getRecentsView().getSplitSelectController().getAppPairsController()
.saveAppPair(taskView);
}
@@ -243,10 +250,11 @@
*/
public Rect getTaskSnapshotBounds() {
int[] location = new int[2];
- mThumbnailView.getLocationOnScreen(location);
+ mTaskContainer.getThumbnailViewDeprecated().getLocationOnScreen(location);
- return new Rect(location[0], location[1], mThumbnailView.getWidth() + location[0],
- mThumbnailView.getHeight() + location[1]);
+ return new Rect(location[0], location[1],
+ mTaskContainer.getThumbnailViewDeprecated().getWidth() + location[0],
+ mTaskContainer.getThumbnailViewDeprecated().getHeight() + location[1]);
}
/**
@@ -256,7 +264,7 @@
*/
@RequiresApi(api = Build.VERSION_CODES.Q)
public Insets getTaskSnapshotInsets() {
- return mThumbnailView.getScaledInsets();
+ return mTaskContainer.getThumbnailViewDeprecated().getScaledInsets();
}
/**
@@ -267,17 +275,21 @@
protected void showBlockedByPolicyMessage() {
ActivityContext activityContext = ActivityContext.lookupContext(
- mThumbnailView.getContext());
+ mTaskContainer.getThumbnailViewDeprecated().getContext());
String message = activityContext.getStringCache() != null
? activityContext.getStringCache().disabledByAdminMessage
- : mThumbnailView.getContext().getString(R.string.blocked_by_policy);
+ : mTaskContainer.getThumbnailViewDeprecated().getContext().getString(
+ R.string.blocked_by_policy);
- Snackbar.show(BaseActivity.fromContext(mThumbnailView.getContext()), message, null);
+ Snackbar.show(BaseActivity.fromContext(
+ mTaskContainer.getThumbnailViewDeprecated().getContext()), message, null);
}
/** Called when the snapshot has updated its full screen drawing parameters. */
- public void setFullscreenParams(TaskView.FullscreenDrawParams fullscreenParams) {
- }
+ public void setFullscreenParams(TaskView.FullscreenDrawParams fullscreenParams) {}
+
+ /** Sets visibility for the overlay associated elements. */
+ public void setVisibility(int visibility) {}
private class ScreenshotSystemShortcut extends SystemShortcut {
@@ -292,7 +304,8 @@
@Override
public void onClick(View view) {
- saveScreenshot(mThumbnailView.getTaskView().getFirstTask());
+ saveScreenshot(
+ mTaskContainer.getThumbnailViewDeprecated().getTaskView().getFirstTask());
dismissTaskMenuView();
}
}
diff --git a/quickstep/src/com/android/quickstep/TaskShortcutFactory.java b/quickstep/src/com/android/quickstep/TaskShortcutFactory.java
index 537f432..4b5c826 100644
--- a/quickstep/src/com/android/quickstep/TaskShortcutFactory.java
+++ b/quickstep/src/com/android/quickstep/TaskShortcutFactory.java
@@ -128,7 +128,8 @@
public SplitSelectSystemShortcut(RecentsViewContainer container, TaskView taskView,
SplitPositionOption option) {
- super(option.iconResId, option.textResId, container, taskView.getItemInfo(), taskView);
+ super(option.iconResId, option.textResId, container, taskView.getFirstItemInfo(),
+ taskView);
mTaskView = taskView;
mSplitPositionOption = option;
}
@@ -149,8 +150,8 @@
public SaveAppPairSystemShortcut(RecentsViewContainer container, GroupedTaskView taskView,
int iconResId) {
- super(iconResId, R.string.save_app_pair, container,
- taskView.getItemInfo(), taskView);
+ super(iconResId, R.string.save_app_pair, container, taskView.getFirstItemInfo(),
+ taskView);
mTaskView = taskView;
}
@@ -180,7 +181,7 @@
mHandler = new Handler(Looper.getMainLooper());
mTaskView = taskContainer.getTaskView();
mRecentsView = container.getOverviewPanel();
- mThumbnailView = taskContainer.getThumbnailView();
+ mThumbnailView = taskContainer.getThumbnailViewDeprecated();
}
@Override
@@ -240,7 +241,7 @@
overridePendingAppTransitionMultiThumbFuture(
future, animStartedListener, mHandler, true /* scaleUp */,
taskKey.displayId);
- mTarget.getStatsLogManager().logger().withItemInfo(mTaskView.getItemInfo())
+ mTarget.getStatsLogManager().logger().withItemInfo(mTaskView.getFirstItemInfo())
.log(mLauncherEvent);
}
}
@@ -424,7 +425,7 @@
mTaskView.getFirstTask().key.id);
}
dismissTaskMenuView();
- mTarget.getStatsLogManager().logger().withItemInfo(mTaskView.getItemInfo())
+ mTarget.getStatsLogManager().logger().withItemInfo(mTaskView.getFirstItemInfo())
.log(LauncherEvent.LAUNCHER_SYSTEM_SHORTCUT_PIN_TAP);
}
}
@@ -469,10 +470,8 @@
}
}
- SystemShortcut screenshotShortcut =
- taskContainer.getThumbnailView().getTaskOverlay()
- .getScreenshotShortcut(container, taskContainer.getItemInfo(),
- taskContainer.getTaskView());
+ SystemShortcut screenshotShortcut = taskContainer.getOverlay().getScreenshotShortcut(
+ container, taskContainer.getItemInfo(), taskContainer.getTaskView());
return createSingletonShortcutList(screenshotShortcut);
}
@@ -503,9 +502,8 @@
}
SystemShortcut modalStateSystemShortcut =
- taskContainer.getThumbnailView().getTaskOverlay()
- .getModalStateSystemShortcut(
- taskContainer.getItemInfo(), taskContainer.getTaskView());
+ taskContainer.getOverlay().getModalStateSystemShortcut(
+ taskContainer.getItemInfo(), taskContainer.getTaskView());
return createSingletonShortcutList(modalStateSystemShortcut);
}
};
diff --git a/quickstep/src/com/android/quickstep/util/SplitAnimationController.kt b/quickstep/src/com/android/quickstep/util/SplitAnimationController.kt
index 40ea70f..8243ede 100644
--- a/quickstep/src/com/android/quickstep/util/SplitAnimationController.kt
+++ b/quickstep/src/com/android/quickstep/util/SplitAnimationController.kt
@@ -118,8 +118,8 @@
if (container.task.getKey().getId() == splitSelectStateController.initialTaskId) {
val drawable = getDrawable(container.iconView, splitSelectSource)
return SplitAnimInitProps(
- container.thumbnailView,
- container.thumbnailView.thumbnail,
+ container.thumbnailViewDeprecated,
+ container.thumbnailViewDeprecated.thumbnail,
drawable!!,
fadeWithThumbnail = true,
isStagedTask = true,
@@ -137,8 +137,8 @@
taskView.taskContainers.first().let {
val drawable = getDrawable(it.iconView, splitSelectSource)
return SplitAnimInitProps(
- it.thumbnailView,
- it.thumbnailView.thumbnail,
+ it.thumbnailViewDeprecated,
+ it.thumbnailViewDeprecated.thumbnail,
drawable!!,
fadeWithThumbnail = true,
isStagedTask = true,
@@ -182,7 +182,7 @@
taskViewHeight: Int,
isPrimaryTaskSplitting: Boolean
) {
- val thumbnail = taskIdAttributeContainer.thumbnailView
+ val thumbnail = taskIdAttributeContainer.thumbnailViewDeprecated
val iconView: View = taskIdAttributeContainer.iconView.asView()
builder.add(ObjectAnimator.ofFloat(thumbnail, TaskThumbnailViewDeprecated.SPLASH_ALPHA, 1f))
thumbnail.setShowSplashForSplitSelection(true)
diff --git a/quickstep/src/com/android/quickstep/views/DesktopTaskView.kt b/quickstep/src/com/android/quickstep/views/DesktopTaskView.kt
index 3935c67..936f6a1 100644
--- a/quickstep/src/com/android/quickstep/views/DesktopTaskView.kt
+++ b/quickstep/src/com/android/quickstep/views/DesktopTaskView.kt
@@ -28,24 +28,20 @@
import android.view.ViewGroup
import androidx.core.view.updateLayoutParams
import com.android.launcher3.R
-import com.android.launcher3.util.CancellableTask
import com.android.launcher3.util.RunnableList
import com.android.launcher3.util.SplitConfigurationOptions
+import com.android.launcher3.util.TransformingTouchDelegate
import com.android.launcher3.util.ViewPool
import com.android.launcher3.util.rects.set
import com.android.quickstep.BaseContainerInterface
-import com.android.quickstep.RecentsModel
import com.android.quickstep.TaskOverlayFactory
import com.android.quickstep.util.RecentsOrientedState
import com.android.systemui.shared.recents.model.Task
-import com.android.systemui.shared.recents.model.ThumbnailData
/** TaskView that contains all tasks that are part of the desktop. */
-// TODO(b/249371338): TaskView needs to be refactored to have better support for N tasks.
class DesktopTaskView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
TaskView(context, attrs) {
- private val pendingThumbnailRequests = mutableListOf<CancellableTask<*>>()
private val snapshotDrawParams =
object : FullscreenDrawParams(context) {
// DesktopTaskView thumbnail's corner radius is independent of fullscreenProgress.
@@ -57,31 +53,39 @@
context,
this,
R.layout.task_thumbnail,
- 10,
- 0 // As DesktopTaskView is inflated in background, use initialSize=0 to avoid initPool.
+ VIEW_POOL_MAX_SIZE,
+ VIEW_POOL_INITIAL_SIZE
)
private val tempPointF = PointF()
private val tempRect = Rect()
private lateinit var backgroundView: View
+ private lateinit var iconView: TaskViewIcon
private var childCountAtInflation = 0
override fun onFinishInflate() {
super.onFinishInflate()
-
- backgroundView = findViewById(R.id.background)!!
- val topMarginPx = container.deviceProfile.overviewTaskThumbnailTopMarginPx
- backgroundView.updateLayoutParams<LayoutParams> { topMargin = topMarginPx }
-
- val outerRadii = FloatArray(8) { taskCornerRadius }
- backgroundView.background =
- ShapeDrawable(RoundRectShape(outerRadii, null, null)).apply {
- setTint(resources.getColor(android.R.color.system_neutral2_300, context.theme))
+ backgroundView =
+ findViewById<View>(R.id.background)!!.apply {
+ updateLayoutParams<LayoutParams> {
+ topMargin = container.deviceProfile.overviewTaskThumbnailTopMarginPx
+ }
+ background =
+ ShapeDrawable(RoundRectShape(FloatArray(8) { taskCornerRadius }, null, null))
+ .apply {
+ setTint(
+ resources.getColor(
+ android.R.color.system_neutral2_300,
+ context.theme
+ )
+ )
+ }
}
-
- val iconBackground = resources.getDrawable(R.drawable.bg_circle, context.theme)
- val icon = resources.getDrawable(R.drawable.ic_desktop, context.theme)
- setIcon(iconView, LayerDrawable(arrayOf(iconBackground, icon)))
-
+ iconView =
+ getOrInflateIconView(R.id.icon).apply {
+ val iconBackground = resources.getDrawable(R.drawable.bg_circle, context.theme)
+ val icon = resources.getDrawable(R.drawable.ic_desktop, context.theme)
+ setIcon(this, LayerDrawable(arrayOf(iconBackground, icon)))
+ }
childCountAtInflation = childCount
}
@@ -124,7 +128,7 @@
}
val thumbWidth = (taskSize.width() * scaleWidth).toInt()
val thumbHeight = (taskSize.height() * scaleHeight).toInt()
- it.thumbnailView.measure(
+ it.thumbnailViewDeprecated.measure(
MeasureSpec.makeMeasureSpec(thumbWidth, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(thumbHeight, MeasureSpec.EXACTLY)
)
@@ -135,8 +139,8 @@
var taskY = (positionInParent.y * scaleHeight).toInt()
// move task down by margin size
taskY += thumbnailTopMarginPx
- it.thumbnailView.x = taskX.toFloat()
- it.thumbnailView.y = taskY.toFloat()
+ it.thumbnailViewDeprecated.x = taskX.toFloat()
+ it.thumbnailViewDeprecated.y = taskY.toFloat()
if (DEBUG) {
Log.d(
TAG,
@@ -148,23 +152,10 @@
}
override fun onRecycle() {
- resetPersistentViewTransforms()
- // Clear any references to the thumbnail (it will be re-read either from the cache or the
- // system on next bind)
- taskContainers.forEach { it.thumbnailView.setThumbnail(it.task, null) }
- setOverlayEnabled(false)
- onTaskListVisibilityChanged(false)
+ super.onRecycle()
visibility = VISIBLE
}
- override fun bind(
- task: Task,
- orientedState: RecentsOrientedState,
- taskOverlayFactory: TaskOverlayFactory
- ) {
- bind(listOf(task), orientedState, taskOverlayFactory)
- }
-
/** Updates this desktop task to the gives task list defined in `tasks` */
fun bind(
tasks: List<Task>,
@@ -185,12 +176,12 @@
val taskContainers = taskContainers as ArrayList
taskContainers.ensureCapacity(tasks.size)
tasks.forEachIndexed { index, task ->
- val thumbnailView: TaskThumbnailViewDeprecated
+ val thumbnailViewDeprecated: TaskThumbnailViewDeprecated
if (index >= taskContainers.size) {
- thumbnailView = taskThumbnailViewPool.view
+ thumbnailViewDeprecated = taskThumbnailViewPool.view
// Add thumbnailView from to position after the initial child views.
addView(
- thumbnailView,
+ thumbnailViewDeprecated,
childCountAtInflation,
LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
@@ -198,17 +189,22 @@
)
)
} else {
- thumbnailView = taskContainers[index].thumbnailView
+ thumbnailViewDeprecated = taskContainers[index].thumbnailViewDeprecated
}
- thumbnailView.bind(task, taskOverlayFactory)
val taskContainer =
TaskContainer(
- task,
- thumbnailView,
- iconView,
- SplitConfigurationOptions.STAGE_POSITION_UNDEFINED,
- null
- )
+ task,
+ // TODO(b/338360089): Support new TTV for DesktopTaskView
+ thumbnailView = null,
+ thumbnailViewDeprecated,
+ iconView,
+ TransformingTouchDelegate(iconView.asView()),
+ SplitConfigurationOptions.STAGE_POSITION_UNDEFINED,
+ digitalWellBeingToast = null,
+ showWindowsView = null,
+ taskOverlayFactory
+ )
+ .apply { thumbnailViewDeprecated.bind(task, overlay) }
if (index >= taskContainers.size) {
taskContainers.add(taskContainer)
} else {
@@ -216,42 +212,20 @@
}
}
repeat(taskContainers.size - tasks.size) {
- taskContainers.removeLast().apply {
- removeView(thumbnailView)
- taskThumbnailViewPool.recycle(thumbnailView)
+ with(taskContainers.removeLast()) {
+ removeView(thumbnailViewDeprecated)
+ taskThumbnailViewPool.recycle(thumbnailViewDeprecated)
}
}
setOrientationState(orientedState)
}
+ override fun needsUpdate(dataChange: Int, flag: Int) =
+ if (flag == FLAG_UPDATE_THUMBNAIL) super.needsUpdate(dataChange, flag) else false
+
// thumbnailView is laid out differently and is handled in onMeasure
- override fun setThumbnailOrientation(orientationState: RecentsOrientedState) {}
-
- override fun onTaskListVisibilityChanged(visible: Boolean, changes: Int) {
- cancelPendingLoadTasks()
- if (needsUpdate(changes, FLAG_UPDATE_THUMBNAIL)) {
- taskContainers.forEach {
- if (visible) {
- RecentsModel.INSTANCE.get(context)
- .thumbnailCache
- .updateThumbnailInBackground(it.task) { thumbnailData: ThumbnailData ->
- it.thumbnailView.setThumbnail(it.task, thumbnailData)
- }
- ?.apply { pendingThumbnailRequests.add(this) }
- } else {
- it.thumbnailView.setThumbnail(null, null)
- // Reset the task thumbnail ref
- it.task.thumbnail = null
- }
- }
- }
- }
-
- override fun cancelPendingLoadTasks() {
- pendingThumbnailRequests.forEach { it.cancel() }
- pendingThumbnailRequests.clear()
- }
+ override fun updateThumbnailSize() {}
override fun getThumbnailBounds(bounds: Rect, relativeToDragLayer: Boolean) {
if (relativeToDragLayer) {
@@ -279,59 +253,30 @@
callback(true)
}
- override fun refreshThumbnails(thumbnailDatas: HashMap<Int, ThumbnailData?>?) {
- // Sets new thumbnails based on the incoming data and refreshes the rest.
- thumbnailDatas?.let {
- taskContainers.forEach {
- val thumbnailData = thumbnailDatas[it.task.key.id]
- if (thumbnailData != null) {
- it.thumbnailView.setThumbnail(it.task, thumbnailData)
- } else {
- // Refresh the rest that were not updated.
- it.thumbnailView.refresh()
- }
- }
- }
- }
-
// Desktop tile can't be in split screen
override fun confirmSecondSplitSelectApp(): Boolean = false
- override fun setColorTint(amount: Float, tintColor: Int) {
- taskContainers.forEach { it.thumbnailView.dimAlpha = amount }
- }
-
- override fun setThumbnailVisibility(visibility: Int, taskId: Int) {
- taskContainers.forEach { it.thumbnailView.visibility = visibility }
- }
-
// TODO(b/330685808) support overlay for Screenshot action
override fun setOverlayEnabled(overlayEnabled: Boolean) {}
override fun onFullscreenProgressChanged(fullscreenProgress: Float) {
- // TODO(b/249371338): this copies parent implementation and makes it work for N thumbs
- iconView.setVisibility(if (fullscreenProgress < 1) VISIBLE else INVISIBLE)
// Don't show background while we are transitioning to/from fullscreen
backgroundView.visibility = if (fullscreenProgress > 0) INVISIBLE else VISIBLE
- taskContainers.forEach {
- it.thumbnailView.taskOverlay.setFullscreenProgress(fullscreenProgress)
- }
- setIconsAndBannersFullscreenProgress(fullscreenProgress)
- updateSnapshotRadius()
}
- override fun updateSnapshotRadius() {
+ override fun updateCurrentFullscreenParams() {
+ super.updateCurrentFullscreenParams()
updateFullscreenParams(snapshotDrawParams)
- taskContainers.forEach { it.thumbnailView.setFullscreenParams(snapshotDrawParams) }
}
- override fun applyThumbnailSplashAlpha() {
- taskContainers.forEach { it.thumbnailView.setSplashAlpha(taskThumbnailSplashAlpha) }
- }
+ override fun getThumbnailFullscreenParams() = snapshotDrawParams
companion object {
private const val TAG = "DesktopTaskView"
private const val DEBUG = false
+ private const val VIEW_POOL_MAX_SIZE = 10
+ // As DesktopTaskView is inflated in background, use initialSize=0 to avoid initPool.
+ private const val VIEW_POOL_INITIAL_SIZE = 0
private val ORIGIN = Point(0, 0)
}
}
diff --git a/quickstep/src/com/android/quickstep/views/DigitalWellBeingToast.java b/quickstep/src/com/android/quickstep/views/DigitalWellBeingToast.java
index 4df9414..a8ebe51 100644
--- a/quickstep/src/com/android/quickstep/views/DigitalWellBeingToast.java
+++ b/quickstep/src/com/android/quickstep/views/DigitalWellBeingToast.java
@@ -320,7 +320,7 @@
(FrameLayout.LayoutParams) mBanner.getLayoutParams();
DeviceProfile deviceProfile = mContainer.getDeviceProfile();
layoutParams.bottomMargin = ((ViewGroup.MarginLayoutParams)
- mTaskView.getFirstThumbnailView().getLayoutParams()).bottomMargin;
+ mTaskView.getFirstThumbnailViewDeprecated().getLayoutParams()).bottomMargin;
RecentsPagedOrientationHandler orientationHandler = mTaskView.getPagedOrientationHandler();
Pair<Float, Float> translations = orientationHandler
.getDwbLayoutTranslations(mTaskView.getMeasuredWidth(),
diff --git a/quickstep/src/com/android/quickstep/views/GroupedTaskView.kt b/quickstep/src/com/android/quickstep/views/GroupedTaskView.kt
index f6ae038..efbfa09 100644
--- a/quickstep/src/com/android/quickstep/views/GroupedTaskView.kt
+++ b/quickstep/src/com/android/quickstep/views/GroupedTaskView.kt
@@ -18,31 +18,24 @@
import android.app.ActivityTaskManager.INVALID_TASK_ID
import android.content.Context
import android.graphics.PointF
-import android.graphics.Rect
import android.util.AttributeSet
import android.util.Log
-import android.view.MotionEvent
import android.view.View
-import android.view.ViewStub
import com.android.internal.jank.Cuj
import com.android.launcher3.Flags.enableOverviewIconMenu
import com.android.launcher3.R
import com.android.launcher3.Utilities
import com.android.launcher3.config.FeatureFlags
-import com.android.launcher3.util.CancellableTask
import com.android.launcher3.util.RunnableList
import com.android.launcher3.util.SplitConfigurationOptions
import com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT
import com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT
import com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_UNDEFINED
-import com.android.launcher3.util.TransformingTouchDelegate
-import com.android.quickstep.RecentsModel
import com.android.quickstep.TaskOverlayFactory
import com.android.quickstep.util.RecentsOrientedState
import com.android.quickstep.util.SplitScreenUtils.Companion.convertLauncherSplitBoundsToShell
import com.android.quickstep.util.SplitSelectStateController
import com.android.systemui.shared.recents.model.Task
-import com.android.systemui.shared.recents.model.ThumbnailData
import com.android.systemui.shared.recents.utilities.PreviewPositionHelper
import com.android.systemui.shared.system.InteractionJankMonitorWrapper
import com.android.wm.shell.common.split.SplitScreenConstants.PersistentSnapPosition
@@ -60,42 +53,14 @@
class GroupedTaskView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
TaskView(context, attrs) {
// TODO(b/336612373): Support new TTV for GroupedTaskView
- private val icon2CenterCoordinates = FloatArray(2)
- private val digitalWellBeingToast2: DigitalWellBeingToast =
- DigitalWellBeingToast(container, this)
-
- private lateinit var snapshotView2: TaskThumbnailViewDeprecated
- private lateinit var iconView2: TaskViewIcon
- private lateinit var icon2TouchDelegate: TransformingTouchDelegate
-
var splitBoundsConfig: SplitConfigurationOptions.SplitBounds? = null
private set
- private var thumbnailLoadRequest2: CancellableTask<ThumbnailData>? = null
- private var iconLoadRequest2: CancellableTask<*>? = null
@get:PersistentSnapPosition
val snapPosition: Int
/** Returns the [PersistentSnapPosition] of this pair of tasks. */
get() = splitBoundsConfig?.snapPosition ?: STAGE_POSITION_UNDEFINED
- @get:Deprecated("Use {@link #mTaskContainers} instead.")
- private val secondTask: Task
- /** Returns the second task bound to this TaskView. */
- get() = taskContainers[1].task
-
- override fun onFinishInflate() {
- super.onFinishInflate()
- snapshotView2 = findViewById(R.id.bottomright_snapshot)!!
- val iconViewStub2 =
- findViewById<ViewStub>(R.id.bottomRight_icon)!!.apply {
- layoutResource =
- if (enableOverviewIconMenu()) R.layout.icon_app_chip_view
- else R.layout.icon_view
- }
- iconView2 = iconViewStub2.inflate() as TaskViewIcon
- icon2TouchDelegate = TransformingTouchDelegate(iconView2.asView())
- }
-
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
val widthSize = MeasureSpec.getSize(widthMeasureSpec)
@@ -105,8 +70,8 @@
val initSplitTaskId = getThisTaskCurrentlyInSplitSelection()
if (initSplitTaskId == INVALID_TASK_ID) {
pagedOrientationHandler.measureGroupedTaskViewThumbnailBounds(
- taskThumbnailViewDeprecated,
- snapshotView2,
+ taskContainers[0].thumbnailViewDeprecated,
+ taskContainers[1].thumbnailViewDeprecated,
widthSize,
heightSize,
splitBoundsConfig,
@@ -117,20 +82,24 @@
// The following only applies to large screen for now, but for future reference
// we'd want to abstract this out in PagedViewHandlers to get the primary/secondary
// translation directions
- taskThumbnailViewDeprecated.applySplitSelectTranslateX(
- taskThumbnailViewDeprecated.translationX
- )
- taskThumbnailViewDeprecated.applySplitSelectTranslateY(
- taskThumbnailViewDeprecated.translationY
- )
- snapshotView2.applySplitSelectTranslateX(snapshotView2.translationX)
- snapshotView2.applySplitSelectTranslateY(snapshotView2.translationY)
+ taskContainers[0]
+ .thumbnailViewDeprecated
+ .applySplitSelectTranslateX(taskContainers[0].thumbnailViewDeprecated.translationX)
+ taskContainers[0]
+ .thumbnailViewDeprecated
+ .applySplitSelectTranslateY(taskContainers[0].thumbnailViewDeprecated.translationY)
+ taskContainers[1]
+ .thumbnailViewDeprecated
+ .applySplitSelectTranslateX(taskContainers[1].thumbnailViewDeprecated.translationX)
+ taskContainers[1]
+ .thumbnailViewDeprecated
+ .applySplitSelectTranslateY(taskContainers[1].thumbnailViewDeprecated.translationY)
} else {
// Currently being split with this taskView, let the non-split selected thumbnail
// take up full thumbnail area
taskContainers
.firstOrNull { it.task.key.id != initSplitTaskId }
- ?.thumbnailView
+ ?.thumbnailViewDeprecated
?.measure(
widthMeasureSpec,
MeasureSpec.makeMeasureSpec(
@@ -146,7 +115,6 @@
override fun onRecycle() {
super.onRecycle()
- snapshotView2.setThumbnail(secondTask, null)
splitBoundsConfig = null
}
@@ -158,30 +126,42 @@
splitBoundsConfig: SplitConfigurationOptions.SplitBounds?,
) {
cancelPendingLoadTasks()
- setupTaskContainers(primaryTask, taskOverlayFactory)
taskContainers =
listOf(
- taskContainers[0].apply { stagePosition = STAGE_POSITION_TOP_OR_LEFT },
- TaskContainer(
+ createTaskContainer(
+ primaryTask,
+ R.id.snapshot,
+ R.id.icon,
+ R.id.show_windows,
+ STAGE_POSITION_TOP_OR_LEFT,
+ taskOverlayFactory
+ ),
+ createTaskContainer(
secondaryTask,
- findViewById(R.id.bottomright_snapshot)!!,
- iconView2,
+ R.id.bottomright_snapshot,
+ R.id.bottomRight_icon,
+ R.id.show_windows_right,
STAGE_POSITION_BOTTOM_OR_RIGHT,
- digitalWellBeingToast2
+ taskOverlayFactory
)
)
- snapshotView2.bind(secondaryTask, taskOverlayFactory)
- this.splitBoundsConfig = splitBoundsConfig
- this.splitBoundsConfig?.let {
- taskThumbnailViewDeprecated.previewPositionHelper.setSplitBounds(
- convertLauncherSplitBoundsToShell(it),
- PreviewPositionHelper.STAGE_POSITION_TOP_OR_LEFT
- )
- snapshotView2.previewPositionHelper.setSplitBounds(
- convertLauncherSplitBoundsToShell(it),
- PreviewPositionHelper.STAGE_POSITION_BOTTOM_OR_RIGHT
- )
- }
+ this.splitBoundsConfig =
+ splitBoundsConfig?.also {
+ taskContainers[0]
+ .thumbnailViewDeprecated
+ .previewPositionHelper
+ .setSplitBounds(
+ convertLauncherSplitBoundsToShell(it),
+ PreviewPositionHelper.STAGE_POSITION_TOP_OR_LEFT
+ )
+ taskContainers[1]
+ .thumbnailViewDeprecated
+ .previewPositionHelper
+ .setSplitBounds(
+ convertLauncherSplitBoundsToShell(it),
+ PreviewPositionHelper.STAGE_POSITION_BOTTOM_OR_RIGHT
+ )
+ }
setOrientationState(orientedState)
}
@@ -206,24 +186,18 @@
val iconMargins = (iconViewMarginStart + iconViewBackgroundMarginStart) * 2
// setMaxWidth() needs to be called before mIconView.setIconOrientation which is
// called in the super below.
- (iconView as IconAppChipView).setMaxWidth(
+ (taskContainers[0].iconView as IconAppChipView).setMaxWidth(
groupedTaskViewSizes.first.x - iconMargins
)
- (iconView2 as IconAppChipView).setMaxWidth(
+ (taskContainers[1].iconView as IconAppChipView).setMaxWidth(
groupedTaskViewSizes.second.x - iconMargins
)
}
}
super.setOrientationState(orientationState)
- iconView2.setIconOrientation(orientationState, isGridTask)
updateIconPlacement()
}
- override fun setThumbnailOrientation(orientationState: RecentsOrientedState) {
- super.setThumbnailOrientation(orientationState)
- digitalWellBeingToast2.initialize(secondTask)
- }
-
private fun updateIconPlacement() {
val splitBoundsConfig = splitBoundsConfig ?: return
val taskIconHeight = container.deviceProfile.overviewTaskIconSizePx
@@ -237,8 +211,8 @@
layoutParams.height
)
pagedOrientationHandler.setSplitIconParams(
- iconView.asView(),
- iconView2.asView(),
+ taskContainers[0].iconView.asView(),
+ taskContainers[1].iconView.asView(),
taskIconHeight,
groupedTaskViewSizes.first.x,
groupedTaskViewSizes.first.y,
@@ -250,11 +224,11 @@
)
} else {
pagedOrientationHandler.setSplitIconParams(
- iconView.asView(),
- iconView2.asView(),
+ taskContainers[0].iconView.asView(),
+ taskContainers[1].iconView.asView(),
taskIconHeight,
- taskThumbnailViewDeprecated.measuredWidth,
- taskThumbnailViewDeprecated.measuredHeight,
+ taskContainers[0].thumbnailViewDeprecated.measuredWidth,
+ taskContainers[0].thumbnailViewDeprecated.measuredHeight,
measuredHeight,
measuredWidth,
isRtl,
@@ -264,104 +238,11 @@
}
}
- override fun onTaskListVisibilityChanged(visible: Boolean, changes: Int) {
- super.onTaskListVisibilityChanged(visible, changes)
- val model = RecentsModel.INSTANCE.get(context)
- if (needsUpdate(changes, FLAG_UPDATE_THUMBNAIL)) {
- if (visible) {
- thumbnailLoadRequest2 =
- model.thumbnailCache.updateThumbnailInBackground(secondTask) {
- snapshotView2.setThumbnail(secondTask, it)
- }
- } else {
- snapshotView2.setThumbnail(null, null)
- // Reset the task thumbnail reference as well (it will be fetched from the cache or
- // reloaded next time we need it)
- secondTask.thumbnail = null
- }
- }
- if (needsUpdate(changes, FLAG_UPDATE_ICON)) {
- if (visible) {
- iconLoadRequest2 =
- model.iconCache.updateIconInBackground(secondTask) {
- setIcon(iconView2, it.icon)
- if (enableOverviewIconMenu()) {
- setText(iconView2, it.title)
- }
- digitalWellBeingToast2.initialize(secondTask)
- digitalWellBeingToast2.setSplitConfiguration(splitBoundsConfig)
- digitalWellBeingToast.setSplitConfiguration(splitBoundsConfig)
- }
- } else {
- setIcon(iconView2, null)
- if (enableOverviewIconMenu()) {
- setText(iconView2, null)
- }
- }
- }
- }
-
- override fun cancelPendingLoadTasks() {
- super.cancelPendingLoadTasks()
- thumbnailLoadRequest2?.cancel()
- thumbnailLoadRequest2 = null
- iconLoadRequest2?.cancel()
- iconLoadRequest2 = null
- }
-
- override fun getThumbnailBounds(bounds: Rect, relativeToDragLayer: Boolean) {
- splitBoundsConfig ?: return super.getThumbnailBounds(bounds, relativeToDragLayer)
- if (relativeToDragLayer) {
- val firstThumbnailBounds = Rect()
- val secondThumbnailBounds = Rect()
- with(container.dragLayer) {
- getDescendantRectRelativeToSelf(snapshotView, firstThumbnailBounds)
- getDescendantRectRelativeToSelf(snapshotView2, secondThumbnailBounds)
- }
- bounds.set(firstThumbnailBounds)
- bounds.union(secondThumbnailBounds)
- } else {
- bounds.set(getSnapshotViewBounds(snapshotView))
- bounds.union(getSnapshotViewBounds(snapshotView2))
- }
- }
-
- private fun getSnapshotViewBounds(snapshotView: View): Rect {
- val snapshotViewX = Math.round(snapshotView.x)
- val snapshotViewY = Math.round(snapshotView.y)
- return Rect(
- snapshotViewX,
- snapshotViewY,
- snapshotViewX + snapshotView.width,
- snapshotViewY + snapshotView.height
- )
- }
-
- /**
- * Sets up an on-click listener and the visibility for show_windows icon on top of each task.
- */
- override fun setUpShowAllInstancesListener() {
- // sets up the listener for the left/top task
- super.setUpShowAllInstancesListener()
- // right/bottom task's base package name
- val taskPackageName = taskContainers[1].task.key.packageName
- // icon of the right/bottom task
- val showWindowsView = findViewById<View>(R.id.show_windows_right)!!
- updateFilterCallback(showWindowsView, getFilterUpdateCallback(taskPackageName))
- }
-
fun updateSplitBoundsConfig(splitBounds: SplitConfigurationOptions.SplitBounds?) {
splitBoundsConfig = splitBounds
invalidate()
}
- override fun offerTouchToChildren(event: MotionEvent): Boolean {
- computeAndSetIconTouchDelegate(iconView2, icon2CenterCoordinates, icon2TouchDelegate)
- return if (icon2TouchDelegate.onTouchEvent(event)) {
- true
- } else super.offerTouchToChildren(event)
- }
-
override fun launchTaskAnimated(): RunnableList? {
if (taskContainers.isEmpty()) {
Log.d(TAG, "launchTaskAnimated - task is not bound")
@@ -414,12 +295,6 @@
}
}
- override fun refreshThumbnails(thumbnailDatas: HashMap<Int, ThumbnailData?>?) {
- super.refreshThumbnails(thumbnailDatas)
- thumbnailDatas?.get(secondTask.key.id)?.let { snapshotView2.setThumbnail(secondTask, it) }
- ?: { snapshotView2.refresh() }
- }
-
/**
* Returns taskId that split selection was initiated with, [INVALID_TASK_ID] if no tasks in this
* TaskView are part of split selection
@@ -437,14 +312,14 @@
// checks below aren't reliable since both of those views may be gone/transformed
val initSplitTaskId = getThisTaskCurrentlyInSplitSelection()
if (initSplitTaskId != INVALID_TASK_ID) {
- return if (initSplitTaskId == firstTask.key.id) 1 else 0
+ return if (initSplitTaskId == taskContainers[0].task.key.id) 1 else 0
}
}
// Check which of the two apps was selected
if (
- iconView2.asView().containsPoint(mLastTouchDownPosition) ||
- snapshotView2.containsPoint(mLastTouchDownPosition)
+ taskContainers[1].iconView.asView().containsPoint(lastTouchDownPosition) ||
+ taskContainers[1].thumbnailViewDeprecated.containsPoint(lastTouchDownPosition)
) {
return 1
}
@@ -457,36 +332,6 @@
return Utilities.pointInView(this, localPos[0], localPos[1], 0f /* slop */)
}
- override fun setIconsAndBannersTransitionProgress(progress: Float, invert: Boolean) {
- super.setIconsAndBannersTransitionProgress(progress, invert)
- getIconContentScale(invert).let {
- iconView2.setContentAlpha(it)
- digitalWellBeingToast2.updateBannerOffset(1f - it)
- }
- }
-
- override fun setColorTint(amount: Float, tintColor: Int) {
- super.setColorTint(amount, tintColor)
- iconView2.setIconColorTint(tintColor, amount)
- snapshotView2.dimAlpha = amount
- digitalWellBeingToast2.setBannerColorTint(tintColor, amount)
- }
-
- /**
- * Sets visibility for thumbnails and associated elements (DWB banners). IconView is unaffected.
- *
- * When setting INVISIBLE, sets the visibility for the last selected child task. When setting
- * VISIBLE (as a reset), sets the visibility for both tasks.
- */
- override fun setThumbnailVisibility(visibility: Int, taskId: Int) {
- taskContainers.forEach {
- if (visibility == VISIBLE || it.task.key.id == taskId) {
- it.thumbnailView.visibility = visibility
- it.digitalWellBeingToast?.setBannerVisibility(visibility)
- }
- }
- }
-
override fun setOverlayEnabled(overlayEnabled: Boolean) {
if (FeatureFlags.enableAppPairs()) {
super.setOverlayEnabled(overlayEnabled)
@@ -495,26 +340,6 @@
}
}
- override fun refreshTaskThumbnailSplash() {
- super.refreshTaskThumbnailSplash()
- snapshotView2.refreshSplashView()
- }
-
- override fun updateSnapshotRadius() {
- super.updateSnapshotRadius()
- snapshotView2.setFullscreenParams(currentFullscreenParams)
- }
-
- override fun applyThumbnailSplashAlpha() {
- super.applyThumbnailSplashAlpha()
- snapshotView2.setSplashAlpha(taskThumbnailSplashAlpha)
- }
-
- override fun resetViewTransforms() {
- super.resetViewTransforms()
- snapshotView2.resetViewTransforms()
- }
-
companion object {
private const val TAG = "GroupedTaskView"
}
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 3c0445f..4e5d646 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -1006,7 +1006,8 @@
if (container == null || taskId != container.getTask().key.id) {
continue;
}
- container.getThumbnailView().setThumbnail(container.getTask(), thumbnailData);
+ container.getThumbnailViewDeprecated().setThumbnail(container.getTask(),
+ thumbnailData);
}
}
}
@@ -1020,8 +1021,8 @@
Task task = tv.getFirstTask();
if (pkg.equals(task.key.getPackageName()) && task.key.userId == user.getIdentifier()) {
task.icon = null;
- TaskViewIcon firstIconView = tv.getFirstIconView();
- if (firstIconView.getDrawable() != null) {
+ if (tv.getTaskContainers().stream().anyMatch(
+ container -> container.getIconView().getDrawable() != null)) {
tv.onTaskListVisibilityChanged(true /* visible */);
}
}
@@ -1058,7 +1059,7 @@
}
Task task = taskAttributes.getTask();
TaskThumbnailViewDeprecated taskThumbnailViewDeprecated =
- taskAttributes.getThumbnailView();
+ taskAttributes.getThumbnailViewDeprecated();
taskThumbnailViewDeprecated.setThumbnail(task, thumbnail, refreshNow);
// thumbnailData can contain 1-2 ids, but they should correspond to the same
// TaskView, so overwriting is ok
@@ -3832,7 +3833,7 @@
announceForAccessibility(
getResources().getString(R.string.task_view_closed));
mContainer.getStatsLogManager().logger()
- .withItemInfo(dismissedTaskView.getItemInfo())
+ .withItemInfo(dismissedTaskView.getFirstItemInfo())
.log(LAUNCHER_TASK_DISMISS_SWIPE_UP);
}
@@ -4743,7 +4744,8 @@
*/
public void resetModalVisuals() {
if (mSelectedTask != null) {
- mSelectedTask.getFirstThumbnailView().getTaskOverlay().resetModalVisuals();
+ mSelectedTask.taskContainers.forEach(
+ taskContainer -> taskContainer.getOverlay().resetModalVisuals());
}
}
@@ -4761,8 +4763,8 @@
public void initiateSplitSelect(TaskView taskView, @StagePosition int stagePosition,
StatsLogManager.EventEnum splitEvent) {
mSplitHiddenTaskView = taskView;
- mSplitSelectStateController.setInitialTaskSelect(null /*intent*/,
- stagePosition, taskView.getItemInfo(), splitEvent, taskView.getFirstTask().key.id);
+ mSplitSelectStateController.setInitialTaskSelect(null /*intent*/, stagePosition,
+ taskView.getFirstItemInfo(), splitEvent, taskView.getFirstTask().key.id);
mSplitSelectStateController.setAnimateCurrentTaskDismissal(
true /*animateCurrentTaskDismissal*/);
mSplitHiddenTaskViewIndex = indexOfChild(taskView);
@@ -4815,7 +4817,7 @@
== mSplitSelectStateController.getInitialTaskId();
TaskContainer taskContainer = mSplitHiddenTaskView
.getTaskContainers().get(primaryTaskSelected ? 1 : 0);
- TaskThumbnailViewDeprecated thumbnail = taskContainer.getThumbnailView();
+ TaskThumbnailViewDeprecated thumbnail = taskContainer.getThumbnailViewDeprecated();
mSplitSelectStateController.getSplitAnimationController()
.addInitialSplitFromPair(taskContainer, builder,
mContainer.getDeviceProfile(),
@@ -5215,7 +5217,7 @@
updateGridProperties();
updateScrollSynchronously();
- int targetSysUiFlags = tv.getFirstThumbnailView().getSysUiStatusNavFlags();
+ int targetSysUiFlags = tv.getFirstThumbnailViewDeprecated().getSysUiStatusNavFlags();
final boolean[] passedOverviewThreshold = new boolean[] {false};
ValueAnimator progressAnim = ValueAnimator.ofFloat(0, 1);
progressAnim.addUpdateListener(animator -> {
@@ -5279,7 +5281,7 @@
} else {
tv.launchTask(this::onTaskLaunchAnimationEnd);
}
- mContainer.getStatsLogManager().logger().withItemInfo(tv.getItemInfo())
+ mContainer.getStatsLogManager().logger().withItemInfo(tv.getFirstItemInfo())
.log(LAUNCHER_TASK_LAUNCH_SWIPE_DOWN);
} else {
onTaskLaunchAnimationEnd(false);
@@ -5917,7 +5919,7 @@
ThumbnailData td =
mRecentsAnimationController.screenshotTask(container.getTask().key.id);
- TaskThumbnailViewDeprecated thumbnailView = container.getThumbnailView();
+ TaskThumbnailViewDeprecated thumbnailView = container.getThumbnailViewDeprecated();
if (td != null) {
thumbnailView.setThumbnail(container.getTask(), td);
} else {
diff --git a/quickstep/src/com/android/quickstep/views/TaskMenuView.java b/quickstep/src/com/android/quickstep/views/TaskMenuView.java
index 578d471..59ffc39 100644
--- a/quickstep/src/com/android/quickstep/views/TaskMenuView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskMenuView.java
@@ -241,12 +241,13 @@
mContainer.getDragLayer().getDescendantRectRelativeToSelf(
enableOverviewIconMenu()
? getIconView().findViewById(R.id.icon_view_menu_anchor)
- : taskContainer.getThumbnailView(),
+ : taskContainer.getThumbnailViewDeprecated(),
sTempRect);
Rect insets = mContainer.getDragLayer().getInsets();
BaseDragLayer.LayoutParams params = (BaseDragLayer.LayoutParams) getLayoutParams();
- params.width = orientationHandler.getTaskMenuWidth(taskContainer.getThumbnailView(),
- deviceProfile, taskContainer.getStagePosition());
+ params.width = orientationHandler.getTaskMenuWidth(
+ taskContainer.getThumbnailViewDeprecated(), deviceProfile,
+ taskContainer.getStagePosition());
// Gravity set to Left instead of Start as sTempRect.left measures Left distance not Start
params.gravity = Gravity.LEFT;
setLayoutParams(params);
@@ -279,10 +280,10 @@
// Margin that insets the menuView inside the taskView
float taskInsetMargin = getResources().getDimension(R.dimen.task_card_margin);
setTranslationX(orientationHandler.getTaskMenuX(thumbnailAlignedX,
- mTaskContainer.getThumbnailView(), deviceProfile, taskInsetMargin,
+ mTaskContainer.getThumbnailViewDeprecated(), deviceProfile, taskInsetMargin,
getIconView()));
setTranslationY(orientationHandler.getTaskMenuY(
- thumbnailAlignedY, mTaskContainer.getThumbnailView(),
+ thumbnailAlignedY, mTaskContainer.getThumbnailViewDeprecated(),
mTaskContainer.getStagePosition(), this, taskInsetMargin,
getIconView()));
}
@@ -367,7 +368,7 @@
}
mOpenCloseAnimator.playTogether(mRevealAnimator,
ObjectAnimator.ofFloat(
- mTaskContainer.getThumbnailView(), DIM_ALPHA,
+ mTaskContainer.getThumbnailViewDeprecated(), DIM_ALPHA,
closing ? 0 : TaskView.MAX_PAGE_SCRIM_ALPHA),
ObjectAnimator.ofFloat(this, ALPHA, closing ? 0 : 1));
mOpenCloseAnimator.addListener(new AnimationSuccessListener() {
diff --git a/quickstep/src/com/android/quickstep/views/TaskThumbnailViewDeprecated.java b/quickstep/src/com/android/quickstep/views/TaskThumbnailViewDeprecated.java
index fed6af5..447002f 100644
--- a/quickstep/src/com/android/quickstep/views/TaskThumbnailViewDeprecated.java
+++ b/quickstep/src/com/android/quickstep/views/TaskThumbnailViewDeprecated.java
@@ -54,7 +54,6 @@
import com.android.launcher3.util.SystemUiController;
import com.android.launcher3.util.SystemUiController.SystemUiControllerFlags;
import com.android.launcher3.util.ViewPool;
-import com.android.quickstep.TaskOverlayFactory;
import com.android.quickstep.TaskOverlayFactory.TaskOverlay;
import com.android.quickstep.orientation.RecentsPagedOrientationHandler;
import com.android.quickstep.views.TaskView.FullscreenDrawParams;
@@ -129,9 +128,7 @@
};
private final RecentsViewContainer mContainer;
- private TaskOverlayFactory mTaskOverlayFactory;
- @Nullable
- private TaskOverlay mOverlay;
+ private TaskOverlay<?> mOverlay;
private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private final Paint mBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private final Paint mSplashBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
@@ -190,9 +187,9 @@
/**
* Updates the thumbnail to draw the provided task
*/
- public void bind(Task task, TaskOverlayFactory taskOverlayFactory) {
- mTaskOverlayFactory = taskOverlayFactory;
- getTaskOverlay().reset();
+ public void bind(Task task, TaskOverlay<?> overlay) {
+ mOverlay = overlay;
+ mOverlay.reset();
mTask = task;
int color = task == null ? Color.BLACK : task.colorBackground | 0xFF000000;
mPaint.setColor(color);
@@ -202,14 +199,14 @@
}
/**
- * Sets TaskOverlayFactory without binding a task.
+ * Sets TaskOverlay without binding a task.
*
* @deprecated Should only be used when using new
* {@link com.android.quickstep.task.thumbnail.TaskThumbnailView}.
*/
@Deprecated
- public void setTaskOverlayFactory(TaskOverlayFactory taskOverlayFactory) {
- mTaskOverlayFactory = taskOverlayFactory;
+ public void setTaskOverlay(TaskOverlay<?> overlay) {
+ mOverlay = overlay;
}
/**
@@ -265,7 +262,7 @@
mBitmapShader = null;
mThumbnailData = null;
mPaint.setShader(null);
- getTaskOverlay().reset();
+ mOverlay.reset();
}
updateThumbnailPaintFilter();
}
@@ -293,13 +290,6 @@
invalidate();
}
- public TaskOverlay getTaskOverlay() {
- if (mOverlay == null) {
- mOverlay = mTaskOverlayFactory.createOverlay(this);
- }
- return mOverlay;
- }
-
public float getDimAlpha() {
return mDimAlpha;
}
@@ -374,7 +364,6 @@
public void setFullscreenParams(TaskView.FullscreenDrawParams fullscreenParams) {
mFullscreenParams = fullscreenParams;
- getTaskOverlay().setFullscreenParams(fullscreenParams);
invalidate();
}
@@ -551,10 +540,10 @@
*/
private void refreshOverlay() {
if (mOverlayEnabled) {
- getTaskOverlay().initOverlay(mTask, mThumbnailData, mPreviewPositionHelper.getMatrix(),
+ mOverlay.initOverlay(mTask, mThumbnailData, mPreviewPositionHelper.getMatrix(),
mPreviewPositionHelper.isOrientationChanged());
} else {
- getTaskOverlay().reset();
+ mOverlay.reset();
}
}
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.kt b/quickstep/src/com/android/quickstep/views/TaskView.kt
index baeaa87..1490fd0 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.kt
+++ b/quickstep/src/com/android/quickstep/views/TaskView.kt
@@ -42,7 +42,6 @@
import android.widget.Toast
import androidx.annotation.IntDef
import androidx.annotation.VisibleForTesting
-import androidx.core.view.children
import androidx.core.view.updateLayoutParams
import com.android.app.animation.Interpolators
import com.android.launcher3.Flags.enableCursorHoverStates
@@ -57,6 +56,7 @@
import com.android.launcher3.Utilities
import com.android.launcher3.config.FeatureFlags.ENABLE_KEYBOARD_QUICK_SWITCH
import com.android.launcher3.logging.StatsLogManager.LauncherEvent
+import com.android.launcher3.model.data.ItemInfo
import com.android.launcher3.model.data.ItemInfoWithIcon
import com.android.launcher3.model.data.WorkspaceItemInfo
import com.android.launcher3.pm.UserCache
@@ -79,6 +79,7 @@
import com.android.quickstep.RemoteAnimationTargets
import com.android.quickstep.TaskAnimationManager
import com.android.quickstep.TaskOverlayFactory
+import com.android.quickstep.TaskOverlayFactory.TaskOverlay
import com.android.quickstep.TaskUtils
import com.android.quickstep.TaskViewUtils
import com.android.quickstep.orientation.RecentsPagedOrientationHandler
@@ -132,7 +133,7 @@
/** Returns a copy of integer array containing taskIds of all tasks in the TaskView. */
get() = taskContainers.map { it.task.key.id }.toIntArray()
val thumbnailViews: Array<TaskThumbnailViewDeprecated>
- get() = taskContainers.map { it.thumbnailView }.toTypedArray()
+ get() = taskContainers.map { it.thumbnailViewDeprecated }.toTypedArray()
val isGridTask: Boolean
/** Returns whether the task is part of overview grid and not being focused. */
get() = container.deviceProfile.isTablet && !isFocusedTask
@@ -147,27 +148,22 @@
val pagedOrientationHandler: RecentsPagedOrientationHandler
get() = orientedState.orientationHandler
- @get:Deprecated("Use {@link #mTaskContainers} instead.")
+ @get:Deprecated("Use [taskContainers] instead.")
val firstTask: Task
/** Returns the first task bound to this TaskView. */
get() = taskContainers[0].task
- @get:Deprecated("Use {@link #mTaskContainers} instead.")
- val firstThumbnailView: TaskThumbnailViewDeprecated
+ @get:Deprecated("Use [taskContainers] instead.")
+ val firstThumbnailViewDeprecated: TaskThumbnailViewDeprecated
/** Returns the first thumbnailView of the TaskView. */
- get() = taskContainers[0].thumbnailView
- @get:Deprecated("Use {@link #mTaskContainers} instead.")
- val firstIconView: TaskViewIcon
- /** Returns the first iconView of the TaskView. */
- get() = taskContainers[0].iconView
- protected val currentFullscreenParams = FullscreenDrawParams(context)
+ get() = taskContainers[0].thumbnailViewDeprecated
+ @get:Deprecated("Use [taskContainers] instead.")
+ val firstItemInfo: ItemInfo
+ get() = taskContainers[0].itemInfo
+
+ private val currentFullscreenParams = FullscreenDrawParams(context)
protected val container: RecentsViewContainer =
RecentsViewContainer.containerFromContext(context)
- @VisibleForTesting(otherwise = VisibleForTesting.PROTECTED)
- val digitalWellBeingToast = DigitalWellBeingToast(container, this)
- protected val mLastTouchDownPosition = PointF()
- protected val snapshotView: View
- get() =
- if (enableRefactorTaskThumbnail()) taskThumbnailView!! else taskThumbnailViewDeprecated
+ protected val lastTouchDownPosition = PointF()
// Derived view properties
protected val persistentScale: Float
@@ -228,9 +224,9 @@
TASK_RESISTANCE_TRANSLATION_Y
)
- private val mIconCenterCoordinates = FloatArray(2)
- private val mFocusBorderAnimator: BorderAnimator?
- private val mHoverBorderAnimator: BorderAnimator?
+ private val tempCoordinates = FloatArray(2)
+ private val focusBorderAnimator: BorderAnimator?
+ private val hoverBorderAnimator: BorderAnimator?
private val rootViewDisplayId: Int
get() = rootView.display?.displayId ?: Display.DEFAULT_DISPLAY
@@ -238,16 +234,6 @@
lateinit var taskContainers: List<TaskContainer>
protected set
lateinit var orientedState: RecentsOrientedState
- protected lateinit var taskThumbnailViewDeprecated: TaskThumbnailViewDeprecated
- protected lateinit var iconView: TaskViewIcon
- /**
- * This technically can be a vanilla [android.view.TouchDelegate] class, however that class
- * requires setting the touch bounds at construction, so we'd repeatedly be created many
- * instances unnecessarily as scrolling occurs, whereas [TransformingTouchDelegate] allows touch
- * delegated bounds only to be updated.
- */
- private lateinit var iconTouchDelegate: TransformingTouchDelegate
- private var taskThumbnailView: TaskThumbnailView? = null
var taskViewId = -1
var isEndQuickSwitchCuj = false
@@ -382,26 +368,26 @@
field = value
// Set the animation correctly in case it misses the hover/focus event during state
// transition
- mHoverBorderAnimator?.setBorderVisibility(visible = field && isHovered, animated = true)
- mFocusBorderAnimator?.setBorderVisibility(visible = field && isFocused, animated = true)
+ hoverBorderAnimator?.setBorderVisibility(visible = field && isHovered, animated = true)
+ focusBorderAnimator?.setBorderVisibility(visible = field && isFocused, animated = true)
}
protected var iconScaleAnimStartProgress = 0f
private var focusTransitionProgress = 1f
private var iconAndDimAnimator: ObjectAnimator? = null
// The current background requests to load the task thumbnail and icon
- private var thumbnailLoadRequest: CancellableTask<*>? = null
- private var iconLoadRequest: CancellableTask<*>? = null
+ private val pendingThumbnailLoadRequests = mutableListOf<CancellableTask<*>>()
+ private val pendingIconLoadRequests = mutableListOf<CancellableTask<*>>()
private var isClickableAsLiveTile = true
init {
- setOnClickListener { view: View -> onClick(view) }
+ setOnClickListener { _ -> onClick() }
val keyboardFocusHighlightEnabled =
(ENABLE_KEYBOARD_QUICK_SWITCH.get() || enableFocusOutline())
val cursorHoverStatesEnabled = enableCursorHoverStates()
setWillNotDraw(!keyboardFocusHighlightEnabled && !cursorHoverStatesEnabled)
context.obtainStyledAttributes(attrs, R.styleable.TaskView, defStyleAttr, defStyleRes).use {
- mFocusBorderAnimator =
+ this.focusBorderAnimator =
focusBorderAnimator
?: if (keyboardFocusHighlightEnabled)
createSimpleBorderAnimator(
@@ -417,7 +403,7 @@
)
)
else null
- mHoverBorderAnimator =
+ this.hoverBorderAnimator =
hoverBorderAnimator
?: if (cursorHoverStatesEnabled)
createSimpleBorderAnimator(
@@ -436,28 +422,6 @@
}
}
- override fun onFinishInflate() {
- super.onFinishInflate()
- taskThumbnailViewDeprecated = findViewById(R.id.snapshot)!!
- if (enableRefactorTaskThumbnail()) {
- val indexOfSnapshotView = indexOfChild(taskThumbnailViewDeprecated)
- taskThumbnailView =
- TaskThumbnailView(mContext).apply {
- layoutParams = taskThumbnailViewDeprecated.layoutParams
- addView(this, indexOfSnapshotView)
- }
- taskThumbnailViewDeprecated.visibility = GONE
- }
- val iconViewStub =
- findViewById<ViewStub>(R.id.icon)!!.apply {
- layoutResource =
- if (enableOverviewIconMenu()) R.layout.icon_app_chip_view
- else R.layout.icon_view
- }
- iconView = iconViewStub.inflate() as TaskViewIcon
- iconTouchDelegate = TransformingTouchDelegate(iconView.asView())
- }
-
@VisibleForTesting(otherwise = VisibleForTesting.PROTECTED)
public override fun onFocusChanged(
gainFocus: Boolean,
@@ -466,7 +430,7 @@
) {
super.onFocusChanged(gainFocus, direction, previouslyFocusedRect)
if (borderEnabled) {
- mFocusBorderAnimator?.setBorderVisibility(gainFocus, /* animated= */ true)
+ focusBorderAnimator?.setBorderVisibility(gainFocus, /* animated= */ true)
}
}
@@ -474,9 +438,9 @@
if (borderEnabled) {
when (event.action) {
MotionEvent.ACTION_HOVER_ENTER ->
- mHoverBorderAnimator?.setBorderVisibility(visible = true, animated = true)
+ hoverBorderAnimator?.setBorderVisibility(visible = true, animated = true)
MotionEvent.ACTION_HOVER_EXIT ->
- mHoverBorderAnimator?.setBorderVisibility(visible = false, animated = true)
+ hoverBorderAnimator?.setBorderVisibility(visible = false, animated = true)
else -> {}
}
}
@@ -491,16 +455,15 @@
override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
val recentsView = recentsView ?: return false
val splitSelectStateController = recentsView.splitSelectController
- // Disable taps for split selection animation unless we have multiple tasks
+ // Disable taps for split selection animation unless we have a task not being selected
if (
splitSelectStateController.isSplitSelectActive &&
- splitSelectStateController.initialTaskId == firstTask.key.id &&
- !containsMultipleTasks()
+ taskContainers.none { it.task.key.id != splitSelectStateController.initialTaskId }
) {
return false
}
if (ev.action == MotionEvent.ACTION_DOWN) {
- mLastTouchDownPosition.apply {
+ with(lastTouchDownPosition) {
x = ev.x
y = ev.y
}
@@ -510,8 +473,8 @@
override fun draw(canvas: Canvas) {
// Draw border first so any child views outside of the thumbnail bounds are drawn above it.
- mFocusBorderAnimator?.drawBorder(canvas)
- mHoverBorderAnimator?.drawBorder(canvas)
+ focusBorderAnimator?.drawBorder(canvas)
+ hoverBorderAnimator?.drawBorder(canvas)
super.draw(canvas)
}
@@ -540,7 +503,7 @@
if (enableRefactorTaskThumbnail()) {
notifyIsRunningTaskUpdated()
} else {
- taskThumbnailViewDeprecated.setThumbnail(firstTask, null)
+ taskContainers.forEach { it.thumbnailViewDeprecated.setThumbnail(it.task, null) }
}
setOverlayEnabled(false)
onTaskListVisibilityChanged(false)
@@ -566,7 +529,8 @@
}
}
}
- if (digitalWellBeingToast.hasLimit()) {
+ // TODO(b/341672022): handle multiple digitalWellBeingToast accessibility actions
+ if (taskContainers[0].digitalWellBeingToast?.hasLimit() == true) {
addAction(
AccessibilityNodeInfo.AccessibilityAction(
R.string.accessibility_app_usage_settings,
@@ -593,7 +557,8 @@
return true
}
if (action == R.string.accessibility_app_usage_settings) {
- digitalWellBeingToast.openAppUsageSettings(this)
+ // TODO(b/341672022): handle multiple digitalWellBeingToast accessibility actions
+ taskContainers[0].digitalWellBeingToast?.openAppUsageSettings(this)
return true
}
taskContainers.forEach {
@@ -614,27 +579,73 @@
taskOverlayFactory: TaskOverlayFactory
) {
cancelPendingLoadTasks()
- setupTaskContainers(task, taskOverlayFactory)
+ taskContainers =
+ listOf(
+ createTaskContainer(
+ task,
+ R.id.snapshot,
+ R.id.icon,
+ R.id.show_windows,
+ STAGE_POSITION_UNDEFINED,
+ taskOverlayFactory
+ )
+ )
setOrientationState(orientedState)
}
- protected fun setupTaskContainers(task: Task, taskOverlayFactory: TaskOverlayFactory) {
- taskContainers =
- listOf(
- TaskContainer(
- task,
- taskThumbnailViewDeprecated,
- iconView,
- STAGE_POSITION_UNDEFINED,
- digitalWellBeingToast
- )
- )
+ protected fun createTaskContainer(
+ task: Task,
+ @IdRes thumbnailViewId: Int,
+ @IdRes iconViewId: Int,
+ @IdRes showWindowViewId: Int,
+ @StagePosition stagePosition: Int,
+ taskOverlayFactory: TaskOverlayFactory
+ ): TaskContainer {
+ val thumbnailViewDeprecated: TaskThumbnailViewDeprecated = findViewById(thumbnailViewId)!!
+ val thumbnailView: TaskThumbnailView?
if (enableRefactorTaskThumbnail()) {
- taskThumbnailViewDeprecated.setTaskOverlayFactory(taskOverlayFactory)
- bindTaskThumbnailView()
+ val indexOfSnapshotView = indexOfChild(thumbnailViewDeprecated)
+ thumbnailView =
+ TaskThumbnailView(context).apply {
+ layoutParams = thumbnailViewDeprecated.layoutParams
+ addView(this, indexOfSnapshotView)
+ }
+ thumbnailViewDeprecated.visibility = GONE
} else {
- taskThumbnailViewDeprecated.bind(task, taskOverlayFactory)
+ thumbnailView = null
}
+ val iconView = getOrInflateIconView(iconViewId)
+ return TaskContainer(
+ task,
+ thumbnailView,
+ thumbnailViewDeprecated,
+ iconView,
+ TransformingTouchDelegate(iconView.asView()),
+ stagePosition,
+ DigitalWellBeingToast(container, this),
+ findViewById(showWindowViewId)!!,
+ taskOverlayFactory
+ )
+ .apply {
+ if (enableRefactorTaskThumbnail()) {
+ thumbnailViewDeprecated.setTaskOverlay(overlay)
+ bindThumbnailView()
+ } else {
+ thumbnailViewDeprecated.bind(task, overlay)
+ }
+ }
+ }
+
+ protected fun getOrInflateIconView(@IdRes iconViewId: Int): TaskViewIcon {
+ val iconView = findViewById<View>(iconViewId)!!
+ return iconView as? TaskViewIcon
+ ?: (iconView as ViewStub)
+ .apply {
+ layoutResource =
+ if (enableOverviewIconMenu()) R.layout.icon_app_chip_view
+ else R.layout.icon_view
+ }
+ .inflate() as TaskViewIcon
}
protected fun isTaskContainersInitialized() = this::taskContainers.isInitialized
@@ -650,31 +661,17 @@
/** Check if given `taskId` is tracked in this view */
fun containsTaskId(taskId: Int) = getTaskContainerById(taskId) != null
- // TODO(b/335649589): TaskView's VM will already have access to TaskThumbnailView's VM
- // so there will be no need to access TaskThumbnailView's VM through the TaskThumbnailView
- private fun bindTaskThumbnailView() {
- taskThumbnailView!!.viewModel.bind(TaskThumbnail(firstTask, isRunningTask))
- }
-
open fun setOrientationState(orientationState: RecentsOrientedState) {
this.orientedState = orientationState
- iconView.setIconOrientation(orientationState, isGridTask)
+ taskContainers.forEach { it.iconView.setIconOrientation(orientationState, isGridTask) }
setThumbnailOrientation(orientationState)
}
protected open fun setThumbnailOrientation(orientationState: RecentsOrientedState) {
- val thumbnailTopMargin = container.deviceProfile.overviewTaskThumbnailTopMarginPx
-
- // TODO(b/271468547), we should default to setting translations only on the snapshot instead
- // of a hybrid of both margins and translations
- snapshotView.updateLayoutParams<LayoutParams> { topMargin = thumbnailTopMargin }
-
- // TODO(b/335606129) Investigate the usage of [TaskOverlay] in the new TaskThumbnailView.
- // and if it's still necessary we should support that in the new TTV class.
- if (!enableRefactorTaskThumbnail()) {
- taskThumbnailViewDeprecated.taskOverlay.updateOrientationState(orientationState)
+ taskContainers.forEach {
+ it.overlay.updateOrientationState(orientationState)
+ it.digitalWellBeingToast?.initialize(it.task)
}
- digitalWellBeingToast.initialize(firstTask)
}
/**
@@ -696,7 +693,6 @@
if (container.deviceProfile.isTablet) {
val boxWidth: Int
val boxHeight: Int
- val isFocusedTask = isFocusedTask
if (isFocusedTask) {
// Task will be focused and should use focused task size. Use focusTaskRatio
// that is associated with the original orientation of the focused task.
@@ -736,19 +732,29 @@
width = expectedWidth
height = expectedHeight
}
+ updateThumbnailSize()
+ }
+
+ protected open fun updateThumbnailSize() {
+ // TODO(b/271468547), we should default to setting translations only on the snapshot instead
+ // of a hybrid of both margins and translations
+ taskContainers[0].snapshotView.updateLayoutParams<LayoutParams> {
+ topMargin = container.deviceProfile.overviewTaskThumbnailTopMarginPx
+ }
}
/** Returns the thumbnail's bounds, optionally relative to the screen. */
@JvmOverloads
open fun getThumbnailBounds(bounds: Rect, relativeToDragLayer: Boolean = false) {
- val snapshotView = snapshotView
- if (relativeToDragLayer) {
- container.dragLayer.getDescendantRectRelativeToSelf(snapshotView, bounds)
- } else {
- bounds.apply {
- set(snapshotView)
- offset(Math.round(snapshotView.translationX), Math.round(snapshotView.translationY))
+ bounds.setEmpty()
+ taskContainers.forEach {
+ val thumbnailBounds = Rect()
+ if (relativeToDragLayer) {
+ container.dragLayer.getDescendantRectRelativeToSelf(it.snapshotView, bounds)
+ } else {
+ thumbnailBounds.set(it.snapshotView)
}
+ bounds.union(thumbnailBounds)
}
}
@@ -768,42 +774,45 @@
*/
open fun onTaskListVisibilityChanged(visible: Boolean, @TaskDataChanges changes: Int) {
cancelPendingLoadTasks()
- val model = RecentsModel.INSTANCE.get(context)
+ val recentsModel = RecentsModel.INSTANCE.get(context)
// These calls are no-ops if the data is already loaded, try and load the high
// resolution thumbnail if the state permits
if (needsUpdate(changes, FLAG_UPDATE_THUMBNAIL)) {
- if (visible) {
- thumbnailLoadRequest =
- model.thumbnailCache.updateThumbnailInBackground(firstTask) {
- if (!enableRefactorTaskThumbnail()) {
- // TODO(b/334825222) add thumbnail state
- taskThumbnailViewDeprecated.setThumbnail(firstTask, it)
- }
+ if (!enableRefactorTaskThumbnail()) {
+ // TODO(b/334825222) add thumbnail state
+ taskContainers.forEach {
+ if (visible) {
+ recentsModel.thumbnailCache
+ .updateThumbnailInBackground(it.task) { thumbnailData ->
+ it.thumbnailViewDeprecated.setThumbnail(it.task, thumbnailData)
+ }
+ ?.also { request -> pendingThumbnailLoadRequests.add(request) }
+ } else {
+ it.thumbnailViewDeprecated.setThumbnail(null, null)
+ // Reset the task thumbnail reference as well (it will be fetched from the
+ // cache or reloaded next time we need it)
+ it.task.thumbnail = null
}
- } else {
- if (!enableRefactorTaskThumbnail()) {
- // TODO(b/334825222) add thumbnail state
- taskThumbnailViewDeprecated.setThumbnail(null, null)
}
- // Reset the task thumbnail reference as well (it will be fetched from the cache or
- // reloaded next time we need it)
- firstTask.thumbnail = null
}
}
if (needsUpdate(changes, FLAG_UPDATE_ICON)) {
- if (visible) {
- iconLoadRequest =
- model.iconCache.updateIconInBackground(firstTask) {
- setIcon(iconView, it.icon)
- if (enableOverviewIconMenu()) {
- setText(iconView, it.title)
+ taskContainers.forEach {
+ if (visible) {
+ recentsModel.iconCache
+ .updateIconInBackground(it.task) { thumbnailData ->
+ setIcon(it.iconView, thumbnailData.icon)
+ if (enableOverviewIconMenu()) {
+ setText(it.iconView, thumbnailData.title)
+ }
+ it.digitalWellBeingToast?.initialize(thumbnailData)
}
- digitalWellBeingToast.initialize(it)
+ ?.also { request -> pendingIconLoadRequests.add(request) }
+ } else {
+ setIcon(it.iconView, null)
+ if (enableOverviewIconMenu()) {
+ setText(it.iconView, null)
}
- } else {
- setIcon(iconView, null)
- if (enableOverviewIconMenu()) {
- setText(iconView, null)
}
}
}
@@ -812,14 +821,14 @@
}
}
- protected fun needsUpdate(@TaskDataChanges dataChange: Int, @TaskDataChanges flag: Int) =
+ protected open fun needsUpdate(@TaskDataChanges dataChange: Int, @TaskDataChanges flag: Int) =
(dataChange and flag) == flag
protected open fun cancelPendingLoadTasks() {
- thumbnailLoadRequest?.cancel()
- thumbnailLoadRequest = null
- iconLoadRequest?.cancel()
- iconLoadRequest = null
+ pendingThumbnailLoadRequests.forEach { it.cancel() }
+ pendingThumbnailLoadRequests.clear()
+ pendingIconLoadRequests.forEach { it.cancel() }
+ pendingIconLoadRequests.clear()
}
protected fun setIcon(iconView: TaskViewIcon, icon: Drawable?) {
@@ -852,13 +861,18 @@
// TODO(b/334825222) add thumbnail logic
return
}
- thumbnailDatas?.get(firstTask.key.id)?.let {
- taskThumbnailViewDeprecated.setThumbnail(firstTask, it)
+
+ taskContainers.forEach {
+ val thumbnailData = thumbnailDatas?.get(it.task.key.id)
+ if (thumbnailData != null) {
+ it.thumbnailViewDeprecated.setThumbnail(it.task, thumbnailData)
+ } else {
+ it.thumbnailViewDeprecated.refresh()
+ }
}
- ?: { taskThumbnailViewDeprecated.refresh() }
}
- private fun onClick(view: View) {
+ private fun onClick() {
if (confirmSecondSplitSelectApp()) {
Log.d("b/310064698", "${taskIds.contentToString()} - onClick - split select is active")
return
@@ -872,7 +886,7 @@
Log.d("b/310064698", "${taskIds.contentToString()} - onClick - callbackList: $callbackList")
container.statsLogManager
.logger()
- .withItemInfo(getItemInfo())
+ .withItemInfo(firstItemInfo)
.log(LauncherEvent.LAUNCHER_TASK_LAUNCH_TAP)
}
@@ -893,7 +907,7 @@
}
if (
ActivityManagerWrapper.getInstance()
- .startActivityFromRecents(firstTask.key, opts.options)
+ .startActivityFromRecents(taskContainers[0].task.key, opts.options)
) {
Log.d(
TAG,
@@ -937,12 +951,13 @@
"startActivityFromRecentsAsync",
taskIds.contentToString()
)
+ val firstContainer = taskContainers[0]
val failureListener = TaskRemovedDuringLaunchListener(context.applicationContext)
if (isQuickSwitch) {
// We only listen for failures to launch in quickswitch because the during this
// gesture launcher is in the background state, vs other launches which are in
// the actual overview state
- failureListener.register(container, firstTask.key.id) {
+ failureListener.register(container, firstContainer.task.key.id) {
notifyTaskLaunchFailed()
recentsView?.let {
// Disable animations for now, as it is an edge case and the app usually
@@ -976,12 +991,14 @@
}
// TODO(b/334826842) add splash functionality to new TTV
if (!enableRefactorTaskThumbnail()) {
- disableStartingWindow = taskThumbnailViewDeprecated.shouldShowSplashView()
+ disableStartingWindow =
+ firstContainer.thumbnailViewDeprecated.shouldShowSplashView()
}
}
Executors.UI_HELPER_EXECUTOR.execute {
if (
- !ActivityManagerWrapper.getInstance().startActivityFromRecents(firstTask.key, opts)
+ !ActivityManagerWrapper.getInstance()
+ .startActivityFromRecents(firstContainer.task.key, opts)
) {
// If the call to start activity failed, then post the result immediately,
// otherwise, wait for the animation start callback from the activity options
@@ -1039,7 +1056,7 @@
return runnableList
}
val runnableList = RunnableList()
- AnimatorSet().apply {
+ with(AnimatorSet()) {
TaskViewUtils.composeRecentsLaunchAnimator(
this,
this@TaskView,
@@ -1054,7 +1071,7 @@
addListener(
object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animator: Animator) {
- if (firstTask.key.displayId != rootViewDisplayId) {
+ if (taskContainers.any { it.task.key.displayId != rootViewDisplayId }) {
launchTaskAnimated()
}
isClickableAsLiveTile = true
@@ -1078,10 +1095,11 @@
}
private fun notifyTaskLaunchFailed() {
- Log.w(
- TAG,
- "Failed to launch task (task=${firstTask.key.baseIntent} userId=${firstTask.key.userId})"
- )
+ val sb = StringBuilder("Failed to launch task \n")
+ taskContainers.forEach {
+ sb.append("(task=${it.task.key.baseIntent} userId=${it.task.key.userId})\n")
+ }
+ Log.w(TAG, sb.toString())
Toast.makeText(context, R.string.activity_not_available, Toast.LENGTH_SHORT).show()
}
@@ -1108,8 +1126,8 @@
this,
container.task,
container.iconView.drawable,
- container.thumbnailView,
- container.thumbnailView.thumbnail, /* intent */
+ container.thumbnailViewDeprecated,
+ container.thumbnailViewDeprecated.thumbnail, /* intent */
null, /* user */
null,
container.itemInfo
@@ -1172,41 +1190,23 @@
}
}
- @Deprecated("Use {@link #getItemInfo(Task)} instead.")
- /** Builds proto for logging. */
- fun getItemInfo() = getItemInfo(firstTask)
-
- /** Builds proto for logging */
- @VisibleForTesting
- fun getItemInfo(task: Task): WorkspaceItemInfo {
- return WorkspaceItemInfo().apply {
- itemType = LauncherSettings.Favorites.ITEM_TYPE_TASK
- container = LauncherSettings.Favorites.CONTAINER_TASKSWITCHER
- val componentKey = TaskUtils.getLaunchComponentKeyForTask(task.key)
- user = componentKey.user
- intent = Intent().setComponent(componentKey.componentName)
- title = task.title
- recentsView?.let { screenId = it.indexOfChild(this@TaskView) }
- if (privateSpaceRestrictAccessibilityDrag()) {
- if (UserCache.getInstance(context).getUserInfo(componentKey.user).isPrivate) {
- runtimeStatusFlags = runtimeStatusFlags or ItemInfoWithIcon.FLAG_NOT_PINNABLE
- }
- }
- }
- }
-
/**
* Whether the taskview should take the touch event from parent. Events passed to children that
* might require special handling.
*/
open fun offerTouchToChildren(event: MotionEvent): Boolean {
- if (event.action == MotionEvent.ACTION_DOWN) {
- computeAndSetIconTouchDelegate(iconView, mIconCenterCoordinates, iconTouchDelegate)
+ taskContainers.forEach {
+ if (event.action == MotionEvent.ACTION_DOWN) {
+ computeAndSetIconTouchDelegate(it.iconView, tempCoordinates, it.iconTouchDelegate)
+ if (it.iconTouchDelegate.onTouchEvent(event)) {
+ return true
+ }
+ }
}
- return iconTouchDelegate.onTouchEvent(event)
+ return false
}
- protected fun computeAndSetIconTouchDelegate(
+ private fun computeAndSetIconTouchDelegate(
view: TaskViewIcon,
tempCenterCoordinates: FloatArray,
transformingTouchDelegate: TransformingTouchDelegate
@@ -1232,10 +1232,14 @@
/** Sets up an on-click listener and the visibility for show_windows icon on top of the task. */
open fun setUpShowAllInstancesListener() {
- val taskPackageName = taskContainers[0].task.key.packageName
- // icon of the top/left task
- val showWindowsView = findViewById<View>(R.id.show_windows)!!
- updateFilterCallback(showWindowsView, getFilterUpdateCallback(taskPackageName))
+ taskContainers.forEach {
+ it.showWindowsView?.let { showWindowsView ->
+ updateFilterCallback(
+ showWindowsView,
+ getFilterUpdateCallback(it.task.key.packageName)
+ )
+ }
+ }
}
/**
@@ -1243,7 +1247,7 @@
*
* @param taskPackageName package name of the task to filter by
*/
- protected fun getFilterUpdateCallback(taskPackageName: String?) =
+ private fun getFilterUpdateCallback(taskPackageName: String?) =
if (recentsView?.filterState?.shouldShowFilterUI(taskPackageName) == true)
OnClickListener { recentsView?.setAndApplyFilter(taskPackageName) }
else null
@@ -1252,11 +1256,13 @@
* Sets the correct visibility and callback on the provided filterView based on whether the
* callback is null or not
*/
- protected fun updateFilterCallback(filterView: View, callback: OnClickListener?) {
+ private fun updateFilterCallback(filterView: View, callback: OnClickListener?) {
// Filtering changes alpha instead of the visibility since visibility
// can be altered separately through RecentsView#resetFromSplitSelectionState()
- filterView.alpha = if (callback == null) 0f else 1f
- filterView.setOnClickListener(callback)
+ with(filterView) {
+ alpha = if (callback == null) 0f else 1f
+ setOnClickListener(callback)
+ }
}
protected open fun setIconsAndBannersFullscreenProgress(progress: Float) {
@@ -1275,12 +1281,14 @@
protected open fun setIconsAndBannersTransitionProgress(progress: Float, invert: Boolean) {
focusTransitionProgress = if (invert) 1 - progress else progress
getIconContentScale(invert).let { iconContentScale ->
- iconView.setContentAlpha(iconContentScale)
- digitalWellBeingToast.updateBannerOffset(1f - iconContentScale)
+ taskContainers.forEach {
+ it.iconView.setContentAlpha(iconContentScale)
+ it.digitalWellBeingToast?.updateBannerOffset(1f - iconContentScale)
+ }
}
}
- protected fun getIconContentScale(invert: Boolean): Float {
+ private fun getIconContentScale(invert: Boolean): Float {
val iconScalePercentage = SCALE_ICON_DURATION.toFloat() / DIM_ANIM_DURATION
val lowerClamp = if (invert) 1f - iconScalePercentage else 0f
val upperClamp = if (invert) 1f else iconScalePercentage
@@ -1312,12 +1320,14 @@
/** Set a color tint on the snapshot and supporting views. */
open fun setColorTint(amount: Float, tintColor: Int) {
- if (!enableRefactorTaskThumbnail()) {
- // TODO(b/334832108) Add scrim to new TTV
- taskThumbnailViewDeprecated.setDimAlpha(amount)
+ taskContainers.forEach {
+ if (!enableRefactorTaskThumbnail()) {
+ // TODO(b/334832108) Add scrim to new TTV
+ it.thumbnailViewDeprecated.dimAlpha = amount
+ }
+ it.iconView.setIconColorTint(tintColor, amount)
+ it.digitalWellBeingToast?.setBannerColorTint(tintColor, amount)
}
- iconView.setIconColorTint(tintColor, amount)
- digitalWellBeingToast.setBannerColorTint(tintColor, amount)
}
/**
@@ -1327,21 +1337,28 @@
* @param taskId is only used when setting visibility to a non-[View.VISIBLE] value
*/
open fun setThumbnailVisibility(visibility: Int, taskId: Int) {
- children.filterNot { it === iconView }.forEach { it.visibility = visibility }
+ taskContainers.forEach {
+ if (visibility == VISIBLE || it.task.key.id == taskId) {
+ it.snapshotView.visibility = visibility
+ it.digitalWellBeingToast?.setBannerVisibility(visibility)
+ it.showWindowsView?.visibility = visibility
+ it.overlay.setVisibility(visibility)
+ }
+ }
}
open fun setOverlayEnabled(overlayEnabled: Boolean) {
// TODO(b/335606129) Investigate the usage of [TaskOverlay] in the new TaskThumbnailView.
// and if it's still necessary we should support that in the new TTV class.
if (!enableRefactorTaskThumbnail()) {
- taskThumbnailViewDeprecated.setOverlayEnabled(overlayEnabled)
+ taskContainers.forEach { it.thumbnailViewDeprecated.setOverlayEnabled(overlayEnabled) }
}
}
protected open fun refreshTaskThumbnailSplash() {
if (!enableRefactorTaskThumbnail()) {
// TODO(b/334826842) add splash functionality to new TTV
- taskThumbnailViewDeprecated.refreshSplashView()
+ taskContainers.forEach { it.thumbnailViewDeprecated.refreshSplashView() }
}
}
@@ -1365,7 +1382,9 @@
protected open fun applyThumbnailSplashAlpha() {
if (!enableRefactorTaskThumbnail()) {
// TODO(b/334826842) add splash functionality to new TTV
- taskThumbnailViewDeprecated.setSplashAlpha(taskThumbnailSplashAlpha)
+ taskContainers.forEach {
+ it.thumbnailViewDeprecated.setSplashAlpha(taskThumbnailSplashAlpha)
+ }
}
}
@@ -1395,18 +1414,23 @@
}
protected open fun onFullscreenProgressChanged(fullscreenProgress: Float) {
- iconView.setVisibility(if (fullscreenProgress < 1) VISIBLE else INVISIBLE)
- taskThumbnailViewDeprecated.taskOverlay.setFullscreenProgress(fullscreenProgress)
+ taskContainers.forEach {
+ it.iconView.setVisibility(if (fullscreenProgress < 1) VISIBLE else INVISIBLE)
+ it.overlay.setFullscreenProgress(fullscreenProgress)
+ }
setIconsAndBannersFullscreenProgress(fullscreenProgress)
updateSnapshotRadius()
}
protected open fun updateSnapshotRadius() {
updateCurrentFullscreenParams()
- taskThumbnailViewDeprecated.setFullscreenParams(currentFullscreenParams)
+ taskContainers.forEach {
+ it.thumbnailViewDeprecated.setFullscreenParams(getThumbnailFullscreenParams())
+ it.overlay.setFullscreenParams(getThumbnailFullscreenParams())
+ }
}
- protected fun updateCurrentFullscreenParams() {
+ protected open fun updateCurrentFullscreenParams() {
updateFullscreenParams(currentFullscreenParams)
}
@@ -1414,18 +1438,21 @@
recentsView?.let { fullscreenParams.setProgress(fullscreenProgress, it.scaleX, scaleX) }
}
+ protected open fun getThumbnailFullscreenParams(): FullscreenDrawParams =
+ currentFullscreenParams
+
private fun onModalnessUpdated(modalness: Float) {
- iconView.setModalAlpha(1 - modalness)
- digitalWellBeingToast.updateBannerOffset(modalness)
+ taskContainers.forEach {
+ it.iconView.setModalAlpha(1 - modalness)
+ it.digitalWellBeingToast?.updateBannerOffset(modalness)
+ }
}
/** Updates [TaskThumbnailView] to reflect the latest [Task] state (i.e., task isRunning). */
fun notifyIsRunningTaskUpdated() {
// TODO(b/335649589): TaskView's VM will already have access to TaskThumbnailView's VM
// so there will be no need to access TaskThumbnailView's VM through the TaskThumbnailView
- if (taskContainers.isNotEmpty()) {
- bindTaskThumbnailView()
- }
+ taskContainers.forEach { it.bindThumbnailView() }
}
fun resetPersistentViewTransforms() {
@@ -1458,7 +1485,7 @@
setColorTint(0f, 0)
if (!enableRefactorTaskThumbnail()) {
// TODO(b/335399428) add split select functionality to new TTV
- taskThumbnailViewDeprecated.resetViewTransforms()
+ taskContainers.forEach { it.thumbnailViewDeprecated.resetViewTransforms() }
}
}
@@ -1508,21 +1535,61 @@
/** Holder for all Task dependent information. */
inner class TaskContainer(
val task: Task,
- val thumbnailView: TaskThumbnailViewDeprecated,
+ val thumbnailView: TaskThumbnailView?,
+ val thumbnailViewDeprecated: TaskThumbnailViewDeprecated,
val iconView: TaskViewIcon,
+ /**
+ * This technically can be a vanilla [android.view.TouchDelegate] class, however that class
+ * requires setting the touch bounds at construction, so we'd repeatedly be created many
+ * instances unnecessarily as scrolling occurs, whereas [TransformingTouchDelegate] allows
+ * touch delegated bounds only to be updated.
+ */
+ val iconTouchDelegate: TransformingTouchDelegate,
/** Defaults to STAGE_POSITION_UNDEFINED if in not a split screen task view */
- @field:StagePosition var stagePosition: Int,
- val digitalWellBeingToast: DigitalWellBeingToast?
+ @StagePosition val stagePosition: Int,
+ val digitalWellBeingToast: DigitalWellBeingToast?,
+ val showWindowsView: View?,
+ taskOverlayFactory: TaskOverlayFactory
) {
+ val overlay: TaskOverlay<*> = taskOverlayFactory.createOverlay(this)
+
@IdRes
val a11yNodeId: Int =
if (stagePosition == STAGE_POSITION_BOTTOM_OR_RIGHT) R.id.split_bottomRight_appInfo
else R.id.split_topLeft_appInfo
+ val snapshotView: View
+ get() = thumbnailView ?: thumbnailViewDeprecated
+
+ /** Builds proto for logging */
val itemInfo: WorkspaceItemInfo
- get() = getItemInfo(task)
+ get() =
+ WorkspaceItemInfo().apply {
+ itemType = LauncherSettings.Favorites.ITEM_TYPE_TASK
+ container = LauncherSettings.Favorites.CONTAINER_TASKSWITCHER
+ val componentKey = TaskUtils.getLaunchComponentKeyForTask(task.key)
+ user = componentKey.user
+ intent = Intent().setComponent(componentKey.componentName)
+ title = task.title
+ recentsView?.let { screenId = it.indexOfChild(this@TaskView) }
+ if (privateSpaceRestrictAccessibilityDrag()) {
+ if (
+ UserCache.getInstance(context).getUserInfo(componentKey.user).isPrivate
+ ) {
+ runtimeStatusFlags =
+ runtimeStatusFlags or ItemInfoWithIcon.FLAG_NOT_PINNABLE
+ }
+ }
+ }
+
val taskView: TaskView
get() = this@TaskView
+
+ // TODO(b/335649589): TaskView's VM will already have access to TaskThumbnailView's VM
+ // so there will be no need to access TaskThumbnailView's VM through the TaskThumbnailView
+ fun bindThumbnailView() {
+ thumbnailView?.viewModel?.bind(TaskThumbnail(task, isRunningTask))
+ }
}
companion object {
diff --git a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimatorTest.kt b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimatorTest.kt
index c54755b..49e54fb 100644
--- a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimatorTest.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimatorTest.kt
@@ -299,6 +299,7 @@
InstrumentationRegistry.getInstrumentation().runOnMainSync {}
PhysicsAnimatorTestUtils.blockUntilAnimationsEnd(DynamicAnimation.TRANSLATION_Y)
+ InstrumentationRegistry.getInstrumentation().waitForIdleSync()
assertThat(bubbleBarView.isAnimatingNewBubble).isFalse()
assertThat(bubbleBarView.alpha).isEqualTo(0)
assertThat(handle.translationY).isEqualTo(0)
diff --git a/quickstep/tests/src/com/android/quickstep/FullscreenDrawParamsTest.kt b/quickstep/tests/multivalentTests/src/com/android/quickstep/FullscreenDrawParamsTest.kt
similarity index 100%
rename from quickstep/tests/src/com/android/quickstep/FullscreenDrawParamsTest.kt
rename to quickstep/tests/multivalentTests/src/com/android/quickstep/FullscreenDrawParamsTest.kt
diff --git a/quickstep/tests/src/com/android/quickstep/HotseatWidthCalculationTest.kt b/quickstep/tests/multivalentTests/src/com/android/quickstep/HotseatWidthCalculationTest.kt
similarity index 100%
rename from quickstep/tests/src/com/android/quickstep/HotseatWidthCalculationTest.kt
rename to quickstep/tests/multivalentTests/src/com/android/quickstep/HotseatWidthCalculationTest.kt
diff --git a/quickstep/tests/src/com/android/quickstep/util/AppPairsControllerTest.kt b/quickstep/tests/multivalentTests/src/com/android/quickstep/util/AppPairsControllerTest.kt
similarity index 100%
rename from quickstep/tests/src/com/android/quickstep/util/AppPairsControllerTest.kt
rename to quickstep/tests/multivalentTests/src/com/android/quickstep/util/AppPairsControllerTest.kt
diff --git a/quickstep/tests/src/com/android/quickstep/util/RecentsOrientedStateTest.java b/quickstep/tests/multivalentTests/src/com/android/quickstep/util/RecentsOrientedStateTest.java
similarity index 100%
rename from quickstep/tests/src/com/android/quickstep/util/RecentsOrientedStateTest.java
rename to quickstep/tests/multivalentTests/src/com/android/quickstep/util/RecentsOrientedStateTest.java
diff --git a/quickstep/tests/src/com/android/quickstep/util/SplitAnimationControllerTest.kt b/quickstep/tests/multivalentTests/src/com/android/quickstep/util/SplitAnimationControllerTest.kt
similarity index 98%
rename from quickstep/tests/src/com/android/quickstep/util/SplitAnimationControllerTest.kt
rename to quickstep/tests/multivalentTests/src/com/android/quickstep/util/SplitAnimationControllerTest.kt
index f29df61..250dc7b 100644
--- a/quickstep/tests/src/com/android/quickstep/util/SplitAnimationControllerTest.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/util/SplitAnimationControllerTest.kt
@@ -87,7 +87,7 @@
@Before
fun setup() {
- whenever(mockTaskContainer.thumbnailView).thenReturn(mockThumbnailView)
+ whenever(mockTaskContainer.thumbnailViewDeprecated).thenReturn(mockThumbnailView)
whenever(mockThumbnailView.thumbnail).thenReturn(mockBitmap)
whenever(mockTaskContainer.iconView).thenReturn(mockIconView)
whenever(mockIconView.drawable).thenReturn(mockTaskViewDrawable)
@@ -180,7 +180,7 @@
whenever(mockTaskContainer.task).thenReturn(mockTask)
whenever(mockTaskContainer.iconView).thenReturn(mockIconView)
- whenever(mockTaskContainer.thumbnailView).thenReturn(mockThumbnailView)
+ whenever(mockTaskContainer.thumbnailViewDeprecated).thenReturn(mockThumbnailView)
whenever(mockTask.getKey()).thenReturn(mockTaskKey)
whenever(mockTaskKey.getId()).thenReturn(taskId)
whenever(mockSplitSelectStateController.initialTaskId).thenReturn(taskId)
diff --git a/quickstep/tests/src/com/android/quickstep/DesktopSystemShortcutTest.kt b/quickstep/tests/src/com/android/quickstep/DesktopSystemShortcutTest.kt
index 33a8e79..36f2ccf 100644
--- a/quickstep/tests/src/com/android/quickstep/DesktopSystemShortcutTest.kt
+++ b/quickstep/tests/src/com/android/quickstep/DesktopSystemShortcutTest.kt
@@ -19,7 +19,7 @@
import android.content.ComponentName
import android.content.Intent
import android.platform.test.flag.junit.SetFlagsRule
-import com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn
+import com.android.dx.mockito.inline.extended.ExtendedMockito
import com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession
import com.android.dx.mockito.inline.extended.StaticMockitoSession
import com.android.launcher3.AbstractFloatingView
@@ -29,6 +29,8 @@
import com.android.launcher3.model.data.WorkspaceItemInfo
import com.android.launcher3.uioverrides.QuickstepLauncher
import com.android.launcher3.util.SplitConfigurationOptions
+import com.android.launcher3.util.TransformingTouchDelegate
+import com.android.quickstep.TaskOverlayFactory.TaskOverlay
import com.android.quickstep.views.LauncherRecentsView
import com.android.quickstep.views.TaskThumbnailViewDeprecated
import com.android.quickstep.views.TaskView
@@ -43,8 +45,10 @@
import org.junit.Rule
import org.junit.Test
import org.mockito.kotlin.any
+import org.mockito.kotlin.doReturn
import org.mockito.kotlin.eq
import org.mockito.kotlin.mock
+import org.mockito.kotlin.spy
import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever
import org.mockito.quality.Strictness
@@ -61,10 +65,13 @@
private val taskView: TaskView = mock()
private val workspaceItemInfo: WorkspaceItemInfo = mock()
private val abstractFloatingViewHelper: AbstractFloatingViewHelper = mock()
- private val thumbnailView: TaskThumbnailViewDeprecated = mock()
+ private val thumbnailViewDeprecated: TaskThumbnailViewDeprecated = mock()
private val iconView: TaskViewIcon = mock()
+ private val transformingTouchDelegate: TransformingTouchDelegate = mock()
private val factory: TaskShortcutFactory =
DesktopSystemShortcut.createFactory(abstractFloatingViewHelper)
+ private val overlayFactory: TaskOverlayFactory = mock()
+ private val overlay: TaskOverlay<*> = mock()
private lateinit var mockitoSession: StaticMockitoSession
@@ -75,8 +82,9 @@
.strictness(Strictness.LENIENT)
.spyStatic(DesktopModeStatus::class.java)
.startMocking()
- doReturn(true).`when` { DesktopModeStatus.enforceDeviceRestrictions() }
- doReturn(true).`when` { DesktopModeStatus.isDesktopModeSupported(any()) }
+ ExtendedMockito.doReturn(true).`when` { DesktopModeStatus.enforceDeviceRestrictions() }
+ ExtendedMockito.doReturn(true).`when` { DesktopModeStatus.isDesktopModeSupported(any()) }
+ whenever(overlayFactory.createOverlay(any())).thenReturn(overlay)
}
@After
@@ -92,14 +100,7 @@
Task(TaskKey(1, 0, Intent(), ComponentName("", ""), 0, 2000)).apply {
isDockable = true
}
- val taskContainer =
- taskView.TaskContainer(
- task,
- thumbnailView,
- iconView,
- SplitConfigurationOptions.STAGE_POSITION_UNDEFINED,
- null
- )
+ val taskContainer = createTaskContainer(task)
val shortcuts = factory.getShortcuts(launcher, taskContainer)
assertThat(shortcuts).isNull()
@@ -108,20 +109,9 @@
@Test
fun createDesktopTaskShortcutFactory_desktopModeEnabled_DeviceNotSupported() {
setFlagsRule.enableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
- doReturn(false).`when` { DesktopModeStatus.isDesktopModeSupported(any()) }
+ ExtendedMockito.doReturn(false).`when` { DesktopModeStatus.isDesktopModeSupported(any()) }
- val task =
- Task(TaskKey(1, 0, Intent(), ComponentName("", ""), 0, 2000)).apply {
- isDockable = true
- }
- val taskContainer =
- taskView.TaskContainer(
- task,
- thumbnailView,
- iconView,
- SplitConfigurationOptions.STAGE_POSITION_UNDEFINED,
- null
- )
+ val taskContainer = createTaskContainer(createTask())
val shortcuts = factory.getShortcuts(launcher, taskContainer)
assertThat(shortcuts).isNull()
@@ -130,21 +120,11 @@
@Test
fun createDesktopTaskShortcutFactory_desktopModeEnabled_DeviceNotSupported_OverrideEnabled() {
setFlagsRule.enableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
- doReturn(false).`when` { DesktopModeStatus.isDesktopModeSupported(any()) }
- doReturn(false).`when` { DesktopModeStatus.enforceDeviceRestrictions() }
+ ExtendedMockito.doReturn(false).`when` { DesktopModeStatus.isDesktopModeSupported(any()) }
+ ExtendedMockito.doReturn(false).`when` { DesktopModeStatus.enforceDeviceRestrictions() }
- val task =
- Task(TaskKey(1, 0, Intent(), ComponentName("", ""), 0, 2000)).apply {
- isDockable = true
- }
- val taskContainer =
- taskView.TaskContainer(
- task,
- thumbnailView,
- iconView,
- SplitConfigurationOptions.STAGE_POSITION_UNDEFINED,
- null
- )
+ val taskContainer = spy(createTaskContainer(createTask()))
+ doReturn(workspaceItemInfo).whenever(taskContainer).itemInfo
val shortcuts = factory.getShortcuts(launcher, taskContainer)
assertThat(shortcuts).isNotNull()
@@ -154,18 +134,8 @@
fun createDesktopTaskShortcutFactory_undockable() {
setFlagsRule.enableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
- val task =
- Task(TaskKey(1, 0, Intent(), ComponentName("", ""), 0, 2000)).apply {
- isDockable = false
- }
- val taskContainer =
- taskView.TaskContainer(
- task,
- thumbnailView,
- iconView,
- SplitConfigurationOptions.STAGE_POSITION_UNDEFINED,
- null
- )
+ val unDockableTask = createTask().apply { isDockable = false }
+ val taskContainer = createTaskContainer(unDockableTask)
val shortcuts = factory.getShortcuts(launcher, taskContainer)
assertThat(shortcuts).isNull()
@@ -175,28 +145,18 @@
fun desktopSystemShortcutClicked() {
setFlagsRule.enableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
- val task =
- Task(TaskKey(1, 0, Intent(), ComponentName("", ""), 0, 2000)).apply {
- isDockable = true
- }
- val taskContainer =
- taskView.TaskContainer(
- task,
- thumbnailView,
- iconView,
- SplitConfigurationOptions.STAGE_POSITION_UNDEFINED,
- null
- )
+ val task = createTask()
+ val taskContainer = spy(createTaskContainer(task))
whenever(launcher.getOverviewPanel<LauncherRecentsView>()).thenReturn(recentsView)
whenever(launcher.statsLogManager).thenReturn(statsLogManager)
whenever(statsLogManager.logger()).thenReturn(statsLogger)
whenever(statsLogger.withItemInfo(any())).thenReturn(statsLogger)
- whenever(taskView.getItemInfo(task)).thenReturn(workspaceItemInfo)
whenever(recentsView.moveTaskToDesktop(any(), any())).thenAnswer {
val successCallback = it.getArgument<Runnable>(1)
successCallback.run()
}
+ doReturn(workspaceItemInfo).whenever(taskContainer).itemInfo
val shortcuts = factory.getShortcuts(launcher, taskContainer)
assertThat(shortcuts).hasSize(1)
@@ -213,4 +173,24 @@
verify(statsLogger).withItemInfo(workspaceItemInfo)
verify(statsLogger).log(LauncherEvent.LAUNCHER_SYSTEM_SHORTCUT_DESKTOP_TAP)
}
+
+ private fun createTask(): Task {
+ return Task(TaskKey(1, 0, Intent(), ComponentName("", ""), 0, 2000)).apply {
+ isDockable = true
+ }
+ }
+
+ private fun createTaskContainer(task: Task): TaskView.TaskContainer {
+ return taskView.TaskContainer(
+ task,
+ thumbnailView = null,
+ thumbnailViewDeprecated,
+ iconView,
+ transformingTouchDelegate,
+ SplitConfigurationOptions.STAGE_POSITION_UNDEFINED,
+ digitalWellBeingToast = null,
+ showWindowsView = null,
+ overlayFactory
+ )
+ }
}
diff --git a/quickstep/tests/src/com/android/quickstep/TaplDigitalWellBeingToastTest.java b/quickstep/tests/src/com/android/quickstep/TaplDigitalWellBeingToastTest.java
index 37ab131..07d8f61 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplDigitalWellBeingToastTest.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplDigitalWellBeingToastTest.java
@@ -86,9 +86,10 @@
final TaskView task = getOnceNotNull("No latest task", launcher -> getLatestTask(launcher));
return getFromLauncher(launcher -> {
+ TaskView.TaskContainer taskContainer = task.getTaskContainers().get(0);
assertTrue("Latest task is not Calculator", CALCULATOR_PACKAGE.equals(
- task.getFirstTask().getTopComponent().getPackageName()));
- return task.getDigitalWellBeingToast();
+ taskContainer.getTask().getTopComponent().getPackageName()));
+ return taskContainer.getDigitalWellBeingToast();
});
}
diff --git a/src/com/android/launcher3/util/rects/Rects.kt b/src/com/android/launcher3/util/rects/Rects.kt
index ac1f3f8..1e6d717 100644
--- a/src/com/android/launcher3/util/rects/Rects.kt
+++ b/src/com/android/launcher3/util/rects/Rects.kt
@@ -21,5 +21,6 @@
/** Copy the coordinates of the [view] relative to its parent into this rectangle. */
fun Rect.set(view: View) {
- set(view.left, view.top, view.right, view.bottom)
+ set(0, 0, view.width, view.height)
+ offset(view.x.toInt(), view.y.toInt())
}
diff --git a/tests/Android.bp b/tests/Android.bp
index 11177de..5794cce 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -192,6 +192,7 @@
java_resource_dirs: ["config"],
static_libs: [
"flag-junit-base",
+ "flag-junit",
"com_android_launcher3_flags_lib",
"com_android_wm_shell_flags_lib",
"androidx.test.uiautomator_uiautomator",
@@ -199,9 +200,10 @@
"androidx.test.ext.junit",
"androidx.test.rules",
"uiautomator-helpers",
- "mockito-robolectric-prebuilt",
- "mockito-kotlin2",
+ "inline-mockito-robolectric-prebuilt",
+ "mockito-kotlin-nodeps",
"platform-parametric-runner-lib",
+ "platform-test-rules-deviceless",
"testables",
"Launcher3TestResources",
"SystemUISharedLib",
diff --git a/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelLandscape3Button_decoupleDepth.txt b/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelLandscape3Button_decoupleDepth.txt
new file mode 100644
index 0000000..46cce24
--- /dev/null
+++ b/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelLandscape3Button_decoupleDepth.txt
@@ -0,0 +1,130 @@
+DeviceProfile:
+ 1 dp = 2.625 px
+ isTablet:true
+ isPhone:false
+ transposeLayoutWithOrientation:false
+ isGestureMode:false
+ isLandscape:true
+ isMultiWindowMode:false
+ isTwoPanels:true
+ isLeftRightSplit:true
+ windowX: 0.0px (0.0dp)
+ windowY: 0.0px (0.0dp)
+ widthPx: 2208.0px (841.1429dp)
+ heightPx: 1840.0px (700.9524dp)
+ availableWidthPx: 2208.0px (841.1429dp)
+ availableHeightPx: 1730.0px (659.0476dp)
+ mInsets.left: 0.0px (0.0dp)
+ mInsets.top: 110.0px (41.904762dp)
+ mInsets.right: 0.0px (0.0dp)
+ mInsets.bottom: 0.0px (0.0dp)
+ aspectRatio:1.2
+ isResponsiveGrid:false
+ isScalableGrid:false
+ inv.numRows: 4
+ inv.numColumns: 4
+ inv.numSearchContainerColumns: 4
+ minCellSize: PointF(0.0, 0.0)dp
+ cellWidthPx: 154.0px (58.666668dp)
+ cellHeightPx: 218.0px (83.04762dp)
+ getCellSize().x: 270.0px (102.85714dp)
+ getCellSize().y: 342.0px (130.28572dp)
+ cellLayoutBorderSpacePx Horizontal: 0.0px (0.0dp)
+ cellLayoutBorderSpacePx Vertical: 0.0px (0.0dp)
+ cellLayoutPaddingPx.left: 0.0px (0.0dp)
+ cellLayoutPaddingPx.top: 0.0px (0.0dp)
+ cellLayoutPaddingPx.right: 0.0px (0.0dp)
+ cellLayoutPaddingPx.bottom: 0.0px (0.0dp)
+ iconSizePx: 141.0px (53.714287dp)
+ iconTextSizePx: 34.0px (12.952381dp)
+ iconDrawablePaddingPx: 13.0px (4.952381dp)
+ numFolderRows: 3
+ numFolderColumns: 4
+ folderCellWidthPx: 189.0px (72.0dp)
+ folderCellHeightPx: 219.0px (83.42857dp)
+ folderChildIconSizePx: 141.0px (53.714287dp)
+ folderChildTextSizePx: 34.0px (12.952381dp)
+ folderChildDrawablePaddingPx: 5.0px (1.9047619dp)
+ folderCellLayoutBorderSpacePx.x: 0.0px (0.0dp)
+ folderCellLayoutBorderSpacePx.y: 0.0px (0.0dp)
+ folderContentPaddingLeftRight: 21.0px (8.0dp)
+ folderTopPadding: 63.0px (24.0dp)
+ folderFooterHeight: 147.0px (56.0dp)
+ bottomSheetTopPadding: 110.0px (41.904762dp)
+ bottomSheetOpenDuration: 500
+ bottomSheetCloseDuration: 500
+ bottomSheetWorkspaceScale: 0.97
+ bottomSheetDepth: 0.3
+ allAppsShiftRange: 1840.0px (700.9524dp)
+ allAppsOpenDuration: 500
+ allAppsCloseDuration: 500
+ allAppsIconSizePx: 141.0px (53.714287dp)
+ allAppsIconTextSizePx: 34.0px (12.952381dp)
+ allAppsIconDrawablePaddingPx: 21.0px (8.0dp)
+ allAppsCellHeightPx: 361.0px (137.5238dp)
+ allAppsCellWidthPx: 183.0px (69.71429dp)
+ allAppsBorderSpacePxX: 42.0px (16.0dp)
+ allAppsBorderSpacePxY: 42.0px (16.0dp)
+ numShownAllAppsColumns: 8
+ allAppsPadding.top: 110.0px (41.904762dp)
+ allAppsPadding.left: 42.0px (16.0dp)
+ allAppsPadding.right: 42.0px (16.0dp)
+ allAppsLeftRightMargin: 183.0px (69.71429dp)
+ hotseatBarSizePx: 267.0px (101.71429dp)
+ mHotseatColumnSpan: 4
+ mHotseatWidthPx: 0.0px (0.0dp)
+ hotseatCellHeightPx: 159.0px (60.57143dp)
+ hotseatBarBottomSpacePx: 126.0px (48.0dp)
+ mHotseatBarEdgePaddingPx: 0.0px (0.0dp)
+ mHotseatBarWorkspaceSpacePx: 0.0px (0.0dp)
+ hotseatBarEndOffset: 0.0px (0.0dp)
+ hotseatQsbSpace: 0.0px (0.0dp)
+ hotseatQsbHeight: 0.0px (0.0dp)
+ springLoadedHotseatBarTopMarginPx: 116.0px (44.190475dp)
+ getHotseatLayoutPadding(context).top: 0.0px (0.0dp)
+ getHotseatLayoutPadding(context).bottom: 108.0px (41.142857dp)
+ getHotseatLayoutPadding(context).left: 113.0px (43.04762dp)
+ getHotseatLayoutPadding(context).right: 113.0px (43.04762dp)
+ numShownHotseatIcons: 6
+ hotseatBorderSpace: 0.0px (0.0dp)
+ isQsbInline: false
+ hotseatQsbWidth: 0.0px (0.0dp)
+ isTaskbarPresent:false
+ isTaskbarPresentInApps:true
+ taskbarHeight: 0.0px (0.0dp)
+ stashedTaskbarHeight: 0.0px (0.0dp)
+ taskbarBottomMargin: 0.0px (0.0dp)
+ taskbarIconSize: 0.0px (0.0dp)
+ desiredWorkspaceHorizontalMarginPx: 21.0px (8.0dp)
+ workspacePadding.left: 21.0px (8.0dp)
+ workspacePadding.top: 30.0px (11.428572dp)
+ workspacePadding.right: 21.0px (8.0dp)
+ workspacePadding.bottom: 330.0px (125.71429dp)
+ iconScale: 1.0px (0.3809524dp)
+ cellScaleToFit : 1.0px (0.3809524dp)
+ extraSpace: 498.0px (189.71428dp)
+ unscaled extraSpace: 498.0px (189.71428dp)
+ maxEmptySpace: 0.0px (0.0dp)
+ workspaceTopPadding: 0.0px (0.0dp)
+ workspaceBottomPadding: 0.0px (0.0dp)
+ overviewTaskMarginPx: 0.0px (0.0dp)
+ overviewTaskIconSizePx: 0.0px (0.0dp)
+ overviewTaskIconDrawableSizePx: 0.0px (0.0dp)
+ overviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)
+ overviewTaskThumbnailTopMarginPx: 0.0px (0.0dp)
+ overviewActionsTopMarginPx: 0.0px (0.0dp)
+ overviewActionsHeight: 0.0px (0.0dp)
+ overviewActionsClaimedSpaceBelow: 0.0px (0.0dp)
+ overviewActionsButtonSpacing: 0.0px (0.0dp)
+ overviewPageSpacing: 0.0px (0.0dp)
+ overviewRowSpacing: 0.0px (0.0dp)
+ overviewGridSideMargin: 0.0px (0.0dp)
+ dropTargetBarTopMarginPx: 0.0px (0.0dp)
+ dropTargetBarSizePx: 147.0px (56.0dp)
+ dropTargetBarBottomMarginPx: 42.0px (16.0dp)
+ getCellLayoutSpringLoadShrunkTop(): 299.0px (113.90476dp)
+ getCellLayoutSpringLoadShrunkBottom(): 1457.0px (555.0476dp)
+ workspaceSpringLoadedMinNextPageVisiblePx: 126.0px (48.0dp)
+ getWorkspaceSpringLoadScale(): 0.8452555px (0.32200208dp)
+ getCellLayoutHeight(): 1370.0px (521.9048dp)
+ getCellLayoutWidth(): 1083.0px (412.57144dp)
diff --git a/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelLandscape_decoupleDepth.txt b/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelLandscape_decoupleDepth.txt
new file mode 100644
index 0000000..44b99e9
--- /dev/null
+++ b/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelLandscape_decoupleDepth.txt
@@ -0,0 +1,130 @@
+DeviceProfile:
+ 1 dp = 2.625 px
+ isTablet:true
+ isPhone:false
+ transposeLayoutWithOrientation:false
+ isGestureMode:true
+ isLandscape:true
+ isMultiWindowMode:false
+ isTwoPanels:true
+ isLeftRightSplit:true
+ windowX: 0.0px (0.0dp)
+ windowY: 0.0px (0.0dp)
+ widthPx: 2208.0px (841.1429dp)
+ heightPx: 1840.0px (700.9524dp)
+ availableWidthPx: 2208.0px (841.1429dp)
+ availableHeightPx: 1730.0px (659.0476dp)
+ mInsets.left: 0.0px (0.0dp)
+ mInsets.top: 110.0px (41.904762dp)
+ mInsets.right: 0.0px (0.0dp)
+ mInsets.bottom: 0.0px (0.0dp)
+ aspectRatio:1.2
+ isResponsiveGrid:false
+ isScalableGrid:false
+ inv.numRows: 4
+ inv.numColumns: 4
+ inv.numSearchContainerColumns: 4
+ minCellSize: PointF(0.0, 0.0)dp
+ cellWidthPx: 154.0px (58.666668dp)
+ cellHeightPx: 218.0px (83.04762dp)
+ getCellSize().x: 270.0px (102.85714dp)
+ getCellSize().y: 342.0px (130.28572dp)
+ cellLayoutBorderSpacePx Horizontal: 0.0px (0.0dp)
+ cellLayoutBorderSpacePx Vertical: 0.0px (0.0dp)
+ cellLayoutPaddingPx.left: 0.0px (0.0dp)
+ cellLayoutPaddingPx.top: 0.0px (0.0dp)
+ cellLayoutPaddingPx.right: 0.0px (0.0dp)
+ cellLayoutPaddingPx.bottom: 0.0px (0.0dp)
+ iconSizePx: 141.0px (53.714287dp)
+ iconTextSizePx: 34.0px (12.952381dp)
+ iconDrawablePaddingPx: 13.0px (4.952381dp)
+ numFolderRows: 3
+ numFolderColumns: 4
+ folderCellWidthPx: 189.0px (72.0dp)
+ folderCellHeightPx: 219.0px (83.42857dp)
+ folderChildIconSizePx: 141.0px (53.714287dp)
+ folderChildTextSizePx: 34.0px (12.952381dp)
+ folderChildDrawablePaddingPx: 5.0px (1.9047619dp)
+ folderCellLayoutBorderSpacePx.x: 0.0px (0.0dp)
+ folderCellLayoutBorderSpacePx.y: 0.0px (0.0dp)
+ folderContentPaddingLeftRight: 21.0px (8.0dp)
+ folderTopPadding: 63.0px (24.0dp)
+ folderFooterHeight: 147.0px (56.0dp)
+ bottomSheetTopPadding: 110.0px (41.904762dp)
+ bottomSheetOpenDuration: 500
+ bottomSheetCloseDuration: 500
+ bottomSheetWorkspaceScale: 0.97
+ bottomSheetDepth: 0.3
+ allAppsShiftRange: 1840.0px (700.9524dp)
+ allAppsOpenDuration: 500
+ allAppsCloseDuration: 500
+ allAppsIconSizePx: 141.0px (53.714287dp)
+ allAppsIconTextSizePx: 34.0px (12.952381dp)
+ allAppsIconDrawablePaddingPx: 21.0px (8.0dp)
+ allAppsCellHeightPx: 361.0px (137.5238dp)
+ allAppsCellWidthPx: 183.0px (69.71429dp)
+ allAppsBorderSpacePxX: 42.0px (16.0dp)
+ allAppsBorderSpacePxY: 42.0px (16.0dp)
+ numShownAllAppsColumns: 8
+ allAppsPadding.top: 110.0px (41.904762dp)
+ allAppsPadding.left: 42.0px (16.0dp)
+ allAppsPadding.right: 42.0px (16.0dp)
+ allAppsLeftRightMargin: 183.0px (69.71429dp)
+ hotseatBarSizePx: 267.0px (101.71429dp)
+ mHotseatColumnSpan: 4
+ mHotseatWidthPx: 0.0px (0.0dp)
+ hotseatCellHeightPx: 159.0px (60.57143dp)
+ hotseatBarBottomSpacePx: 126.0px (48.0dp)
+ mHotseatBarEdgePaddingPx: 0.0px (0.0dp)
+ mHotseatBarWorkspaceSpacePx: 0.0px (0.0dp)
+ hotseatBarEndOffset: 0.0px (0.0dp)
+ hotseatQsbSpace: 0.0px (0.0dp)
+ hotseatQsbHeight: 0.0px (0.0dp)
+ springLoadedHotseatBarTopMarginPx: 116.0px (44.190475dp)
+ getHotseatLayoutPadding(context).top: 0.0px (0.0dp)
+ getHotseatLayoutPadding(context).bottom: 108.0px (41.142857dp)
+ getHotseatLayoutPadding(context).left: 113.0px (43.04762dp)
+ getHotseatLayoutPadding(context).right: 113.0px (43.04762dp)
+ numShownHotseatIcons: 6
+ hotseatBorderSpace: 0.0px (0.0dp)
+ isQsbInline: false
+ hotseatQsbWidth: 0.0px (0.0dp)
+ isTaskbarPresent:false
+ isTaskbarPresentInApps:true
+ taskbarHeight: 0.0px (0.0dp)
+ stashedTaskbarHeight: 0.0px (0.0dp)
+ taskbarBottomMargin: 0.0px (0.0dp)
+ taskbarIconSize: 0.0px (0.0dp)
+ desiredWorkspaceHorizontalMarginPx: 21.0px (8.0dp)
+ workspacePadding.left: 21.0px (8.0dp)
+ workspacePadding.top: 30.0px (11.428572dp)
+ workspacePadding.right: 21.0px (8.0dp)
+ workspacePadding.bottom: 330.0px (125.71429dp)
+ iconScale: 1.0px (0.3809524dp)
+ cellScaleToFit : 1.0px (0.3809524dp)
+ extraSpace: 498.0px (189.71428dp)
+ unscaled extraSpace: 498.0px (189.71428dp)
+ maxEmptySpace: 0.0px (0.0dp)
+ workspaceTopPadding: 0.0px (0.0dp)
+ workspaceBottomPadding: 0.0px (0.0dp)
+ overviewTaskMarginPx: 0.0px (0.0dp)
+ overviewTaskIconSizePx: 0.0px (0.0dp)
+ overviewTaskIconDrawableSizePx: 0.0px (0.0dp)
+ overviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)
+ overviewTaskThumbnailTopMarginPx: 0.0px (0.0dp)
+ overviewActionsTopMarginPx: 0.0px (0.0dp)
+ overviewActionsHeight: 0.0px (0.0dp)
+ overviewActionsClaimedSpaceBelow: 0.0px (0.0dp)
+ overviewActionsButtonSpacing: 0.0px (0.0dp)
+ overviewPageSpacing: 0.0px (0.0dp)
+ overviewRowSpacing: 0.0px (0.0dp)
+ overviewGridSideMargin: 0.0px (0.0dp)
+ dropTargetBarTopMarginPx: 0.0px (0.0dp)
+ dropTargetBarSizePx: 147.0px (56.0dp)
+ dropTargetBarBottomMarginPx: 42.0px (16.0dp)
+ getCellLayoutSpringLoadShrunkTop(): 299.0px (113.90476dp)
+ getCellLayoutSpringLoadShrunkBottom(): 1457.0px (555.0476dp)
+ workspaceSpringLoadedMinNextPageVisiblePx: 126.0px (48.0dp)
+ getWorkspaceSpringLoadScale(): 0.8452555px (0.32200208dp)
+ getCellLayoutHeight(): 1370.0px (521.9048dp)
+ getCellLayoutWidth(): 1083.0px (412.57144dp)
diff --git a/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelPortrait3Button_decoupleDepth.txt b/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelPortrait3Button_decoupleDepth.txt
new file mode 100644
index 0000000..e7b72f2
--- /dev/null
+++ b/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelPortrait3Button_decoupleDepth.txt
@@ -0,0 +1,130 @@
+DeviceProfile:
+ 1 dp = 2.625 px
+ isTablet:true
+ isPhone:false
+ transposeLayoutWithOrientation:false
+ isGestureMode:false
+ isLandscape:false
+ isMultiWindowMode:false
+ isTwoPanels:true
+ isLeftRightSplit:false
+ windowX: 0.0px (0.0dp)
+ windowY: 0.0px (0.0dp)
+ widthPx: 1840.0px (700.9524dp)
+ heightPx: 2208.0px (841.1429dp)
+ availableWidthPx: 1840.0px (700.9524dp)
+ availableHeightPx: 2075.0px (790.4762dp)
+ mInsets.left: 0.0px (0.0dp)
+ mInsets.top: 133.0px (50.666668dp)
+ mInsets.right: 0.0px (0.0dp)
+ mInsets.bottom: 0.0px (0.0dp)
+ aspectRatio:1.2
+ isResponsiveGrid:false
+ isScalableGrid:false
+ inv.numRows: 4
+ inv.numColumns: 4
+ inv.numSearchContainerColumns: 4
+ minCellSize: PointF(0.0, 0.0)dp
+ cellWidthPx: 154.0px (58.666668dp)
+ cellHeightPx: 218.0px (83.04762dp)
+ getCellSize().x: 224.0px (85.333336dp)
+ getCellSize().y: 430.0px (163.80952dp)
+ cellLayoutBorderSpacePx Horizontal: 0.0px (0.0dp)
+ cellLayoutBorderSpacePx Vertical: 0.0px (0.0dp)
+ cellLayoutPaddingPx.left: 0.0px (0.0dp)
+ cellLayoutPaddingPx.top: 0.0px (0.0dp)
+ cellLayoutPaddingPx.right: 0.0px (0.0dp)
+ cellLayoutPaddingPx.bottom: 0.0px (0.0dp)
+ iconSizePx: 141.0px (53.714287dp)
+ iconTextSizePx: 34.0px (12.952381dp)
+ iconDrawablePaddingPx: 13.0px (4.952381dp)
+ numFolderRows: 3
+ numFolderColumns: 4
+ folderCellWidthPx: 189.0px (72.0dp)
+ folderCellHeightPx: 219.0px (83.42857dp)
+ folderChildIconSizePx: 141.0px (53.714287dp)
+ folderChildTextSizePx: 34.0px (12.952381dp)
+ folderChildDrawablePaddingPx: 5.0px (1.9047619dp)
+ folderCellLayoutBorderSpacePx.x: 0.0px (0.0dp)
+ folderCellLayoutBorderSpacePx.y: 0.0px (0.0dp)
+ folderContentPaddingLeftRight: 21.0px (8.0dp)
+ folderTopPadding: 63.0px (24.0dp)
+ folderFooterHeight: 147.0px (56.0dp)
+ bottomSheetTopPadding: 133.0px (50.666668dp)
+ bottomSheetOpenDuration: 500
+ bottomSheetCloseDuration: 500
+ bottomSheetWorkspaceScale: 0.97
+ bottomSheetDepth: 0.3
+ allAppsShiftRange: 2208.0px (841.1429dp)
+ allAppsOpenDuration: 500
+ allAppsCloseDuration: 500
+ allAppsIconSizePx: 141.0px (53.714287dp)
+ allAppsIconTextSizePx: 34.0px (12.952381dp)
+ allAppsIconDrawablePaddingPx: 21.0px (8.0dp)
+ allAppsCellHeightPx: 361.0px (137.5238dp)
+ allAppsCellWidthPx: 183.0px (69.71429dp)
+ allAppsBorderSpacePxX: 42.0px (16.0dp)
+ allAppsBorderSpacePxY: 42.0px (16.0dp)
+ numShownAllAppsColumns: 8
+ allAppsPadding.top: 133.0px (50.666668dp)
+ allAppsPadding.left: 42.0px (16.0dp)
+ allAppsPadding.right: 42.0px (16.0dp)
+ allAppsLeftRightMargin: 1.0px (0.3809524dp)
+ hotseatBarSizePx: 267.0px (101.71429dp)
+ mHotseatColumnSpan: 4
+ mHotseatWidthPx: 0.0px (0.0dp)
+ hotseatCellHeightPx: 159.0px (60.57143dp)
+ hotseatBarBottomSpacePx: 126.0px (48.0dp)
+ mHotseatBarEdgePaddingPx: 0.0px (0.0dp)
+ mHotseatBarWorkspaceSpacePx: 0.0px (0.0dp)
+ hotseatBarEndOffset: 0.0px (0.0dp)
+ hotseatQsbSpace: 0.0px (0.0dp)
+ hotseatQsbHeight: 0.0px (0.0dp)
+ springLoadedHotseatBarTopMarginPx: 168.0px (64.0dp)
+ getHotseatLayoutPadding(context).top: 0.0px (0.0dp)
+ getHotseatLayoutPadding(context).bottom: 108.0px (41.142857dp)
+ getHotseatLayoutPadding(context).left: 98.0px (37.333332dp)
+ getHotseatLayoutPadding(context).right: 98.0px (37.333332dp)
+ numShownHotseatIcons: 6
+ hotseatBorderSpace: 0.0px (0.0dp)
+ isQsbInline: false
+ hotseatQsbWidth: 0.0px (0.0dp)
+ isTaskbarPresent:false
+ isTaskbarPresentInApps:true
+ taskbarHeight: 0.0px (0.0dp)
+ stashedTaskbarHeight: 0.0px (0.0dp)
+ taskbarBottomMargin: 0.0px (0.0dp)
+ taskbarIconSize: 0.0px (0.0dp)
+ desiredWorkspaceHorizontalMarginPx: 21.0px (8.0dp)
+ workspacePadding.left: 21.0px (8.0dp)
+ workspacePadding.top: 24.0px (9.142858dp)
+ workspacePadding.right: 21.0px (8.0dp)
+ workspacePadding.bottom: 330.0px (125.71429dp)
+ iconScale: 1.0px (0.3809524dp)
+ cellScaleToFit : 1.0px (0.3809524dp)
+ extraSpace: 849.0px (323.42856dp)
+ unscaled extraSpace: 849.0px (323.42856dp)
+ maxEmptySpace: 0.0px (0.0dp)
+ workspaceTopPadding: 0.0px (0.0dp)
+ workspaceBottomPadding: 0.0px (0.0dp)
+ overviewTaskMarginPx: 0.0px (0.0dp)
+ overviewTaskIconSizePx: 0.0px (0.0dp)
+ overviewTaskIconDrawableSizePx: 0.0px (0.0dp)
+ overviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)
+ overviewTaskThumbnailTopMarginPx: 0.0px (0.0dp)
+ overviewActionsTopMarginPx: 0.0px (0.0dp)
+ overviewActionsHeight: 0.0px (0.0dp)
+ overviewActionsClaimedSpaceBelow: 0.0px (0.0dp)
+ overviewActionsButtonSpacing: 0.0px (0.0dp)
+ overviewPageSpacing: 0.0px (0.0dp)
+ overviewRowSpacing: 0.0px (0.0dp)
+ overviewGridSideMargin: 0.0px (0.0dp)
+ dropTargetBarTopMarginPx: 0.0px (0.0dp)
+ dropTargetBarSizePx: 147.0px (56.0dp)
+ dropTargetBarBottomMarginPx: 84.0px (32.0dp)
+ getCellLayoutSpringLoadShrunkTop(): 364.0px (138.66667dp)
+ getCellLayoutSpringLoadShrunkBottom(): 1773.0px (675.4286dp)
+ workspaceSpringLoadedMinNextPageVisiblePx: 126.0px (48.0dp)
+ getWorkspaceSpringLoadScale(): 0.81871px (0.31188953dp)
+ getCellLayoutHeight(): 1721.0px (655.619dp)
+ getCellLayoutWidth(): 899.0px (342.4762dp)
diff --git a/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelPortrait_decoupleDepth.txt b/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelPortrait_decoupleDepth.txt
new file mode 100644
index 0000000..eae50f1
--- /dev/null
+++ b/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelPortrait_decoupleDepth.txt
@@ -0,0 +1,130 @@
+DeviceProfile:
+ 1 dp = 2.625 px
+ isTablet:true
+ isPhone:false
+ transposeLayoutWithOrientation:false
+ isGestureMode:true
+ isLandscape:false
+ isMultiWindowMode:false
+ isTwoPanels:true
+ isLeftRightSplit:false
+ windowX: 0.0px (0.0dp)
+ windowY: 0.0px (0.0dp)
+ widthPx: 1840.0px (700.9524dp)
+ heightPx: 2208.0px (841.1429dp)
+ availableWidthPx: 1840.0px (700.9524dp)
+ availableHeightPx: 2075.0px (790.4762dp)
+ mInsets.left: 0.0px (0.0dp)
+ mInsets.top: 133.0px (50.666668dp)
+ mInsets.right: 0.0px (0.0dp)
+ mInsets.bottom: 0.0px (0.0dp)
+ aspectRatio:1.2
+ isResponsiveGrid:false
+ isScalableGrid:false
+ inv.numRows: 4
+ inv.numColumns: 4
+ inv.numSearchContainerColumns: 4
+ minCellSize: PointF(0.0, 0.0)dp
+ cellWidthPx: 154.0px (58.666668dp)
+ cellHeightPx: 218.0px (83.04762dp)
+ getCellSize().x: 224.0px (85.333336dp)
+ getCellSize().y: 430.0px (163.80952dp)
+ cellLayoutBorderSpacePx Horizontal: 0.0px (0.0dp)
+ cellLayoutBorderSpacePx Vertical: 0.0px (0.0dp)
+ cellLayoutPaddingPx.left: 0.0px (0.0dp)
+ cellLayoutPaddingPx.top: 0.0px (0.0dp)
+ cellLayoutPaddingPx.right: 0.0px (0.0dp)
+ cellLayoutPaddingPx.bottom: 0.0px (0.0dp)
+ iconSizePx: 141.0px (53.714287dp)
+ iconTextSizePx: 34.0px (12.952381dp)
+ iconDrawablePaddingPx: 13.0px (4.952381dp)
+ numFolderRows: 3
+ numFolderColumns: 4
+ folderCellWidthPx: 189.0px (72.0dp)
+ folderCellHeightPx: 219.0px (83.42857dp)
+ folderChildIconSizePx: 141.0px (53.714287dp)
+ folderChildTextSizePx: 34.0px (12.952381dp)
+ folderChildDrawablePaddingPx: 5.0px (1.9047619dp)
+ folderCellLayoutBorderSpacePx.x: 0.0px (0.0dp)
+ folderCellLayoutBorderSpacePx.y: 0.0px (0.0dp)
+ folderContentPaddingLeftRight: 21.0px (8.0dp)
+ folderTopPadding: 63.0px (24.0dp)
+ folderFooterHeight: 147.0px (56.0dp)
+ bottomSheetTopPadding: 133.0px (50.666668dp)
+ bottomSheetOpenDuration: 500
+ bottomSheetCloseDuration: 500
+ bottomSheetWorkspaceScale: 0.97
+ bottomSheetDepth: 0.3
+ allAppsShiftRange: 2208.0px (841.1429dp)
+ allAppsOpenDuration: 500
+ allAppsCloseDuration: 500
+ allAppsIconSizePx: 141.0px (53.714287dp)
+ allAppsIconTextSizePx: 34.0px (12.952381dp)
+ allAppsIconDrawablePaddingPx: 21.0px (8.0dp)
+ allAppsCellHeightPx: 361.0px (137.5238dp)
+ allAppsCellWidthPx: 183.0px (69.71429dp)
+ allAppsBorderSpacePxX: 42.0px (16.0dp)
+ allAppsBorderSpacePxY: 42.0px (16.0dp)
+ numShownAllAppsColumns: 8
+ allAppsPadding.top: 133.0px (50.666668dp)
+ allAppsPadding.left: 42.0px (16.0dp)
+ allAppsPadding.right: 42.0px (16.0dp)
+ allAppsLeftRightMargin: 1.0px (0.3809524dp)
+ hotseatBarSizePx: 267.0px (101.71429dp)
+ mHotseatColumnSpan: 4
+ mHotseatWidthPx: 0.0px (0.0dp)
+ hotseatCellHeightPx: 159.0px (60.57143dp)
+ hotseatBarBottomSpacePx: 126.0px (48.0dp)
+ mHotseatBarEdgePaddingPx: 0.0px (0.0dp)
+ mHotseatBarWorkspaceSpacePx: 0.0px (0.0dp)
+ hotseatBarEndOffset: 0.0px (0.0dp)
+ hotseatQsbSpace: 0.0px (0.0dp)
+ hotseatQsbHeight: 0.0px (0.0dp)
+ springLoadedHotseatBarTopMarginPx: 168.0px (64.0dp)
+ getHotseatLayoutPadding(context).top: 0.0px (0.0dp)
+ getHotseatLayoutPadding(context).bottom: 108.0px (41.142857dp)
+ getHotseatLayoutPadding(context).left: 98.0px (37.333332dp)
+ getHotseatLayoutPadding(context).right: 98.0px (37.333332dp)
+ numShownHotseatIcons: 6
+ hotseatBorderSpace: 0.0px (0.0dp)
+ isQsbInline: false
+ hotseatQsbWidth: 0.0px (0.0dp)
+ isTaskbarPresent:false
+ isTaskbarPresentInApps:true
+ taskbarHeight: 0.0px (0.0dp)
+ stashedTaskbarHeight: 0.0px (0.0dp)
+ taskbarBottomMargin: 0.0px (0.0dp)
+ taskbarIconSize: 0.0px (0.0dp)
+ desiredWorkspaceHorizontalMarginPx: 21.0px (8.0dp)
+ workspacePadding.left: 21.0px (8.0dp)
+ workspacePadding.top: 24.0px (9.142858dp)
+ workspacePadding.right: 21.0px (8.0dp)
+ workspacePadding.bottom: 330.0px (125.71429dp)
+ iconScale: 1.0px (0.3809524dp)
+ cellScaleToFit : 1.0px (0.3809524dp)
+ extraSpace: 849.0px (323.42856dp)
+ unscaled extraSpace: 849.0px (323.42856dp)
+ maxEmptySpace: 0.0px (0.0dp)
+ workspaceTopPadding: 0.0px (0.0dp)
+ workspaceBottomPadding: 0.0px (0.0dp)
+ overviewTaskMarginPx: 0.0px (0.0dp)
+ overviewTaskIconSizePx: 0.0px (0.0dp)
+ overviewTaskIconDrawableSizePx: 0.0px (0.0dp)
+ overviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)
+ overviewTaskThumbnailTopMarginPx: 0.0px (0.0dp)
+ overviewActionsTopMarginPx: 0.0px (0.0dp)
+ overviewActionsHeight: 0.0px (0.0dp)
+ overviewActionsClaimedSpaceBelow: 0.0px (0.0dp)
+ overviewActionsButtonSpacing: 0.0px (0.0dp)
+ overviewPageSpacing: 0.0px (0.0dp)
+ overviewRowSpacing: 0.0px (0.0dp)
+ overviewGridSideMargin: 0.0px (0.0dp)
+ dropTargetBarTopMarginPx: 0.0px (0.0dp)
+ dropTargetBarSizePx: 147.0px (56.0dp)
+ dropTargetBarBottomMarginPx: 84.0px (32.0dp)
+ getCellLayoutSpringLoadShrunkTop(): 364.0px (138.66667dp)
+ getCellLayoutSpringLoadShrunkBottom(): 1773.0px (675.4286dp)
+ workspaceSpringLoadedMinNextPageVisiblePx: 126.0px (48.0dp)
+ getWorkspaceSpringLoadScale(): 0.81871px (0.31188953dp)
+ getCellLayoutHeight(): 1721.0px (655.619dp)
+ getCellLayoutWidth(): 899.0px (342.4762dp)
diff --git a/tests/src/com/android/launcher3/AbstractDeviceProfileTest.kt b/tests/multivalentTests/src/com/android/launcher3/AbstractDeviceProfileTest.kt
similarity index 100%
rename from tests/src/com/android/launcher3/AbstractDeviceProfileTest.kt
rename to tests/multivalentTests/src/com/android/launcher3/AbstractDeviceProfileTest.kt
diff --git a/tests/src/com/android/launcher3/DeleteDropTargetTest.kt b/tests/multivalentTests/src/com/android/launcher3/DeleteDropTargetTest.kt
similarity index 100%
rename from tests/src/com/android/launcher3/DeleteDropTargetTest.kt
rename to tests/multivalentTests/src/com/android/launcher3/DeleteDropTargetTest.kt
diff --git a/tests/src/com/android/launcher3/FakeInvariantDeviceProfileTest.kt b/tests/multivalentTests/src/com/android/launcher3/FakeInvariantDeviceProfileTest.kt
similarity index 100%
rename from tests/src/com/android/launcher3/FakeInvariantDeviceProfileTest.kt
rename to tests/multivalentTests/src/com/android/launcher3/FakeInvariantDeviceProfileTest.kt
diff --git a/tests/src/com/android/launcher3/LauncherPrefsTest.kt b/tests/multivalentTests/src/com/android/launcher3/LauncherPrefsTest.kt
similarity index 100%
rename from tests/src/com/android/launcher3/LauncherPrefsTest.kt
rename to tests/multivalentTests/src/com/android/launcher3/LauncherPrefsTest.kt
diff --git a/tests/src/com/android/launcher3/allapps/AlphabeticalAppsListTest.java b/tests/multivalentTests/src/com/android/launcher3/allapps/AlphabeticalAppsListTest.java
similarity index 100%
rename from tests/src/com/android/launcher3/allapps/AlphabeticalAppsListTest.java
rename to tests/multivalentTests/src/com/android/launcher3/allapps/AlphabeticalAppsListTest.java
diff --git a/tests/src/com/android/launcher3/folder/FolderNameProviderTest.java b/tests/multivalentTests/src/com/android/launcher3/folder/FolderNameProviderTest.java
similarity index 100%
rename from tests/src/com/android/launcher3/folder/FolderNameProviderTest.java
rename to tests/multivalentTests/src/com/android/launcher3/folder/FolderNameProviderTest.java
diff --git a/tests/src/com/android/launcher3/icons/IconCacheTest.java b/tests/multivalentTests/src/com/android/launcher3/icons/IconCacheTest.java
similarity index 100%
rename from tests/src/com/android/launcher3/icons/IconCacheTest.java
rename to tests/multivalentTests/src/com/android/launcher3/icons/IconCacheTest.java
diff --git a/tests/src/com/android/launcher3/model/DatabaseHelperTest.kt b/tests/multivalentTests/src/com/android/launcher3/model/DatabaseHelperTest.kt
similarity index 100%
rename from tests/src/com/android/launcher3/model/DatabaseHelperTest.kt
rename to tests/multivalentTests/src/com/android/launcher3/model/DatabaseHelperTest.kt
diff --git a/tests/src/com/android/launcher3/model/GridSizeMigrationUtilTest.kt b/tests/multivalentTests/src/com/android/launcher3/model/GridSizeMigrationUtilTest.kt
similarity index 100%
rename from tests/src/com/android/launcher3/model/GridSizeMigrationUtilTest.kt
rename to tests/multivalentTests/src/com/android/launcher3/model/GridSizeMigrationUtilTest.kt
diff --git a/tests/src/com/android/launcher3/responsive/SizeSpecTest.kt b/tests/multivalentTests/src/com/android/launcher3/responsive/SizeSpecTest.kt
similarity index 100%
rename from tests/src/com/android/launcher3/responsive/SizeSpecTest.kt
rename to tests/multivalentTests/src/com/android/launcher3/responsive/SizeSpecTest.kt
diff --git a/tests/src/com/android/launcher3/ui/ActivityAllAppsContainerViewTest.java b/tests/multivalentTests/src/com/android/launcher3/ui/ActivityAllAppsContainerViewTest.java
similarity index 100%
rename from tests/src/com/android/launcher3/ui/ActivityAllAppsContainerViewTest.java
rename to tests/multivalentTests/src/com/android/launcher3/ui/ActivityAllAppsContainerViewTest.java
diff --git a/tests/src/com/android/launcher3/util/CellContentDimensionsTest.kt b/tests/multivalentTests/src/com/android/launcher3/util/CellContentDimensionsTest.kt
similarity index 100%
rename from tests/src/com/android/launcher3/util/CellContentDimensionsTest.kt
rename to tests/multivalentTests/src/com/android/launcher3/util/CellContentDimensionsTest.kt
diff --git a/tests/src/com/android/launcher3/util/PackageManagerHelperTest.java b/tests/multivalentTests/src/com/android/launcher3/util/PackageManagerHelperTest.java
similarity index 100%
rename from tests/src/com/android/launcher3/util/PackageManagerHelperTest.java
rename to tests/multivalentTests/src/com/android/launcher3/util/PackageManagerHelperTest.java
diff --git a/tests/multivalentTests/src/com/android/launcher3/util/WidgetUtils.java b/tests/multivalentTests/src/com/android/launcher3/util/WidgetUtils.java
index deb0ef3..027a31a 100644
--- a/tests/multivalentTests/src/com/android/launcher3/util/WidgetUtils.java
+++ b/tests/multivalentTests/src/com/android/launcher3/util/WidgetUtils.java
@@ -15,12 +15,15 @@
*/
package com.android.launcher3.util;
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
+import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProviderInfo;
import android.content.ComponentName;
import android.content.Context;
-import android.content.pm.ActivityInfo;
-import android.content.pm.ApplicationInfo;
import android.os.Bundle;
+import android.os.Process;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
@@ -84,10 +87,10 @@
* Creates a {@link AppWidgetProviderInfo} for the provided component name
*/
public static AppWidgetProviderInfo createAppWidgetProviderInfo(ComponentName cn) {
- ActivityInfo activityInfo = new ActivityInfo();
- activityInfo.applicationInfo = new ApplicationInfo();
- AppWidgetProviderInfo info = new AppWidgetProviderInfo();
- info.providerInfo = activityInfo;
+ AppWidgetProviderInfo info = AppWidgetManager.getInstance(getApplicationContext())
+ .getInstalledProvidersForPackage(
+ getInstrumentation().getContext().getPackageName(), Process.myUserHandle())
+ .get(0);
info.provider = cn;
return info;
}
diff --git a/tests/src/com/android/launcher3/util/rule/SetFlagsRuleExt.kt b/tests/multivalentTests/src/com/android/launcher3/util/rule/SetFlagsRuleExt.kt
similarity index 100%
rename from tests/src/com/android/launcher3/util/rule/SetFlagsRuleExt.kt
rename to tests/multivalentTests/src/com/android/launcher3/util/rule/SetFlagsRuleExt.kt
diff --git a/tests/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfoTest.java b/tests/multivalentTests/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfoTest.java
similarity index 100%
rename from tests/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfoTest.java
rename to tests/multivalentTests/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfoTest.java
diff --git a/tests/src/com/android/launcher3/AppFilterTest.kt b/tests/src/com/android/launcher3/AppFilterTest.kt
new file mode 100644
index 0000000..f2150a2
--- /dev/null
+++ b/tests/src/com/android/launcher3/AppFilterTest.kt
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2024 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
+
+import android.content.ComponentName
+import android.content.Context
+import android.content.res.Resources
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.`when`
+import org.mockito.junit.MockitoJUnitRunner
+
+@RunWith(MockitoJUnitRunner::class)
+class AppFilterTest {
+
+ @Mock private lateinit var mockContext: Context
+
+ @Mock // Mock the Resources object as well
+ private lateinit var mockResources: Resources
+
+ private lateinit var appFilter: AppFilter
+
+ @Before
+ fun setUp() {
+ `when`(mockContext.resources).thenReturn(mockResources) // Link the context and resources
+ `when`(mockResources.getStringArray(R.array.filtered_components))
+ .thenReturn(arrayOf("com.example.app1/Activity1"))
+ appFilter = AppFilter(mockContext)
+ }
+
+ @Test
+ fun shouldShowApp_notFiltered_returnsTrue() {
+ val appToShow = ComponentName("com.example.app2", "Activity2")
+ assertThat(appFilter.shouldShowApp(appToShow)).isTrue()
+ }
+
+ @Test
+ fun shouldShowApp_filtered_returnsFalse() {
+ val appToHide = ComponentName("com.example.app1", "Activity1")
+ assertThat(appFilter.shouldShowApp(appToHide)).isFalse()
+ }
+}
diff --git a/tests/src/com/android/launcher3/nonquickstep/DeviceProfileDumpTest.kt b/tests/src/com/android/launcher3/nonquickstep/DeviceProfileDumpTest.kt
index 9409ac1..60385a7 100644
--- a/tests/src/com/android/launcher3/nonquickstep/DeviceProfileDumpTest.kt
+++ b/tests/src/com/android/launcher3/nonquickstep/DeviceProfileDumpTest.kt
@@ -15,137 +15,105 @@
*/
package com.android.launcher3.nonquickstep
-import android.content.Context
-import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import androidx.test.platform.app.InstrumentationRegistry
import com.android.launcher3.AbstractDeviceProfileTest
import com.android.launcher3.DeviceProfile
+import com.android.launcher3.Flags
import com.android.launcher3.InvariantDeviceProfile
-import com.google.common.truth.Truth.assertThat
+import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
/** Tests for DeviceProfile. */
@SmallTest
-@RunWith(AndroidJUnit4::class)
+@RunWith(Parameterized::class)
class DeviceProfileDumpTest : AbstractDeviceProfileTest() {
private val folderName: String = "DeviceProfileDumpTest"
- @Test
- fun phonePortrait3Button() {
- initializeVarsForPhone(deviceSpecs["phone"]!!, isGestureMode = false)
- val dp = getDeviceProfileForGrid("5_by_5")
- assertDump(dp, "phonePortrait3Button")
+ @Parameterized.Parameter lateinit var instance: TestCase
+
+ @Before
+ fun setUp() {
+ if (instance.decoupleDepth) {
+ setFlagsRule.enableFlags(Flags.FLAG_ENABLE_SCALING_REVEAL_HOME_ANIMATION)
+ } else {
+ setFlagsRule.disableFlags(Flags.FLAG_ENABLE_SCALING_REVEAL_HOME_ANIMATION)
+ }
}
@Test
- fun phonePortrait() {
- initializeVarsForPhone(deviceSpecs["phone"]!!)
- val dp = getDeviceProfileForGrid("5_by_5")
+ fun dumpPortraitGesture() {
+ initializeDevice(instance.deviceName, isGestureMode = true, isLandscape = false)
+ val dp = getDeviceProfileForGrid(instance.gridName)
+ dp.isTaskbarPresentInApps = instance.isTaskbarPresentInApps
- assertDump(dp, "phonePortrait")
+ assertDump(dp, instance.filename("Portrait"))
}
@Test
- fun phoneVerticalBar3Button() {
- initializeVarsForPhone(deviceSpecs["phone"]!!, isVerticalBar = true, isGestureMode = false)
- val dp = getDeviceProfileForGrid("5_by_5")
+ fun dumpPortrait3Button() {
+ initializeDevice(instance.deviceName, isGestureMode = false, isLandscape = false)
+ val dp = getDeviceProfileForGrid(instance.gridName)
+ dp.isTaskbarPresentInApps = instance.isTaskbarPresentInApps
- assertDump(dp, "phoneVerticalBar3Button")
+ assertDump(dp, instance.filename("Portrait3Button"))
}
@Test
- fun phoneVerticalBar() {
- initializeVarsForPhone(deviceSpecs["phone"]!!, isVerticalBar = true)
- val dp = getDeviceProfileForGrid("5_by_5")
+ fun dumpLandscapeGesture() {
+ initializeDevice(instance.deviceName, isGestureMode = true, isLandscape = true)
+ val dp = getDeviceProfileForGrid(instance.gridName)
+ dp.isTaskbarPresentInApps = instance.isTaskbarPresentInApps
- assertDump(dp, "phoneVerticalBar")
+ val testName =
+ if (instance.deviceName == "phone") {
+ "VerticalBar"
+ } else {
+ "Landscape"
+ }
+ assertDump(dp, instance.filename(testName))
}
@Test
- fun tabletLandscape3Button() {
- initializeVarsForTablet(deviceSpecs["tablet"]!!, isLandscape = true, isGestureMode = false)
- val dp = getDeviceProfileForGrid("6_by_5")
- dp.isTaskbarPresentInApps = true
+ fun dumpLandscape3Button() {
+ initializeDevice(instance.deviceName, isGestureMode = false, isLandscape = true)
+ val dp = getDeviceProfileForGrid(instance.gridName)
+ dp.isTaskbarPresentInApps = instance.isTaskbarPresentInApps
- assertDump(dp, "tabletLandscape3Button")
+ val testName =
+ if (instance.deviceName == "phone") {
+ "VerticalBar3Button"
+ } else {
+ "Landscape3Button"
+ }
+ assertDump(dp, instance.filename(testName))
}
- @Test
- fun tabletLandscape() {
- initializeVarsForTablet(deviceSpecs["tablet"]!!, isLandscape = true)
- val dp = getDeviceProfileForGrid("6_by_5")
- dp.isTaskbarPresentInApps = true
-
- assertDump(dp, "tabletLandscape")
- }
-
- @Test
- fun tabletPortrait3Button() {
- initializeVarsForTablet(deviceSpecs["tablet"]!!, isGestureMode = false)
- val dp = getDeviceProfileForGrid("6_by_5")
- dp.isTaskbarPresentInApps = true
-
- assertDump(dp, "tabletPortrait3Button")
- }
-
- @Test
- fun tabletPortrait() {
- initializeVarsForTablet(deviceSpecs["tablet"]!!)
- val dp = getDeviceProfileForGrid("6_by_5")
- dp.isTaskbarPresentInApps = true
-
- assertDump(dp, "tabletPortrait")
- }
-
- @Test
- fun twoPanelLandscape3Button() {
- initializeVarsForTwoPanel(
- deviceSpecs["twopanel-tablet"]!!,
- deviceSpecs["twopanel-phone"]!!,
- isLandscape = true,
- isGestureMode = false
- )
- val dp = getDeviceProfileForGrid("4_by_4")
- dp.isTaskbarPresentInApps = true
-
- assertDump(dp, "twoPanelLandscape3Button")
- }
-
- @Test
- fun twoPanelLandscape() {
- initializeVarsForTwoPanel(
- deviceSpecs["twopanel-tablet"]!!,
- deviceSpecs["twopanel-phone"]!!,
- isLandscape = true
- )
- val dp = getDeviceProfileForGrid("4_by_4")
- dp.isTaskbarPresentInApps = true
-
- assertDump(dp, "twoPanelLandscape")
- }
-
- @Test
- fun twoPanelPortrait3Button() {
- initializeVarsForTwoPanel(
- deviceSpecs["twopanel-tablet"]!!,
- deviceSpecs["twopanel-phone"]!!,
- isGestureMode = false
- )
- val dp = getDeviceProfileForGrid("4_by_4")
- dp.isTaskbarPresentInApps = true
-
- assertDump(dp, "twoPanelPortrait3Button")
- }
-
- @Test
- fun twoPanelPortrait() {
- initializeVarsForTwoPanel(deviceSpecs["twopanel-tablet"]!!, deviceSpecs["twopanel-phone"]!!)
- val dp = getDeviceProfileForGrid("4_by_4")
- dp.isTaskbarPresentInApps = true
-
- assertDump(dp, "twoPanelPortrait")
+ private fun initializeDevice(deviceName: String, isGestureMode: Boolean, isLandscape: Boolean) {
+ val deviceSpec = deviceSpecs[instance.deviceName]!!
+ when (deviceName) {
+ "twopanel-phone",
+ "twopanel-tablet" ->
+ initializeVarsForTwoPanel(
+ deviceSpecUnfolded = deviceSpecs["twopanel-tablet"]!!,
+ deviceSpecFolded = deviceSpecs["twopanel-phone"]!!,
+ isLandscape = isLandscape,
+ isGestureMode = isGestureMode,
+ )
+ "tablet" ->
+ initializeVarsForTablet(
+ deviceSpec = deviceSpec,
+ isLandscape = isLandscape,
+ isGestureMode = isGestureMode
+ )
+ else ->
+ initializeVarsForPhone(
+ deviceSpec = deviceSpec,
+ isVerticalBar = isLandscape,
+ isGestureMode = isGestureMode
+ )
+ }
}
private fun getDeviceProfileForGrid(gridName: String): DeviceProfile {
@@ -153,6 +121,48 @@
}
private fun assertDump(dp: DeviceProfile, filename: String) {
- assertDump(dp, folderName, filename);
+ assertDump(dp, folderName, filename)
+ }
+
+ companion object {
+ @Parameterized.Parameters(name = "{0}")
+ @JvmStatic
+ fun getInstances(): List<TestCase> {
+ return listOf(
+ TestCase("phone", gridName = "5_by_5"),
+ TestCase("tablet", gridName = "6_by_5", isTaskbarPresentInApps = true),
+ TestCase("twopanel-tablet", gridName = "4_by_4", isTaskbarPresentInApps = true),
+ TestCase(
+ "twopanel-tablet",
+ gridName = "4_by_4",
+ isTaskbarPresentInApps = true,
+ decoupleDepth = true
+ ),
+ )
+ }
+
+ data class TestCase(
+ val deviceName: String,
+ val gridName: String,
+ val isTaskbarPresentInApps: Boolean = false,
+ val decoupleDepth: Boolean = false
+ ) {
+ fun filename(testName: String = ""): String {
+ val device =
+ when (deviceName) {
+ "tablet" -> "tablet"
+ "twopanel-tablet" -> "twoPanel"
+ "twopanel-phone" -> "twoPanelFolded"
+ else -> "phone"
+ }
+ val depth =
+ if (decoupleDepth) {
+ "_decoupleDepth"
+ } else {
+ ""
+ }
+ return "$device$testName$depth"
+ }
+ }
}
}
diff --git a/tests/src/com/android/launcher3/popup/SystemShortcutTest.java b/tests/src/com/android/launcher3/popup/SystemShortcutTest.java
index dc8c17a..c663be0 100644
--- a/tests/src/com/android/launcher3/popup/SystemShortcutTest.java
+++ b/tests/src/com/android/launcher3/popup/SystemShortcutTest.java
@@ -57,6 +57,7 @@
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.pm.UserCache;
+import com.android.launcher3.util.ApiWrapper;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.LauncherModelHelper.SandboxModelContext;
import com.android.launcher3.util.TestSandboxModelContextWrapper;
@@ -88,6 +89,7 @@
private PopupDataProvider mPopupDataProvider;
private AppInfo mAppInfo;
@Mock UserCache mUserCache;
+ @Mock ApiWrapper mApiWrapper;
@Mock BaseDragLayer mBaseDragLayer;
@Mock UserIconInfo mUserIconInfo;
@Mock LauncherActivityInfo mLauncherActivityInfo;
@@ -98,6 +100,7 @@
public void setUp() {
MockitoAnnotations.initMocks(this);
mSandboxContext.putObject(UserCache.INSTANCE, mUserCache);
+ mSandboxContext.putObject(ApiWrapper.INSTANCE, mApiWrapper);
mTestContext = new TestSandboxModelContextWrapper(mSandboxContext);
mView = new View(mSandboxContext);
spyOn(mTestContext);
diff --git a/tests/multivalentTests/src/com/android/launcher3/widget/picker/WidgetImageViewTest.kt b/tests/src/com/android/launcher3/widget/picker/WidgetImageViewTest.kt
similarity index 100%
rename from tests/multivalentTests/src/com/android/launcher3/widget/picker/WidgetImageViewTest.kt
rename to tests/src/com/android/launcher3/widget/picker/WidgetImageViewTest.kt
diff --git a/tests/multivalentTests/src/com/android/launcher3/widget/picker/WidgetRecommendationCategoryProviderTest.java b/tests/src/com/android/launcher3/widget/picker/WidgetRecommendationCategoryProviderTest.java
similarity index 92%
rename from tests/multivalentTests/src/com/android/launcher3/widget/picker/WidgetRecommendationCategoryProviderTest.java
rename to tests/src/com/android/launcher3/widget/picker/WidgetRecommendationCategoryProviderTest.java
index 3024d26..7476454 100644
--- a/tests/multivalentTests/src/com/android/launcher3/widget/picker/WidgetRecommendationCategoryProviderTest.java
+++ b/tests/src/com/android/launcher3/widget/picker/WidgetRecommendationCategoryProviderTest.java
@@ -25,6 +25,7 @@
import static android.content.pm.ApplicationInfo.CATEGORY_VIDEO;
import static android.content.pm.ApplicationInfo.FLAG_INSTALLED;
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
import static com.google.common.truth.Truth.assertThat;
@@ -34,6 +35,7 @@
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.when;
+import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProviderInfo;
import android.content.ComponentName;
import android.content.Context;
@@ -51,7 +53,6 @@
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.model.WidgetItem;
import com.android.launcher3.util.Executors;
-import com.android.launcher3.util.WidgetUtils;
import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
import com.google.common.collect.ImmutableMap;
@@ -151,8 +152,11 @@
doAnswer(invocation -> widgetLabel).when(mIconCache).getTitleNoCache(any());
- AppWidgetProviderInfo providerInfo = WidgetUtils.createAppWidgetProviderInfo(ComponentName
- .createRelative(TEST_PACKAGE, widgetClassName));
+ AppWidgetProviderInfo providerInfo = AppWidgetManager.getInstance(getApplicationContext())
+ .getInstalledProvidersForPackage(
+ getInstrumentation().getContext().getPackageName(), Process.myUserHandle())
+ .get(0);
+ providerInfo.provider = ComponentName.createRelative(TEST_PACKAGE, widgetClassName);
LauncherAppWidgetProviderInfo launcherAppWidgetProviderInfo =
LauncherAppWidgetProviderInfo.fromProviderInfo(mContext, providerInfo);
diff --git a/tests/multivalentTests/src/com/android/launcher3/widget/picker/WidgetsListHeaderAccessibilityTest.java b/tests/src/com/android/launcher3/widget/picker/WidgetsListHeaderAccessibilityTest.java
similarity index 100%
rename from tests/multivalentTests/src/com/android/launcher3/widget/picker/WidgetsListHeaderAccessibilityTest.java
rename to tests/src/com/android/launcher3/widget/picker/WidgetsListHeaderAccessibilityTest.java
diff --git a/tests/multivalentTests/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinderTest.java b/tests/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinderTest.java
similarity index 100%
rename from tests/multivalentTests/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinderTest.java
rename to tests/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinderTest.java
diff --git a/tests/multivalentTests/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinderTest.java b/tests/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinderTest.java
similarity index 100%
rename from tests/multivalentTests/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinderTest.java
rename to tests/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinderTest.java
diff --git a/tests/multivalentTests/src/com/android/launcher3/widget/picker/model/WidgetsListContentEntryTest.java b/tests/src/com/android/launcher3/widget/picker/model/WidgetsListContentEntryTest.java
similarity index 100%
rename from tests/multivalentTests/src/com/android/launcher3/widget/picker/model/WidgetsListContentEntryTest.java
rename to tests/src/com/android/launcher3/widget/picker/model/WidgetsListContentEntryTest.java
diff --git a/tests/multivalentTests/src/com/android/launcher3/widget/picker/search/SimpleWidgetsSearchAlgorithmTest.java b/tests/src/com/android/launcher3/widget/picker/search/SimpleWidgetsSearchAlgorithmTest.java
similarity index 98%
rename from tests/multivalentTests/src/com/android/launcher3/widget/picker/search/SimpleWidgetsSearchAlgorithmTest.java
rename to tests/src/com/android/launcher3/widget/picker/search/SimpleWidgetsSearchAlgorithmTest.java
index 0370a6b..9c03ccf 100644
--- a/tests/multivalentTests/src/com/android/launcher3/widget/picker/search/SimpleWidgetsSearchAlgorithmTest.java
+++ b/tests/src/com/android/launcher3/widget/picker/search/SimpleWidgetsSearchAlgorithmTest.java
@@ -17,7 +17,6 @@
package com.android.launcher3.widget.picker.search;
import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
-import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.WidgetUtils.createAppWidgetProviderInfo;
@@ -164,7 +163,7 @@
.when(mDataProvider)
.getAllWidgets();
mSimpleWidgetsSearchAlgorithm.doSearch("Ca", mSearchCallback);
- getInstrumentation().waitForIdleSync();
+ MAIN_EXECUTOR.submit(() -> { }).get();
verify(mSearchCallback).onSearchResult(
matches("Ca"), argThat(a -> a != null && !a.isEmpty()));
}
diff --git a/tests/multivalentTests/src/com/android/launcher3/widget/picker/util/WidgetPreviewContainerSizesTest.kt b/tests/src/com/android/launcher3/widget/picker/util/WidgetPreviewContainerSizesTest.kt
similarity index 93%
rename from tests/multivalentTests/src/com/android/launcher3/widget/picker/util/WidgetPreviewContainerSizesTest.kt
rename to tests/src/com/android/launcher3/widget/picker/util/WidgetPreviewContainerSizesTest.kt
index 7b629bf..040fbf5 100644
--- a/tests/multivalentTests/src/com/android/launcher3/widget/picker/util/WidgetPreviewContainerSizesTest.kt
+++ b/tests/src/com/android/launcher3/widget/picker/util/WidgetPreviewContainerSizesTest.kt
@@ -43,7 +43,6 @@
private lateinit var context: Context
private lateinit var deviceProfile: DeviceProfile
private lateinit var testInvariantProfile: InvariantDeviceProfile
- private lateinit var widgetItemInvariantProfile: InvariantDeviceProfile
@Mock private lateinit var iconCache: IconCache
@@ -52,11 +51,6 @@
MockitoAnnotations.initMocks(this)
context = ActivityContextWrapper(ApplicationProvider.getApplicationContext())
testInvariantProfile = LauncherAppState.getIDP(context)
- widgetItemInvariantProfile =
- InvariantDeviceProfile().apply {
- numRows = TEST_GRID_SIZE
- numColumns = TEST_GRID_SIZE
- }
deviceProfile = testInvariantProfile.getDeviceProfile(context).copy(context)
}
@@ -66,8 +60,7 @@
val expectedPreviewContainers = testSizes.values.toList()
for ((index, widgetSize) in testSizes.keys.withIndex()) {
- val widgetItem =
- createWidgetItem(widgetSize, context, widgetItemInvariantProfile, iconCache)
+ val widgetItem = createWidgetItem(widgetSize, context, testInvariantProfile, iconCache)
assertWithMessage("size for $widgetSize should be: ${expectedPreviewContainers[index]}")
.that(WidgetPreviewContainerSize.forItem(widgetItem, deviceProfile))
@@ -77,7 +70,6 @@
companion object {
private const val TEST_PACKAGE = "com.google.test"
- private const val TEST_GRID_SIZE = 6
private val HANDHELD_TEST_SIZES: Map<Point, WidgetPreviewContainerSize> =
mapOf(
diff --git a/tests/multivalentTests/src/com/android/launcher3/widget/picker/util/WidgetsTableUtilsTest.java b/tests/src/com/android/launcher3/widget/picker/util/WidgetsTableUtilsTest.java
similarity index 100%
rename from tests/multivalentTests/src/com/android/launcher3/widget/picker/util/WidgetsTableUtilsTest.java
rename to tests/src/com/android/launcher3/widget/picker/util/WidgetsTableUtilsTest.java