From 338bdd1f94d01c4d7514cb4d0adedbc0a57f1032 Mon Sep 17 00:00:00 2001 From: Hongwei Wang Date: Fri, 25 Jun 2021 15:43:50 -0700 Subject: [PATCH 01/19] 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 12f7a59e5ccb4d287f6418607df33e1302c2a946 Mon Sep 17 00:00:00 2001 From: Steven Ng Date: Tue, 29 Jun 2021 15:10:17 +0100 Subject: [PATCH 02/19] Use category icon for pending conversation widgets Fix: 192333050 Test: Manual Change-Id: Ie3895cd4747f1bec1c8ca9af82347bb0eafa7415 --- .../android/launcher3/model/WidgetsModel.java | 6 +++ .../android/launcher3/model/LoaderTask.java | 5 +-- .../widget/PendingAppWidgetHostView.java | 39 ++++++++++++++++--- .../android/launcher3/model/WidgetsModel.java | 8 ++++ 4 files changed, 50 insertions(+), 8 deletions(-) diff --git a/go/src/com/android/launcher3/model/WidgetsModel.java b/go/src/com/android/launcher3/model/WidgetsModel.java index cc5e1cbb46..f8448daf3d 100644 --- a/go/src/com/android/launcher3/model/WidgetsModel.java +++ b/go/src/com/android/launcher3/model/WidgetsModel.java @@ -24,6 +24,7 @@ import androidx.annotation.Nullable; import com.android.launcher3.LauncherAppState; import com.android.launcher3.icons.ComponentWithLabelAndIcon; +import com.android.launcher3.model.data.PackageItemInfo; import com.android.launcher3.util.PackageUserKey; import com.android.launcher3.widget.model.WidgetsListBaseEntry; @@ -81,4 +82,9 @@ public class WidgetsModel { ComponentName providerName) { return null; } + + /** Returns {@link PackageItemInfo} of a pending widget. */ + public static PackageItemInfo newPendingItemInfo(ComponentName provider) { + return new PackageItemInfo(provider.getPackageName()); + } } \ No newline at end of file diff --git a/src/com/android/launcher3/model/LoaderTask.java b/src/com/android/launcher3/model/LoaderTask.java index 318496ad19..ad2d7c281e 100644 --- a/src/com/android/launcher3/model/LoaderTask.java +++ b/src/com/android/launcher3/model/LoaderTask.java @@ -75,7 +75,6 @@ import com.android.launcher3.model.data.FolderInfo; import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.model.data.ItemInfoWithIcon; import com.android.launcher3.model.data.LauncherAppWidgetInfo; -import com.android.launcher3.model.data.PackageItemInfo; import com.android.launcher3.model.data.WorkspaceItemInfo; import com.android.launcher3.pm.InstallSessionHelper; import com.android.launcher3.pm.PackageInstallInfo; @@ -791,8 +790,8 @@ public class LoaderTask implements Runnable { if (appWidgetInfo.restoreStatus != LauncherAppWidgetInfo.RESTORE_COMPLETED) { - String pkg = appWidgetInfo.providerName.getPackageName(); - appWidgetInfo.pendingItemInfo = new PackageItemInfo(pkg); + appWidgetInfo.pendingItemInfo = WidgetsModel.newPendingItemInfo( + appWidgetInfo.providerName); appWidgetInfo.pendingItemInfo.user = appWidgetInfo.user; mIconCache.getTitleAndIconForApp( appWidgetInfo.pendingItemInfo, false); diff --git a/src/com/android/launcher3/widget/PendingAppWidgetHostView.java b/src/com/android/launcher3/widget/PendingAppWidgetHostView.java index 47a8914d2a..47f30be04f 100644 --- a/src/com/android/launcher3/widget/PendingAppWidgetHostView.java +++ b/src/com/android/launcher3/widget/PendingAppWidgetHostView.java @@ -17,6 +17,7 @@ package com.android.launcher3.widget; import static com.android.launcher3.graphics.PreloadIconDrawable.newPendingIcon; +import static com.android.launcher3.model.data.PackageItemInfo.CONVERSATIONS; import android.content.Context; import android.graphics.Canvas; @@ -35,6 +36,8 @@ import android.view.View; import android.view.View.OnClickListener; import android.widget.RemoteViews; +import androidx.annotation.Nullable; + import com.android.launcher3.DeviceProfile; import com.android.launcher3.R; import com.android.launcher3.icons.FastBitmapDrawable; @@ -146,21 +149,32 @@ public class PendingAppWidgetHostView extends LauncherAppWidgetHostView mCenterDrawable = null; } if (info.bitmap.icon != null) { + Drawable widgetCategoryIcon = getWidgetCategoryIcon(); // The view displays three modes, // 1) App icon in the center // 2) Preload icon in the center // 3) App icon in the center with a setup icon on the top left corner. if (mDisabledForSafeMode) { - FastBitmapDrawable disabledIcon = info.newIcon(getContext()); - disabledIcon.setIsDisabled(true); - mCenterDrawable = disabledIcon; + if (widgetCategoryIcon == null) { + FastBitmapDrawable disabledIcon = info.newIcon(getContext()); + disabledIcon.setIsDisabled(true); + mCenterDrawable = disabledIcon; + } else { + widgetCategoryIcon.setColorFilter( + FastBitmapDrawable.getDisabledFColorFilter(/* disabledAlpha= */ 1f)); + mCenterDrawable = widgetCategoryIcon; + } mSettingIconDrawable = null; } else if (isReadyForClickSetup()) { - mCenterDrawable = info.newIcon(getContext()); + mCenterDrawable = widgetCategoryIcon == null + ? info.newIcon(getContext()) + : widgetCategoryIcon; mSettingIconDrawable = getResources().getDrawable(R.drawable.ic_setting).mutate(); updateSettingColor(info.bitmap.color); } else { - mCenterDrawable = newPendingIcon(getContext(), info); + mCenterDrawable = widgetCategoryIcon == null + ? newPendingIcon(getContext(), info) + : widgetCategoryIcon; mSettingIconDrawable = null; applyState(); } @@ -316,4 +330,19 @@ public class PendingAppWidgetHostView extends LauncherAppWidgetHostView } } + + /** + * Returns the widget category icon for {@link #mInfo}. + * + *

If {@link #mInfo}'s category is {@code PackageItemInfo#NO_CATEGORY} or unknown, returns + * {@code null}. + */ + @Nullable + private Drawable getWidgetCategoryIcon() { + switch (mInfo.pendingItemInfo.category) { + case CONVERSATIONS: + return getContext().getDrawable(R.drawable.ic_conversations_widget_category); + } + return null; + } } diff --git a/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java b/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java index a66b031719..631067b929 100644 --- a/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java +++ b/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java @@ -225,6 +225,14 @@ public class WidgetsModel { return null; } + /** Returns {@link PackageItemInfo} of a pending widget. */ + public static PackageItemInfo newPendingItemInfo(ComponentName provider) { + if (CONVERSATION_WIDGET.equals(provider)) { + return new PackageItemInfo(provider.getPackageName(), PackageItemInfo.CONVERSATIONS); + } + return new PackageItemInfo(provider.getPackageName()); + } + private WidgetPackageOrCategoryKey getWidgetPackageOrCategoryKey(WidgetItem item) { if (CONVERSATION_WIDGET.equals(item.componentName)) { return new WidgetPackageOrCategoryKey(PackageItemInfo.CONVERSATIONS, item.user); From f70265f4ec02259faacec1ffb3096aee20d71040 Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Tue, 29 Jun 2021 09:59:02 -0700 Subject: [PATCH 03/19] Add split_display device profile. Bug: 192215417 Test: manual set isSplitDisplay=true, ensure the added device profile gets set on device Change-Id: Ibe33c33d3af140352c0bb4fb44460106ad898285 --- res/xml/device_profiles.xml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/res/xml/device_profiles.xml b/res/xml/device_profiles.xml index 1c99dfcfa7..256999cd7f 100644 --- a/res/xml/device_profiles.xml +++ b/res/xml/device_profiles.xml @@ -115,6 +115,14 @@ launcher:iconTextSize="14.4" launcher:canBeDefault="true" /> + + Date: Tue, 29 Jun 2021 12:53:27 -0700 Subject: [PATCH 04/19] Allow two lines max for text view in system shortcuts. This makes it more accessible for more languages. Bug: 185770234 Test: set language to Spanish, ensure 2 lines ensure deep shortcuts remain 1 lines Change-Id: I652fe6a51bde5d8c30f695a0a56f0879412bca01 --- res/layout/system_shortcut.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/res/layout/system_shortcut.xml b/res/layout/system_shortcut.xml index 2cdf1f4bdb..de091c51c7 100644 --- a/res/layout/system_shortcut.xml +++ b/res/layout/system_shortcut.xml @@ -32,7 +32,8 @@ android:paddingStart="@dimen/deep_shortcuts_text_padding_start" android:paddingEnd="@dimen/popup_padding_end" android:textSize="14sp" - android:singleLine="true" + android:minLines="1" + android:maxLines="2" android:ellipsize="end" android:textColor="?android:attr/textColorPrimary" launcher:iconDisplay="shortcut_popup" From 0f00c3526879a047b1e2024048010618c225f36b Mon Sep 17 00:00:00 2001 From: Lucas Dupin Date: Tue, 29 Jun 2021 13:02:12 -0700 Subject: [PATCH 05/19] Decouple zooms and blurs on app launch We'd like to be able to disable blurs during app launch, but without disabling zooms as well. The previous sysprop would set the depth of BackgroundAppState to 0, when what we want is to conserve wallpaper zoom. Bug: 191969790 Test: adb shell setprop ro.launcher.blur.appLaunch false Change-Id: Ie4b26096f6ac723c3981bba2829557e6cc6c733b --- .../launcher3/QuickstepTransitionManager.java | 9 ++++++--- .../statehandlers/DepthController.java | 20 ++++++++++++++++++- .../states/BackgroundAppState.java | 4 +--- 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java index ae7e4771eb..310e178955 100644 --- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java +++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java @@ -981,11 +981,14 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener depthController.setSurface(dimLayer); backgroundRadiusAnim.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationStart(Animator animation) { + depthController.setIsInLaunchTransition(true); + } + @Override public void onAnimationEnd(Animator animation) { - // Reset depth at the end of the launch animation, so the wallpaper won't be - // zoomed out if an app crashes. - DEPTH.setValue(depthController, 0f); + depthController.setIsInLaunchTransition(false); depthController.setSurface(null); if (dimLayer != null) { new SurfaceControl.Transaction() diff --git a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java index 4503e308e6..bb8b62db71 100644 --- a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java +++ b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java @@ -24,6 +24,7 @@ import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; import android.os.IBinder; +import android.os.SystemProperties; import android.util.FloatProperty; import android.view.CrossWindowBlurListeners; import android.view.SurfaceControl; @@ -117,6 +118,10 @@ public class DepthController implements StateHandler, * @see android.service.wallpaper.WallpaperService.Engine#onZoomChanged(float) */ private float mDepth; + /** + * If we're launching and app and should not be blurring the screen for performance reasons. + */ + private boolean mBlurDisabledForAppLaunch; // Workaround for animating the depth when multiwindow mode changes. private boolean mIgnoreStateChangesDuringMultiWindowAnimation = false; @@ -211,6 +216,19 @@ public class DepthController implements StateHandler, } } + /** + * If we're launching an app from the home screen. + */ + public void setIsInLaunchTransition(boolean inLaunchTransition) { + boolean blurEnabled = SystemProperties.getBoolean("ro.launcher.blur.appLaunch", true); + mBlurDisabledForAppLaunch = inLaunchTransition && !blurEnabled; + if (!inLaunchTransition) { + // Reset depth at the end of the launch animation, so the wallpaper won't be + // zoomed out if an app crashes. + setDepth(0f); + } + } + private void setDepth(float depth) { depth = Utilities.boundToRange(depth, 0, 1); // Round out the depth to dedupe frequent, non-perceptable updates @@ -238,7 +256,7 @@ public class DepthController implements StateHandler, boolean opaque = mLauncher.getScrimView().isFullyOpaque() && !isOverview; int blur = opaque || isOverview || !mCrossWindowBlursEnabled - ? 0 : (int) (mDepth * mMaxBlurRadius); + || mBlurDisabledForAppLaunch ? 0 : (int) (mDepth * mMaxBlurRadius); new SurfaceControl.Transaction() .setBackgroundBlurRadius(mSurface, blur) .setOpaque(mSurface, opaque) diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java b/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java index 01c9e765a8..fe5a3475ff 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java +++ b/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java @@ -19,7 +19,6 @@ import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_BACKG import android.content.Context; import android.graphics.Color; -import android.os.SystemProperties; import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.DeviceProfile; @@ -85,8 +84,7 @@ public class BackgroundAppState extends OverviewState { @Override protected float getDepthUnchecked(Context context) { - //TODO revert when b/178661709 is fixed - return SystemProperties.getBoolean("ro.launcher.depth.appLaunch", true) ? 1 : 0; + return 1; } @Override From 401b921c190199bb73cc2d2218e9d30911b625a8 Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Tue, 29 Jun 2021 14:23:55 -0700 Subject: [PATCH 06/19] Fix bug where status bar was not set properly. - Need to check both alpha of the view, and alpha of the background color. Bug: 187467559 Test: check status bar colors when using: - on white wallpaper, - on black wallpaper, - on wallpaper with white text - on wallpaper with dark text Change-Id: Ie6f34d34dfa9dea716f95bd6a95125fbd650fc29 --- src/com/android/launcher3/views/ScrimView.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/com/android/launcher3/views/ScrimView.java b/src/com/android/launcher3/views/ScrimView.java index fb1485b480..1eb79ad550 100644 --- a/src/com/android/launcher3/views/ScrimView.java +++ b/src/com/android/launcher3/views/ScrimView.java @@ -97,8 +97,10 @@ public class ScrimView extends View implements Insettable { private void updateSysUiColors() { // Use a light system UI (dark icons) if all apps is behind at least half of the // status bar. - boolean forceChange = - getVisibility() == VISIBLE && getAlpha() > STATUS_BAR_COLOR_FORCE_UPDATE_THRESHOLD; + final float threshold = STATUS_BAR_COLOR_FORCE_UPDATE_THRESHOLD; + boolean forceChange = getVisibility() == VISIBLE + && getAlpha() > threshold + && (Color.alpha(mBackgroundColor) / 255f) > threshold; if (forceChange) { getSystemUiController().updateUiState(UI_STATE_SCRIM_VIEW, !isScrimDark()); } else { From 0b9537e6fc9df24eda734bcb0ab6b5070a5eebae Mon Sep 17 00:00:00 2001 From: Hyunyoung Song Date: Mon, 28 Jun 2021 21:48:42 -0700 Subject: [PATCH 07/19] Rebind recycler views if launcher activity restarted Bug: 185038312 Test: manual TL;DR;; What was attempted but was too much refactoring of the code. Failed attempt #1: try re triggering the search. This was not trivial as SearchSession object is yet created. Failed attempt #2: Restoring AdapterItems in AlphabeticalAppsList This meant AdapterItems class and also it's children had to extend Parceleable object. Ultimate fix: Original issue of dupe view id among slice and work recyclerview should be fixed. And restoring should just work. Change-Id: I1bddd6aa5bc736ade3b02f69aa947d64cfa467d6 --- .../android/launcher3/allapps/AllAppsContainerView.java | 7 +++++-- src/com/android/launcher3/allapps/AllAppsRecyclerView.java | 3 ++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java index ab3ea0abe7..d1e643fd9f 100644 --- a/src/com/android/launcher3/allapps/AllAppsContainerView.java +++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java @@ -184,16 +184,19 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo } catch (Exception e) { Log.e("AllAppsContainerView", "restoreInstanceState viewId = 0", e); } + Bundle state = (Bundle) sparseArray.get(R.id.work_tab_state_id, null); if (state != null) { int currentPage = state.getInt(BUNDLE_KEY_CURRENT_PAGE, 0); if (currentPage != 0) { - rebindAdapters(true); mViewPager.setCurrentPage(currentPage); + rebindAdapters(true); + } else { + mSearchUiManager.resetSearch(); } } - } + } @Override protected void dispatchSaveInstanceState(SparseArray container) { diff --git a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java index d7a69f1b01..9a5f3f2be9 100644 --- a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java +++ b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java @@ -40,6 +40,7 @@ import com.android.launcher3.BaseRecyclerView; import com.android.launcher3.DeviceProfile; import com.android.launcher3.LauncherAppState; import com.android.launcher3.R; +import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.logging.StatsLogManager; import com.android.launcher3.views.ActivityContext; import com.android.launcher3.views.RecyclerViewFastScroller; @@ -166,7 +167,7 @@ public class AllAppsRecyclerView extends BaseRecyclerView { // Always scroll the view to the top so the user can see the changed results scrollToTop(); - if (mApps.hasNoFilteredResults()) { + if (mApps.hasNoFilteredResults() && !FeatureFlags.ENABLE_DEVICE_SEARCH.get()) { if (mEmptySearchBackground == null) { mEmptySearchBackground = new AllAppsBackgroundDrawable(getContext()); mEmptySearchBackground.setAlpha(0); From fa73c02172f8c9cae098a22c289b1c924dd09c41 Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Tue, 29 Jun 2021 15:49:46 -0700 Subject: [PATCH 08/19] Set elevation of popup and arrow to match. This ensures no shadow overlap. Bug: 191823198 Test: long press app where arrow is on top and bottom in: workspace, all apps, and search UI Change-Id: Icc4ac259607175d5e12447a844ba166ba28b74af --- src/com/android/launcher3/popup/ArrowPopup.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/com/android/launcher3/popup/ArrowPopup.java b/src/com/android/launcher3/popup/ArrowPopup.java index b7fe3480fa..a534ee3eb4 100644 --- a/src/com/android/launcher3/popup/ArrowPopup.java +++ b/src/com/android/launcher3/popup/ArrowPopup.java @@ -511,8 +511,8 @@ public abstract class ArrowPopup> mArrowOffsetHorizontal, -mArrowOffsetVertical, !mIsAboveIcon, mIsLeftAligned, mArrowColor)); - // TODO: Remove elevation when arrow is above as it casts a shadow on the container - mArrow.setElevation(mIsAboveIcon ? mElevation : 0); + setElevation(mElevation); + mArrow.setElevation(mElevation); } } From ce50b9ed83c9e705ccba328b86321d5352b6b303 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Tue, 29 Jun 2021 16:31:23 -0700 Subject: [PATCH 09/19] AllSet page fixes > Updating background color > Updating activity theme to not be transparent > Updating default accent color > Adding an accessible target to exit Bug: 190447132 Bug: 190136972 Bug: 190454597 Test: Manual Change-Id: Ia8ef67ed429c062a8d1109d7f444343ec4ca09cf --- quickstep/AndroidManifest.xml | 2 + quickstep/res/layout/activity_allset.xml | 13 +- quickstep/res/values-night/styles.xml | 27 ++++ quickstep/res/values/styles.xml | 8 + .../quickstep/interaction/AllSetActivity.java | 111 +++++--------- .../quickstep/interaction/AnnotationSpan.java | 143 ------------------ 6 files changed, 84 insertions(+), 220 deletions(-) create mode 100644 quickstep/res/values-night/styles.xml delete mode 100644 quickstep/src/com/android/quickstep/interaction/AnnotationSpan.java diff --git a/quickstep/AndroidManifest.xml b/quickstep/AndroidManifest.xml index bf9059f1c4..483ddc1905 100644 --- a/quickstep/AndroidManifest.xml +++ b/quickstep/AndroidManifest.xml @@ -130,6 +130,8 @@ android:excludeFromRecents="true" android:screenOrientation="portrait" android:permission="android.permission.REBOOT" + android:theme="@style/AllSetTheme" + android:label="@string/allset_title" android:exported="true"> diff --git a/quickstep/res/layout/activity_allset.xml b/quickstep/res/layout/activity_allset.xml index a6a17e5ebc..e79e57efef 100644 --- a/quickstep/res/layout/activity_allset.xml +++ b/quickstep/res/layout/activity_allset.xml @@ -20,8 +20,7 @@ android:paddingStart="@dimen/allset_page_margin_horizontal" android:paddingEnd="@dimen/allset_page_margin_horizontal" android:layoutDirection="locale" - android:textDirection="locale" - android:background="?android:attr/colorBackground"> + android:textDirection="locale"> + android:gravity="center" + android:layout_marginBottom="72dp" + android:minHeight="48dp" + android:background="?android:attr/selectableItemBackground" + android:text="@string/allset_navigation_settings" /> + + + + + + \ No newline at end of file diff --git a/quickstep/res/values/styles.xml b/quickstep/res/values/styles.xml index cfca1246ad..ca1e8c835e 100644 --- a/quickstep/res/values/styles.xml +++ b/quickstep/res/values/styles.xml @@ -110,6 +110,14 @@ 14sp + + - - \ 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 8ae56bd4e397e762aca90af8a371603b7c2feaab Mon Sep 17 00:00:00 2001 From: Tony Wickham Date: Tue, 29 Jun 2021 17:02:48 -0700 Subject: [PATCH 11/19] Fully null check mRecentsAnimationController It's already null checked everywhere else it's used. Test: none Fixes: 187354606 Change-Id: I50913c38b2653fe292d84fabe111ff3a3e10736d --- .../android/quickstep/AbsSwipeUpHandler.java | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java index 7f38923671..524cd53839 100644 --- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java +++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java @@ -140,7 +140,8 @@ public abstract class AbsSwipeUpHandler, private final ArrayList mRecentsAnimationStartCallbacks = new ArrayList<>(); private final OnScrollChangedListener mOnRecentsScrollListener = this::onRecentsViewScroll; - protected RecentsAnimationController mRecentsAnimationController; + // Null if the recents animation hasn't started yet or has been canceled or finished. + protected @Nullable RecentsAnimationController mRecentsAnimationController; protected RecentsAnimationTargets mRecentsAnimationTargets; protected T mActivity; protected Q mRecentsView; @@ -1353,8 +1354,10 @@ public abstract class AbsSwipeUpHandler, @UiThread private void resumeLastTask() { - mRecentsAnimationController.finish(false /* toRecents */, null); - ActiveGestureLog.INSTANCE.addLog("finishRecentsAnimation", false); + if (mRecentsAnimationController != null) { + mRecentsAnimationController.finish(false /* toRecents */, null); + ActiveGestureLog.INSTANCE.addLog("finishRecentsAnimation", false); + } doLogGesture(LAST_TASK, null); reset(); } @@ -1662,13 +1665,17 @@ public abstract class AbsSwipeUpHandler, } } else { mActivityInterface.onLaunchTaskFailed(); - mRecentsAnimationController.finish(true /* toRecents */, null); + if (mRecentsAnimationController != null) { + mRecentsAnimationController.finish(true /* toRecents */, null); + } } }, true /* freezeTaskList */); } else { mActivityInterface.onLaunchTaskFailed(); Toast.makeText(mContext, R.string.activity_not_available, LENGTH_SHORT).show(); - mRecentsAnimationController.finish(true /* toRecents */, null); + if (mRecentsAnimationController != null) { + mRecentsAnimationController.finish(true /* toRecents */, null); + } } } mCanceled = false; From 58905b4f0a59cad3c7d256971937d38a25f3198f Mon Sep 17 00:00:00 2001 From: Jon Spivack Date: Thu, 24 Jun 2021 14:55:40 -0700 Subject: [PATCH 12/19] 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + +