From 338bdd1f94d01c4d7514cb4d0adedbc0a57f1032 Mon Sep 17 00:00:00 2001 From: Hongwei Wang Date: Fri, 25 Jun 2021 15:43:50 -0700 Subject: [PATCH 01/24] Polish auto-enter-pip from landscape and split-screen - Use Builder for constructing SwipePipToHomeAnimator since the parameter list grows - Use mHomeToWindowPositionMap to adjust the position, this is to fix the position issue when auto-enter-pip from split-screen - The position map and its inverse does not seem to fit the case when auto-enter-pip from landscape, leave it as it is - Setup the SwipePipToHomeAnimator the same way in createWindowAnimationToHome Video: http://recall/-/aaaaaabFQoRHlzixHdtY/b1j4eK7BU18sOGfuDlKMFR Bug: 190749305 Bug: 190855091 Test: manual, see video Change-Id: Ica9ca9f43b8fd5f1898fef4c6d173502dd897872 --- .../android/quickstep/AbsSwipeUpHandler.java | 44 +++-- .../util/SwipePipToHomeAnimator.java | 153 ++++++++++++++---- 2 files changed, 150 insertions(+), 47 deletions(-) diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java index 4d47ef15c1..8da2aaad16 100644 --- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java +++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java @@ -60,6 +60,7 @@ import android.content.Intent; import android.graphics.Matrix; import android.graphics.PointF; import android.graphics.Rect; +import android.graphics.RectF; import android.os.Build; import android.os.IBinder; import android.os.SystemClock; @@ -1217,30 +1218,40 @@ public abstract class AbsSwipeUpHandler, final RecentsOrientedState orientationState = mTaskViewSimulator.getOrientationState(); final int windowRotation = orientationState.getDisplayRotation(); final int homeRotation = orientationState.getRecentsActivityRotation(); + + final Matrix homeToWindowPositionMap = new Matrix(); + final RectF startRect = updateProgressForStartRect(homeToWindowPositionMap, startProgress); + // Move the startRect to Launcher space as floatingIconView runs in Launcher + final Matrix windowToHomePositionMap = new Matrix(); + homeToWindowPositionMap.invert(windowToHomePositionMap); + windowToHomePositionMap.mapRect(startRect); + final Rect destinationBounds = SystemUiProxy.INSTANCE.get(mContext) .startSwipePipToHome(taskInfo.topActivity, TaskInfoCompat.getTopActivityInfo(taskInfo), runningTaskTarget.taskInfo.pictureInPictureParams, homeRotation, mDp.hotseatBarSizePx); - final SwipePipToHomeAnimator swipePipToHomeAnimator = new SwipePipToHomeAnimator( - mContext, - runningTaskTarget.taskId, - taskInfo.topActivity, - runningTaskTarget.leash.getSurfaceControl(), - TaskInfoCompat.getPipSourceRectHint( - runningTaskTarget.taskInfo.pictureInPictureParams), - TaskInfoCompat.getWindowConfigurationBounds(taskInfo), - updateProgressForStartRect(new Matrix(), startProgress), - destinationBounds, - mRecentsView.getPipCornerRadius(), - mRecentsView); + final SwipePipToHomeAnimator.Builder builder = new SwipePipToHomeAnimator.Builder() + .setContext(mContext) + .setTaskId(runningTaskTarget.taskId) + .setComponentName(taskInfo.topActivity) + .setLeash(runningTaskTarget.leash.getSurfaceControl()) + .setSourceRectHint(TaskInfoCompat.getPipSourceRectHint( + runningTaskTarget.taskInfo.pictureInPictureParams)) + .setAppBounds(TaskInfoCompat.getWindowConfigurationBounds(taskInfo)) + .setHomeToWindowPositionMap(homeToWindowPositionMap) + .setStartBounds(startRect) + .setDestinationBounds(destinationBounds) + .setCornerRadius(mRecentsView.getPipCornerRadius()) + .setAttachedView(mRecentsView); // We would assume home and app window always in the same rotation While homeRotation // is not ROTATION_0 (which implies the rotation is turned on in launcher settings). if (homeRotation == ROTATION_0 && (windowRotation == ROTATION_90 || windowRotation == ROTATION_270)) { - swipePipToHomeAnimator.setFromRotation(mTaskViewSimulator, windowRotation); + builder.setFromRotation(mTaskViewSimulator, windowRotation); } + final SwipePipToHomeAnimator swipePipToHomeAnimator = builder.build(); AnimatorPlaybackController activityAnimationToHome = homeAnimFactory.createActivityAnimationToHome(); swipePipToHomeAnimator.addAnimatorListener(new AnimatorListenerAdapter() { @@ -1267,6 +1278,7 @@ public abstract class AbsSwipeUpHandler, mGestureState.setState(STATE_END_TARGET_ANIMATION_FINISHED); } }); + setupWindowAnimation(swipePipToHomeAnimator); return swipePipToHomeAnimator; } @@ -1297,6 +1309,11 @@ public abstract class AbsSwipeUpHandler, HomeAnimationFactory homeAnimationFactory) { RectFSpringAnim anim = super.createWindowAnimationToHome(startProgress, homeAnimationFactory); + setupWindowAnimation(anim); + return anim; + } + + private void setupWindowAnimation(RectFSpringAnim anim) { anim.addOnUpdateListener((v, r, p) -> { updateSysUiFlags(Math.max(p, mCurrentShift.value)); }); @@ -1314,7 +1331,6 @@ public abstract class AbsSwipeUpHandler, if (mRecentsAnimationTargets != null) { mRecentsAnimationTargets.addReleaseCheck(anim); } - return anim; } public void onConsumerAboutToBeSwitched() { diff --git a/quickstep/src/com/android/quickstep/util/SwipePipToHomeAnimator.java b/quickstep/src/com/android/quickstep/util/SwipePipToHomeAnimator.java index 67a635b70b..7488649eb7 100644 --- a/quickstep/src/com/android/quickstep/util/SwipePipToHomeAnimator.java +++ b/quickstep/src/com/android/quickstep/util/SwipePipToHomeAnimator.java @@ -56,7 +56,9 @@ public class SwipePipToHomeAnimator extends RectFSpringAnim { private final ComponentName mComponentName; private final SurfaceControl mLeash; private final Rect mAppBounds = new Rect(); + private final Matrix mHomeToWindowPositionMap = new Matrix(); private final Rect mStartBounds = new Rect(); + private final RectF mCurrentBoundsF = new RectF(); private final Rect mCurrentBounds = new Rect(); private final Rect mDestinationBounds = new Rect(); private final PipSurfaceTransactionHelper mSurfaceTransactionHelper; @@ -66,10 +68,9 @@ public class SwipePipToHomeAnimator extends RectFSpringAnim { private final Rect mSourceHintRectInsets; private final Rect mSourceInsets = new Rect(); - /** for rotation via {@link #setFromRotation(TaskViewSimulator, int)} */ - private @RecentsOrientedState.SurfaceRotation int mFromRotation = Surface.ROTATION_0; + /** for rotation calculations */ + private final @RecentsOrientedState.SurfaceRotation int mFromRotation; private final Rect mDestinationBoundsTransformed = new Rect(); - private final Rect mDestinationBoundsAnimation = new Rect(); /** * Flag to avoid the double-end problem since the leash would have been released @@ -91,31 +92,39 @@ public class SwipePipToHomeAnimator extends RectFSpringAnim { * @param leash {@link SurfaceControl} this animator operates on * @param sourceRectHint See the definition in {@link android.app.PictureInPictureParams} * @param appBounds Bounds of the application, sourceRectHint is based on this bounds + * @param homeToWindowPositionMap {@link Matrix} to map a Rect from home to window space * @param startBounds Bounds of the application when this animator starts. This can be * different from the appBounds if user has swiped a certain distance and * Launcher has performed transform on the leash. * @param destinationBounds Bounds of the destination this animator ends to + * @param fromRotation From rotation if different from final rotation, ROTATION_0 otherwise + * @param destinationBoundsTransformed Destination bounds in window space * @param cornerRadius Corner radius in pixel value for PiP window + * @param view Attached view for logging purpose */ - public SwipePipToHomeAnimator(@NonNull Context context, + private SwipePipToHomeAnimator(@NonNull Context context, int taskId, @NonNull ComponentName componentName, @NonNull SurfaceControl leash, @Nullable Rect sourceRectHint, @NonNull Rect appBounds, + @NonNull Matrix homeToWindowPositionMap, @NonNull RectF startBounds, @NonNull Rect destinationBounds, + @RecentsOrientedState.SurfaceRotation int fromRotation, + @NonNull Rect destinationBoundsTransformed, int cornerRadius, @NonNull View view) { - super(startBounds, new RectF(destinationBounds), context); + super(startBounds, new RectF(destinationBoundsTransformed), context); mTaskId = taskId; mComponentName = componentName; mLeash = leash; mAppBounds.set(appBounds); + mHomeToWindowPositionMap.set(homeToWindowPositionMap); startBounds.round(mStartBounds); mDestinationBounds.set(destinationBounds); - mDestinationBoundsTransformed.set(mDestinationBounds); - mDestinationBoundsAnimation.set(mDestinationBounds); + mFromRotation = fromRotation; + mDestinationBoundsTransformed.set(destinationBoundsTransformed); mSurfaceTransactionHelper = new PipSurfaceTransactionHelper(cornerRadius); if (sourceRectHint != null && (sourceRectHint.width() < destinationBounds.width() @@ -191,37 +200,13 @@ public class SwipePipToHomeAnimator extends RectFSpringAnim { addOnUpdateListener(this::onAnimationUpdate); } - /** sets the from rotation if it's different from the target rotation. */ - public void setFromRotation(TaskViewSimulator taskViewSimulator, - @RecentsOrientedState.SurfaceRotation int fromRotation) { - if (fromRotation != Surface.ROTATION_90 && fromRotation != Surface.ROTATION_270) { - Log.wtf(TAG, "Not a supported rotation, rotation=" + fromRotation); - return; - } - mFromRotation = fromRotation; - final Matrix matrix = new Matrix(); - taskViewSimulator.applyWindowToHomeRotation(matrix); - - // map the destination bounds into window space. mDestinationBounds is always calculated - // in the final home space and the animation runs in original window space. - final RectF transformed = new RectF(mDestinationBounds); - matrix.mapRect(transformed, new RectF(mDestinationBounds)); - transformed.round(mDestinationBoundsTransformed); - - // set the animation destination bounds for RectEvaluator calculation. - // bounds and insets are calculated as if the transition is from mAppBounds to - // mDestinationBoundsAnimation, separated from rotate / scale / position. - mDestinationBoundsAnimation.set(mAppBounds.left, mAppBounds.top, - mAppBounds.left + mDestinationBounds.width(), - mAppBounds.top + mDestinationBounds.height()); - } - private void onAnimationUpdate(@Nullable AppCloseConfig values, RectF currentRect, float progress) { if (mHasAnimationEnded) return; final SurfaceControl.Transaction tx = PipSurfaceTransactionHelper.newSurfaceControlTransaction(); - onAnimationUpdate(tx, currentRect, progress); + mHomeToWindowPositionMap.mapRect(mCurrentBoundsF, currentRect); + onAnimationUpdate(tx, mCurrentBoundsF, progress); tx.apply(); } @@ -309,6 +294,108 @@ public class SwipePipToHomeAnimator extends RectFSpringAnim { return new RotatedPosition(degree, positionX, positionY); } + /** Builder class for {@link SwipePipToHomeAnimator} */ + public static class Builder { + private Context mContext; + private int mTaskId; + private ComponentName mComponentName; + private SurfaceControl mLeash; + private Rect mSourceRectHint; + private Rect mAppBounds; + private Matrix mHomeToWindowPositionMap; + private RectF mStartBounds; + private Rect mDestinationBounds; + private int mCornerRadius; + private View mAttachedView; + private @RecentsOrientedState.SurfaceRotation int mFromRotation = Surface.ROTATION_0; + private final Rect mDestinationBoundsTransformed = new Rect(); + + public Builder setContext(Context context) { + mContext = context; + return this; + } + + public Builder setTaskId(int taskId) { + mTaskId = taskId; + return this; + } + + public Builder setComponentName(ComponentName componentName) { + mComponentName = componentName; + return this; + } + + public Builder setLeash(SurfaceControl leash) { + mLeash = leash; + return this; + } + + public Builder setSourceRectHint(Rect sourceRectHint) { + mSourceRectHint = new Rect(sourceRectHint); + return this; + } + + public Builder setAppBounds(Rect appBounds) { + mAppBounds = new Rect(appBounds); + return this; + } + + public Builder setHomeToWindowPositionMap(Matrix homeToWindowPositionMap) { + mHomeToWindowPositionMap = new Matrix(homeToWindowPositionMap); + return this; + } + + public Builder setStartBounds(RectF startBounds) { + mStartBounds = new RectF(startBounds); + return this; + } + + public Builder setDestinationBounds(Rect destinationBounds) { + mDestinationBounds = new Rect(destinationBounds); + return this; + } + + public Builder setCornerRadius(int cornerRadius) { + mCornerRadius = cornerRadius; + return this; + } + + public Builder setAttachedView(View attachedView) { + mAttachedView = attachedView; + return this; + } + + public Builder setFromRotation(TaskViewSimulator taskViewSimulator, + @RecentsOrientedState.SurfaceRotation int fromRotation) { + if (fromRotation != Surface.ROTATION_90 && fromRotation != Surface.ROTATION_270) { + Log.wtf(TAG, "Not a supported rotation, rotation=" + fromRotation); + return this; + } + final Matrix matrix = new Matrix(); + taskViewSimulator.applyWindowToHomeRotation(matrix); + + // map the destination bounds into window space. mDestinationBounds is always calculated + // in the final home space and the animation runs in original window space. + final RectF transformed = new RectF(mDestinationBounds); + matrix.mapRect(transformed, new RectF(mDestinationBounds)); + transformed.round(mDestinationBoundsTransformed); + + mFromRotation = fromRotation; + return this; + } + + public SwipePipToHomeAnimator build() { + if (mDestinationBoundsTransformed.isEmpty()) { + mDestinationBoundsTransformed.set(mDestinationBounds); + } + return new SwipePipToHomeAnimator(mContext, mTaskId, mComponentName, mLeash, + mSourceRectHint, mAppBounds, + mHomeToWindowPositionMap, mStartBounds, mDestinationBounds, + mFromRotation, mDestinationBoundsTransformed, + mCornerRadius, mAttachedView); + } + } + private static class RotatedPosition { private final float degree; private final float positionX; From 610e43f90eae6da890e9c237dd1866668be9779f Mon Sep 17 00:00:00 2001 From: Brian Isganitis Date: Tue, 29 Jun 2021 18:12:38 -0400 Subject: [PATCH 02/24] Intercept touch events for launcher preview root view This change prevents any accidental touches on any widgets in the preview. Test: Tapping on launcher preview in wallpaper app should never activate a widget. Fix: 191623924 Change-Id: Iac7eab057ec33ff491365a993af75a0b06a27f7e Merged-In: I98d462eca699cf368dcd5894f15584f280932ccc --- res/layout/launcher_preview_layout.xml | 4 ++-- .../launcher3/graphics/LauncherPreviewRenderer.java | 13 +++++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/res/layout/launcher_preview_layout.xml b/res/layout/launcher_preview_layout.xml index 16916800f3..cf2f2c75ee 100644 --- a/res/layout/launcher_preview_layout.xml +++ b/res/layout/launcher_preview_layout.xml @@ -13,7 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. --> - - \ No newline at end of file + \ No newline at end of file diff --git a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java index 2a1aec84a3..cf3da4b9b7 100644 --- a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java +++ b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java @@ -43,6 +43,7 @@ import android.os.Process; import android.util.AttributeSet; import android.view.ContextThemeWrapper; import android.view.LayoutInflater; +import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.WindowInsets; @@ -467,4 +468,16 @@ public class LauncherPreviewRenderer extends ContextWrapper view.measure(makeMeasureSpec(width, EXACTLY), makeMeasureSpec(height, EXACTLY)); view.layout(0, 0, width, height); } + + /** Root layout for launcher preview that intercepts all touch events. */ + public static class LauncherPreviewLayout extends InsettableFrameLayout { + public LauncherPreviewLayout(Context context, AttributeSet attrs) { + super(context, attrs); + } + + @Override + public boolean onInterceptTouchEvent(MotionEvent ev) { + return true; + } + } } From 58905b4f0a59cad3c7d256971937d38a25f3198f Mon Sep 17 00:00:00 2001 From: Jon Spivack Date: Thu, 24 Jun 2021 14:55:40 -0700 Subject: [PATCH 03/24] NIU Actions: Add privacy confirmation dialog This adds a dialog to inform the user that the NIU Actions buttons need to send data to Google in order to function. The user can accept or reject this. The dialog will block use of the feature until the user accepts. Bug: 191818216 Test: Manual (Pixel 3A with multiple user profiles) Test: m -j RunLauncherGoGoogleRoboTests Change-Id: Iedd056ce239de5269d02a31d28a9778efae34ede --- .../res/drawable/round_rect_dialog.xml | 20 ++++ .../niu_actions_confirmation_dialog.xml | 94 +++++++++++++++++++ go/quickstep/res/values-land/dimens.xml | 22 +++++ go/quickstep/res/values/attrs.xml | 2 + go/quickstep/res/values/colors.xml | 3 + go/quickstep/res/values/dimens.xml | 8 ++ go/quickstep/res/values/strings.xml | 9 ++ go/quickstep/res/values/styles.xml | 31 ++++++ .../quickstep/TaskOverlayFactoryGo.java | 57 +++++++++++ 9 files changed, 246 insertions(+) create mode 100644 go/quickstep/res/drawable/round_rect_dialog.xml create mode 100644 go/quickstep/res/layout/niu_actions_confirmation_dialog.xml create mode 100644 go/quickstep/res/values-land/dimens.xml diff --git a/go/quickstep/res/drawable/round_rect_dialog.xml b/go/quickstep/res/drawable/round_rect_dialog.xml new file mode 100644 index 0000000000..bbb7c5b545 --- /dev/null +++ b/go/quickstep/res/drawable/round_rect_dialog.xml @@ -0,0 +1,20 @@ + + + + + diff --git a/go/quickstep/res/layout/niu_actions_confirmation_dialog.xml b/go/quickstep/res/layout/niu_actions_confirmation_dialog.xml new file mode 100644 index 0000000000..db1531ac58 --- /dev/null +++ b/go/quickstep/res/layout/niu_actions_confirmation_dialog.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + +