Merge "Cleanup obsolete generated preview tests" into main
diff --git a/aconfig/launcher.aconfig b/aconfig/launcher.aconfig
index f1f9966..15ac9e3 100644
--- a/aconfig/launcher.aconfig
+++ b/aconfig/launcher.aconfig
@@ -311,6 +311,13 @@
}
flag {
+ name: "enable_container_return_animations"
+ namespace: "launcher"
+ description: "Enables the container return animation mirroring launches."
+ bug: "341017746"
+}
+
+flag {
name: "floating_search_bar"
namespace: "launcher"
description: "Search bar persists at the bottom of the screen across Launcher states"
diff --git a/go/quickstep/res/values-fa/strings.xml b/go/quickstep/res/values-fa/strings.xml
index 47786e9..8453d4e 100644
--- a/go/quickstep/res/values-fa/strings.xml
+++ b/go/quickstep/res/values-fa/strings.xml
@@ -14,7 +14,7 @@
<string name="assistant_not_selected_text" msgid="3244613673884359276">"برای گوش کردن به نوشتار در صفحهنمایشتان یا ترجمه کردن آن، یکی از برنامههای دستیار دیجیتالی را در «تنظیمات» انتخاب کنید"</string>
<string name="assistant_not_supported_title" msgid="1675788067597484142">"برای استفاده از این ویژگی، دستیارتان را تغییر دهید"</string>
<string name="assistant_not_supported_text" msgid="1708031078549268884">"برای گوش کردن به نوشتار در صفحهنمایشتان یا ترجمه کردن آن، برنامه دستیار دیجیتالیتان را در «تنظیمات» تغییر دهید"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"برای گوش کردن به نوشتار در این صفحه، اینجا ضربه بزنید"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"برای ترجمه نوشتار در این صفحه، اینجا ضربه بزنید"</string>
+ <string name="tooltip_listen" msgid="7634466447860989102">"برای گوش کردن به نوشتار در این صفحه، اینجا تکضرب بزنید"</string>
+ <string name="tooltip_translate" msgid="4184845868901542567">"برای ترجمه نوشتار در این صفحه، اینجا تکضرب بزنید"</string>
<string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"نمیتوان این برنامه را همرسانی کرد"</string>
</resources>
diff --git a/go/quickstep/res/values-nb/strings.xml b/go/quickstep/res/values-nb/strings.xml
index 662b544..6299cc8 100644
--- a/go/quickstep/res/values-nb/strings.xml
+++ b/go/quickstep/res/values-nb/strings.xml
@@ -9,7 +9,7 @@
<string name="dialog_cancel" msgid="6464336969134856366">"AVBRYT"</string>
<string name="dialog_settings" msgid="6564397136021186148">"INNSTILLINGER"</string>
<string name="niu_actions_confirmation_title" msgid="3863451714863526143">"Oversett eller lytt til tekst på skjermen"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"Informasjon som tekst på skjermen, nettadresser og skjermdumper kan deles med Google.\n\nFor å endre hvilken informasjon du deler, gå til "<b>"Innstillinger > Apper > Standardapper > Digital assistent-app"</b>"."</string>
+ <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"Informasjon som tekst på skjermen, nettadresser og skjermbilder kan deles med Google.\n\nFor å endre hvilken informasjon du deler, gå til "<b>"Innstillinger > Apper > Standardapper > Digital assistent-app"</b>"."</string>
<string name="assistant_not_selected_title" msgid="5017072974603345228">"Velg en assistent for å bruke denne funksjonen"</string>
<string name="assistant_not_selected_text" msgid="3244613673884359276">"For å høre eller oversette tekst på skjermen, velg en digital assistent-app i innstillingene"</string>
<string name="assistant_not_supported_title" msgid="1675788067597484142">"Endre assistenten for å bruke denne funksjonen"</string>
diff --git a/quickstep/res/values-en-rAU/strings.xml b/quickstep/res/values-en-rAU/strings.xml
index eedb29e..b84f646 100644
--- a/quickstep/res/values-en-rAU/strings.xml
+++ b/quickstep/res/values-en-rAU/strings.xml
@@ -87,7 +87,7 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Try again"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Nice!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Tutorial <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"Ready!"</string>
+ <string name="allset_title" msgid="5021126669778966707">"All set!"</string>
<string name="allset_hint" msgid="459504134589971527">"Swipe up to go home"</string>
<string name="allset_button_hint" msgid="2395219947744706291">"Tap the home button to go to your home screen"</string>
<string name="allset_description_generic" msgid="5385500062202019855">"You’re ready to start using your <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
diff --git a/quickstep/res/values-en-rGB/strings.xml b/quickstep/res/values-en-rGB/strings.xml
index eedb29e..b84f646 100644
--- a/quickstep/res/values-en-rGB/strings.xml
+++ b/quickstep/res/values-en-rGB/strings.xml
@@ -87,7 +87,7 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Try again"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Nice!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Tutorial <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"Ready!"</string>
+ <string name="allset_title" msgid="5021126669778966707">"All set!"</string>
<string name="allset_hint" msgid="459504134589971527">"Swipe up to go home"</string>
<string name="allset_button_hint" msgid="2395219947744706291">"Tap the home button to go to your home screen"</string>
<string name="allset_description_generic" msgid="5385500062202019855">"You’re ready to start using your <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
diff --git a/quickstep/res/values-en-rIN/strings.xml b/quickstep/res/values-en-rIN/strings.xml
index eedb29e..b84f646 100644
--- a/quickstep/res/values-en-rIN/strings.xml
+++ b/quickstep/res/values-en-rIN/strings.xml
@@ -87,7 +87,7 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Try again"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Nice!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Tutorial <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"Ready!"</string>
+ <string name="allset_title" msgid="5021126669778966707">"All set!"</string>
<string name="allset_hint" msgid="459504134589971527">"Swipe up to go home"</string>
<string name="allset_button_hint" msgid="2395219947744706291">"Tap the home button to go to your home screen"</string>
<string name="allset_description_generic" msgid="5385500062202019855">"You’re ready to start using your <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
diff --git a/quickstep/res/values-fa/strings.xml b/quickstep/res/values-fa/strings.xml
index b296080..bafc2d5 100644
--- a/quickstep/res/values-fa/strings.xml
+++ b/quickstep/res/values-fa/strings.xml
@@ -89,7 +89,7 @@
<string name="gesture_tutorial_step" msgid="1279786122817620968">"آموزش گامبهگام <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
<string name="allset_title" msgid="5021126669778966707">"همه چیز آماده است!"</string>
<string name="allset_hint" msgid="459504134589971527">"برای رفتن به صفحه اصلی، تند بهبالا بکشید"</string>
- <string name="allset_button_hint" msgid="2395219947744706291">"برای رفتن به صفحه اصلی، روی دکمه صفحه اصلی ضربه بزنید"</string>
+ <string name="allset_button_hint" msgid="2395219947744706291">"برای رفتن به صفحه اصلی، روی دکمه صفحه اصلی تکضرب بزنید"</string>
<string name="allset_description_generic" msgid="5385500062202019855">"آمادهاید از <xliff:g id="DEVICE">%1$s</xliff:g> خود استفاده کنید"</string>
<string name="default_device_name" msgid="6660656727127422487">"دستگاه"</string>
<string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"تنظیمات پیمایش سیستم"</annotation></string>
diff --git a/quickstep/res/values-ko/strings.xml b/quickstep/res/values-ko/strings.xml
index 1f4275a..c27b7f8 100644
--- a/quickstep/res/values-ko/strings.xml
+++ b/quickstep/res/values-ko/strings.xml
@@ -141,7 +141,7 @@
<string name="quick_switch_desktop" msgid="4834587349322698616">"{count,plural, =1{데스크톱 앱 #개를 표시합니다.}other{데스크톱 앱 #개를 표시합니다.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> 및 <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
<string name="bubble_bar_bubble_fallback_description" msgid="7811684548953452009">"풍선"</string>
- <string name="bubble_bar_overflow_description" msgid="8617628132733151708">"오버플로"</string>
+ <string name="bubble_bar_overflow_description" msgid="8617628132733151708">"더보기"</string>
<string name="bubble_bar_bubble_description" msgid="1882466152448446446">"<xliff:g id="APP_NAME">%2$s</xliff:g>의 <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_bar_description_multiple_bubbles" msgid="3922207715357143648">"<xliff:g id="BUBBLE_BAR_BUBBLE_DESCRIPTION">%1$s</xliff:g> 외 <xliff:g id="BUBBLE_COUNT">%2$d</xliff:g>개"</string>
</resources>
diff --git a/quickstep/res/values-mn/strings.xml b/quickstep/res/values-mn/strings.xml
index 7a4c7e9..fe2e4a4 100644
--- a/quickstep/res/values-mn/strings.xml
+++ b/quickstep/res/values-mn/strings.xml
@@ -141,7 +141,7 @@
<string name="quick_switch_desktop" msgid="4834587349322698616">"{count,plural, =1{Компьютерын # аппыг харуулна уу.}other{Компьютерын # аппыг харуулна уу.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> болон <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
<string name="bubble_bar_bubble_fallback_description" msgid="7811684548953452009">"Бөмбөлөг"</string>
- <string name="bubble_bar_overflow_description" msgid="8617628132733151708">"Урт цэс"</string>
+ <string name="bubble_bar_overflow_description" msgid="8617628132733151708">"Илүү хэсэг"</string>
<string name="bubble_bar_bubble_description" msgid="1882466152448446446">"<xliff:g id="APP_NAME">%2$s</xliff:g>-с ирсэн <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_bar_description_multiple_bubbles" msgid="3922207715357143648">"<xliff:g id="BUBBLE_BAR_BUBBLE_DESCRIPTION">%1$s</xliff:g> болон бусад <xliff:g id="BUBBLE_COUNT">%2$d</xliff:g>"</string>
</resources>
diff --git a/quickstep/res/values-pt-rPT/strings.xml b/quickstep/res/values-pt-rPT/strings.xml
index 47498cc..e4d07bd 100644
--- a/quickstep/res/values-pt-rPT/strings.xml
+++ b/quickstep/res/values-pt-rPT/strings.xml
@@ -113,7 +113,7 @@
<string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Arraste uma app para o lado para usar 2 apps em simultâneo"</string>
<string name="taskbar_edu_stashing" msgid="5645461372669217294">"Deslize lentamente para cima para ver a Barra de tarefas"</string>
<string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Receba sugestões de apps baseadas na sua rotina"</string>
- <string name="taskbar_edu_pinning" msgid="6708550858580071558">"Mantenha o divisor premido para fixar a Barra de tarefas"</string>
+ <string name="taskbar_edu_pinning" msgid="6708550858580071558">"Mantenha o divisor pressionado para fixar a Barra de tarefas"</string>
<string name="taskbar_edu_features" msgid="3320337287472848162">"Faça mais com a Barra de tarefas"</string>
<string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Mostre sempre a Barra de tarefas"</string>
<string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Para mostrar sempre a Barra de tarefas no fundo do ecrã, toque sem soltar no divisor"</string>
diff --git a/quickstep/res/values-zh-rCN/strings.xml b/quickstep/res/values-zh-rCN/strings.xml
index a89227e..79ea299 100644
--- a/quickstep/res/values-zh-rCN/strings.xml
+++ b/quickstep/res/values-zh-rCN/strings.xml
@@ -141,7 +141,7 @@
<string name="quick_switch_desktop" msgid="4834587349322698616">"{count,plural, =1{显示 # 款桌面应用。}other{显示 # 款桌面应用。}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g>和<xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
<string name="bubble_bar_bubble_fallback_description" msgid="7811684548953452009">"气泡框"</string>
- <string name="bubble_bar_overflow_description" msgid="8617628132733151708">"菜单"</string>
+ <string name="bubble_bar_overflow_description" msgid="8617628132733151708">"溢出式气泡框"</string>
<string name="bubble_bar_bubble_description" msgid="1882466152448446446">"来自“<xliff:g id="APP_NAME">%2$s</xliff:g>”的<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_bar_description_multiple_bubbles" msgid="3922207715357143648">"<xliff:g id="BUBBLE_BAR_BUBBLE_DESCRIPTION">%1$s</xliff:g>以及另外 <xliff:g id="BUBBLE_COUNT">%2$d</xliff:g> 个"</string>
</resources>
diff --git a/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java b/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java
index 15180ef..d973149 100644
--- a/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java
+++ b/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java
@@ -238,5 +238,12 @@
@Override
@UiThread
default void onAnimationCancelled() {}
+
+ /**
+ * Returns whether this animation factory supports a tightly coupled return animation.
+ */
+ default boolean supportsReturnTransition() {
+ return false;
+ }
}
}
diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
index fae281a..5a74f4a 100644
--- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
+++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
@@ -43,6 +43,7 @@
import static com.android.launcher3.BaseActivity.INVISIBLE_BY_APP_TRANSITIONS;
import static com.android.launcher3.BaseActivity.INVISIBLE_BY_PENDING_FLAGS;
import static com.android.launcher3.BaseActivity.PENDING_INVISIBLE_BY_WALLPAPER_ANIMATION;
+import static com.android.launcher3.Flags.enableContainerReturnAnimations;
import static com.android.launcher3.Flags.enableScalingRevealHomeAnimation;
import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
import static com.android.launcher3.LauncherAnimUtils.VIEW_BACKGROUND_COLOR;
@@ -68,6 +69,7 @@
import static com.android.quickstep.TaskViewUtils.findTaskViewToLaunch;
import static com.android.quickstep.util.AnimUtils.clampToDuration;
import static com.android.quickstep.util.AnimUtils.completeRunnableListCallback;
+import static com.android.systemui.shared.Flags.returnAnimationFrameworkLibrary;
import static com.android.systemui.shared.system.QuickStepContract.getWindowCornerRadius;
import static com.android.systemui.shared.system.QuickStepContract.supportsRoundedCornersOnWindows;
@@ -181,6 +183,9 @@
*/
public class QuickstepTransitionManager implements OnDeviceProfileChangeListener {
+ private static final String TRANSITION_COOKIE_PREFIX =
+ "com.android.launcher3.QuickstepTransitionManager_activityLaunch";
+
private static final boolean ENABLE_SHELL_STARTING_SURFACE =
SystemProperties.getBoolean("persist.debug.shell_starting_surface", true);
@@ -333,17 +338,7 @@
restartedListener.register(onEndCallback::executeAllAndDestroy);
onEndCallback.add(restartedListener::unregister);
- mAppLaunchRunner = new AppLaunchAnimationRunner(v, onEndCallback);
- ItemInfo tag = (ItemInfo) v.getTag();
- if (tag != null && tag.shouldUseBackgroundAnimation()) {
- ContainerAnimationRunner containerAnimationRunner = ContainerAnimationRunner.from(
- v, mLauncher, mStartingWindowListener, onEndCallback);
- if (containerAnimationRunner != null) {
- mAppLaunchRunner = containerAnimationRunner;
- }
- }
- RemoteAnimationRunnerCompat runner = new LauncherAnimationRunner(
- mHandler, mAppLaunchRunner, true /* startAtFrontOfQueue */);
+ RemoteAnimationRunnerCompat runner = createAppLaunchRunner(v, onEndCallback);
// Note that this duration is a guess as we do not know if the animation will be a
// recents launch or not for sure until we know the opening app targets.
@@ -360,10 +355,95 @@
IRemoteCallback endCallback = completeRunnableListCallback(onEndCallback);
options.setOnAnimationAbortListener(endCallback);
options.setOnAnimationFinishedListener(endCallback);
+
+ IBinder cookie = mAppLaunchRunner.supportsReturnTransition()
+ ? ((ContainerAnimationRunner) mAppLaunchRunner).getCookie() : null;
+ addLaunchCookie(cookie, (ItemInfo) v.getTag(), options);
+
+ // Register the return animation so it can be triggered on back from the app to home.
+ maybeRegisterAppReturnTransition(v);
+
return new ActivityOptionsWrapper(options, onEndCallback);
}
/**
+ * Selects the appropriate type of launch runner for the given view, builds it, and returns it.
+ * {@link QuickstepTransitionManager#mAppLaunchRunner} is updated as a by-product of this
+ * method.
+ */
+ private RemoteAnimationRunnerCompat createAppLaunchRunner(View v, RunnableList onEndCallback) {
+ ItemInfo tag = (ItemInfo) v.getTag();
+ ContainerAnimationRunner containerRunner = null;
+ if (tag != null && tag.shouldUseBackgroundAnimation()) {
+ // The cookie should only override the default used by launcher if container return
+ // animations are enabled.
+ ActivityTransitionAnimator.TransitionCookie cookie =
+ checkReturnAnimationsFlags()
+ ? new ActivityTransitionAnimator.TransitionCookie(
+ TRANSITION_COOKIE_PREFIX + tag.id)
+ : null;
+ ContainerAnimationRunner launchAnimationRunner =
+ ContainerAnimationRunner.fromView(
+ v, cookie, true /* forLaunch */, mLauncher, mStartingWindowListener,
+ onEndCallback);
+
+ if (launchAnimationRunner != null) {
+ containerRunner = launchAnimationRunner;
+ }
+ }
+
+ mAppLaunchRunner = containerRunner != null
+ ? containerRunner : new AppLaunchAnimationRunner(v, onEndCallback);
+ return new LauncherAnimationRunner(
+ mHandler, mAppLaunchRunner, true /* startAtFrontOfQueue */);
+ }
+
+ /**
+ * If container return animations are enabled and the current launch runner is itself a
+ * {@link ContainerAnimationRunner}, registers a matching return animation that de-registers
+ * itself after it has run once or is made obsolete by the view going away.
+ */
+ private void maybeRegisterAppReturnTransition(View v) {
+ if (!checkReturnAnimationsFlags() || !mAppLaunchRunner.supportsReturnTransition()) {
+ return;
+ }
+
+ ActivityTransitionAnimator.TransitionCookie cookie =
+ ((ContainerAnimationRunner) mAppLaunchRunner).getCookie();
+ RunnableList onEndCallback = new RunnableList();
+ ContainerAnimationRunner runner =
+ ContainerAnimationRunner.fromView(
+ v, cookie, false /* forLaunch */, mLauncher, mStartingWindowListener,
+ onEndCallback);
+ RemoteTransition transition =
+ new RemoteTransition(
+ new LauncherAnimationRunner(
+ mHandler, runner, true /* startAtFrontOfQueue */
+ ).toRemoteTransition()
+ );
+
+ SystemUiProxy.INSTANCE.get(mLauncher).registerRemoteTransition(
+ transition, ContainerAnimationRunner.buildBackToHomeFilter(cookie, mLauncher));
+ ContainerAnimationRunner.setUpRemoteAnimationCleanup(
+ v, transition, onEndCallback, mLauncher);
+ }
+
+ /**
+ * Adds a new launch cookie for the activity launch if supported.
+ * Prioritizes the explicitly provided cookie, falling back on extracting one from the given
+ * {@link ItemInfo} if necessary.
+ */
+ private void addLaunchCookie(IBinder cookie, ItemInfo info, ActivityOptions options) {
+ if (cookie == null) {
+ cookie = mLauncher.getLaunchCookie(info);
+ }
+
+ if (cookie != null) {
+ options.setLaunchCookie(cookie);
+ }
+ }
+
+ /**
* Whether the launch is a recents app transition and we should do a launch animation
* from the recents view. Note that if the remote animation targets are not provided, this
* may not always be correct as we may resolve the opening app to a task when the animation
@@ -1728,6 +1808,10 @@
}
}
+ private static boolean checkReturnAnimationsFlags() {
+ return enableContainerReturnAnimations() && returnAnimationFrameworkLibrary();
+ }
+
/**
* Remote animation runner for animation from the app to Launcher, including recents.
*/
@@ -1844,38 +1928,45 @@
/** The delegate runner that handles the actual animation. */
private final RemoteAnimationDelegate<IRemoteAnimationFinishedCallback> mDelegate;
+ @Nullable
+ private final ActivityTransitionAnimator.TransitionCookie mCookie;
+
private ContainerAnimationRunner(
- RemoteAnimationDelegate<IRemoteAnimationFinishedCallback> delegate) {
+ RemoteAnimationDelegate<IRemoteAnimationFinishedCallback> delegate,
+ ActivityTransitionAnimator.TransitionCookie cookie) {
mDelegate = delegate;
+ mCookie = cookie;
}
@Nullable
- private static ContainerAnimationRunner from(View v, Launcher launcher,
- StartingWindowListener startingWindowListener, RunnableList onEndCallback) {
- View viewToUse = findLaunchableViewWithBackground(v);
- if (viewToUse == null) {
- return null;
+ ActivityTransitionAnimator.TransitionCookie getCookie() {
+ return mCookie;
+ }
+
+ @Nullable
+ static ContainerAnimationRunner fromView(
+ View v,
+ ActivityTransitionAnimator.TransitionCookie cookie,
+ boolean forLaunch,
+ Launcher launcher,
+ StartingWindowListener startingWindowListener,
+ RunnableList onEndCallback) {
+ if (!forLaunch && !checkReturnAnimationsFlags()) {
+ throw new IllegalStateException(
+ "forLaunch cannot be false when the enableContainerReturnAnimations or "
+ + "returnAnimationFrameworkLibrary flag is disabled");
}
- // The CUJ is logged by the click handler, so we don't log it inside the animation
- // library.
- ActivityTransitionAnimator.Controller controllerDelegate =
- ActivityTransitionAnimator.Controller.fromView(viewToUse, null /* cujType */);
-
- if (controllerDelegate == null) {
- return null;
- }
-
- // This wrapper allows us to override the default value, telling the controller that the
- // current window is below the animating window.
+ // First the controller is created. This is used by the runner to animate the
+ // origin/target view.
ActivityTransitionAnimator.Controller controller =
- new DelegateTransitionAnimatorController(controllerDelegate) {
- @Override
- public boolean isBelowAnimatingWindow() {
- return true;
- }
- };
+ buildController(v, cookie, forLaunch);
+ if (controller == null) {
+ return null;
+ }
+ // The callback is used to make sure that we use the right color to fade between view
+ // and the window.
ActivityTransitionAnimator.Callback callback = task -> {
final int backgroundColor =
startingWindowListener.mBackgroundColor == Color.TRANSPARENT
@@ -1894,7 +1985,52 @@
return new ContainerAnimationRunner(
new ActivityTransitionAnimator.AnimationDelegate(
- MAIN_EXECUTOR, controller, callback, listener));
+ MAIN_EXECUTOR, controller, callback, listener),
+ cookie);
+ }
+
+ /**
+ * Constructs a {@link ActivityTransitionAnimator.Controller} that can be used by a
+ * {@link ContainerAnimationRunner} to animate a view into an opening window or from a
+ * closing one.
+ */
+ @Nullable
+ private static ActivityTransitionAnimator.Controller buildController(
+ View v, ActivityTransitionAnimator.TransitionCookie cookie, boolean isLaunching) {
+ View viewToUse = findLaunchableViewWithBackground(v);
+ if (viewToUse == null) {
+ return null;
+ }
+
+ // The CUJ is logged by the click handler, so we don't log it inside the animation
+ // library. TODO: figure out return CUJ.
+ ActivityTransitionAnimator.Controller controllerDelegate =
+ ActivityTransitionAnimator.Controller.fromView(viewToUse, null /* cujType */);
+
+ if (controllerDelegate == null) {
+ return null;
+ }
+
+ // This wrapper allows us to override the default value, telling the controller that the
+ // current window is below the animating window as well as information about the return
+ // animation.
+ return new DelegateTransitionAnimatorController(controllerDelegate) {
+ @Override
+ public boolean isLaunching() {
+ return isLaunching;
+ }
+
+ @Override
+ public boolean isBelowAnimatingWindow() {
+ return true;
+ }
+
+ @Nullable
+ @Override
+ public ActivityTransitionAnimator.TransitionCookie getTransitionCookie() {
+ return cookie;
+ }
+ };
}
/**
@@ -1916,6 +2052,67 @@
return (T) current;
}
+ /**
+ * Builds the filter used by WM Shell to match app closing transitions (only back, no home
+ * button/gesture) to the given launch cookie.
+ */
+ static TransitionFilter buildBackToHomeFilter(
+ ActivityTransitionAnimator.TransitionCookie cookie, Launcher launcher) {
+ // Closing activity must include the cookie in its list of launch cookies.
+ TransitionFilter.Requirement appRequirement = new TransitionFilter.Requirement();
+ appRequirement.mActivityType = ACTIVITY_TYPE_STANDARD;
+ appRequirement.mLaunchCookie = cookie;
+ appRequirement.mModes = new int[]{TRANSIT_CLOSE, TRANSIT_TO_BACK};
+ // Opening activity must be Launcher.
+ TransitionFilter.Requirement launcherRequirement = new TransitionFilter.Requirement();
+ launcherRequirement.mActivityType = ACTIVITY_TYPE_HOME;
+ launcherRequirement.mModes = new int[]{TRANSIT_OPEN, TRANSIT_TO_FRONT};
+ launcherRequirement.mTopActivity = launcher.getComponentName();
+ // Transition types CLOSE and TO_BACK match the back button/gesture but not the home
+ // button/gesture.
+ TransitionFilter filter = new TransitionFilter();
+ filter.mTypeSet = new int[]{TRANSIT_CLOSE, TRANSIT_TO_BACK};
+ filter.mRequirements =
+ new TransitionFilter.Requirement[]{appRequirement, launcherRequirement};
+ return filter;
+ }
+
+ /**
+ * Creates various conditions to ensure that the given transition is cleaned up correctly
+ * when necessary:
+ * - if the transition has run, it is the callback that unregisters it;
+ * - if the associated view is detached before the transition has had an opportunity to run,
+ * a {@link View.OnAttachStateChangeListener} allows us to do the same (and removes
+ * itself).
+ */
+ static void setUpRemoteAnimationCleanup(
+ View v, RemoteTransition transition, RunnableList callback, Launcher launcher) {
+ View.OnAttachStateChangeListener listener = new View.OnAttachStateChangeListener() {
+ @Override
+ public void onViewAttachedToWindow(@NonNull View v) {}
+
+ @Override
+ public void onViewDetachedFromWindow(@NonNull View v) {
+ SystemUiProxy.INSTANCE.get(launcher)
+ .unregisterRemoteTransition(transition);
+ v.removeOnAttachStateChangeListener(this);
+ }
+ };
+
+ // Remove the animation as soon as it has run once.
+ callback.add(() -> {
+ SystemUiProxy.INSTANCE.get(launcher).unregisterRemoteTransition(transition);
+ if (v != null) {
+ v.removeOnAttachStateChangeListener(listener);
+ }
+ });
+
+ // Remove the animation when the view is detached from the hierarchy.
+ // This is so that if back is not invoked (e.g. if we go back home through the home
+ // gesture) we don't have obsolete transitions staying registered.
+ v.addOnAttachStateChangeListener(listener);
+ }
+
@Override
public void onAnimationStart(int transit, RemoteAnimationTarget[] appTargets,
RemoteAnimationTarget[] wallpaperTargets, RemoteAnimationTarget[] nonAppTargets,
@@ -1928,6 +2125,11 @@
public void onAnimationCancelled() {
mDelegate.onAnimationCancelled();
}
+
+ @Override
+ public boolean supportsReturnTransition() {
+ return true;
+ }
}
/**
diff --git a/quickstep/src/com/android/launcher3/WidgetPickerActivity.java b/quickstep/src/com/android/launcher3/WidgetPickerActivity.java
index 7e52ea1..7cdca74 100644
--- a/quickstep/src/com/android/launcher3/WidgetPickerActivity.java
+++ b/quickstep/src/com/android/launcher3/WidgetPickerActivity.java
@@ -120,10 +120,6 @@
WindowInsetsController wc = mDragLayer.getWindowInsetsController();
wc.hide(navigationBars() + statusBars());
- BaseWidgetSheet widgetSheet = WidgetsFullSheet.show(this, true);
- widgetSheet.disableNavBarScrim(true);
- widgetSheet.addOnCloseListener(this::finish);
-
parseIntentExtras();
refreshAndBindWidgets();
}
@@ -224,9 +220,10 @@
};
}
- /** Updates the model with widgets and provides them after applying the provided filter. */
+ /** Updates the model with widgets, applies filters and launches the widgets sheet once
+ * widgets are available */
private void refreshAndBindWidgets() {
- MODEL_EXECUTOR.execute(() -> {
+ MODEL_EXECUTOR.getHandler().postDelayed(() -> {
LauncherAppState app = LauncherAppState.getInstance(this);
mModel.update(app, null);
final List<WidgetsListBaseEntry> allWidgets =
@@ -240,6 +237,9 @@
}
);
bindWidgets(allWidgets);
+ // Open sheet once widgets are available, so that it doesn't interrupt the open
+ // animation.
+ openWidgetsSheet();
if (mUiSurface != null) {
Map<ComponentKey, WidgetItem> allWidgetItems = allWidgets.stream()
.filter(entry -> entry instanceof WidgetsListContentEntry)
@@ -253,15 +253,26 @@
mUiSurface, allWidgetItems);
mWidgetPredictionsRequester.request(mAddedWidgets, this::bindRecommendedWidgets);
}
- });
+ }, mDeviceProfile.bottomSheetOpenDuration);
}
private void bindWidgets(List<WidgetsListBaseEntry> widgets) {
MAIN_EXECUTOR.execute(() -> mPopupDataProvider.setAllWidgets(widgets));
}
+ private void openWidgetsSheet() {
+ MAIN_EXECUTOR.execute(() -> {
+ BaseWidgetSheet widgetSheet = WidgetsFullSheet.show(this, true);
+ widgetSheet.disableNavBarScrim(true);
+ widgetSheet.addOnCloseListener(this::finish);
+ });
+ }
+
private void bindRecommendedWidgets(List<ItemInfo> recommendedWidgets) {
- MAIN_EXECUTOR.execute(() -> mPopupDataProvider.setRecommendedWidgets(recommendedWidgets));
+ // Bind recommendations once picker has finished open animation.
+ MAIN_EXECUTOR.getHandler().postDelayed(
+ () -> mPopupDataProvider.setRecommendedWidgets(recommendedWidgets),
+ mDeviceProfile.bottomSheetOpenDuration);
}
@Override
diff --git a/quickstep/src/com/android/launcher3/model/WidgetPredictionsRequester.java b/quickstep/src/com/android/launcher3/model/WidgetPredictionsRequester.java
index 5730273..41fcf61 100644
--- a/quickstep/src/com/android/launcher3/model/WidgetPredictionsRequester.java
+++ b/quickstep/src/com/android/launcher3/model/WidgetPredictionsRequester.java
@@ -65,6 +65,7 @@
private final Context mContext;
@NonNull
private final String mUiSurface;
+ private boolean mPredictionsAvailable;
@NonNull
private final Map<ComponentKey, WidgetItem> mAllWidgets;
@@ -76,8 +77,8 @@
}
/**
- * Requests predictions from the app predictions manager and registers the provided callback to
- * receive updates when predictions are available.
+ * Requests one time predictions from the app predictions manager and invokes provided callback
+ * once predictions are available.
*
* @param existingWidgets widgets that are currently added to the surface;
* @param callback consumer of prediction results to be called when predictions are
@@ -159,10 +160,14 @@
@WorkerThread
private void bindPredictions(List<AppTarget> targets, Predicate<WidgetItem> filter,
Consumer<List<ItemInfo>> callback) {
- List<WidgetItem> filteredPredictions = filterPredictions(targets, mAllWidgets, filter);
- List<ItemInfo> mappedPredictions = mapWidgetItemsToItemInfo(filteredPredictions);
+ if (!mPredictionsAvailable) {
+ mPredictionsAvailable = true;
+ List<WidgetItem> filteredPredictions = filterPredictions(targets, mAllWidgets, filter);
+ List<ItemInfo> mappedPredictions = mapWidgetItemsToItemInfo(filteredPredictions);
- MAIN_EXECUTOR.execute(() -> callback.accept(mappedPredictions));
+ MAIN_EXECUTOR.execute(() -> callback.accept(mappedPredictions));
+ MODEL_EXECUTOR.execute(this::clear);
+ }
}
/**
@@ -214,5 +219,6 @@
mAppPredictor.destroy();
mAppPredictor = null;
}
+ mPredictionsAvailable = false;
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
index ce281c3..f24bc21 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
@@ -269,8 +269,8 @@
foundTaskView,
foundTask,
taskContainer.getIconView().getDrawable(),
- taskContainer.getThumbnailViewDeprecated(),
- taskContainer.getThumbnailViewDeprecated().getThumbnail(),
+ taskContainer.getSnapshotView(),
+ taskContainer.getThumbnail(),
null /* intent */,
null /* user */,
info);
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index 037f2f6..be6f690 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -1200,7 +1200,6 @@
: Display.DEFAULT_DISPLAY);
activityOptions.options.setPendingIntentBackgroundActivityStartMode(
ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED);
- addLaunchCookie(item, activityOptions.options);
return activityOptions;
}
@@ -1225,19 +1224,6 @@
}
/**
- * Adds a new launch cookie for the activity launch if supported.
- *
- * @param info the item info for the launch
- * @param opts the options to set the launchCookie on.
- */
- public void addLaunchCookie(ItemInfo info, ActivityOptions opts) {
- IBinder launchCookie = getLaunchCookie(info);
- if (launchCookie != null) {
- opts.setLaunchCookie(launchCookie);
- }
- }
-
- /**
* Return a new launch cookie for the activity launch if supported.
*
* @param info the item info for the launch
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java
index 4bc3c16..3c7f335 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java
@@ -252,7 +252,7 @@
mTaskBeingDragged, maxDuration, currentInterpolator);
// Since the thumbnail is what is filling the screen, based the end displacement on it.
- View thumbnailView = mTaskBeingDragged.getFirstThumbnailViewDeprecated();
+ View thumbnailView = mTaskBeingDragged.getFirstSnapshotView();
mTempCords[1] = orientationHandler.getSecondaryDimension(thumbnailView);
dl.getDescendantCoordRelativeToSelf(thumbnailView, mTempCords);
mEndDisplacement = secondaryLayerDimension - mTempCords[1];
diff --git a/quickstep/src/com/android/quickstep/RecentTasksList.java b/quickstep/src/com/android/quickstep/RecentTasksList.java
index 66091d4..3d4167a 100644
--- a/quickstep/src/com/android/quickstep/RecentTasksList.java
+++ b/quickstep/src/com/android/quickstep/RecentTasksList.java
@@ -44,6 +44,7 @@
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
@@ -324,7 +325,9 @@
// leftover TYPE_FREEFORM tasks created when flag was on should be ignored.
if (enableDesktopWindowingMode()) {
GroupTask desktopTask = createDesktopTask(rawTask);
- allTasks.add(desktopTask);
+ if (desktopTask != null) {
+ allTasks.add(desktopTask);
+ }
}
continue;
}
@@ -368,8 +371,13 @@
return allTasks;
}
- private DesktopTask createDesktopTask(GroupedRecentTaskInfo recentTaskInfo) {
+ private @Nullable DesktopTask createDesktopTask(GroupedRecentTaskInfo recentTaskInfo) {
ArrayList<Task> tasks = new ArrayList<>(recentTaskInfo.getTaskInfoList().size());
+ int[] minimizedTaskIds = recentTaskInfo.getMinimizedTaskIds();
+ if (minimizedTaskIds.length == recentTaskInfo.getTaskInfoList().size()) {
+ // All Tasks are minimized -> don't create a DesktopTask
+ return null;
+ }
for (ActivityManager.RecentTaskInfo taskInfo : recentTaskInfo.getTaskInfoList()) {
Task.TaskKey key = new Task.TaskKey(taskInfo);
Task task = Task.from(key, taskInfo, false);
@@ -377,6 +385,8 @@
task.positionInParent = taskInfo.positionInParent;
task.appBounds = taskInfo.configuration.windowConfiguration.getAppBounds();
task.isVisible = taskInfo.isVisible;
+ task.isMinimized =
+ Arrays.stream(minimizedTaskIds).anyMatch(taskId -> taskId == taskInfo.taskId);
tasks.add(task);
}
return new DesktopTask(tasks);
diff --git a/quickstep/src/com/android/quickstep/TaskOverlayFactory.java b/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
index b183ae3..5d0d074 100644
--- a/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
+++ b/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
@@ -44,7 +44,6 @@
import com.android.quickstep.views.OverviewActionsView;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.RecentsViewContainer;
-import com.android.quickstep.views.TaskThumbnailViewDeprecated;
import com.android.quickstep.views.TaskView;
import com.android.quickstep.views.TaskView.TaskContainer;
import com.android.systemui.shared.recents.model.Task;
@@ -134,20 +133,20 @@
mApplicationContext = taskContainer.getTaskView().getContext().getApplicationContext();
mTaskContainer = taskContainer;
mImageApi = new ImageActionsApi(
- mApplicationContext, mTaskContainer.getThumbnailViewDeprecated()::getThumbnail);
+ mApplicationContext, mTaskContainer::getThumbnail);
}
protected T getActionsView() {
if (mActionsView == null) {
mActionsView = BaseActivity.fromContext(
- mTaskContainer.getThumbnailViewDeprecated().getContext()).findViewById(
+ mTaskContainer.getTaskView().getContext()).findViewById(
R.id.overview_actions_view);
}
return mActionsView;
}
- public TaskThumbnailViewDeprecated getThumbnailView() {
- return mTaskContainer.getThumbnailViewDeprecated();
+ public TaskView getTaskView() {
+ return mTaskContainer.getTaskView();
}
/**
@@ -159,8 +158,7 @@
if (thumbnail != null) {
getActionsView().updateDisabledFlags(DISABLED_ROTATED, rotated);
- boolean isAllowedByPolicy =
- mTaskContainer.getThumbnailViewDeprecated().isRealSnapshot();
+ boolean isAllowedByPolicy = mTaskContainer.isRealSnapshot();
getActionsView().setCallbacks(new OverlayUICallbacksImpl(isAllowedByPolicy, task));
}
}
@@ -172,7 +170,7 @@
*/
public void endLiveTileMode(@NonNull Runnable callback) {
RecentsView recentsView =
- mTaskContainer.getThumbnailViewDeprecated().getTaskView().getRecentsView();
+ mTaskContainer.getTaskView().getRecentsView();
// Task has already been dismissed
if (recentsView == null) return;
recentsView.switchToScreenshot(
@@ -185,8 +183,8 @@
*/
@SuppressLint("NewApi")
protected void saveScreenshot(Task task) {
- if (mTaskContainer.getThumbnailViewDeprecated().isRealSnapshot()) {
- mImageApi.saveScreenshot(mTaskContainer.getThumbnailViewDeprecated().getThumbnail(),
+ if (mTaskContainer.isRealSnapshot()) {
+ mImageApi.saveScreenshot(mTaskContainer.getThumbnail(),
getTaskSnapshotBounds(), getTaskSnapshotInsets(), task.key);
} else {
showBlockedByPolicyMessage();
@@ -194,17 +192,14 @@
}
protected void enterSplitSelect() {
- RecentsView overviewPanel =
- mTaskContainer.getThumbnailViewDeprecated().getTaskView().getRecentsView();
+ RecentsView overviewPanel = mTaskContainer.getTaskView().getRecentsView();
// Task has already been dismissed
if (overviewPanel == null) return;
- overviewPanel.initiateSplitSelect(
- mTaskContainer.getThumbnailViewDeprecated().getTaskView());
+ overviewPanel.initiateSplitSelect(mTaskContainer.getTaskView());
}
protected void saveAppPair() {
- GroupedTaskView taskView =
- (GroupedTaskView) mTaskContainer.getThumbnailViewDeprecated().getTaskView();
+ GroupedTaskView taskView = (GroupedTaskView) mTaskContainer.getTaskView();
taskView.getRecentsView().getSplitSelectController().getAppPairsController()
.saveAppPair(taskView);
}
@@ -250,11 +245,11 @@
*/
public Rect getTaskSnapshotBounds() {
int[] location = new int[2];
- mTaskContainer.getThumbnailViewDeprecated().getLocationOnScreen(location);
+ mTaskContainer.getSnapshotView().getLocationOnScreen(location);
return new Rect(location[0], location[1],
- mTaskContainer.getThumbnailViewDeprecated().getWidth() + location[0],
- mTaskContainer.getThumbnailViewDeprecated().getHeight() + location[1]);
+ mTaskContainer.getSnapshotView().getWidth() + location[0],
+ mTaskContainer.getSnapshotView().getHeight() + location[1]);
}
/**
@@ -264,7 +259,7 @@
*/
@RequiresApi(api = Build.VERSION_CODES.Q)
public Insets getTaskSnapshotInsets() {
- return mTaskContainer.getThumbnailViewDeprecated().getScaledInsets();
+ return mTaskContainer.getScaledInsets();
}
/**
@@ -275,14 +270,14 @@
protected void showBlockedByPolicyMessage() {
ActivityContext activityContext = ActivityContext.lookupContext(
- mTaskContainer.getThumbnailViewDeprecated().getContext());
+ mTaskContainer.getTaskView().getContext());
String message = activityContext.getStringCache() != null
? activityContext.getStringCache().disabledByAdminMessage
- : mTaskContainer.getThumbnailViewDeprecated().getContext().getString(
+ : mTaskContainer.getTaskView().getContext().getString(
R.string.blocked_by_policy);
Snackbar.show(BaseActivity.fromContext(
- mTaskContainer.getThumbnailViewDeprecated().getContext()), message, null);
+ mTaskContainer.getTaskView().getContext()), message, null);
}
/** Called when the snapshot has updated its full screen drawing parameters. */
@@ -304,8 +299,7 @@
@Override
public void onClick(View view) {
- saveScreenshot(
- mTaskContainer.getThumbnailViewDeprecated().getTaskView().getFirstTask());
+ saveScreenshot(mTaskContainer.getTaskView().getFirstTask());
dismissTaskMenuView();
}
}
diff --git a/quickstep/src/com/android/quickstep/TaskShortcutFactory.java b/quickstep/src/com/android/quickstep/TaskShortcutFactory.java
index 4691ea9..b4862fd 100644
--- a/quickstep/src/com/android/quickstep/TaskShortcutFactory.java
+++ b/quickstep/src/com/android/quickstep/TaskShortcutFactory.java
@@ -20,6 +20,7 @@
import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
import static android.view.Surface.ROTATION_0;
+import static com.android.launcher3.Flags.enableRefactorTaskThumbnail;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SYSTEM_SHORTCUT_FREE_FORM_TAP;
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT;
import static com.android.window.flags.Flags.enableDesktopWindowingMode;
@@ -55,7 +56,6 @@
import com.android.quickstep.views.GroupedTaskView;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.RecentsViewContainer;
-import com.android.quickstep.views.TaskThumbnailViewDeprecated;
import com.android.quickstep.views.TaskView;
import com.android.quickstep.views.TaskView.TaskContainer;
import com.android.systemui.shared.recents.model.Task;
@@ -174,7 +174,7 @@
private Handler mHandler;
private final RecentsView mRecentsView;
- private final TaskThumbnailViewDeprecated mThumbnailView;
+ private final TaskContainer mTaskContainer;
private final TaskView mTaskView;
private final LauncherEvent mLauncherEvent;
@@ -186,7 +186,7 @@
mHandler = new Handler(Looper.getMainLooper());
mTaskView = taskContainer.getTaskView();
mRecentsView = container.getOverviewPanel();
- mThumbnailView = taskContainer.getThumbnailViewDeprecated();
+ mTaskContainer = taskContainer;
}
@Override
@@ -220,20 +220,25 @@
};
final int[] position = new int[2];
- mThumbnailView.getLocationOnScreen(position);
- final int width = (int) (mThumbnailView.getWidth() * mTaskView.getScaleX());
- final int height = (int) (mThumbnailView.getHeight() * mTaskView.getScaleY());
+ View snapShotView = mTaskContainer.getSnapshotView();
+ snapShotView.getLocationOnScreen(position);
+ final int width = (int) (snapShotView.getWidth() * mTaskView.getScaleX());
+ final int height = (int) (snapShotView.getHeight() * mTaskView.getScaleY());
final Rect taskBounds = new Rect(position[0], position[1],
position[0] + width, position[1] + height);
// Take the thumbnail of the task without a scrim and apply it back after
- float alpha = mThumbnailView.getDimAlpha();
// TODO(b/348643341) add ability to get override the scrim for this Bitmap retrieval
- mThumbnailView.setDimAlpha(0);
+ float alpha = 0f;
+ if (!enableRefactorTaskThumbnail()) {
+ alpha = mTaskContainer.getThumbnailViewDeprecated().getDimAlpha();
+ mTaskContainer.getThumbnailViewDeprecated().setDimAlpha(0);
+ }
Bitmap thumbnail = RecentsTransition.drawViewIntoHardwareBitmap(
- taskBounds.width(), taskBounds.height(), mThumbnailView, 1f,
- Color.BLACK);
- mThumbnailView.setDimAlpha(alpha);
+ taskBounds.width(), taskBounds.height(), snapShotView, 1f, Color.BLACK);
+ if (!enableRefactorTaskThumbnail()) {
+ mTaskContainer.getThumbnailViewDeprecated().setDimAlpha(alpha);
+ }
AppTransitionAnimationSpecsFuture future =
new AppTransitionAnimationSpecsFuture(mHandler) {
diff --git a/quickstep/src/com/android/quickstep/TaskViewUtils.java b/quickstep/src/com/android/quickstep/TaskViewUtils.java
index ecd84f8..bd44283 100644
--- a/quickstep/src/com/android/quickstep/TaskViewUtils.java
+++ b/quickstep/src/com/android/quickstep/TaskViewUtils.java
@@ -80,7 +80,6 @@
import com.android.quickstep.views.DesktopTaskView;
import com.android.quickstep.views.GroupedTaskView;
import com.android.quickstep.views.RecentsView;
-import com.android.quickstep.views.TaskThumbnailViewDeprecated;
import com.android.quickstep.views.TaskView;
import com.android.systemui.animation.RemoteAnimationTargetCompat;
import com.android.systemui.shared.recents.model.Task;
@@ -334,7 +333,7 @@
// During animation we apply transformation on the thumbnailView (and not the rootView)
// to follow the TaskViewSimulator. So the final matrix applied on the thumbnailView is:
// Mt K(0)` K(t) Mt`
- TaskThumbnailViewDeprecated[] thumbnails = v.getThumbnailViews();
+ View[] thumbnails = v.getSnapshotViews();
// In case simulator copies and thumbnail size do no match, ensure we get the lesser.
// This ensures we do not create arrays with empty elements or attempt to references
@@ -344,7 +343,7 @@
Matrix[] mt = new Matrix[matrixSize];
Matrix[] mti = new Matrix[matrixSize];
for (int i = 0; i < matrixSize; i++) {
- TaskThumbnailViewDeprecated ttv = thumbnails[i];
+ View ttv = thumbnails[i];
RectF localBounds = new RectF(0, 0, ttv.getWidth(), ttv.getHeight());
float[] tvBoundsMapped = new float[]{0, 0, ttv.getWidth(), ttv.getHeight()};
getDescendantCoordRelativeToAncestor(ttv, ttv.getRootView(), tvBoundsMapped, false);
@@ -391,7 +390,7 @@
out.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
- for (TaskThumbnailViewDeprecated ttv : thumbnails) {
+ for (View ttv : thumbnails) {
ttv.setAnimationMatrix(null);
}
}
diff --git a/quickstep/src/com/android/quickstep/util/SplitAnimationController.kt b/quickstep/src/com/android/quickstep/util/SplitAnimationController.kt
index 7ea04b1..876a4ea 100644
--- a/quickstep/src/com/android/quickstep/util/SplitAnimationController.kt
+++ b/quickstep/src/com/android/quickstep/util/SplitAnimationController.kt
@@ -43,6 +43,7 @@
import com.android.app.animation.Interpolators
import com.android.launcher3.DeviceProfile
import com.android.launcher3.Flags.enableOverviewIconMenu
+import com.android.launcher3.Flags.enableRefactorTaskThumbnail
import com.android.launcher3.InsettableFrameLayout
import com.android.launcher3.QuickstepTransitionManager
import com.android.launcher3.R
@@ -118,8 +119,8 @@
if (container.task.getKey().getId() == splitSelectStateController.initialTaskId) {
val drawable = getDrawable(container.iconView, splitSelectSource)
return SplitAnimInitProps(
- container.thumbnailViewDeprecated,
- container.thumbnailViewDeprecated.thumbnail,
+ container.snapshotView,
+ container.thumbnail,
drawable!!,
fadeWithThumbnail = true,
isStagedTask = true,
@@ -137,8 +138,8 @@
taskView.taskContainers.first().let {
val drawable = getDrawable(it.iconView, splitSelectSource)
return SplitAnimInitProps(
- it.thumbnailViewDeprecated,
- it.thumbnailViewDeprecated.thumbnail,
+ it.snapshotView,
+ it.thumbnail,
drawable!!,
fadeWithThumbnail = true,
isStagedTask = true,
@@ -165,27 +166,37 @@
/**
* When selecting first app from split pair, second app's thumbnail remains. This animates the
* second thumbnail by expanding it to take up the full taskViewWidth/Height and overlaying it
- * with [TaskThumbnailViewDeprecated]'s splashView. Adds animations to the provided builder.
- * Note: The app that **was not** selected as the first split app should be the container that's
- * passed through.
+ * with [TaskContainer]'s splashView. Adds animations to the provided builder. Note: The app
+ * that **was not** selected as the first split app should be the container that's passed
+ * through.
*
* @param builder Adds animation to this
- * @param taskIdAttributeContainer container of the app that **was not** selected
+ * @param taskContainer container of the app that **was not** selected
* @param isPrimaryTaskSplitting if true, task that was split would be top/left in the pair
- * (opposite of that representing [taskIdAttributeContainer])
+ * (opposite of that representing [taskContainer])
*/
fun addInitialSplitFromPair(
- taskIdAttributeContainer: TaskContainer,
+ taskContainer: TaskContainer,
builder: PendingAnimation,
deviceProfile: DeviceProfile,
taskViewWidth: Int,
taskViewHeight: Int,
isPrimaryTaskSplitting: Boolean
) {
- val thumbnail = taskIdAttributeContainer.thumbnailViewDeprecated
- val iconView: View = taskIdAttributeContainer.iconView.asView()
- builder.add(ObjectAnimator.ofFloat(thumbnail, TaskThumbnailViewDeprecated.SPLASH_ALPHA, 1f))
- thumbnail.setShowSplashForSplitSelection(true)
+ val snapshot = taskContainer.snapshotView
+ val iconView: View = taskContainer.iconView.asView()
+ // TODO(334826842): Switch to splash state in TaskThumbnailView
+ if (!enableRefactorTaskThumbnail()) {
+ val thumbnailViewDeprecated = taskContainer.thumbnailViewDeprecated
+ builder.add(
+ ObjectAnimator.ofFloat(
+ thumbnailViewDeprecated,
+ TaskThumbnailViewDeprecated.SPLASH_ALPHA,
+ 1f
+ )
+ )
+ thumbnailViewDeprecated.setShowSplashForSplitSelection(true)
+ }
// With the new `IconAppChipView`, we always want to keep the chip pinned to the
// top left of the task / thumbnail.
if (enableOverviewIconMenu()) {
@@ -202,14 +213,10 @@
}
if (deviceProfile.isLeftRightSplit) {
// Center view first so scaling happens uniformly, alternatively we can move pivotX to 0
- val centerThumbnailTranslationX: Float = (taskViewWidth - thumbnail.width) / 2f
- val finalScaleX: Float = taskViewWidth.toFloat() / thumbnail.width
+ val centerThumbnailTranslationX: Float = (taskViewWidth - snapshot.width) / 2f
+ val finalScaleX: Float = taskViewWidth.toFloat() / snapshot.width
builder.add(
- ObjectAnimator.ofFloat(
- thumbnail,
- TaskThumbnailViewDeprecated.SPLIT_SELECT_TRANSLATE_X,
- centerThumbnailTranslationX
- )
+ ObjectAnimator.ofFloat(snapshot, View.TRANSLATION_X, centerThumbnailTranslationX)
)
if (!enableOverviewIconMenu()) {
// icons are anchored from Gravity.END, so need to use negative translation
@@ -218,21 +225,15 @@
ObjectAnimator.ofFloat(iconView, View.TRANSLATION_X, -centerIconTranslationX)
)
}
- builder.add(ObjectAnimator.ofFloat(thumbnail, View.SCALE_X, finalScaleX))
+ builder.add(ObjectAnimator.ofFloat(snapshot, View.SCALE_X, finalScaleX))
// Reset other dimensions
// TODO(b/271468547), can't set Y translate to 0, need to account for top space
- thumbnail.scaleY = 1f
+ snapshot.scaleY = 1f
val translateYResetVal: Float =
if (!isPrimaryTaskSplitting) 0f
else deviceProfile.overviewTaskThumbnailTopMarginPx.toFloat()
- builder.add(
- ObjectAnimator.ofFloat(
- thumbnail,
- TaskThumbnailViewDeprecated.SPLIT_SELECT_TRANSLATE_Y,
- translateYResetVal
- )
- )
+ builder.add(ObjectAnimator.ofFloat(snapshot, View.TRANSLATION_Y, translateYResetVal))
} else {
val thumbnailSize = taskViewHeight - deviceProfile.overviewTaskThumbnailTopMarginPx
// Center view first so scaling happens uniformly, alternatively we can move pivotY to 0
@@ -247,36 +248,26 @@
// thumbnail needs to take that into account. We should migrate to only using
// translations otherwise this asymmetry causes problems..
if (isPrimaryTaskSplitting) {
- centerThumbnailTranslationY = (thumbnailSize - thumbnail.height) / 2f
+ centerThumbnailTranslationY = (thumbnailSize - snapshot.height) / 2f
centerThumbnailTranslationY +=
deviceProfile.overviewTaskThumbnailTopMarginPx.toFloat()
} else {
- centerThumbnailTranslationY = (thumbnailSize - thumbnail.height) / 2f
+ centerThumbnailTranslationY = (thumbnailSize - snapshot.height) / 2f
}
- val finalScaleY: Float = thumbnailSize.toFloat() / thumbnail.height
+ val finalScaleY: Float = thumbnailSize.toFloat() / snapshot.height
builder.add(
- ObjectAnimator.ofFloat(
- thumbnail,
- TaskThumbnailViewDeprecated.SPLIT_SELECT_TRANSLATE_Y,
- centerThumbnailTranslationY
- )
+ ObjectAnimator.ofFloat(snapshot, View.TRANSLATION_Y, centerThumbnailTranslationY)
)
if (!enableOverviewIconMenu()) {
// icons are anchored from Gravity.END, so need to use negative translation
builder.add(ObjectAnimator.ofFloat(iconView, View.TRANSLATION_X, 0f))
}
- builder.add(ObjectAnimator.ofFloat(thumbnail, View.SCALE_Y, finalScaleY))
+ builder.add(ObjectAnimator.ofFloat(snapshot, View.SCALE_Y, finalScaleY))
// Reset other dimensions
- thumbnail.scaleX = 1f
- builder.add(
- ObjectAnimator.ofFloat(
- thumbnail,
- TaskThumbnailViewDeprecated.SPLIT_SELECT_TRANSLATE_X,
- 0f
- )
- )
+ snapshot.scaleX = 1f
+ builder.add(ObjectAnimator.ofFloat(snapshot, View.TRANSLATION_X, 0f))
}
}
diff --git a/quickstep/src/com/android/quickstep/util/SplitScreenUtils.kt b/quickstep/src/com/android/quickstep/util/SplitScreenUtils.kt
index 38bbe60..4820c35 100644
--- a/quickstep/src/com/android/quickstep/util/SplitScreenUtils.kt
+++ b/quickstep/src/com/android/quickstep/util/SplitScreenUtils.kt
@@ -31,29 +31,13 @@
null
} else {
SplitConfigurationOptions.SplitBounds(
- shellSplitBounds.leftTopBounds, shellSplitBounds.rightBottomBounds,
- shellSplitBounds.leftTopTaskId, shellSplitBounds.rightBottomTaskId,
+ shellSplitBounds.leftTopBounds,
+ shellSplitBounds.rightBottomBounds,
+ shellSplitBounds.leftTopTaskId,
+ shellSplitBounds.rightBottomTaskId,
shellSplitBounds.snapPosition
)
}
}
-
- /** Converts the launcher version of SplitBounds to the shell version */
- @JvmStatic
- fun convertLauncherSplitBoundsToShell(
- launcherSplitBounds: SplitConfigurationOptions.SplitBounds?
- ): SplitBounds? {
- return if (launcherSplitBounds == null) {
- null
- } else {
- SplitBounds(
- launcherSplitBounds.leftTopBounds,
- launcherSplitBounds.rightBottomBounds,
- launcherSplitBounds.leftTopTaskId,
- launcherSplitBounds.rightBottomTaskId,
- launcherSplitBounds.snapPosition
- )
- }
- }
}
}
diff --git a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
index 49f4e5f..d9b7d20 100644
--- a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
+++ b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
@@ -27,7 +27,6 @@
import static com.android.quickstep.TaskAnimationManager.ENABLE_SHELL_TRANSITIONS;
import static com.android.quickstep.util.RecentsOrientedState.postDisplayRotation;
import static com.android.quickstep.util.RecentsOrientedState.preDisplayRotation;
-import static com.android.quickstep.util.SplitScreenUtils.convertLauncherSplitBoundsToShell;
import android.animation.TimeInterpolator;
import android.content.Context;
@@ -247,8 +246,6 @@
} else {
mStagePosition = runningTarget.taskId == splitInfo.leftTopTaskId
? STAGE_POSITION_TOP_OR_LEFT : STAGE_POSITION_BOTTOM_OR_RIGHT;
- mPositionHelper.setSplitBounds(convertLauncherSplitBoundsToShell(mSplitBounds),
- mStagePosition);
}
calculateTaskSize();
}
diff --git a/quickstep/src/com/android/quickstep/views/DesktopTaskView.kt b/quickstep/src/com/android/quickstep/views/DesktopTaskView.kt
index 4c78e21..46ed2ee 100644
--- a/quickstep/src/com/android/quickstep/views/DesktopTaskView.kt
+++ b/quickstep/src/com/android/quickstep/views/DesktopTaskView.kt
@@ -128,7 +128,7 @@
}
val thumbWidth = (taskSize.width() * scaleWidth).toInt()
val thumbHeight = (taskSize.height() * scaleHeight).toInt()
- it.thumbnailViewDeprecated.measure(
+ it.snapshotView.measure(
MeasureSpec.makeMeasureSpec(thumbWidth, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(thumbHeight, MeasureSpec.EXACTLY)
)
@@ -139,8 +139,8 @@
var taskY = (positionInParent.y * scaleHeight).toInt()
// move task down by margin size
taskY += thumbnailTopMarginPx
- it.thumbnailViewDeprecated.x = taskX.toFloat()
- it.thumbnailViewDeprecated.y = taskY.toFloat()
+ it.snapshotView.x = taskX.toFloat()
+ it.snapshotView.y = taskY.toFloat()
if (DEBUG) {
Log.d(
TAG,
diff --git a/quickstep/src/com/android/quickstep/views/DigitalWellBeingToast.java b/quickstep/src/com/android/quickstep/views/DigitalWellBeingToast.java
index 4a5b9e4..9f268a0 100644
--- a/quickstep/src/com/android/quickstep/views/DigitalWellBeingToast.java
+++ b/quickstep/src/com/android/quickstep/views/DigitalWellBeingToast.java
@@ -332,12 +332,12 @@
(FrameLayout.LayoutParams) mBanner.getLayoutParams();
DeviceProfile deviceProfile = mContainer.getDeviceProfile();
layoutParams.bottomMargin = ((ViewGroup.MarginLayoutParams)
- mTaskView.getFirstThumbnailViewDeprecated().getLayoutParams()).bottomMargin;
+ mTaskView.getFirstSnapshotView().getLayoutParams()).bottomMargin;
RecentsPagedOrientationHandler orientationHandler = mTaskView.getPagedOrientationHandler();
Pair<Float, Float> translations = orientationHandler
.getDwbLayoutTranslations(mTaskView.getMeasuredWidth(),
mTaskView.getMeasuredHeight(), mSplitBounds, deviceProfile,
- mTaskView.getThumbnailViews(), mTask.key.id, mBanner);
+ mTaskView.getSnapshotViews(), mTask.key.id, mBanner);
mSplitOffsetTranslationX = translations.first;
mSplitOffsetTranslationY = translations.second;
updateTranslationY();
diff --git a/quickstep/src/com/android/quickstep/views/GroupedTaskView.kt b/quickstep/src/com/android/quickstep/views/GroupedTaskView.kt
index 6296b0e..b070244 100644
--- a/quickstep/src/com/android/quickstep/views/GroupedTaskView.kt
+++ b/quickstep/src/com/android/quickstep/views/GroupedTaskView.kt
@@ -33,10 +33,8 @@
import com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_UNDEFINED
import com.android.quickstep.TaskOverlayFactory
import com.android.quickstep.util.RecentsOrientedState
-import com.android.quickstep.util.SplitScreenUtils.Companion.convertLauncherSplitBoundsToShell
import com.android.quickstep.util.SplitSelectStateController
import com.android.systemui.shared.recents.model.Task
-import com.android.systemui.shared.recents.utilities.PreviewPositionHelper
import com.android.systemui.shared.system.InteractionJankMonitorWrapper
import com.android.wm.shell.common.split.SplitScreenConstants.PersistentSnapPosition
@@ -70,36 +68,20 @@
val initSplitTaskId = getThisTaskCurrentlyInSplitSelection()
if (initSplitTaskId == INVALID_TASK_ID) {
pagedOrientationHandler.measureGroupedTaskViewThumbnailBounds(
- taskContainers[0].thumbnailViewDeprecated,
- taskContainers[1].thumbnailViewDeprecated,
+ taskContainers[0].snapshotView,
+ taskContainers[1].snapshotView,
widthSize,
heightSize,
splitBoundsConfig,
container.deviceProfile,
layoutDirection == LAYOUT_DIRECTION_RTL
)
- // Should we be having a separate translation step apart from the measuring above?
- // The following only applies to large screen for now, but for future reference
- // we'd want to abstract this out in PagedViewHandlers to get the primary/secondary
- // translation directions
- taskContainers[0]
- .thumbnailViewDeprecated
- .applySplitSelectTranslateX(taskContainers[0].thumbnailViewDeprecated.translationX)
- taskContainers[0]
- .thumbnailViewDeprecated
- .applySplitSelectTranslateY(taskContainers[0].thumbnailViewDeprecated.translationY)
- taskContainers[1]
- .thumbnailViewDeprecated
- .applySplitSelectTranslateX(taskContainers[1].thumbnailViewDeprecated.translationX)
- taskContainers[1]
- .thumbnailViewDeprecated
- .applySplitSelectTranslateY(taskContainers[1].thumbnailViewDeprecated.translationY)
} else {
// Currently being split with this taskView, let the non-split selected thumbnail
// take up full thumbnail area
taskContainers
.firstOrNull { it.task.key.id != initSplitTaskId }
- ?.thumbnailViewDeprecated
+ ?.snapshotView
?.measure(
widthMeasureSpec,
MeasureSpec.makeMeasureSpec(
@@ -147,23 +129,7 @@
)
taskContainers.forEach { it.bind() }
- this.splitBoundsConfig =
- splitBoundsConfig?.also {
- taskContainers[0]
- .thumbnailViewDeprecated
- .previewPositionHelper
- .setSplitBounds(
- convertLauncherSplitBoundsToShell(it),
- PreviewPositionHelper.STAGE_POSITION_TOP_OR_LEFT
- )
- taskContainers[1]
- .thumbnailViewDeprecated
- .previewPositionHelper
- .setSplitBounds(
- convertLauncherSplitBoundsToShell(it),
- PreviewPositionHelper.STAGE_POSITION_BOTTOM_OR_RIGHT
- )
- }
+ this.splitBoundsConfig = splitBoundsConfig
taskContainers.forEach { it.digitalWellBeingToast?.setSplitBounds(splitBoundsConfig) }
setOrientationState(orientedState)
}
@@ -230,8 +196,8 @@
taskContainers[0].iconView.asView(),
taskContainers[1].iconView.asView(),
taskIconHeight,
- taskContainers[0].thumbnailViewDeprecated.measuredWidth,
- taskContainers[0].thumbnailViewDeprecated.measuredHeight,
+ taskContainers[0].snapshotView.measuredWidth,
+ taskContainers[0].snapshotView.measuredHeight,
measuredHeight,
measuredWidth,
isRtl,
@@ -326,7 +292,7 @@
// Check which of the two apps was selected
if (
taskContainers[1].iconView.asView().containsPoint(lastTouchDownPosition) ||
- taskContainers[1].thumbnailViewDeprecated.containsPoint(lastTouchDownPosition)
+ taskContainers[1].snapshotView.containsPoint(lastTouchDownPosition)
) {
return 1
}
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index d806e3d..c1e112a 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -1826,8 +1826,13 @@
((GroupedTaskView) taskView).bind(leftTopTask, rightBottomTask, mOrientationState,
mTaskOverlayFactory, groupTask.mSplitBounds);
} else if (taskView instanceof DesktopTaskView) {
- ((DesktopTaskView) taskView).bind(((DesktopTask) groupTask).tasks,
- mOrientationState, mTaskOverlayFactory);
+ // Minimized tasks should not be shown in Overview
+ List<Task> nonMinimizedTasks =
+ ((DesktopTask) groupTask).tasks.stream()
+ .filter(task -> !task.isMinimized)
+ .toList();
+ ((DesktopTaskView) taskView).bind(nonMinimizedTasks, mOrientationState,
+ mTaskOverlayFactory);
mDesktopTaskView = (DesktopTaskView) taskView;
} else {
Task task = groupTask.task1.key.id == stagedTaskIdToBeRemoved ? groupTask.task2
diff --git a/quickstep/src/com/android/quickstep/views/TaskMenuView.java b/quickstep/src/com/android/quickstep/views/TaskMenuView.java
index 4f446b2..8d5ba77 100644
--- a/quickstep/src/com/android/quickstep/views/TaskMenuView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskMenuView.java
@@ -238,12 +238,12 @@
mContainer.getDragLayer().getDescendantRectRelativeToSelf(
enableOverviewIconMenu()
? getIconView().findViewById(R.id.icon_view_menu_anchor)
- : taskContainer.getThumbnailViewDeprecated(),
+ : taskContainer.getSnapshotView(),
sTempRect);
Rect insets = mContainer.getDragLayer().getInsets();
BaseDragLayer.LayoutParams params = (BaseDragLayer.LayoutParams) getLayoutParams();
params.width = orientationHandler.getTaskMenuWidth(
- taskContainer.getThumbnailViewDeprecated(), deviceProfile,
+ taskContainer.getSnapshotView(), deviceProfile,
taskContainer.getStagePosition());
// Gravity set to Left instead of Start as sTempRect.left measures Left distance not Start
params.gravity = Gravity.LEFT;
@@ -277,10 +277,10 @@
// Margin that insets the menuView inside the taskView
float taskInsetMargin = getResources().getDimension(R.dimen.task_card_margin);
setTranslationX(orientationHandler.getTaskMenuX(thumbnailAlignedX,
- mTaskContainer.getThumbnailViewDeprecated(), deviceProfile, taskInsetMargin,
+ mTaskContainer.getSnapshotView(), deviceProfile, taskInsetMargin,
getIconView()));
setTranslationY(orientationHandler.getTaskMenuY(
- thumbnailAlignedY, mTaskContainer.getThumbnailViewDeprecated(),
+ thumbnailAlignedY, mTaskContainer.getSnapshotView(),
mTaskContainer.getStagePosition(), this, taskInsetMargin,
getIconView()));
}
@@ -316,7 +316,7 @@
.createRevealAnimator(this, closing, revealAnimationStartProgress);
mRevealAnimator.setInterpolator(enableOverviewIconMenu() ? Interpolators.EMPHASIZED
: Interpolators.DECELERATE);
-
+ AnimatorSet.Builder openCloseAnimatorBuilder = mOpenCloseAnimator.play(mRevealAnimator);
if (enableOverviewIconMenu()) {
IconAppChipView iconAppChip = (IconAppChipView) mTaskContainer.getIconView().asView();
@@ -334,11 +334,13 @@
closing ? mMenuTranslationYBeforeOpen
: mMenuTranslationYBeforeOpen + additionalTranslationY);
translationYAnim.setInterpolator(EMPHASIZED);
+ openCloseAnimatorBuilder.with(translationYAnim);
ObjectAnimator menuTranslationYAnim = ObjectAnimator.ofFloat(
iconAppChip.getMenuTranslationY(),
MULTI_PROPERTY_VALUE, closing ? 0 : additionalTranslationY);
menuTranslationYAnim.setInterpolator(EMPHASIZED);
+ openCloseAnimatorBuilder.with(menuTranslationYAnim);
float additionalTranslationX = 0;
if (mContainer.getDeviceProfile().isLandscape
@@ -354,20 +356,15 @@
closing ? mMenuTranslationXBeforeOpen
: mMenuTranslationXBeforeOpen - additionalTranslationX);
translationXAnim.setInterpolator(EMPHASIZED);
+ openCloseAnimatorBuilder.with(translationXAnim);
ObjectAnimator menuTranslationXAnim = ObjectAnimator.ofFloat(
iconAppChip.getMenuTranslationX(),
MULTI_PROPERTY_VALUE, closing ? 0 : -additionalTranslationX);
menuTranslationXAnim.setInterpolator(EMPHASIZED);
-
- mOpenCloseAnimator.playTogether(translationYAnim, translationXAnim,
- menuTranslationXAnim, menuTranslationYAnim);
+ openCloseAnimatorBuilder.with(menuTranslationXAnim);
}
- mOpenCloseAnimator.playTogether(mRevealAnimator,
- ObjectAnimator.ofFloat(
- mTaskContainer.getThumbnailViewDeprecated(), DIM_ALPHA,
- closing ? 0 : TaskView.MAX_PAGE_SCRIM_ALPHA),
- ObjectAnimator.ofFloat(this, ALPHA, closing ? 0 : 1));
+ openCloseAnimatorBuilder.with(ObjectAnimator.ofFloat(this, ALPHA, closing ? 0 : 1));
if (enableRefactorTaskThumbnail()) {
mRevealAnimator.addUpdateListener(animation -> {
float animatedFraction = animation.getAnimatedFraction();
@@ -375,6 +372,10 @@
mTaskContainer.getTaskContainerData()
.getTaskMenuOpenProgress().setValue(openProgress);
});
+ } else {
+ openCloseAnimatorBuilder.with(ObjectAnimator.ofFloat(
+ mTaskContainer.getThumbnailViewDeprecated(), DIM_ALPHA,
+ closing ? 0 : TaskView.MAX_PAGE_SCRIM_ALPHA));
}
mOpenCloseAnimator.addListener(new AnimationSuccessListener() {
@Override
diff --git a/quickstep/src/com/android/quickstep/views/TaskThumbnailViewDeprecated.java b/quickstep/src/com/android/quickstep/views/TaskThumbnailViewDeprecated.java
index 4283d0e..2afb6a6 100644
--- a/quickstep/src/com/android/quickstep/views/TaskThumbnailViewDeprecated.java
+++ b/quickstep/src/com/android/quickstep/views/TaskThumbnailViewDeprecated.java
@@ -99,36 +99,6 @@
}
};
- /** Use to animate thumbnail translationX while first app in split selection is initiated */
- public static final Property<TaskThumbnailViewDeprecated, Float> SPLIT_SELECT_TRANSLATE_X =
- new FloatProperty<TaskThumbnailViewDeprecated>("splitSelectTranslateX") {
- @Override
- public void setValue(TaskThumbnailViewDeprecated thumbnail,
- float splitSelectTranslateX) {
- thumbnail.applySplitSelectTranslateX(splitSelectTranslateX);
- }
-
- @Override
- public Float get(TaskThumbnailViewDeprecated thumbnailView) {
- return thumbnailView.mSplitSelectTranslateX;
- }
- };
-
- /** Use to animate thumbnail translationY while first app in split selection is initiated */
- public static final Property<TaskThumbnailViewDeprecated, Float> SPLIT_SELECT_TRANSLATE_Y =
- new FloatProperty<TaskThumbnailViewDeprecated>("splitSelectTranslateY") {
- @Override
- public void setValue(TaskThumbnailViewDeprecated thumbnail,
- float splitSelectTranslateY) {
- thumbnail.applySplitSelectTranslateY(splitSelectTranslateY);
- }
-
- @Override
- public Float get(TaskThumbnailViewDeprecated thumbnailView) {
- return thumbnailView.mSplitSelectTranslateY;
- }
- };
-
private final RecentsViewContainer mContainer;
private TaskOverlay<?> mOverlay;
private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
@@ -160,8 +130,6 @@
private boolean mOverlayEnabled;
/** Used as a placeholder when the original thumbnail animates out to. */
private boolean mShowSplashForSplitSelection;
- private float mSplitSelectTranslateX;
- private float mSplitSelectTranslateY;
public TaskThumbnailViewDeprecated(Context context) {
this(context, null);
@@ -415,31 +383,6 @@
}
}
- /** See {@link #SPLIT_SELECT_TRANSLATE_X} */
- protected void applySplitSelectTranslateX(float splitSelectTranslateX) {
- mSplitSelectTranslateX = splitSelectTranslateX;
- applyTranslateX();
- }
-
- /** See {@link #SPLIT_SELECT_TRANSLATE_Y} */
- protected void applySplitSelectTranslateY(float splitSelectTranslateY) {
- mSplitSelectTranslateY = splitSelectTranslateY;
- applyTranslateY();
- }
-
- private void applyTranslateX() {
- setTranslationX(mSplitSelectTranslateX);
- }
-
- private void applyTranslateY() {
- setTranslationY(mSplitSelectTranslateY);
- }
-
- protected void resetViewTransforms() {
- mSplitSelectTranslateX = 0;
- mSplitSelectTranslateY = 0;
- }
-
public TaskView getTaskView() {
return (TaskView) getParent();
}
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.kt b/quickstep/src/com/android/quickstep/views/TaskView.kt
index 7a3b00f..d4b0040 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.kt
+++ b/quickstep/src/com/android/quickstep/views/TaskView.kt
@@ -23,7 +23,9 @@
import android.app.ActivityOptions
import android.content.Context
import android.content.Intent
+import android.graphics.Bitmap
import android.graphics.Canvas
+import android.graphics.Insets
import android.graphics.PointF
import android.graphics.Rect
import android.graphics.drawable.Drawable
@@ -138,8 +140,8 @@
/** Returns a copy of integer array containing taskIds of all tasks in the TaskView. */
get() = taskContainers.map { it.task.key.id }.toIntArray()
- val thumbnailViews: Array<TaskThumbnailViewDeprecated>
- get() = taskContainers.map { it.thumbnailViewDeprecated }.toTypedArray()
+ val snapshotViews: Array<View>
+ get() = taskContainers.map { it.snapshotView }.toTypedArray()
val isGridTask: Boolean
/** Returns whether the task is part of overview grid and not being focused. */
@@ -171,6 +173,11 @@
get() = taskContainers[0].thumbnailViewDeprecated
@get:Deprecated("Use [taskContainers] instead.")
+ val firstSnapshotView: View
+ /** Returns the first snapshotView of the TaskView. */
+ get() = taskContainers[0].snapshotView
+
+ @get:Deprecated("Use [taskContainers] instead.")
val firstItemInfo: ItemInfo
get() = taskContainers[0].itemInfo
@@ -1197,10 +1204,10 @@
this,
container.task,
container.iconView.drawable,
- container.thumbnailViewDeprecated,
- container.thumbnailViewDeprecated.thumbnail, /* intent */
- null, /* user */
- null,
+ container.snapshotView,
+ container.thumbnail,
+ /* intent */ null,
+ /* user */ null,
container.itemInfo
)
}
@@ -1512,6 +1519,10 @@
gridTranslationY = 0f
boxTranslationY = 0f
nonGridPivotTranslationX = 0f
+ taskContainers.forEach {
+ it.snapshotView.translationX = 0f
+ it.snapshotView.translationY = 0f
+ }
resetViewTransforms()
}
@@ -1537,10 +1548,6 @@
alpha = stableAlpha
setIconScaleAndDim(1f)
setColorTint(0f, 0)
- if (!enableRefactorTaskThumbnail()) {
- // TODO(b/335399428) add split select functionality to new TTV
- taskContainers.forEach { it.thumbnailViewDeprecated.resetViewTransforms() }
- }
}
private fun getGridTrans(endTranslation: Float) =
@@ -1624,6 +1631,18 @@
val snapshotView: View
get() = thumbnailView ?: thumbnailViewDeprecated
+ // TODO(b/349120849): Extract ThumbnailData from TaskContainerData/TaskThumbnailViewModel
+ val thumbnail: Bitmap?
+ get() = thumbnailViewDeprecated.thumbnail
+
+ // TODO(b/349120849): Extract ThumbnailData from TaskContainerData/TaskThumbnailViewModel
+ val isRealSnapshot: Boolean
+ get() = thumbnailViewDeprecated.isRealSnapshot()
+
+ // TODO(b/349120849): Extract ThumbnailData from TaskContainerData/TaskThumbnailViewModel
+ val scaledInsets: Insets
+ get() = thumbnailViewDeprecated.scaledInsets
+
/** Builds proto for logging */
val itemInfo: WorkspaceItemInfo
get() =
diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/util/SplitAnimationControllerTest.kt b/quickstep/tests/multivalentTests/src/com/android/quickstep/util/SplitAnimationControllerTest.kt
index d40f8ab..c8893ad 100644
--- a/quickstep/tests/multivalentTests/src/com/android/quickstep/util/SplitAnimationControllerTest.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/util/SplitAnimationControllerTest.kt
@@ -33,7 +33,6 @@
import com.android.launcher3.util.SplitConfigurationOptions
import com.android.quickstep.views.GroupedTaskView
import com.android.quickstep.views.IconView
-import com.android.quickstep.views.TaskThumbnailViewDeprecated
import com.android.quickstep.views.TaskView
import com.android.quickstep.views.TaskView.TaskContainer
import com.android.systemui.shared.recents.model.Task
@@ -59,7 +58,7 @@
private val mockSplitSelectStateController: SplitSelectStateController = mock()
// TaskView
private val mockTaskView: TaskView = mock()
- private val mockThumbnailView: TaskThumbnailViewDeprecated = mock()
+ private val mockSnapshotView: View = mock()
private val mockBitmap: Bitmap = mock()
private val mockIconView: IconView = mock()
private val mockTaskViewDrawable: Drawable = mock()
@@ -87,8 +86,8 @@
@Before
fun setup() {
- whenever(mockTaskContainer.thumbnailViewDeprecated).thenReturn(mockThumbnailView)
- whenever(mockThumbnailView.thumbnail).thenReturn(mockBitmap)
+ whenever(mockTaskContainer.snapshotView).thenReturn(mockSnapshotView)
+ whenever(mockTaskContainer.thumbnail).thenReturn(mockBitmap)
whenever(mockTaskContainer.iconView).thenReturn(mockIconView)
whenever(mockIconView.drawable).thenReturn(mockTaskViewDrawable)
whenever(mockTaskView.taskContainers).thenReturn(List(1) { mockTaskContainer })
@@ -180,7 +179,6 @@
whenever(mockTaskContainer.task).thenReturn(mockTask)
whenever(mockTaskContainer.iconView).thenReturn(mockIconView)
- whenever(mockTaskContainer.thumbnailViewDeprecated).thenReturn(mockThumbnailView)
whenever(mockTask.getKey()).thenReturn(mockTaskKey)
whenever(mockTaskKey.getId()).thenReturn(taskId)
whenever(mockSplitSelectStateController.initialTaskId).thenReturn(taskId)
diff --git a/quickstep/tests/src/com/android/quickstep/RecentTasksListTest.java b/quickstep/tests/src/com/android/quickstep/RecentTasksListTest.java
index 03244eb..ce16b70 100644
--- a/quickstep/tests/src/com/android/quickstep/RecentTasksListTest.java
+++ b/quickstep/tests/src/com/android/quickstep/RecentTasksListTest.java
@@ -32,6 +32,8 @@
import com.android.launcher3.util.LooperExecutor;
import com.android.quickstep.util.GroupTask;
+import com.android.quickstep.views.TaskView;
+import com.android.systemui.shared.recents.model.Task;
import com.android.wm.shell.util.GroupedRecentTaskInfo;
import org.junit.Before;
@@ -40,8 +42,11 @@
import org.mockito.MockitoAnnotations;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
@SmallTest
public class RecentTasksListTest {
@@ -104,4 +109,52 @@
assertEquals(taskDescription, taskList.get(0).task1.taskDescription.getLabel());
assertNull(taskList.get(0).task2.taskDescription.getLabel());
}
+
+ @Test
+ public void loadTasksInBackground_freeformTask_createsDesktopTask() {
+ ActivityManager.RecentTaskInfo[] tasks = {
+ createRecentTaskInfo(1 /* taskId */),
+ createRecentTaskInfo(4 /* taskId */),
+ createRecentTaskInfo(5 /* taskId */)};
+ GroupedRecentTaskInfo recentTaskInfos = GroupedRecentTaskInfo.forFreeformTasks(
+ tasks, Collections.emptySet() /* minimizedTaskIds */);
+ when(mockSystemUiProxy.getRecentTasks(anyInt(), anyInt()))
+ .thenReturn(new ArrayList<>(Collections.singletonList(recentTaskInfos)));
+
+ List<GroupTask> taskList = mRecentTasksList.loadTasksInBackground(
+ Integer.MAX_VALUE /* numTasks */, -1 /* requestId */, false /* loadKeysOnly */);
+
+ assertEquals(1, taskList.size());
+ assertEquals(TaskView.Type.DESKTOP, taskList.get(0).taskViewType);
+ List<Task> actualFreeformTasks = taskList.get(0).getTasks();
+ assertEquals(3, actualFreeformTasks.size());
+ assertEquals(1, actualFreeformTasks.get(0).key.id);
+ assertEquals(4, actualFreeformTasks.get(1).key.id);
+ assertEquals(5, actualFreeformTasks.get(2).key.id);
+ }
+
+ @Test
+ public void loadTasksInBackground_freeformTask_onlyMinimizedTasks_doesNotCreateDesktopTask() {
+ ActivityManager.RecentTaskInfo[] tasks = {
+ createRecentTaskInfo(1 /* taskId */),
+ createRecentTaskInfo(4 /* taskId */),
+ createRecentTaskInfo(5 /* taskId */)};
+ Set<Integer> minimizedTaskIds =
+ Arrays.stream(new Integer[]{1, 4, 5}).collect(Collectors.toSet());
+ GroupedRecentTaskInfo recentTaskInfos =
+ GroupedRecentTaskInfo.forFreeformTasks(tasks, minimizedTaskIds);
+ when(mockSystemUiProxy.getRecentTasks(anyInt(), anyInt()))
+ .thenReturn(new ArrayList<>(Collections.singletonList(recentTaskInfos)));
+
+ List<GroupTask> taskList = mRecentTasksList.loadTasksInBackground(
+ Integer.MAX_VALUE /* numTasks */, -1 /* requestId */, false /* loadKeysOnly */);
+
+ assertEquals(0, taskList.size());
+ }
+
+ private ActivityManager.RecentTaskInfo createRecentTaskInfo(int taskId) {
+ ActivityManager.RecentTaskInfo recentTaskInfo = new ActivityManager.RecentTaskInfo();
+ recentTaskInfo.taskId = taskId;
+ return recentTaskInfo;
+ }
}
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index b39945b..27ce075 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -67,7 +67,7 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"یادداشتبرداری"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"افزودن"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"افزودن ابزارک <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"برای تغییر تنظیمات ابزارک، ضربه بزنید"</string>
+ <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"برای تغییر تنظیمات ابزارک، تکضرب بزنید"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"تغییر تنظیمات ابزارک"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"جستجوی برنامهها"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"درحال بارگیری برنامهها…"</string>
@@ -99,7 +99,7 @@
<string name="permdesc_write_settings" msgid="726859348127868466">"به برنامه اجازه میدهد تنظیمات و میانبرهای صفحه اصلی را تغییر دهد."</string>
<string name="gadget_error_text" msgid="740356548025791839">"ابزارک را نمیتوان بار کرد"</string>
<string name="gadget_setup_text" msgid="8348374825537681407">"تنظیمات ابزارک"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"برای تکمیل راهاندازی ضربه بزنید"</string>
+ <string name="gadget_complete_setup_text" msgid="309040266978007925">"برای تکمیل راهاندازی تکضرب بزنید"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"این برنامه سیستمی است و حذف نصب نمیشود."</string>
<string name="folder_hint_text" msgid="5174843001373488816">"ویرایش نام"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> غیرفعال شد"</string>
@@ -108,8 +108,8 @@
<string name="workspace_scroll_format" msgid="8458889198184077399">"صفحه اصلی %1$d از %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"صفحه اصلی جدید"</string>
<string name="folder_opened" msgid="94695026776264709">"پوشه باز شده، <xliff:g id="WIDTH">%1$d</xliff:g> در <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
- <string name="folder_tap_to_close" msgid="4625795376335528256">"برای بستن پوشه، ضربه بزنید"</string>
- <string name="folder_tap_to_rename" msgid="4017685068016979677">"برای ذخیره تغییر نام، ضربه بزنید"</string>
+ <string name="folder_tap_to_close" msgid="4625795376335528256">"برای بستن پوشه، تکضرب بزنید"</string>
+ <string name="folder_tap_to_rename" msgid="4017685068016979677">"برای ذخیره تغییر نام، تکضرب بزنید"</string>
<string name="folder_closed" msgid="4100806530910930934">"پوشه بسته شد"</string>
<string name="folder_renamed" msgid="1794088362165669656">"نام پوشه به <xliff:g id="NAME">%1$s</xliff:g> تغییر کرد"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"پوشه: <xliff:g id="NAME">%1$s</xliff:g>، <xliff:g id="SIZE">%2$d</xliff:g> مورد"</string>
@@ -139,7 +139,7 @@
<string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> درحال نصب است، <xliff:g id="PROGRESS">%2$s</xliff:g> تکمیل شده است"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"درحال بارگیری <xliff:g id="NAME">%1$s</xliff:g>، <xliff:g id="PROGRESS">%2$s</xliff:g> کامل شد"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> درانتظار نصب"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"<xliff:g id="NAME">%1$s</xliff:g> بایگانی شده است. برای بارگیری و بازیابی ضربه بزنید."</string>
+ <string name="app_archived_title" msgid="7717956158562544081">"<xliff:g id="NAME">%1$s</xliff:g> بایگانی شده است. برای بارگیری و بازیابی تکضرب بزنید."</string>
<string name="dialog_update_title" msgid="114234265740994042">"برنامه باید بهروز شود"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"برنامه برای این نماد بهروز نشده است. میتوانید آن را بهصورت دستی بهروز کنید تا میانبر دوباره فعال شود، یا نماد را بردارید."</string>
<string name="dialog_update" msgid="2178028071796141234">"بهروزرسانی"</string>
@@ -187,7 +187,7 @@
<string name="developer_options_filter_hint" msgid="5896817443635989056">"فیلتر"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"ناموفق بود: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"فضای خصوصی"</string>
- <string name="private_space_secondary_label" msgid="9203933341714508907">"برای راهاندازی یا باز کردن، ضربه بزنید"</string>
+ <string name="private_space_secondary_label" msgid="9203933341714508907">"برای راهاندازی یا باز کردن، تکضرب بزنید"</string>
<string name="ps_container_title" msgid="4391796149519594205">"خصوصی"</string>
<string name="ps_container_settings" msgid="6059734123353320479">"تنظیمات «فضای خصوصی»"</string>
<string name="ps_container_unlock_button_content_description" msgid="9181551784092204234">"خصوصی، باز."</string>
diff --git a/src/com/android/launcher3/widget/BaseWidgetSheet.java b/src/com/android/launcher3/widget/BaseWidgetSheet.java
index 1368084..c59e295 100644
--- a/src/com/android/launcher3/widget/BaseWidgetSheet.java
+++ b/src/com/android/launcher3/widget/BaseWidgetSheet.java
@@ -331,8 +331,21 @@
* status bar, into account.
*/
protected void doMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ int widthUsed = getInsetsWidth();
+
DeviceProfile deviceProfile = mActivityContext.getDeviceProfile();
+ measureChildWithMargins(mContent, widthMeasureSpec,
+ widthUsed, heightMeasureSpec, deviceProfile.bottomSheetTopPadding);
+ setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec),
+ MeasureSpec.getSize(heightMeasureSpec));
+ }
+
+ /**
+ * Returns the width used on left and right by the insets / padding.
+ */
+ protected int getInsetsWidth() {
int widthUsed;
+ DeviceProfile deviceProfile = mActivityContext.getDeviceProfile();
if (deviceProfile.isTablet) {
widthUsed = Math.max(2 * getTabletHorizontalMargin(deviceProfile),
2 * (mInsets.left + mInsets.right));
@@ -343,11 +356,7 @@
widthUsed = Math.max(padding.left + padding.right,
2 * (mInsets.left + mInsets.right));
}
-
- measureChildWithMargins(mContent, widthMeasureSpec,
- widthUsed, heightMeasureSpec, deviceProfile.bottomSheetTopPadding);
- setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec),
- MeasureSpec.getSize(heightMeasureSpec));
+ return widthUsed;
}
/** Returns the horizontal margins to be applied to the widget sheet. **/
diff --git a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
index 9929892..fd15677 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
@@ -55,7 +55,6 @@
import com.android.launcher3.BaseActivity;
import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.LauncherAppState;
import com.android.launcher3.R;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.compat.AccessibilityManagerCompat;
@@ -416,19 +415,18 @@
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ int availableWidth = MeasureSpec.getSize(widthMeasureSpec);
+ updateMaxSpansPerRow(availableWidth);
doMeasure(widthMeasureSpec, heightMeasureSpec);
-
- if (updateMaxSpansPerRow()) {
- doMeasure(widthMeasureSpec, heightMeasureSpec);
- }
}
- /** Returns {@code true} if the max spans have been updated. */
- private boolean updateMaxSpansPerRow() {
- if (getMeasuredWidth() == 0) return false;
-
- @Px int maxHorizontalSpan = getContentView().getMeasuredWidth()
- - (2 * mContentHorizontalMargin);
+ /** Returns {@code true} if the max spans have been updated.
+ *
+ * @param availableWidth Total width available within parent (includes insets).
+ */
+ private void updateMaxSpansPerRow(int availableWidth) {
+ @Px int maxHorizontalSpan = getAvailableWidthForSuggestions(
+ availableWidth - getInsetsWidth());
if (mMaxSpanPerRow != maxHorizontalSpan) {
mMaxSpanPerRow = maxHorizontalSpan;
mAdapters.get(AdapterHolder.PRIMARY).mWidgetsListAdapter.setMaxHorizontalSpansPxPerRow(
@@ -439,16 +437,15 @@
mAdapters.get(AdapterHolder.WORK).mWidgetsListAdapter.setMaxHorizontalSpansPxPerRow(
maxHorizontalSpan);
}
- onRecommendedWidgetsBound();
- return true;
+ post(this::onRecommendedWidgetsBound);
}
- return false;
}
- protected View getContentView() {
- return mHasWorkProfile
- ? mViewPager
- : mAdapters.get(AdapterHolder.PRIMARY).mWidgetsRecyclerView;
+ /**
+ * Returns the width available to display suggestions.
+ */
+ protected int getAvailableWidthForSuggestions(int pickerAvailableWidth) {
+ return pickerAvailableWidth - (2 * mContentHorizontalMargin);
}
@Override
@@ -493,7 +490,7 @@
.mWidgetsListAdapter.hasVisibleEntries());
if (mIsNoWidgetsViewNeeded != isNoWidgetsViewNeeded) {
mIsNoWidgetsViewNeeded = isNoWidgetsViewNeeded;
- onRecommendedWidgetsBound();
+ post(this::onRecommendedWidgetsBound);
}
}
@@ -549,7 +546,7 @@
mAdapters.get(AdapterHolder.SEARCH).mWidgetsRecyclerView.setVisibility(GONE);
// Visibility of recommended widgets, recycler views and headers are handled in methods
// below.
- onRecommendedWidgetsBound();
+ post(this::onRecommendedWidgetsBound);
onWidgetsBound();
}
}
diff --git a/src/com/android/launcher3/widget/picker/WidgetsTwoPaneSheet.java b/src/com/android/launcher3/widget/picker/WidgetsTwoPaneSheet.java
index ae8b5db..840d98a 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsTwoPaneSheet.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsTwoPaneSheet.java
@@ -323,6 +323,30 @@
}
@Override
+ @Px
+ protected int getAvailableWidthForSuggestions(int pickerAvailableWidth) {
+ int rightPaneWidth = (int) Math.ceil(0.67 * pickerAvailableWidth);
+
+ if (mDeviceProfile.isTwoPanels && enableUnfoldedTwoPanePicker()) {
+ // See onLayout
+ int leftPaneWidth = (int) (0.33 * pickerAvailableWidth);
+ @Px int minLeftPaneWidthPx = Utilities.dpToPx(MINIMUM_WIDTH_LEFT_PANE_FOLDABLE_DP);
+ @Px int maxLeftPaneWidthPx = Utilities.dpToPx(MAXIMUM_WIDTH_LEFT_PANE_FOLDABLE_DP);
+ if (leftPaneWidth < minLeftPaneWidthPx) {
+ leftPaneWidth = minLeftPaneWidthPx;
+ } else if (leftPaneWidth > maxLeftPaneWidthPx) {
+ leftPaneWidth = maxLeftPaneWidthPx;
+ }
+ rightPaneWidth = pickerAvailableWidth - leftPaneWidth;
+ }
+
+ // Since suggestions are shown in right pane, the available width is 2/3 of total width of
+ // bottom sheet.
+ return rightPaneWidth - getResources().getDimensionPixelSize(
+ R.dimen.widget_list_horizontal_margin_two_pane); // right pane end margin.
+ }
+
+ @Override
public void onActivePageChanged(int currentActivePage) {
super.onActivePageChanged(currentActivePage);
@@ -384,11 +408,6 @@
}
- @Override
- protected View getContentView() {
- return mRightPane;
- }
-
private HeaderChangeListener getHeaderChangeListener() {
return new HeaderChangeListener() {
@Override