Fixing background jump when closing a widget
We do not add background animation when opening target is translucent
Added additional check to not animate background if launcher is not
closing (which is already a subset of all-targets-translucent)
Also removing reverse background animation from widgets, similar
to app-icons as it is never added for launcherNotClosing path
Bug: 242379946
Test: Added translucent activtiy and widget and verified manually
that the behavior does not change
Change-Id: Icda8007c0063295bf8431c00a0f0b665ecdef109
diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
index 938aa5e..c779175 100644
--- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
+++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
@@ -364,13 +364,10 @@
// before our internal listeners.
mLauncher.getStateManager().setCurrentAnimation(anim);
- final int rotationChange = getRotationChange(appTargets);
// Note: the targetBounds are relative to the launcher
int startDelay = getSingleFrameMs(mLauncher);
- Rect windowTargetBounds = getWindowTargetBounds(appTargets, rotationChange);
- Animator windowAnimator = getOpeningWindowAnimators(v, appTargets, wallpaperTargets,
- nonAppTargets, windowTargetBounds, areAllTargetsTranslucent(appTargets),
- rotationChange);
+ Animator windowAnimator = getOpeningWindowAnimators(
+ v, appTargets, wallpaperTargets, nonAppTargets, launcherClosing);
windowAnimator.setStartDelay(startDelay);
anim.play(windowAnimator);
if (launcherClosing) {
@@ -384,17 +381,6 @@
launcherContentAnimator.second.run();
}
});
- } else {
- anim.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationStart(Animator animation) {
- mLauncher.addOnResumeCallback(() ->
- ObjectAnimator.ofFloat(mLauncher.getDepthController().stateDepth,
- MULTI_PROPERTY_VALUE,
- mLauncher.getStateManager().getState().getDepth(
- mLauncher)).start());
- }
- });
}
}
@@ -403,23 +389,11 @@
@NonNull LauncherAppWidgetHostView v,
@NonNull RemoteAnimationTarget[] appTargets,
@NonNull RemoteAnimationTarget[] wallpaperTargets,
- @NonNull RemoteAnimationTarget[] nonAppTargets) {
+ @NonNull RemoteAnimationTarget[] nonAppTargets,
+ boolean launcherClosing) {
mLauncher.getStateManager().setCurrentAnimation(anim);
-
- Rect windowTargetBounds = getWindowTargetBounds(appTargets, getRotationChange(appTargets));
- anim.play(getOpeningWindowAnimatorsForWidget(v, appTargets, wallpaperTargets, nonAppTargets,
- windowTargetBounds, areAllTargetsTranslucent(appTargets)));
-
- anim.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationStart(Animator animation) {
- mLauncher.addOnResumeCallback(() ->
- ObjectAnimator.ofFloat(mLauncher.getDepthController().stateDepth,
- MULTI_PROPERTY_VALUE,
- mLauncher.getStateManager().getState().getDepth(
- mLauncher)).start());
- }
- });
+ anim.play(getOpeningWindowAnimatorsForWidget(
+ v, appTargets, wallpaperTargets, nonAppTargets, launcherClosing));
}
/**
@@ -657,7 +631,11 @@
RemoteAnimationTarget[] appTargets,
RemoteAnimationTarget[] wallpaperTargets,
RemoteAnimationTarget[] nonAppTargets,
- Rect windowTargetBounds, boolean appTargetsAreTranslucent, int rotationChange) {
+ boolean launcherClosing) {
+ int rotationChange = getRotationChange(appTargets);
+ Rect windowTargetBounds = getWindowTargetBounds(appTargets, rotationChange);
+ boolean appTargetsAreTranslucent = areAllTargetsTranslucent(appTargets);
+
RectF launcherIconBounds = new RectF();
FloatingIconView floatingView = FloatingIconView.getFloatingIconView(mLauncher, v,
!appTargetsAreTranslucent, launcherIconBounds, true /* isOpening */);
@@ -853,7 +831,6 @@
.setShadowRadius(mShadowRadius.value);
} else if (target.mode == MODE_CLOSING) {
if (target.localBounds != null) {
- final Rect localBounds = target.localBounds;
tmpPos.set(target.localBounds.left, target.localBounds.top);
} else {
tmpPos.set(target.position.x, target.position.y);
@@ -898,7 +875,7 @@
// If app targets are translucent, do not animate the background as it causes a visible
// flicker when it resets itself at the end of its animation.
- if (appTargetsAreTranslucent) {
+ if (appTargetsAreTranslucent || !launcherClosing) {
animatorSet.play(appAnimator);
} else {
animatorSet.playTogether(appAnimator, getBackgroundAnimator());
@@ -909,8 +886,10 @@
private Animator getOpeningWindowAnimatorsForWidget(LauncherAppWidgetHostView v,
RemoteAnimationTarget[] appTargets,
RemoteAnimationTarget[] wallpaperTargets,
- RemoteAnimationTarget[] nonAppTargets, Rect windowTargetBounds,
- boolean appTargetsAreTranslucent) {
+ RemoteAnimationTarget[] nonAppTargets, boolean launcherClosing) {
+ Rect windowTargetBounds = getWindowTargetBounds(appTargets, getRotationChange(appTargets));
+ boolean appTargetsAreTranslucent = areAllTargetsTranslucent(appTargets);
+
final RectF widgetBackgroundBounds = new RectF();
final Rect appWindowCrop = new Rect();
final Matrix matrix = new Matrix();
@@ -1037,7 +1016,7 @@
// If app targets are translucent, do not animate the background as it causes a visible
// flicker when it resets itself at the end of its animation.
- if (appTargetsAreTranslucent) {
+ if (appTargetsAreTranslucent || !launcherClosing) {
animatorSet.play(appAnimator);
} else {
animatorSet.playTogether(appAnimator, getBackgroundAnimator());
@@ -1717,7 +1696,7 @@
final boolean skipFirstFrame;
if (launchingFromWidget) {
composeWidgetLaunchAnimator(anim, (LauncherAppWidgetHostView) mV, appTargets,
- wallpaperTargets, nonAppTargets);
+ wallpaperTargets, nonAppTargets, launcherClosing);
addCujInstrumentation(
anim, InteractionJankMonitorWrapper.CUJ_APP_LAUNCH_FROM_WIDGET);
skipFirstFrame = true;
diff --git a/tests/AndroidManifest-common.xml b/tests/AndroidManifest-common.xml
index ae1060e..4af8468 100644
--- a/tests/AndroidManifest-common.xml
+++ b/tests/AndroidManifest-common.xml
@@ -62,6 +62,17 @@
</receiver>
<receiver
+ android:name="com.android.launcher3.testcomponent.AppWidgetWithDialog"
+ android:exported="true"
+ android:label="With Dialog">
+ <intent-filter>
+ <action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
+ </intent-filter>
+ <meta-data android:name="android.appwidget.provider"
+ android:resource="@xml/appwidget_no_config"/>
+ </receiver>
+
+ <receiver
android:name="com.android.launcher3.testcomponent.AppWidgetDynamicColors"
android:exported="true"
android:label="Dynamic Colors">
@@ -276,7 +287,17 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
-
+ <activity
+ android:name="com.android.launcher3.testcomponent.DialogTestActivity"
+ android:label="Dialog Activity"
+ android:theme="@android:style/Theme.Dialog"
+ android:exported="true"
+ android:taskAffinity="com.android.launcher3.testcomponent.Affinity2">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
+ </intent-filter>
+ </activity>
<activity android:name="com.android.launcher3.testcomponent.ImeTestActivity"
android:label="ImeTestActivity"
android:icon="@drawable/test_theme_icon"
diff --git a/tests/res/layout/test_layout_appwidget_blue.xml b/tests/res/layout/test_layout_appwidget_blue.xml
index 8111978..f33e575 100644
--- a/tests/res/layout/test_layout_appwidget_blue.xml
+++ b/tests/res/layout/test_layout_appwidget_blue.xml
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@android:id/content"
android:orientation="vertical"
android:background="#FF0000FF"
android:layout_width="match_parent"
diff --git a/tests/src/com/android/launcher3/testcomponent/AppWidgetWithDialog.java b/tests/src/com/android/launcher3/testcomponent/AppWidgetWithDialog.java
new file mode 100644
index 0000000..6d617fa
--- /dev/null
+++ b/tests/src/com/android/launcher3/testcomponent/AppWidgetWithDialog.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 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.testcomponent;
+
+import android.app.PendingIntent;
+import android.appwidget.AppWidgetManager;
+import android.content.Context;
+import android.content.Intent;
+import android.widget.RemoteViews;
+
+/**
+ * A simple app widget with shows a dialog on clicking.
+ */
+public class AppWidgetWithDialog extends AppWidgetNoConfig {
+
+ @Override
+ public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
+ int layoutId = context.getResources().getIdentifier(
+ "test_layout_appwidget_blue", "layout", context.getPackageName());
+ RemoteViews views = new RemoteViews(context.getPackageName(), layoutId);
+
+ PendingIntent pi = PendingIntent.getActivity(context, 0,
+ new Intent(context, DialogTestActivity.class), PendingIntent.FLAG_IMMUTABLE);
+ views.setOnClickPendingIntent(android.R.id.content, pi);
+ AppWidgetManager.getInstance(context).updateAppWidget(appWidgetIds, views);
+ }
+}
diff --git a/tests/src/com/android/launcher3/testcomponent/DialogTestActivity.java b/tests/src/com/android/launcher3/testcomponent/DialogTestActivity.java
new file mode 100644
index 0000000..9e5a274
--- /dev/null
+++ b/tests/src/com/android/launcher3/testcomponent/DialogTestActivity.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2022 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.testcomponent;
+
+
+/**
+ * Extension of BaseTestingActivity with a Dialog theme
+ */
+public class DialogTestActivity extends BaseTestingActivity {}