Merge "Fix bug with portrait-fold devices animating app pairs launch wrongly" into main
diff --git a/Android.bp b/Android.bp
index eca0778..61042f6 100644
--- a/Android.bp
+++ b/Android.bp
@@ -108,6 +108,7 @@
],
srcs: [
"tests/multivalentTests/tapl/**/*.java",
+ "tests/multivalentTests/tapl/**/*.kt",
],
resource_dirs: [],
manifest: "tests/multivalentTests/tapl/AndroidManifest.xml",
diff --git a/quickstep/res/layout/task.xml b/quickstep/res/layout/task.xml
index 823a86e..9d599c9 100644
--- a/quickstep/res/layout/task.xml
+++ b/quickstep/res/layout/task.xml
@@ -19,6 +19,7 @@
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
xmlns:launcher="http://schemas.android.com/apk/res-auto"
+ android:id="@+id/task"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
diff --git a/quickstep/res/layout/task_desktop.xml b/quickstep/res/layout/task_desktop.xml
index 60827cd..3cafcfd 100644
--- a/quickstep/res/layout/task_desktop.xml
+++ b/quickstep/res/layout/task_desktop.xml
@@ -19,6 +19,7 @@
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
xmlns:launcher="http://schemas.android.com/apk/res-auto"
+ android:id="@+id/task"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="true"
diff --git a/quickstep/res/layout/task_grouped.xml b/quickstep/res/layout/task_grouped.xml
index d20afd3..e91e773 100644
--- a/quickstep/res/layout/task_grouped.xml
+++ b/quickstep/res/layout/task_grouped.xml
@@ -24,6 +24,7 @@
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
xmlns:launcher="http://schemas.android.com/apk/res-auto"
+ android:id="@+id/task"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
diff --git a/quickstep/res/values/config.xml b/quickstep/res/values/config.xml
index 8a3ffb5..e45d9fd 100644
--- a/quickstep/res/values/config.xml
+++ b/quickstep/res/values/config.xml
@@ -53,5 +53,5 @@
<string name="setup_wizard_pkg" translatable="false" />
<!-- This is a float because it is converted to dp later in DeviceProfile -->
- <item name="taskbar_icon_size" type="dimen" format="float">48.4</item>
+ <item name="taskbar_icon_size" type="dimen" format="float">44</item>
</resources>
diff --git a/quickstep/res/values/strings.xml b/quickstep/res/values/strings.xml
index b23c283..325c255 100644
--- a/quickstep/res/values/strings.xml
+++ b/quickstep/res/values/strings.xml
@@ -267,7 +267,7 @@
<string name="taskbar_edu_features">Do more with the Taskbar</string>
<!-- Title in dialog that shows a user how to pin the Taskbar. [CHAR_LIMIT 60] -->
<string name="taskbar_edu_pinning_title">Always show the Taskbar</string>
- <!-- Text in dialog that shows a user how to pin the Taskbar. [CHAR_LIMIT 60] -->
+ <!-- Text in dialog that shows a user how to pin the Taskbar. [CHAR_LIMIT 150] -->
<string name="taskbar_edu_pinning_standalone">To always show the Taskbar on the bottom of your screen, touch & hold the divider</string>
<!-- Text on button to exit a tutorial [CHAR_LIMIT=16] -->
<string name="taskbar_edu_close">Close</string>
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index ac0e53e..a70e7f3 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -1355,7 +1355,7 @@
@Override
public boolean handleIncorrectSplitTargetSelection() {
- if (enableSplitContextually() && !mSplitSelectStateController.isSplitSelectActive()) {
+ if (!enableSplitContextually() || !mSplitSelectStateController.isSplitSelectActive()) {
return false;
}
mSplitSelectStateController.getSplitInstructionsView().goBoing();
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java
index d98e608..74ba006 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java
@@ -31,6 +31,8 @@
import android.view.Window;
import android.view.WindowManager;
+import androidx.annotation.VisibleForTesting;
+
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
@@ -51,12 +53,12 @@
private final Launcher mLauncher;
private final SystemUiProxy mSystemUiProxy;
- private final float mTouchSlop;
+ @VisibleForTesting final float mTouchSlop;
private int mLastAction;
private final SparseArray<PointF> mDownEvents;
/* If {@code false}, this controller should not handle the input {@link MotionEvent}.*/
- private boolean mCanIntercept;
+ @VisibleForTesting boolean mCanIntercept;
private boolean mIsTrackpadReverseScroll;
@@ -85,9 +87,9 @@
@Override
public final boolean onControllerInterceptTouchEvent(MotionEvent ev) {
- int action = ev.getActionMasked();
- int idx = ev.getActionIndex();
- int pid = ev.getPointerId(idx);
+ final int action = ev.getActionMasked();
+ final int idx = ev.getActionIndex();
+ final int pid = ev.getPointerId(idx);
if (action == ACTION_DOWN) {
mCanIntercept = canInterceptTouch(ev);
if (!mCanIntercept) {
@@ -135,7 +137,6 @@
.log(LAUNCHER_SWIPE_DOWN_WORKSPACE_NOTISHADE_OPEN);
setWindowSlippery(false);
mIsTrackpadReverseScroll = false;
- return true;
}
return true;
}
@@ -149,7 +150,8 @@
* Touches can slide out of the window but they cannot necessarily slide
* back in (unless the other window with touch focus permits it).
*/
- private void setWindowSlippery(boolean enable) {
+ @VisibleForTesting
+ void setWindowSlippery(boolean enable) {
Window w = mLauncher.getWindow();
WindowManager.LayoutParams wlp = w.getAttributes();
if (enable) {
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
index c8c7dc2..0f8ceba 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
@@ -154,6 +154,7 @@
mSquaredTouchSlop = mDeviceState.getSquaredTouchSlop();
mPassedPilferInputSlop = mPassedWindowMoveSlop = continuingPreviousGesture;
+ mStartDisplacement = continuingPreviousGesture ? 0 : -mTouchSlop;
mDisableHorizontalSwipe = !mPassedPilferInputSlop && disableHorizontalSwipe;
mRotationTouchHelper = mDeviceState.getRotationTouchHelper();
}
@@ -280,7 +281,7 @@
if (mGestureState.isTrackpadGesture() || Math.abs(displacement)
> mTouchSlop) {
mPassedWindowMoveSlop = true;
- mStartDisplacement = Math.min(displacement, -mTouchSlop);
+ mStartDisplacement = -mTouchSlop;
}
}
}
@@ -336,7 +337,7 @@
}
if (!mPassedWindowMoveSlop) {
mPassedWindowMoveSlop = true;
- mStartDisplacement = Math.min(displacement, -mTouchSlop);
+ mStartDisplacement = -mTouchSlop;
}
notifyGestureStarted(isLikelyToStartNewTask);
}
diff --git a/quickstep/src/com/android/quickstep/orientation/LandscapePagedViewHandler.java b/quickstep/src/com/android/quickstep/orientation/LandscapePagedViewHandler.java
index e41832b..a7ca515 100644
--- a/quickstep/src/com/android/quickstep/orientation/LandscapePagedViewHandler.java
+++ b/quickstep/src/com/android/quickstep/orientation/LandscapePagedViewHandler.java
@@ -36,6 +36,7 @@
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_TYPE_MAIN;
import android.content.res.Resources;
+import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
@@ -533,34 +534,52 @@
int dividerBar = Math.round(totalThumbnailHeight * (splitBoundsConfig.appsStackedVertically
? splitBoundsConfig.dividerHeightPercent
: splitBoundsConfig.dividerWidthPercent));
- int primarySnapshotHeight;
- int primarySnapshotWidth;
- int secondarySnapshotHeight;
- int secondarySnapshotWidth;
- float taskPercent = splitBoundsConfig.appsStackedVertically ?
- splitBoundsConfig.topTaskPercent : splitBoundsConfig.leftTaskPercent;
- primarySnapshotWidth = parentWidth;
- primarySnapshotHeight = (int) (totalThumbnailHeight * (taskPercent));
+ Pair<Point, Point> taskViewSizes =
+ getGroupedTaskViewSizes(dp, splitBoundsConfig, parentWidth, parentHeight);
- secondarySnapshotWidth = parentWidth;
- secondarySnapshotHeight = totalThumbnailHeight - primarySnapshotHeight - dividerBar;
-
- int translationY = primarySnapshotHeight + spaceAboveSnapshot + dividerBar;
+ int translationY = taskViewSizes.first.y + spaceAboveSnapshot + dividerBar;
primarySnapshot.setTranslationY(spaceAboveSnapshot);
secondarySnapshot.setTranslationY(translationY - spaceAboveSnapshot);
primarySnapshot.measure(
- View.MeasureSpec.makeMeasureSpec(primarySnapshotWidth, View.MeasureSpec.EXACTLY),
- View.MeasureSpec.makeMeasureSpec(primarySnapshotHeight, View.MeasureSpec.EXACTLY)
+ View.MeasureSpec.makeMeasureSpec(taskViewSizes.first.x, View.MeasureSpec.EXACTLY),
+ View.MeasureSpec.makeMeasureSpec(taskViewSizes.first.y, View.MeasureSpec.EXACTLY)
);
secondarySnapshot.measure(
- View.MeasureSpec.makeMeasureSpec(secondarySnapshotWidth, View.MeasureSpec.EXACTLY),
- View.MeasureSpec.makeMeasureSpec(secondarySnapshotHeight, View.MeasureSpec.EXACTLY)
+ View.MeasureSpec.makeMeasureSpec(taskViewSizes.second.x, View.MeasureSpec.EXACTLY),
+ View.MeasureSpec.makeMeasureSpec(taskViewSizes.second.y, View.MeasureSpec.EXACTLY)
);
}
@Override
+ public Pair<Point, Point> getGroupedTaskViewSizes(
+ DeviceProfile dp,
+ SplitBounds splitBoundsConfig,
+ int parentWidth,
+ int parentHeight) {
+ int spaceAboveSnapshot = dp.overviewTaskThumbnailTopMarginPx;
+ int totalThumbnailHeight = parentHeight - spaceAboveSnapshot;
+ int dividerBar = Math.round(totalThumbnailHeight * (splitBoundsConfig.appsStackedVertically
+ ? splitBoundsConfig.dividerHeightPercent
+ : splitBoundsConfig.dividerWidthPercent));
+ float taskPercent = splitBoundsConfig.appsStackedVertically
+ ? splitBoundsConfig.topTaskPercent
+ : splitBoundsConfig.leftTaskPercent;
+
+ Point firstTaskViewSize = new Point(
+ parentWidth,
+ (int) (totalThumbnailHeight * taskPercent)
+ );
+ Point secondTaskViewSize = new Point(
+ parentWidth,
+ totalThumbnailHeight - firstTaskViewSize.y - dividerBar
+ );
+
+ return new Pair<>(firstTaskViewSize, secondTaskViewSize);
+ }
+
+ @Override
public void setTaskIconParams(FrameLayout.LayoutParams iconParams, int taskIconMargin,
int taskIconHeight, int thumbnailTopMargin, boolean isRtl) {
if (enableOverviewIconMenu()) {
diff --git a/quickstep/src/com/android/quickstep/orientation/PortraitPagedViewHandler.java b/quickstep/src/com/android/quickstep/orientation/PortraitPagedViewHandler.java
index 3d7065b..5d9a668 100644
--- a/quickstep/src/com/android/quickstep/orientation/PortraitPagedViewHandler.java
+++ b/quickstep/src/com/android/quickstep/orientation/PortraitPagedViewHandler.java
@@ -34,6 +34,7 @@
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_TYPE_MAIN;
import android.graphics.Matrix;
+import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
@@ -530,25 +531,16 @@
float dividerScale = splitBoundsConfig.appsStackedVertically
? splitBoundsConfig.dividerHeightPercent
: splitBoundsConfig.dividerWidthPercent;
- int primarySnapshotHeight;
- int primarySnapshotWidth;
- int secondarySnapshotHeight;
- int secondarySnapshotWidth;
- float taskPercent = splitBoundsConfig.appsStackedVertically ?
- splitBoundsConfig.topTaskPercent : splitBoundsConfig.leftTaskPercent;
+ Pair<Point, Point> taskViewSizes =
+ getGroupedTaskViewSizes(dp, splitBoundsConfig, parentWidth, parentHeight);
if (dp.isLeftRightSplit) {
int scaledDividerBar = Math.round(parentWidth * dividerScale);
- primarySnapshotHeight = totalThumbnailHeight;
- primarySnapshotWidth = Math.round(parentWidth * taskPercent);
-
- secondarySnapshotHeight = totalThumbnailHeight;
- secondarySnapshotWidth = parentWidth - primarySnapshotWidth - scaledDividerBar;
if (isRtl) {
- int translationX = secondarySnapshotWidth + scaledDividerBar;
+ int translationX = taskViewSizes.second.x + scaledDividerBar;
primarySnapshot.setTranslationX(-translationX);
secondarySnapshot.setTranslationX(0);
} else {
- int translationX = primarySnapshotWidth + scaledDividerBar;
+ int translationX = taskViewSizes.first.x + scaledDividerBar;
secondarySnapshot.setTranslationX(translationX);
primarySnapshot.setTranslationX(0);
}
@@ -557,18 +549,8 @@
// Reset unused translations
primarySnapshot.setTranslationY(0);
} else {
- int taskbarHeight = dp.isTransientTaskbar ? 0 : dp.taskbarHeight;
- float scale = (float) totalThumbnailHeight / (dp.availableHeightPx - taskbarHeight);
- float topTaskHeight = dp.availableHeightPx * taskPercent;
float finalDividerHeight = Math.round(totalThumbnailHeight * dividerScale);
- float scaledTopTaskHeight = topTaskHeight * scale;
- primarySnapshotWidth = parentWidth;
- primarySnapshotHeight = Math.round(scaledTopTaskHeight);
-
- secondarySnapshotWidth = parentWidth;
- secondarySnapshotHeight = Math.round(totalThumbnailHeight - primarySnapshotHeight
- - finalDividerHeight);
- float translationY = primarySnapshotHeight + spaceAboveSnapshot + finalDividerHeight;
+ float translationY = taskViewSizes.first.y + spaceAboveSnapshot + finalDividerHeight;
secondarySnapshot.setTranslationY(translationY);
FrameLayout.LayoutParams primaryParams =
@@ -584,11 +566,11 @@
primarySnapshot.setTranslationX(0);
}
primarySnapshot.measure(
- View.MeasureSpec.makeMeasureSpec(primarySnapshotWidth, View.MeasureSpec.EXACTLY),
- View.MeasureSpec.makeMeasureSpec(primarySnapshotHeight, View.MeasureSpec.EXACTLY));
+ View.MeasureSpec.makeMeasureSpec(taskViewSizes.first.x, View.MeasureSpec.EXACTLY),
+ View.MeasureSpec.makeMeasureSpec(taskViewSizes.first.y, View.MeasureSpec.EXACTLY));
secondarySnapshot.measure(
- View.MeasureSpec.makeMeasureSpec(secondarySnapshotWidth, View.MeasureSpec.EXACTLY),
- View.MeasureSpec.makeMeasureSpec(secondarySnapshotHeight,
+ View.MeasureSpec.makeMeasureSpec(taskViewSizes.second.x, View.MeasureSpec.EXACTLY),
+ View.MeasureSpec.makeMeasureSpec(taskViewSizes.second.y,
View.MeasureSpec.EXACTLY));
primarySnapshot.setScaleX(1);
secondarySnapshot.setScaleX(1);
@@ -597,6 +579,48 @@
}
@Override
+ public Pair<Point, Point> getGroupedTaskViewSizes(
+ DeviceProfile dp,
+ SplitBounds splitBoundsConfig,
+ int parentWidth,
+ int parentHeight) {
+ int spaceAboveSnapshot = dp.overviewTaskThumbnailTopMarginPx;
+ int totalThumbnailHeight = parentHeight - spaceAboveSnapshot;
+ float dividerScale = splitBoundsConfig.appsStackedVertically
+ ? splitBoundsConfig.dividerHeightPercent
+ : splitBoundsConfig.dividerWidthPercent;
+ float taskPercent = splitBoundsConfig.appsStackedVertically
+ ? splitBoundsConfig.topTaskPercent
+ : splitBoundsConfig.leftTaskPercent;
+
+ Point firstTaskViewSize = new Point();
+ Point secondTaskViewSize = new Point();
+
+ if (dp.isLeftRightSplit) {
+ int scaledDividerBar = Math.round(parentWidth * dividerScale);
+ firstTaskViewSize.x = Math.round(parentWidth * taskPercent);
+ firstTaskViewSize.y = totalThumbnailHeight;
+
+ secondTaskViewSize.x = parentWidth - firstTaskViewSize.x - scaledDividerBar;
+ secondTaskViewSize.y = totalThumbnailHeight;
+ } else {
+ int taskbarHeight = dp.isTransientTaskbar ? 0 : dp.taskbarHeight;
+ float scale = (float) totalThumbnailHeight / (dp.availableHeightPx - taskbarHeight);
+ float topTaskHeight = dp.availableHeightPx * taskPercent;
+ float finalDividerHeight = Math.round(totalThumbnailHeight * dividerScale);
+ float scaledTopTaskHeight = topTaskHeight * scale;
+ firstTaskViewSize.x = parentWidth;
+ firstTaskViewSize.y = Math.round(scaledTopTaskHeight);
+
+ secondTaskViewSize.x = parentWidth;
+ secondTaskViewSize.y = Math.round(totalThumbnailHeight - firstTaskViewSize.y
+ - finalDividerHeight);
+ }
+
+ return new Pair<>(firstTaskViewSize, secondTaskViewSize);
+ }
+
+ @Override
public void setTaskIconParams(FrameLayout.LayoutParams iconParams, int taskIconMargin,
int taskIconHeight, int thumbnailTopMargin, boolean isRtl) {
if (enableOverviewIconMenu()) {
diff --git a/quickstep/src/com/android/quickstep/orientation/RecentsPagedOrientationHandler.java b/quickstep/src/com/android/quickstep/orientation/RecentsPagedOrientationHandler.java
index 34756b4..9084297 100644
--- a/quickstep/src/com/android/quickstep/orientation/RecentsPagedOrientationHandler.java
+++ b/quickstep/src/com/android/quickstep/orientation/RecentsPagedOrientationHandler.java
@@ -17,6 +17,7 @@
package com.android.quickstep.orientation;
+import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
@@ -135,6 +136,15 @@
int parentWidth, int parentHeight,
SplitBounds splitBoundsConfig, DeviceProfile dp, boolean isRtl);
+ /**
+ * Creates two Points representing the dimensions of the two tasks in a GroupedTaskView
+ *
+ * @return first -> primary task snapshot, second -> secondary task snapshot.
+ * x -> width, y -> height
+ */
+ Pair<Point, Point> getGroupedTaskViewSizes(DeviceProfile dp, SplitBounds splitBoundsConfig,
+ int parentWidth, int parentHeight);
+
// Overview TaskMenuView methods
void setTaskIconParams(FrameLayout.LayoutParams iconParams,
int taskIconMargin, int taskIconHeight, int thumbnailTopMargin, boolean isRtl);
diff --git a/quickstep/src/com/android/quickstep/orientation/SeascapePagedViewHandler.java b/quickstep/src/com/android/quickstep/orientation/SeascapePagedViewHandler.java
index 7e53cf1..f3001fc 100644
--- a/quickstep/src/com/android/quickstep/orientation/SeascapePagedViewHandler.java
+++ b/quickstep/src/com/android/quickstep/orientation/SeascapePagedViewHandler.java
@@ -31,6 +31,7 @@
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_TYPE_MAIN;
import android.content.res.Resources;
+import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
import android.util.Pair;
@@ -342,31 +343,52 @@
int dividerBar = Math.round(totalThumbnailHeight * (splitBoundsConfig.appsStackedVertically
? splitBoundsConfig.dividerHeightPercent
: splitBoundsConfig.dividerWidthPercent));
- int primarySnapshotHeight;
- int primarySnapshotWidth;
- int secondarySnapshotHeight;
- int secondarySnapshotWidth;
- float taskPercent = splitBoundsConfig.appsStackedVertically ?
- splitBoundsConfig.topTaskPercent : splitBoundsConfig.leftTaskPercent;
- primarySnapshotWidth = parentWidth;
- primarySnapshotHeight = (int) (totalThumbnailHeight * (taskPercent));
+ Pair<Point, Point> taskViewSizes =
+ getGroupedTaskViewSizes(dp, splitBoundsConfig, parentWidth, parentHeight);
- secondarySnapshotWidth = parentWidth;
- secondarySnapshotHeight = totalThumbnailHeight - primarySnapshotHeight - dividerBar;
secondarySnapshot.setTranslationY(0);
- primarySnapshot.setTranslationY(secondarySnapshotHeight + spaceAboveSnapshot + dividerBar);
+ primarySnapshot.setTranslationY(taskViewSizes.second.y + spaceAboveSnapshot + dividerBar);
primarySnapshot.measure(
- View.MeasureSpec.makeMeasureSpec(primarySnapshotWidth, View.MeasureSpec.EXACTLY),
- View.MeasureSpec.makeMeasureSpec(primarySnapshotHeight, View.MeasureSpec.EXACTLY)
+ View.MeasureSpec.makeMeasureSpec(taskViewSizes.first.x, View.MeasureSpec.EXACTLY),
+ View.MeasureSpec.makeMeasureSpec(taskViewSizes.first.y, View.MeasureSpec.EXACTLY)
);
secondarySnapshot.measure(
- View.MeasureSpec.makeMeasureSpec(secondarySnapshotWidth, View.MeasureSpec.EXACTLY),
- View.MeasureSpec.makeMeasureSpec(secondarySnapshotHeight, View.MeasureSpec.EXACTLY)
+ View.MeasureSpec.makeMeasureSpec(taskViewSizes.second.x, View.MeasureSpec.EXACTLY),
+ View.MeasureSpec.makeMeasureSpec(taskViewSizes.second.y, View.MeasureSpec.EXACTLY)
);
}
+ @Override
+ public Pair<Point, Point> getGroupedTaskViewSizes(
+ DeviceProfile dp,
+ SplitBounds splitBoundsConfig,
+ int parentWidth,
+ int parentHeight) {
+ // Measure and layout the thumbnails bottom up, since the primary is on the visual left
+ // (portrait bottom) and secondary is on the right (portrait top)
+ int spaceAboveSnapshot = dp.overviewTaskThumbnailTopMarginPx;
+ int totalThumbnailHeight = parentHeight - spaceAboveSnapshot;
+ int dividerBar = Math.round(totalThumbnailHeight * (splitBoundsConfig.appsStackedVertically
+ ? splitBoundsConfig.dividerHeightPercent
+ : splitBoundsConfig.dividerWidthPercent));
+ float taskPercent = splitBoundsConfig.appsStackedVertically
+ ? splitBoundsConfig.topTaskPercent
+ : splitBoundsConfig.leftTaskPercent;
+
+ Point firstTaskViewSize = new Point(
+ parentWidth,
+ (int) (totalThumbnailHeight * taskPercent)
+ );
+ Point secondTaskViewSize = new Point(
+ parentWidth,
+ totalThumbnailHeight - firstTaskViewSize.y - dividerBar
+ );
+
+ return new Pair<>(firstTaskViewSize, secondTaskViewSize);
+ }
+
/* ---------- The following are only used by TaskViewTouchHandler. ---------- */
@Override
diff --git a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
index 2ae64ff..66c67e7 100644
--- a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
+++ b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
@@ -7,11 +7,14 @@
import static com.android.quickstep.util.SplitScreenUtils.convertLauncherSplitBoundsToShell;
import android.content.Context;
+import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
import android.util.AttributeSet;
+import android.util.Pair;
import android.view.MotionEvent;
import android.view.View;
+import android.view.ViewGroup;
import android.view.ViewStub;
import androidx.annotation.NonNull;
@@ -37,10 +40,11 @@
import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
import com.android.wm.shell.common.split.SplitScreenConstants.PersistentSnapPosition;
+import kotlin.Unit;
+
import java.util.HashMap;
import java.util.function.Consumer;
-import kotlin.Unit;
/**
* TaskView that contains and shows thumbnails for not one, BUT TWO(!!) tasks
@@ -374,18 +378,7 @@
}
if (!enableOverviewIconMenu()) {
updateIconPlacement();
- return;
}
-
- if (getRecentsView() == null) {
- return;
- }
-
- int iconMargins = getResources().getDimensionPixelSize(
- R.dimen.task_thumbnail_icon_menu_start_margin) * 2;
- ((IconAppChipView) mIconView).setMaxWidth(mSnapshotView.getMeasuredWidth() - iconMargins);
- ((IconAppChipView) mIconView2).setMaxWidth(mSnapshotView2.getMeasuredWidth() - iconMargins);
- setOrientationState(getRecentsView().getPagedViewOrientedState());
}
@Override
@@ -395,8 +388,25 @@
@Override
public void setOrientationState(RecentsOrientedState orientationState) {
- super.setOrientationState(orientationState);
DeviceProfile deviceProfile = mActivity.getDeviceProfile();
+ if (enableOverviewIconMenu() && mSplitBoundsConfig != null) {
+ ViewGroup.LayoutParams layoutParams = getLayoutParams();
+ Pair<Point, Point> groupedTaskViewSizes =
+ orientationState.getOrientationHandler().getGroupedTaskViewSizes(
+ deviceProfile,
+ mSplitBoundsConfig,
+ layoutParams.width,
+ layoutParams.height
+ );
+ int iconMargins = getResources().getDimensionPixelSize(
+ R.dimen.task_thumbnail_icon_menu_start_margin) * 2;
+ ((IconAppChipView) mIconView).setMaxWidth(groupedTaskViewSizes.first.x - iconMargins);
+ ((IconAppChipView) mIconView2).setMaxWidth(groupedTaskViewSizes.second.x - iconMargins);
+ }
+ // setMaxWidth() needs to be called before mIconView.setIconOrientation which is called in
+ // the super below.
+ super.setOrientationState(orientationState);
+
boolean isGridTask = deviceProfile.isTablet && !isFocusedTask();
mIconView2.setIconOrientation(orientationState, isGridTask);
updateIconPlacement();
@@ -412,10 +422,27 @@
int taskIconHeight = deviceProfile.overviewTaskIconSizePx;
boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
- getPagedOrientationHandler().setSplitIconParams(mIconView.asView(), mIconView2.asView(),
- taskIconHeight, mSnapshotView.getMeasuredWidth(), mSnapshotView.getMeasuredHeight(),
- getMeasuredHeight(), getMeasuredWidth(), isRtl, deviceProfile,
- mSplitBoundsConfig);
+ if (enableOverviewIconMenu()) {
+ ViewGroup.LayoutParams layoutParams = getLayoutParams();
+ Pair<Point, Point> groupedTaskViewSizes =
+ getPagedOrientationHandler()
+ .getGroupedTaskViewSizes(
+ deviceProfile,
+ mSplitBoundsConfig,
+ layoutParams.width,
+ layoutParams.height
+ );
+
+ getPagedOrientationHandler().setSplitIconParams(mIconView.asView(), mIconView2.asView(),
+ taskIconHeight, groupedTaskViewSizes.first.x, groupedTaskViewSizes.first.y,
+ getLayoutParams().height, getLayoutParams().width, isRtl, deviceProfile,
+ mSplitBoundsConfig);
+ } else {
+ getPagedOrientationHandler().setSplitIconParams(mIconView.asView(), mIconView2.asView(),
+ taskIconHeight, mSnapshotView.getMeasuredWidth(),
+ mSnapshotView.getMeasuredHeight(), getMeasuredHeight(), getMeasuredWidth(),
+ isRtl, deviceProfile, mSplitBoundsConfig);
+ }
}
private void updateSecondaryDwbPlacement() {
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index d10541a..fecbf08 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -1811,9 +1811,7 @@
mFocusedTaskViewId = newFocusedTaskView != null && !enableGridOnlyOverview()
? newFocusedTaskView.getTaskViewId() : INVALID_TASK_ID;
updateTaskSize();
- if (newFocusedTaskView != null) {
- newFocusedTaskView.setOrientationState(mOrientationState);
- }
+ updateChildTaskOrientations();
TaskView newRunningTaskView = null;
if (hasAnyValidTaskIds(runningTaskId)) {
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index b971f67..1b3e3c4 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -1720,12 +1720,11 @@
int expectedWidth;
int expectedHeight;
DeviceProfile deviceProfile = mActivity.getDeviceProfile();
+ final int thumbnailPadding = deviceProfile.overviewTaskThumbnailTopMarginPx;
+ final Rect lastComputedTaskSize = getRecentsView().getLastComputedTaskSize();
+ final int taskWidth = lastComputedTaskSize.width();
+ final int taskHeight = lastComputedTaskSize.height();
if (deviceProfile.isTablet) {
- final int thumbnailPadding = deviceProfile.overviewTaskThumbnailTopMarginPx;
- final Rect lastComputedTaskSize = getRecentsView().getLastComputedTaskSize();
- final int taskWidth = lastComputedTaskSize.width();
- final int taskHeight = lastComputedTaskSize.height();
-
int boxWidth;
int boxHeight;
boolean isFocusedTask = isFocusedTask();
@@ -1758,8 +1757,10 @@
} else {
nonGridScale = 1f;
boxTranslationY = 0f;
- expectedWidth = ViewGroup.LayoutParams.MATCH_PARENT;
- expectedHeight = ViewGroup.LayoutParams.MATCH_PARENT;
+ expectedWidth = enableOverviewIconMenu() ? taskWidth : LayoutParams.MATCH_PARENT;
+ expectedHeight = enableOverviewIconMenu()
+ ? taskHeight + thumbnailPadding
+ : LayoutParams.MATCH_PARENT;
}
setNonGridScale(nonGridScale);
diff --git a/quickstep/tests/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchControllerTest.kt b/quickstep/tests/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchControllerTest.kt
new file mode 100644
index 0000000..119b862
--- /dev/null
+++ b/quickstep/tests/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchControllerTest.kt
@@ -0,0 +1,152 @@
+/*
+ * 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.uioverrides.touchcontrollers
+
+import android.view.MotionEvent
+import android.view.WindowManager
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.launcher3.Launcher
+import com.android.launcher3.ui.AbstractLauncherUiTest
+import junit.framework.Assert.assertEquals
+import junit.framework.Assert.assertFalse
+import junit.framework.Assert.assertTrue
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class StatusBarTouchControllerTest : AbstractLauncherUiTest() {
+ @Before
+ @Throws(Exception::class)
+ fun setup() {
+ super.setUp()
+ initialize(this)
+ }
+
+ @Test
+ fun interceptActionDown_canIntercept() {
+ executeOnLauncher { launcher ->
+ val underTest = StatusBarTouchController(launcher)
+ assertFalse(underTest.mCanIntercept)
+ val downEvent = MotionEvent.obtain(1, 1, MotionEvent.ACTION_DOWN, 0f, 0f, 0)
+
+ underTest.onControllerInterceptTouchEvent(downEvent)
+
+ assertTrue(underTest.mCanIntercept)
+ }
+ }
+
+ @Test
+ fun interceptVerticalActionMove_handledAndSetSlippery() {
+ executeOnLauncher { launcher ->
+ val underTest = StatusBarTouchController(launcher)
+ val downEvent = MotionEvent.obtain(1, 1, MotionEvent.ACTION_DOWN, 0f, 0f, 0)
+ underTest.onControllerInterceptTouchEvent(downEvent)
+ val w = launcher.window
+ assertEquals(0, w.attributes.flags and WindowManager.LayoutParams.FLAG_SLIPPERY)
+ val moveEvent =
+ MotionEvent.obtain(
+ 2,
+ 2,
+ MotionEvent.ACTION_MOVE,
+ underTest.mTouchSlop,
+ underTest.mTouchSlop + 10,
+ 0
+ )
+
+ val handled = underTest.onControllerInterceptTouchEvent(moveEvent)
+
+ assertTrue(handled)
+ assertEquals(
+ WindowManager.LayoutParams.FLAG_SLIPPERY,
+ w.attributes.flags and WindowManager.LayoutParams.FLAG_SLIPPERY
+ )
+ }
+ }
+
+ @Test
+ fun interceptHorizontalActionMove_not_handled() {
+ executeOnLauncher { launcher ->
+ val underTest = StatusBarTouchController(launcher)
+ val downEvent = MotionEvent.obtain(1, 1, MotionEvent.ACTION_DOWN, 0f, 0f, 0)
+ underTest.onControllerInterceptTouchEvent(downEvent)
+ val moveEvent =
+ MotionEvent.obtain(
+ 2,
+ 2,
+ MotionEvent.ACTION_MOVE,
+ underTest.mTouchSlop + 10,
+ underTest.mTouchSlop,
+ 0
+ )
+
+ val handled = underTest.onControllerInterceptTouchEvent(moveEvent)
+
+ assertFalse(handled)
+ }
+ }
+
+ @Test
+ fun interceptActionMoveAsFirstGestureEvent_notCrashedNorHandled() {
+ executeOnLauncher { launcher ->
+ val underTest = StatusBarTouchController(launcher)
+ underTest.mCanIntercept = true
+ val moveEvent = MotionEvent.obtain(2, 2, MotionEvent.ACTION_MOVE, 10f, 10f, 0)
+
+ val handled = underTest.onControllerInterceptTouchEvent(moveEvent)
+
+ assertFalse(handled)
+ }
+ }
+
+ @Test
+ fun handleActionUp_setNotSlippery() {
+ executeOnLauncher { launcher: Launcher ->
+ val underTest = StatusBarTouchController(launcher)
+ underTest.mCanIntercept = true
+ underTest.setWindowSlippery(true)
+ val moveEvent = MotionEvent.obtain(2, 2, MotionEvent.ACTION_UP, 10f, 10f, 0)
+
+ val handled = underTest.onControllerTouchEvent(moveEvent)
+
+ assertTrue(handled)
+ assertEquals(
+ 0,
+ launcher.window.attributes.flags and WindowManager.LayoutParams.FLAG_SLIPPERY
+ )
+ }
+ }
+
+ @Test
+ fun handleActionCancel_setNotSlippery() {
+ executeOnLauncher { launcher ->
+ val underTest = StatusBarTouchController(launcher)
+ underTest.mCanIntercept = true
+ underTest.setWindowSlippery(true)
+ val moveEvent = MotionEvent.obtain(2, 2, MotionEvent.ACTION_CANCEL, 10f, 10f, 0)
+
+ val handled = underTest.onControllerTouchEvent(moveEvent)
+
+ assertTrue(handled)
+ assertEquals(
+ 0,
+ launcher.window.attributes.flags and WindowManager.LayoutParams.FLAG_SLIPPERY
+ )
+ }
+ }
+}
diff --git a/quickstep/tests/src/com/android/quickstep/TaplOverviewIconTest.java b/quickstep/tests/src/com/android/quickstep/TaplOverviewIconTest.java
index 3f806d1..7c1b7f3 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplOverviewIconTest.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplOverviewIconTest.java
@@ -15,7 +15,6 @@
*/
package com.android.quickstep;
-import static com.android.launcher3.ui.AbstractLauncherUiTest.initialize;
import static com.android.launcher3.util.rule.TestStabilityRule.LOCAL;
import static com.android.launcher3.util.rule.TestStabilityRule.PLATFORM_POSTSUBMIT;
@@ -25,6 +24,7 @@
import android.content.Intent;
import android.platform.test.annotations.PlatinumTest;
+import com.android.launcher3.tapl.OverviewTask.OverviewSplitTask;
import com.android.launcher3.tapl.OverviewTaskMenu;
import com.android.launcher3.ui.AbstractLauncherUiTest;
import com.android.launcher3.util.rule.TestStabilityRule;
@@ -86,7 +86,8 @@
taskMenu.touchOutsideTaskMenuToDismiss();
OverviewTaskMenu splitMenu =
- mLauncher.goHome().switchToOverview().getCurrentTask().tapSplitTaskMenu();
+ mLauncher.goHome().switchToOverview().getCurrentTask().tapMenu(
+ OverviewSplitTask.SPLIT_BOTTOM_OR_RIGHT);
assertTrue("App info item not appearing in expanded split task's menu.",
splitMenu.hasMenuItem("App info"));
splitMenu.touchOutsideTaskMenuToDismiss();
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsKeyboardQuickSwitch.java b/quickstep/tests/src/com/android/quickstep/TaplTestsKeyboardQuickSwitch.java
index 36c591e..a050464 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsKeyboardQuickSwitch.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsKeyboardQuickSwitch.java
@@ -22,6 +22,8 @@
import androidx.test.runner.AndroidJUnit4;
import com.android.launcher3.tapl.KeyboardQuickSwitch;
+import com.android.launcher3.tapl.LaunchedAppState;
+import com.android.launcher3.tapl.Taskbar;
import com.android.launcher3.taskbar.KeyboardQuickSwitchController;
import com.android.launcher3.ui.AbstractLauncherUiTest;
@@ -36,6 +38,7 @@
private enum TestSurface {
HOME(true),
LAUNCHED_APP(false),
+ TASKBAR_ALL_APPS(false),
HOME_ALL_APPS(true),
WIDGETS(true);
@@ -82,6 +85,11 @@
}
@Test
+ public void testDismiss_fromTaskbarAllApps() {
+ runTest(TestSurface.TASKBAR_ALL_APPS, TestCase.DISMISS);
+ }
+
+ @Test
public void testDismiss_fromHomeAllApps() {
runTest(TestSurface.HOME_ALL_APPS, TestCase.DISMISS);
}
@@ -102,6 +110,11 @@
}
@Test
+ public void testLaunchLastTask_fromTaskbarAllApps() {
+ runTest(TestSurface.TASKBAR_ALL_APPS, TestCase.LAUNCH_LAST_APP);
+ }
+
+ @Test
public void testLaunchLastTask_fromHomeAllApps() {
runTest(TestSurface.HOME_ALL_APPS, TestCase.LAUNCH_LAST_APP);
}
@@ -122,6 +135,11 @@
}
@Test
+ public void testLaunchSelectedTask_fromTaskbarAllApps() {
+ runTest(TestSurface.TASKBAR_ALL_APPS, TestCase.LAUNCH_SELECTED_APP);
+ }
+
+ @Test
public void testLaunchSelectedTask_fromHomeAllApps() {
runTest(TestSurface.HOME_ALL_APPS, TestCase.LAUNCH_SELECTED_APP);
}
@@ -142,6 +160,11 @@
}
@Test
+ public void testLaunchOverviewTask_fromTaskbarAllApps() {
+ runTest(TestSurface.TASKBAR_ALL_APPS, TestCase.LAUNCH_OVERVIEW);
+ }
+
+ @Test
public void testLaunchOverviewTask_fromHomeAllApps() {
runTest(TestSurface.HOME_ALL_APPS, TestCase.LAUNCH_OVERVIEW);
}
@@ -165,6 +188,12 @@
mLauncher.setIgnoreTaskbarVisibility(true);
kqs = mLauncher.getLaunchedAppState().showQuickSwitchView();
break;
+ case TASKBAR_ALL_APPS:
+ LaunchedAppState launchedApp = mLauncher.getLaunchedAppState();
+ Taskbar taskbar = mLauncher.isTransientTaskbar()
+ ? launchedApp.swipeUpToUnstashTaskbar() : launchedApp.getTaskbar();
+ kqs = taskbar.openAllApps().showQuickSwitchView();
+ break;
case HOME_ALL_APPS:
kqs = mLauncher.goHome().switchToAllApps().showQuickSwitchView();
break;
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsSplitscreen.java b/quickstep/tests/src/com/android/quickstep/TaplTestsSplitscreen.java
index 1e33635..c472ef2 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsSplitscreen.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsSplitscreen.java
@@ -16,6 +16,7 @@
package com.android.quickstep;
+import static com.android.launcher3.config.FeatureFlags.enableSplitContextually;
import static com.android.launcher3.util.rule.TestStabilityRule.LOCAL;
import static com.android.launcher3.util.rule.TestStabilityRule.PLATFORM_POSTSUBMIT;
@@ -40,6 +41,7 @@
import org.junit.After;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -103,10 +105,18 @@
.getSplitScreenMenuItem()
.click();
- mLauncher.getLaunchedAppState()
- .getTaskbar()
- .getAppIcon(CALCULATOR_APP_NAME)
- .launchIntoSplitScreen();
+ if (enableSplitContextually()) {
+ // We're staying in all apps, use same instance
+ mLauncher.getAllApps()
+ .getAppIcon(CALCULATOR_APP_NAME)
+ .launch(CALCULATOR_APP_PACKAGE);
+ } else {
+ // We're in overview, use taskbar instance
+ mLauncher.getLaunchedAppState()
+ .getTaskbar()
+ .getAppIcon(CALCULATOR_APP_NAME)
+ .launchIntoSplitScreen();
+ }
}
@Test
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 798b238..496cb4e 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -411,8 +411,6 @@
private final SettingsCache.OnChangeListener mNaturalScrollingChangedListener =
enabled -> mIsNaturalScrollingEnabled = enabled;
- private int mActivityStopCount; // Used only by tests
-
public static Launcher getLauncher(Context context) {
return fromContext(context);
}
@@ -1054,18 +1052,10 @@
mAppWidgetHolder.setActivityStarted(false);
NotificationListener.removeNotificationsChangedListener(getPopupDataProvider());
FloatingIconView.resetIconLoadResult();
- ++mActivityStopCount;
AccessibilityManagerCompat.sendTestProtocolEventToTest(
this, LAUNCHER_ACTIVITY_STOPPED_MESSAGE);
}
- /** Return activity stop count and reset it. Used only by tests. */
- public int getAndResetActivityStopCount() {
- final int activityStopCount = mActivityStopCount;
- mActivityStopCount = 0;
- return activityStopCount;
- }
-
@Override
protected void onStart() {
TraceHelper.INSTANCE.beginSection(ON_START_EVT);
diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java
index 1b2cebd..c3cbd2b 100644
--- a/src/com/android/launcher3/LauncherAppState.java
+++ b/src/com/android/launcher3/LauncherAppState.java
@@ -34,6 +34,7 @@
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.content.pm.LauncherApps;
+import android.content.pm.LauncherApps.ArchiveCompatibilityParams;
import android.os.UserHandle;
import android.util.Log;
@@ -109,8 +110,9 @@
mOnTerminateCallback.add(() ->
mContext.getSystemService(LauncherApps.class).unregisterCallback(callbacks));
if (Flags.enableSupportForArchiving()) {
- launcherApps.setArchiveCompatibilityOptions(/* enableIconOverlay= */ true,
- /* enableUnarchivalConfirmation= */ false);
+ ArchiveCompatibilityParams params = new ArchiveCompatibilityParams();
+ params.setEnableUnarchivalConfirmation(false);
+ launcherApps.setArchiveCompatibility(params);
}
SimpleBroadcastReceiver modelChangeReceiver =
diff --git a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
index e65e614..a846e68 100644
--- a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
+++ b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
@@ -415,6 +415,8 @@
screenId, coordinates[0], coordinates[1]);
bindItem(info, accessibility);
} else if (item instanceof FolderInfo fi) {
+ Workspace<?> workspace = mContext.getWorkspace();
+ workspace.snapToPage(workspace.getPageIndexForScreenId(screenId));
mContext.getModelWriter().addItemToDatabase(fi,
LauncherSettings.Favorites.CONTAINER_DESKTOP, screenId, coordinates[0],
coordinates[1]);
diff --git a/src/com/android/launcher3/allapps/PrivateSpaceHeaderViewController.java b/src/com/android/launcher3/allapps/PrivateSpaceHeaderViewController.java
index bc55597..fcdfaa6 100644
--- a/src/com/android/launcher3/allapps/PrivateSpaceHeaderViewController.java
+++ b/src/com/android/launcher3/allapps/PrivateSpaceHeaderViewController.java
@@ -55,6 +55,9 @@
assert quietModeButton != null;
addQuietModeButton(quietModeButton);
+ //Trigger lock/unlock action from header.
+ addHeaderOnClickListener(parent);
+
//Add image and action for private space settings button
ImageButton settingsButton = parent.findViewById(R.id.ps_settings_button);
assert settingsButton != null;
@@ -71,26 +74,35 @@
case STATE_ENABLED -> {
quietModeButton.setVisibility(View.VISIBLE);
quietModeButton.setImageResource(R.drawable.bg_ps_lock_button);
- quietModeButton.setOnClickListener(
- view -> {
- mPrivateProfileManager.logEvents(LAUNCHER_PRIVATE_SPACE_LOCK_TAP);
- mPrivateProfileManager.lockPrivateProfile();
- });
+ quietModeButton.setOnClickListener(view -> lockAction());
}
case STATE_DISABLED -> {
quietModeButton.setVisibility(View.VISIBLE);
quietModeButton.setImageResource(R.drawable.bg_ps_unlock_button);
- quietModeButton.setOnClickListener(
- view -> {
- mPrivateProfileManager.logEvents(LAUNCHER_PRIVATE_SPACE_UNLOCK_TAP);
- mPrivateProfileManager.unlockPrivateProfile((this::
- onPrivateProfileUnlocked));
- });
+ quietModeButton.setOnClickListener(view -> unLockAction());
}
default -> quietModeButton.setVisibility(View.GONE);
}
}
+ private void addHeaderOnClickListener(RelativeLayout header) {
+ if (mPrivateProfileManager.getCurrentState() == STATE_DISABLED) {
+ header.setOnClickListener(view -> unLockAction());
+ } else {
+ header.setOnClickListener(null);
+ }
+ }
+
+ private void unLockAction() {
+ mPrivateProfileManager.logEvents(LAUNCHER_PRIVATE_SPACE_UNLOCK_TAP);
+ mPrivateProfileManager.unlockPrivateProfile((this::onPrivateProfileUnlocked));
+ }
+
+ private void lockAction() {
+ mPrivateProfileManager.logEvents(LAUNCHER_PRIVATE_SPACE_LOCK_TAP);
+ mPrivateProfileManager.lockPrivateProfile();
+ }
+
private void addPrivateSpaceSettingsButton(ImageButton settingsButton) {
if (mPrivateProfileManager.getCurrentState() == STATE_ENABLED
&& mPrivateProfileManager.isPrivateSpaceSettingsAvailable()) {
diff --git a/src/com/android/launcher3/testing/TestInformationHandler.java b/src/com/android/launcher3/testing/TestInformationHandler.java
index 27a153b..5636405 100644
--- a/src/com/android/launcher3/testing/TestInformationHandler.java
+++ b/src/com/android/launcher3/testing/TestInformationHandler.java
@@ -214,16 +214,6 @@
.forceAllowRotationForTesting(Boolean.parseBoolean(arg)));
return response;
- case TestProtocol.REQUEST_GET_AND_RESET_ACTIVITY_STOP_COUNT: {
- final Bundle bundle = getLauncherUIProperty(Bundle::putInt,
- launcher -> launcher.getAndResetActivityStopCount());
- if (bundle != null) return bundle;
-
- // If Launcher activity wasn't created, 'it' was stopped 0 times.
- response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD, 0);
- return response;
- }
-
case TestProtocol.REQUEST_WORKSPACE_CELL_LAYOUT_SIZE:
return getLauncherUIProperty(Bundle::putIntArray, launcher -> {
final Workspace<?> workspace = launcher.getWorkspace();
diff --git a/tests/multivalentTests/shared/com/android/launcher3/testing/shared/TestProtocol.java b/tests/multivalentTests/shared/com/android/launcher3/testing/shared/TestProtocol.java
index 187daca..2f9945d 100644
--- a/tests/multivalentTests/shared/com/android/launcher3/testing/shared/TestProtocol.java
+++ b/tests/multivalentTests/shared/com/android/launcher3/testing/shared/TestProtocol.java
@@ -178,9 +178,6 @@
public static final String REQUEST_UNSTASH_BUBBLE_BAR_IF_STASHED =
"unstash-bubble-bar-if-stashed";
- public static final String REQUEST_GET_AND_RESET_ACTIVITY_STOP_COUNT =
- "get-and-reset-activity-stops";
-
/** Logs {@link Log#d(String, String)} if {@link #sDebugTracing} is true. */
public static void testLogD(String tag, String message) {
if (!sDebugTracing) {
diff --git a/tests/multivalentTests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/multivalentTests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
index dcf56f8..f0d2e20 100644
--- a/tests/multivalentTests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
+++ b/tests/multivalentTests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
@@ -599,9 +599,6 @@
Wait.atMost("Launcher activity didn't stop",
() -> !launcherInstrumentation.isLauncherActivityStarted(),
DEFAULT_ACTIVITY_TIMEOUT, launcherInstrumentation);
-
- // Reset activity stop count.
- launcherInstrumentation.getAndResetActivityStopCount();
}
public static ActivityInfo resolveSystemAppInfo(String category) {
diff --git a/tests/multivalentTests/src/com/android/launcher3/util/rule/TestIsolationRule.java b/tests/multivalentTests/src/com/android/launcher3/util/rule/TestIsolationRule.java
index e98dcf4..2b45902 100644
--- a/tests/multivalentTests/src/com/android/launcher3/util/rule/TestIsolationRule.java
+++ b/tests/multivalentTests/src/com/android/launcher3/util/rule/TestIsolationRule.java
@@ -44,15 +44,11 @@
return new Statement() {
@Override
public void evaluate() throws Throwable {
- // Reset activity stop count.
- mLauncher.getAndResetActivityStopCount();
-
base.evaluate();
-
// Make sure that Launcher workspace looks correct.
+
UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()).pressHome();
AbstractLauncherUiTest.checkDetectedLeaks(mLauncher, mRequireOneActiveActivity);
- mLauncher.assertNoUnexpectedStops();
}
};
}
diff --git a/tests/multivalentTests/tapl/com/android/launcher3/tapl/Background.java b/tests/multivalentTests/tapl/com/android/launcher3/tapl/Background.java
index 9f2ce22..988aa94 100644
--- a/tests/multivalentTests/tapl/com/android/launcher3/tapl/Background.java
+++ b/tests/multivalentTests/tapl/com/android/launcher3/tapl/Background.java
@@ -16,6 +16,7 @@
package com.android.launcher3.tapl;
+import static com.android.launcher3.tapl.BaseOverview.TASK_RES_ID;
import static com.android.launcher3.tapl.OverviewTask.TASK_START_EVENT;
import static com.android.launcher3.testing.shared.TestProtocol.OVERVIEW_STATE_ORDINAL;
@@ -116,10 +117,10 @@
// non-tablet overview, snapshots can be on either side of the swiped
// task, but we still check that they become visible after swiping and
// pausing.
- mLauncher.waitForOverviewObject("snapshot");
+ mLauncher.waitForOverviewObject(TASK_RES_ID);
if (mLauncher.isTablet()) {
List<UiObject2> tasks = mLauncher.getDevice().findObjects(
- mLauncher.getOverviewObjectSelector("snapshot"));
+ mLauncher.getOverviewObjectSelector(TASK_RES_ID));
final int centerX = mLauncher.getDevice().getDisplayWidth() / 2;
mLauncher.assertTrue(
"All tasks not to the left of the swiped task",
diff --git a/tests/multivalentTests/tapl/com/android/launcher3/tapl/BaseOverview.java b/tests/multivalentTests/tapl/com/android/launcher3/tapl/BaseOverview.java
index d337b91..ad95ecf 100644
--- a/tests/multivalentTests/tapl/com/android/launcher3/tapl/BaseOverview.java
+++ b/tests/multivalentTests/tapl/com/android/launcher3/tapl/BaseOverview.java
@@ -44,6 +44,7 @@
* Common overview panel for both Launcher and fallback recents
*/
public class BaseOverview extends LauncherInstrumentation.VisibleContainer {
+ protected static final String TASK_RES_ID = "task";
private static final Pattern EVENT_ALT_ESC_DOWN = Pattern.compile(
"Key event: KeyEvent.*?action=ACTION_DOWN.*?keyCode=KEYCODE_ESCAPE.*?metaState=0");
@@ -281,10 +282,10 @@
// The widest, and most top-right task should be the current task
UiObject2 currentTask = Collections.max(taskViews,
- Comparator.comparingInt((UiObject2 t) -> t.getParent().getVisibleBounds().width())
- .thenComparingInt((UiObject2 t) -> t.getParent().getVisibleCenter().x)
+ Comparator.comparingInt((UiObject2 t) -> t.getVisibleBounds().width())
+ .thenComparingInt((UiObject2 t) -> t.getVisibleCenter().x)
.thenComparing(Comparator.comparing(
- (UiObject2 t) -> t.getParent().getVisibleCenter().y).reversed()));
+ (UiObject2 t) -> t.getVisibleCenter().y).reversed()));
return new OverviewTask(mLauncher, currentTask, this);
}
@@ -329,10 +330,11 @@
"want to get overview tasks")) {
verifyActiveContainer();
return mLauncher.getDevice().findObjects(
- mLauncher.getOverviewObjectSelector("snapshot"));
+ mLauncher.getOverviewObjectSelector(TASK_RES_ID));
}
}
+
int getTaskCount() {
return getTasks().size();
}
diff --git a/tests/multivalentTests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/multivalentTests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index 90ca990..6c9f5ed 100644
--- a/tests/multivalentTests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/multivalentTests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -207,7 +207,6 @@
private TrackpadGestureType mTrackpadGestureType = TrackpadGestureType.NONE;
private int mPointerCount = 0;
- private final boolean mIsLauncherTest;
private static Pattern getKeyEventPattern(String action, String keyCode) {
return Pattern.compile("Key event: KeyEvent.*action=" + action + ".*keyCode=" + keyCode);
@@ -244,7 +243,6 @@
*/
@Deprecated
public LauncherInstrumentation(Instrumentation instrumentation, boolean isLauncherTest) {
- mIsLauncherTest = isLauncherTest;
mInstrumentation = instrumentation;
mDevice = UiDevice.getInstance(instrumentation);
@@ -417,11 +415,6 @@
TestProtocol.TEST_INFO_RESPONSE_FIELD);
}
- public int getAndResetActivityStopCount() {
- return getTestInfo(TestProtocol.REQUEST_GET_AND_RESET_ACTIVITY_STOP_COUNT).getInt(
- TestProtocol.TEST_INFO_RESPONSE_FIELD);
- }
-
Rect getGridTaskRectForTablet() {
return ((Rect) getTestInfo(TestProtocol.REQUEST_GET_GRID_TASK_SIZE_RECT_FOR_TABLET)
.getParcelable(TestProtocol.TEST_INFO_RESPONSE_FIELD));
@@ -635,19 +628,10 @@
public void onTestStart() {
mTestStartTime = System.currentTimeMillis();
- assertNoUnexpectedStops();
}
public void onTestFinish() {
mTestStartTime = -1;
- assertNoUnexpectedStops();
- }
-
- /** Verify that the activity stop count is zero. */
- public void assertNoUnexpectedStops() {
- if (mIsLauncherTest) {
- assertEquals("Unexpected activity stops", 0, getAndResetActivityStopCount());
- }
}
private String formatSystemHealthMessage(String message) {
@@ -1021,9 +1005,6 @@
event -> TestProtocol.LAUNCHER_ACTIVITY_STOPPED_MESSAGE
.equals(event.getClassName().toString()),
() -> "Launcher activity didn't stop", actionName);
-
- // Reset activity stop count.
- getAndResetActivityStopCount();
}
/**
@@ -2276,7 +2257,6 @@
}
public Closable eventsCheck() {
- assertNoUnexpectedStops();
Assert.assertTrue("Nested event checking", mEventChecker == null);
disableSensorRotation();
final Integer initialPid = getPid();
@@ -2284,7 +2264,6 @@
if (eventChecker.start()) mEventChecker = eventChecker;
return () -> {
- assertNoUnexpectedStops();
if (initialPid != null && initialPid.intValue() != getPid()) {
if (mOnLauncherCrashed != null) mOnLauncherCrashed.run();
checkForAnomaly();
diff --git a/tests/multivalentTests/tapl/com/android/launcher3/tapl/OverviewTask.java b/tests/multivalentTests/tapl/com/android/launcher3/tapl/OverviewTask.java
index f383e99..afe5722 100644
--- a/tests/multivalentTests/tapl/com/android/launcher3/tapl/OverviewTask.java
+++ b/tests/multivalentTests/tapl/com/android/launcher3/tapl/OverviewTask.java
@@ -16,6 +16,10 @@
package com.android.launcher3.tapl;
+import static com.android.launcher3.tapl.OverviewTask.OverviewSplitTask.DEFAULT;
+import static com.android.launcher3.tapl.OverviewTask.OverviewSplitTask.SPLIT_BOTTOM_OR_RIGHT;
+import static com.android.launcher3.tapl.OverviewTask.OverviewSplitTask.SPLIT_TOP_OR_LEFT;
+
import android.graphics.Rect;
import androidx.annotation.NonNull;
@@ -34,9 +38,6 @@
*/
public final class OverviewTask {
private static final String SYSTEMUI_PACKAGE = "com.android.systemui";
- private static final String TASK_SNAPSHOT_1 = "snapshot";
- private static final String TASK_SNAPSHOT_2 = "bottomright_snapshot";
-
static final Pattern TASK_START_EVENT = Pattern.compile("startActivityFromRecentsAsync");
static final Pattern SPLIT_SELECT_EVENT = Pattern.compile("enterSplitSelect");
static final Pattern SPLIT_START_EVENT = Pattern.compile("launchSplitTasks");
@@ -64,15 +65,16 @@
return getCombinedSplitTaskHeight();
}
- return mTask.getVisibleBounds().height();
+ UiObject2 taskSnapshot1 = findObjectInTask(DEFAULT.snapshotRes);
+ return taskSnapshot1.getVisibleBounds().height();
}
/**
* Calculates the visible height for split tasks, containing 2 snapshot tiles and a divider.
*/
private int getCombinedSplitTaskHeight() {
- UiObject2 taskSnapshot1 = findObjectInTask(TASK_SNAPSHOT_1);
- UiObject2 taskSnapshot2 = findObjectInTask(TASK_SNAPSHOT_2);
+ UiObject2 taskSnapshot1 = findObjectInTask(SPLIT_TOP_OR_LEFT.snapshotRes);
+ UiObject2 taskSnapshot2 = findObjectInTask(SPLIT_BOTTOM_OR_RIGHT.snapshotRes);
// If the split task is partly off screen, taskSnapshot1 can be invisible.
if (taskSnapshot1 == null) {
@@ -96,15 +98,16 @@
return getCombinedSplitTaskWidth();
}
- return mTask.getVisibleBounds().width();
+ UiObject2 taskSnapshot1 = findObjectInTask(DEFAULT.snapshotRes);
+ return taskSnapshot1.getVisibleBounds().width();
}
/**
* Calculates the visible width for split tasks, containing 2 snapshot tiles and a divider.
*/
private int getCombinedSplitTaskWidth() {
- UiObject2 taskSnapshot1 = findObjectInTask(TASK_SNAPSHOT_1);
- UiObject2 taskSnapshot2 = findObjectInTask(TASK_SNAPSHOT_2);
+ UiObject2 taskSnapshot1 = findObjectInTask(SPLIT_TOP_OR_LEFT.snapshotRes);
+ UiObject2 taskSnapshot2 = findObjectInTask(SPLIT_BOTTOM_OR_RIGHT.snapshotRes);
int left = Math.min(
taskSnapshot1.getVisibleBounds().left, taskSnapshot2.getVisibleBounds().left);
@@ -115,15 +118,15 @@
}
int getTaskCenterX() {
- return mTask.getParent().getVisibleCenter().x;
+ return mTask.getVisibleCenter().x;
}
int getTaskCenterY() {
- return mTask.getParent().getVisibleCenter().y;
+ return mTask.getVisibleCenter().y;
}
float getExactCenterX() {
- return mTask.getParent().getVisibleBounds().exactCenterX();
+ return mTask.getVisibleBounds().exactCenterX();
}
UiObject2 getUiObject() {
@@ -225,11 +228,17 @@
/** Taps the task menu. Returns the task menu object. */
@NonNull
public OverviewTaskMenu tapMenu() {
+ return tapMenu(DEFAULT);
+ }
+
+ /** Taps the task menu of the split task. Returns the split task's menu object. */
+ @NonNull
+ public OverviewTaskMenu tapMenu(OverviewSplitTask task) {
try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
"want to tap the task menu")) {
mLauncher.clickLauncherObject(
- mLauncher.waitForObjectInContainer(mTask.getParent(), "icon"));
+ mLauncher.waitForObjectInContainer(mTask, task.iconAppRes));
try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer(
"tapped the task menu")) {
@@ -238,27 +247,31 @@
}
}
- /** Taps the task menu of the split task. Returns the split task's menu object. */
- @NonNull
- public OverviewTaskMenu tapSplitTaskMenu() {
- try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
- LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
- "want to tap the split task's menu")) {
- mLauncher.clickLauncherObject(
- mLauncher.waitForObjectInContainer(mTask.getParent(), "bottomRight_icon"));
-
- try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer(
- "tapped the split task's menu")) {
- return new OverviewTaskMenu(mLauncher);
- }
- }
- }
-
boolean isTaskSplit() {
- return findObjectInTask(TASK_SNAPSHOT_2) != null;
+ return findObjectInTask(SPLIT_BOTTOM_OR_RIGHT.snapshotRes) != null;
}
private UiObject2 findObjectInTask(String resName) {
- return mTask.getParent().findObject(mLauncher.getOverviewObjectSelector(resName));
+ return mTask.findObject(mLauncher.getOverviewObjectSelector(resName));
+ }
+
+ /**
+ * Enum used to specify which task is retrieved when it is a split task.
+ */
+ public enum OverviewSplitTask {
+ // The main task when the task is not split.
+ DEFAULT("snapshot", "icon"),
+ // The first task in split task.
+ SPLIT_TOP_OR_LEFT("snapshot", "icon"),
+ // The second task in split task.
+ SPLIT_BOTTOM_OR_RIGHT("bottomright_snapshot", "bottomRight_icon");
+
+ public final String snapshotRes;
+ public final String iconAppRes;
+
+ OverviewSplitTask(String snapshotRes, String iconAppRes) {
+ this.snapshotRes = snapshotRes;
+ this.iconAppRes = iconAppRes;
+ }
}
}