From 352c0035cb475688c14898e79129f88ac03759c0 Mon Sep 17 00:00:00 2001 From: vadimt Date: Tue, 7 Sep 2021 15:26:19 -0700 Subject: [PATCH 1/3] Adding Winscope Launcher trace artifact Bug: 197991109 Test: local runs Change-Id: I8fe718570e1400e97ea107bc25e169f39257ff43 --- .../launcher3/util/rule/FailureWatcher.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/src/com/android/launcher3/util/rule/FailureWatcher.java b/tests/src/com/android/launcher3/util/rule/FailureWatcher.java index f9a9997e99..65aaa24527 100644 --- a/tests/src/com/android/launcher3/util/rule/FailureWatcher.java +++ b/tests/src/com/android/launcher3/util/rule/FailureWatcher.java @@ -2,6 +2,7 @@ package com.android.launcher3.util.rule; import static androidx.test.InstrumentationRegistry.getInstrumentation; +import android.content.Context; import android.os.FileUtils; import android.os.ParcelFileDescriptor.AutoCloseInputStream; import android.util.Log; @@ -45,11 +46,30 @@ public class FailureWatcher extends TestWatcher { return new Statement() { @Override public void evaluate() throws Throwable { + boolean success = false; try { Log.d("b/196820244", "Before evaluate"); + mDevice.executeShellCommand("cmd statusbar tracing start"); FailureWatcher.super.apply(base, description).evaluate(); Log.d("b/196820244", "After evaluate"); + success = true; } finally { + // Save artifact for Launcher Winscope trace. + mDevice.executeShellCommand("cmd statusbar tracing stop"); + final Context nexusLauncherContext = + getInstrumentation().getTargetContext() + .createPackageContext("com.google.android.apps.nexuslauncher", + 0); + final File launcherTrace = + new File(nexusLauncherContext.getFilesDir(), "launcher_trace.pb"); + if (success) { + mDevice.executeShellCommand("rm " + launcherTrace); + } else { + mDevice.executeShellCommand("mv " + launcherTrace + " " + + diagFile(description, "LauncherWinscope", "pb")); + } + + // Detect touch events coming from physical screen. if (mLauncher.hadNontestEvents()) { throw new AssertionError( "Launcher received events not sent by the test. This may mean " From f66f8271cfe6bd4e9f2c1de8f907ef1b6291a3fa Mon Sep 17 00:00:00 2001 From: Vinit Nayak Date: Mon, 13 Sep 2021 12:57:17 -0700 Subject: [PATCH 2/3] Use FakeTransformParams instead of real ones for gesture tutorial * SwipeUpAnimationLogic was ignoring the TransformParams arg that was being passed in, because for staged split we are creating/pairing TaskViewSimulators and TransformParams in SwipeUpAnimationLogic itself. * Override the remote handle that gets created during the gesture tutorial (which shouldn't be done in other cases, but because tutorial is a one-off it should be fine) Fixes: 199482330 Test: Launched gesture tutorial from launcher home settings No crash Change-Id: I346211a422e46981a994bd40e34e46b44f9f5d0e --- quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java | 2 +- .../src/com/android/quickstep/SwipeUpAnimationLogic.java | 2 +- .../interaction/SwipeUpGestureTutorialController.java | 5 ++++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java index 1e841da40b..fff89156cd 100644 --- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java +++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java @@ -270,7 +270,7 @@ public abstract class AbsSwipeUpHandler, TaskAnimationManager taskAnimationManager, GestureState gestureState, long touchTimeMs, boolean continuingLastGesture, InputConsumerController inputConsumer) { - super(context, deviceState, gestureState, new TransformParams()); + super(context, deviceState, gestureState); mActivityInterface = gestureState.getActivityInterface(); mActivityInitListener = mActivityInterface.createActivityInitListener(this::onActivityInit); mInputConsumerProxy = diff --git a/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java b/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java index 51a491ebf6..e68af2e0a1 100644 --- a/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java +++ b/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java @@ -80,7 +80,7 @@ public abstract class SwipeUpAnimationLogic implements protected boolean mIsSwipeForStagedSplit; public SwipeUpAnimationLogic(Context context, RecentsAnimationDeviceState deviceState, - GestureState gestureState, TransformParams transformParams) { + GestureState gestureState) { mContext = context; mDeviceState = deviceState; mGestureState = gestureState; diff --git a/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java index 1f75936dd4..ce8047ec9e 100644 --- a/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java +++ b/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java @@ -50,6 +50,7 @@ import com.android.quickstep.AnimatedFloat; import com.android.quickstep.GestureState; import com.android.quickstep.OverviewComponentObserver; import com.android.quickstep.RecentsAnimationDeviceState; +import com.android.quickstep.RemoteTargetGluer; import com.android.quickstep.SwipeUpAnimationLogic; import com.android.quickstep.SwipeUpAnimationLogic.RunningWindowAnim; import com.android.quickstep.util.AppCloseConfig; @@ -254,7 +255,9 @@ abstract class SwipeUpGestureTutorialController extends TutorialController { ViewSwipeUpAnimation(Context context, RecentsAnimationDeviceState deviceState, GestureState gestureState) { - super(context, deviceState, gestureState, new FakeTransformParams()); + super(context, deviceState, gestureState); + mRemoteTargetHandles[0] = new RemoteTargetGluer.RemoteTargetHandle( + mRemoteTargetHandles[0].getTaskViewSimulator(), new FakeTransformParams()); } void initDp(DeviceProfile dp) { From e6abfca7ab99da1a0092cf812435402f1a01e788 Mon Sep 17 00:00:00 2001 From: Vinit Nayak Date: Mon, 13 Sep 2021 18:00:52 -0700 Subject: [PATCH 3/3] Set GroupedTaskView child thumbnails in onMeasure * Also add indicator if split was originally started in portrait of landscape, so we know which dimension of the divider bar to use if user goes to overview and then rotates device (horizontal divider vs vertical) Fixes: 199461137 Test: Swipe to overview with staged split Rotate device with and without live tile Doesn't overlap with overview actions Change-Id: I8b7f104f16d5b7265828f1b3d98ba3426b28d44f --- .../quickstep/views/GroupedTaskView.java | 30 +++++----- .../touch/LandscapePagedViewHandler.java | 32 ++++++---- .../touch/PagedOrientationHandler.java | 3 +- .../touch/PortraitPagedViewHandler.java | 58 +++++++++++-------- .../util/SplitConfigurationOptions.java | 10 +++- 5 files changed, 82 insertions(+), 51 deletions(-) diff --git a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java index 85627191c0..16303f3a02 100644 --- a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java +++ b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java @@ -31,6 +31,7 @@ public class GroupedTaskView extends TaskView { private Task mSecondaryTask; private TaskThumbnailView mSnapshotView2; private CancellableTask mThumbnailLoadRequest2; + private SplitConfigurationOptions.StagedSplitBounds mSplitBoundsConfig; public GroupedTaskView(Context context) { super(context); @@ -57,7 +58,7 @@ public class GroupedTaskView extends TaskView { mTaskIdContainer[1] = secondary.key.id; mTaskIdAttributeContainer[1] = new TaskIdAttributeContainer(secondary, mSnapshotView2); mSnapshotView2.bind(secondary); - adjustThumbnailBoundsForSplit(splitBoundsConfig, orientedState); + mSplitBoundsConfig = splitBoundsConfig; } @Override @@ -121,6 +122,21 @@ public class GroupedTaskView extends TaskView { public void onRecycle() { super.onRecycle(); mSnapshotView2.setThumbnail(mSecondaryTask, null); + mSplitBoundsConfig = null; + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + int widthSize = MeasureSpec.getSize(widthMeasureSpec); + int heightSize = MeasureSpec.getSize(heightMeasureSpec); + setMeasuredDimension(widthSize, heightSize); + if (mSplitBoundsConfig == null || mSnapshotView == null || mSnapshotView2 == null) { + return; + } + getPagedOrientationHandler().measureGroupedTaskViewThumbnailBounds(mSnapshotView, + mSnapshotView2, widthSize, heightSize, mSplitBoundsConfig, + mActivity.getDeviceProfile()); } @Override @@ -128,16 +144,4 @@ public class GroupedTaskView extends TaskView { super.setOverlayEnabled(overlayEnabled); mSnapshotView2.setOverlayEnabled(overlayEnabled); } - - private void adjustThumbnailBoundsForSplit( - SplitConfigurationOptions.StagedSplitBounds splitBoundsConfig, - RecentsOrientedState orientedState) { - if (splitBoundsConfig == null) { - return; - } - - orientedState.getOrientationHandler().setGroupedTaskViewThumbnailBounds( - mSnapshotView, mSnapshotView2, this, splitBoundsConfig, - mActivity.getDeviceProfile()); - } } diff --git a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java index 895ca08510..2ac6cea636 100644 --- a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java +++ b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java @@ -408,22 +408,30 @@ public class LandscapePagedViewHandler implements PagedOrientationHandler { } @Override - public void setGroupedTaskViewThumbnailBounds(View mSnapshotView, View mSnapshotView2, - View taskParent, SplitConfigurationOptions.StagedSplitBounds splitBoundsConfig, - DeviceProfile dp) { + public void measureGroupedTaskViewThumbnailBounds(View primarySnapshot, View secondarySnapshot, + int parentWidth, int parentHeight, + SplitConfigurationOptions.StagedSplitBounds splitBoundsConfig, DeviceProfile dp) { int spaceAboveSnapshot = dp.overviewTaskThumbnailTopMarginPx; - int totalThumbnailHeight = taskParent.getHeight() - spaceAboveSnapshot; - int totalThumbnailWidth = taskParent.getWidth(); + int totalThumbnailHeight = parentHeight - spaceAboveSnapshot; int dividerBar = splitBoundsConfig.visualDividerBounds.width(); - ViewGroup.LayoutParams primaryLp = mSnapshotView.getLayoutParams(); - ViewGroup.LayoutParams secondaryLp = mSnapshotView2.getLayoutParams(); + int primarySnapshotHeight; + int primarySnapshotWidth; + int secondarySnapshotHeight; + int secondarySnapshotWidth; - primaryLp.width = totalThumbnailWidth; - primaryLp.height = (int) (totalThumbnailHeight * splitBoundsConfig.leftTaskPercent); + primarySnapshotWidth = parentWidth; + primarySnapshotHeight = (int) (totalThumbnailHeight * splitBoundsConfig.leftTaskPercent); - secondaryLp.width = totalThumbnailWidth; - secondaryLp.height = totalThumbnailHeight - primaryLp.height - dividerBar; - mSnapshotView2.setTranslationY(primaryLp.height + spaceAboveSnapshot + dividerBar); + secondarySnapshotWidth = parentWidth; + secondarySnapshotHeight = totalThumbnailHeight - primarySnapshotHeight - dividerBar; + secondarySnapshot.setTranslationY(primarySnapshotHeight + spaceAboveSnapshot + dividerBar); + primarySnapshot.measure( + View.MeasureSpec.makeMeasureSpec(primarySnapshotWidth, View.MeasureSpec.EXACTLY), + View.MeasureSpec.makeMeasureSpec(primarySnapshotHeight, View.MeasureSpec.EXACTLY)); + secondarySnapshot.measure( + View.MeasureSpec.makeMeasureSpec(secondarySnapshotWidth, View.MeasureSpec.EXACTLY), + View.MeasureSpec.makeMeasureSpec(secondarySnapshotHeight, + View.MeasureSpec.EXACTLY)); } @Override diff --git a/src/com/android/launcher3/touch/PagedOrientationHandler.java b/src/com/android/launcher3/touch/PagedOrientationHandler.java index b34a81eaa0..b119e2c0a9 100644 --- a/src/com/android/launcher3/touch/PagedOrientationHandler.java +++ b/src/com/android/launcher3/touch/PagedOrientationHandler.java @@ -162,7 +162,8 @@ public interface PagedOrientationHandler { SplitConfigurationOptions.StagedSplitBounds splitInfo, @SplitConfigurationOptions.StagePosition int desiredStagePosition); - void setGroupedTaskViewThumbnailBounds(View mSnapshot1, View mSnapshot2, View taskParent, + void measureGroupedTaskViewThumbnailBounds(View primarySnapshot, View secondarySnapshot, + int parentWidth, int parentHeight, SplitConfigurationOptions.StagedSplitBounds splitBoundsConfig, DeviceProfile dp); // Overview TaskMenuView methods diff --git a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java index 064d808756..e3fefc0284 100644 --- a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java +++ b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java @@ -35,7 +35,6 @@ import android.view.MotionEvent; import android.view.Surface; import android.view.VelocityTracker; import android.view.View; -import android.view.ViewGroup; import android.view.accessibility.AccessibilityEvent; import android.widget.LinearLayout; @@ -511,35 +510,46 @@ public class PortraitPagedViewHandler implements PagedOrientationHandler { } @Override - public void setGroupedTaskViewThumbnailBounds(View mSnapshotView, View mSnapshotView2, - View taskParent, SplitConfigurationOptions.StagedSplitBounds splitBoundsConfig, - DeviceProfile dp) { + public void measureGroupedTaskViewThumbnailBounds(View primarySnapshot, View secondarySnapshot, + int parentWidth, int parentHeight, + SplitConfigurationOptions.StagedSplitBounds splitBoundsConfig, DeviceProfile dp) { int spaceAboveSnapshot = dp.overviewTaskThumbnailTopMarginPx; - int totalThumbnailHeight = taskParent.getHeight() - spaceAboveSnapshot; - int totalThumbnailWidth = taskParent.getWidth(); - int dividerBar = (dp.isLandscape ? - splitBoundsConfig.visualDividerBounds.width() : - splitBoundsConfig.visualDividerBounds.height()); - ViewGroup.LayoutParams primaryLp = mSnapshotView.getLayoutParams(); - ViewGroup.LayoutParams secondaryLp = mSnapshotView2.getLayoutParams(); - + int totalThumbnailHeight = parentHeight - spaceAboveSnapshot; + int dividerBar = (splitBoundsConfig.appsStackedVertically ? + splitBoundsConfig.visualDividerBounds.height() : + splitBoundsConfig.visualDividerBounds.width()); + int primarySnapshotHeight; + int primarySnapshotWidth; + int secondarySnapshotHeight; + int secondarySnapshotWidth; + float taskPercent = splitBoundsConfig.appsStackedVertically ? + splitBoundsConfig.topTaskPercent : splitBoundsConfig.leftTaskPercent; if (dp.isLandscape) { - primaryLp.height = totalThumbnailHeight; - primaryLp.width = (int) (totalThumbnailWidth * splitBoundsConfig.leftTaskPercent); + primarySnapshotHeight = totalThumbnailHeight; + primarySnapshotWidth = (int) (parentWidth * taskPercent); - secondaryLp.height = totalThumbnailHeight; - secondaryLp.width = totalThumbnailWidth - primaryLp.width - dividerBar; - mSnapshotView2.setTranslationX(primaryLp.width + dividerBar); - mSnapshotView2.setTranslationY(spaceAboveSnapshot); + secondarySnapshotHeight = totalThumbnailHeight; + secondarySnapshotWidth = parentWidth - primarySnapshotWidth - dividerBar; + int translationX = primarySnapshotWidth + dividerBar; + secondarySnapshot.setTranslationX(translationX); + secondarySnapshot.setTranslationY(spaceAboveSnapshot); } else { - primaryLp.width = totalThumbnailWidth; - primaryLp.height = (int) (totalThumbnailHeight * splitBoundsConfig.topTaskPercent); + primarySnapshotWidth = parentWidth; + primarySnapshotHeight = (int) (totalThumbnailHeight * taskPercent); - secondaryLp.width = totalThumbnailWidth; - secondaryLp.height = totalThumbnailHeight - primaryLp.height - dividerBar; - mSnapshotView2.setTranslationY(primaryLp.height + spaceAboveSnapshot + dividerBar); - mSnapshotView2.setTranslationX(0); + secondarySnapshotWidth = parentWidth; + secondarySnapshotHeight = totalThumbnailHeight - primarySnapshotHeight - dividerBar; + int translationY = primarySnapshotHeight + spaceAboveSnapshot + dividerBar; + secondarySnapshot.setTranslationY(translationY); + secondarySnapshot.setTranslationX(0); } + primarySnapshot.measure( + View.MeasureSpec.makeMeasureSpec(primarySnapshotWidth, View.MeasureSpec.EXACTLY), + View.MeasureSpec.makeMeasureSpec(primarySnapshotHeight, View.MeasureSpec.EXACTLY)); + secondarySnapshot.measure( + View.MeasureSpec.makeMeasureSpec(secondarySnapshotWidth, View.MeasureSpec.EXACTLY), + View.MeasureSpec.makeMeasureSpec(secondarySnapshotHeight, + View.MeasureSpec.EXACTLY)); } @Override diff --git a/src/com/android/launcher3/util/SplitConfigurationOptions.java b/src/com/android/launcher3/util/SplitConfigurationOptions.java index 5093d85535..0b083e3af4 100644 --- a/src/com/android/launcher3/util/SplitConfigurationOptions.java +++ b/src/com/android/launcher3/util/SplitConfigurationOptions.java @@ -93,7 +93,13 @@ public final class SplitConfigurationOptions { // This class is orientation-agnostic, so we compute both for later use public final float topTaskPercent; public final float leftTaskPercent; - + /** + * If {@code true}, that means at the time of creation of this object, the + * split-screened apps were vertically stacked. This is useful in scenarios like + * rotation where the bounds won't change, but this variable can indicate what orientation + * the bounds were originally in + */ + public final boolean appsStackedVertically; public StagedSplitBounds(Rect leftTopBounds, Rect rightBottomBounds) { this.leftTopBounds = leftTopBounds; @@ -103,10 +109,12 @@ public final class SplitConfigurationOptions { // vertical apps, horizontal divider this.visualDividerBounds = new Rect(leftTopBounds.left, leftTopBounds.bottom, leftTopBounds.right, rightBottomBounds.top); + appsStackedVertically = true; } else { // horizontal apps, vertical divider this.visualDividerBounds = new Rect(leftTopBounds.right, leftTopBounds.top, rightBottomBounds.left, leftTopBounds.bottom); + appsStackedVertically = false; } leftTaskPercent = this.leftTopBounds.width() / (float) rightBottomBounds.right;