Merge "Use global PackageManagerHelper for LoaderTask" into main
diff --git a/AndroidManifest-common.xml b/AndroidManifest-common.xml
index edbea88..80d2eac 100644
--- a/AndroidManifest-common.xml
+++ b/AndroidManifest-common.xml
@@ -179,7 +179,7 @@
</intent-filter>
</activity>
- <!-- [b/197780098] Disable eager initialization of Jetpack libraries. -->
+ <!-- Disable eager initialization of Jetpack libraries. See bug 197780098. -->
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
diff --git a/aconfig/launcher_search.aconfig b/aconfig/launcher_search.aconfig
index 31d8d34..b243922 100644
--- a/aconfig/launcher_search.aconfig
+++ b/aconfig/launcher_search.aconfig
@@ -42,3 +42,11 @@
description: "This flag disables drag and drop for Private Space Items."
bug: "289223923"
}
+
+
+flag {
+ name: "private_space_floating_mask_view"
+ namespace: "launcher_search"
+ description: "This flag enables the floating mask view as part of the Private Space animation. "
+ bug: "339850589"
+}
diff --git a/protos/launcher_atom.proto b/protos/launcher_atom.proto
index 7c648b6..823c821 100644
--- a/protos/launcher_atom.proto
+++ b/protos/launcher_atom.proto
@@ -121,6 +121,20 @@
}
message TaskSwitcherContainer {
+ /**
+ * Indicates the current OrientationHandler in use in Overview.
+ * In fake landscape, the value will be
+ * {@link com.android.quickstep.orientation.LandscapePagedViewHandler} and in real landscape,
+ * the value will be {@link com.android.quickstep.orientation.PortraitPagedViewHandler} for
+ * example.
+ */
+ optional OrientationHandler orientation_handler = 1;
+
+ enum OrientationHandler {
+ PORTRAIT = 0;
+ LANDSCAPE = 1;
+ SEASCAPE = 2;
+ }
}
// Container for taskbar.
diff --git a/quickstep/res/layout/floating_desktop_app_select.xml b/quickstep/res/layout/floating_desktop_app_select.xml
deleted file mode 100644
index 375fc44..0000000
--- a/quickstep/res/layout/floating_desktop_app_select.xml
+++ /dev/null
@@ -1,56 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
- Copyright (C) 2023 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.
--->
-
-<com.android.quickstep.views.DesktopAppSelectView
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
- android:layout_width="wrap_content"
- android:layout_height="@dimen/desktop_mode_floating_app_select_height"
- android:layout_gravity="top|center_horizontal"
- android:background="@drawable/bg_floating_desktop_select"
- android:elevation="@dimen/desktop_mode_floating_app_select_elevation"
- android:gravity="center_vertical"
- android:orientation="horizontal">
-
- <TextView
- android:id="@+id/desktop_app_select_text"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginEnd="@dimen/desktop_mode_floating_app_select_text_margin"
- android:layout_marginStart="@dimen/desktop_mode_floating_app_select_margin"
- android:drawablePadding="@dimen/desktop_mode_floating_app_select_text_margin"
- android:drawableStart="@drawable/ic_desktop"
- android:drawableTint="?androidprv:attr/materialColorOnPrimaryContainer"
- android:fontFamily="google-sans-medium"
- android:gravity="center_vertical"
- android:text="@string/desktop_select_app_toast"
- android:textColor="?androidprv:attr/materialColorOnPrimaryContainer"
- android:textSize="@dimen/desktop_mode_floating_app_select_text_size" />
-
- <Button
- android:id="@+id/close_button"
- style="@android:style/Widget.DeviceDefault.Button.Borderless"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginEnd="@dimen/desktop_mode_floating_app_select_margin"
- android:minWidth="0dp"
- android:fontFamily="google-sans-medium"
- android:text="@string/desktop_button_close_app_toast"
- android:textAllCaps="false"
- android:textColor="?androidprv:attr/materialColorPrimary"
- android:textSize="@dimen/desktop_mode_floating_app_select_text_size" />
-
-</com.android.quickstep.views.DesktopAppSelectView>
diff --git a/quickstep/res/layout/taskbar_nav_button.xml b/quickstep/res/layout/taskbar_nav_button.xml
index aea4885..8f1c904 100644
--- a/quickstep/res/layout/taskbar_nav_button.xml
+++ b/quickstep/res/layout/taskbar_nav_button.xml
@@ -19,6 +19,7 @@
android:layout_width="@dimen/taskbar_nav_buttons_size"
android:layout_height="@dimen/taskbar_nav_buttons_size"
android:background="@drawable/taskbar_icon_click_feedback_roundrect"
+ android:focusable="false"
android:scaleType="center"
android:tint="@color/taskbar_nav_icon_light_color"
tools:ignore="UseAppTint" />
\ No newline at end of file
diff --git a/quickstep/res/values-hr/strings.xml b/quickstep/res/values-hr/strings.xml
index 6422f8d..5f7bc70 100644
--- a/quickstep/res/values-hr/strings.xml
+++ b/quickstep/res/values-hr/strings.xml
@@ -95,7 +95,7 @@
<string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Postavke navigacije sustavom"</annotation></string>
<string name="action_share" msgid="2648470652637092375">"Podijeli"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Snimka zaslona"</string>
- <string name="action_split" msgid="2098009717623550676">"Podijeli"</string>
+ <string name="action_split" msgid="2098009717623550676">"Podjela"</string>
<string name="action_save_app_pair" msgid="5974823919237645229">"Spremi par apl."</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"Dodirnite drugu aplikaciju za podijeljeni zaslon"</string>
<string name="toast_contextual_split_select_app" msgid="433510957123687090">"Odaberite drugu aplikaciju za upotrebu podijeljenog zaslona"</string>
diff --git a/quickstep/res/values-hy/strings.xml b/quickstep/res/values-hy/strings.xml
index d35aba1..b89cd3c 100644
--- a/quickstep/res/values-hy/strings.xml
+++ b/quickstep/res/values-hy/strings.xml
@@ -118,7 +118,7 @@
<string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Ամրացրեք հավելվածների վահանակը"</string>
<string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Հավելվածների վահանակն էկրանի ներքևում ամրացնելու համար հպեք և պահեք բաժանիչը"</string>
<string name="taskbar_search_edu_title" msgid="5569194922234364530">"Սեղմած պահեք գործողության ստեղնը՝ էկրանին բովանդակություն որոնելու համար"</string>
- <string name="taskbar_edu_search_disclosure" msgid="8734536088447779686">"Այս պրոդուկտն օգտագործում է էկրանի ընտրված հատվածը որոնման համար։ Կիրառվում են Google-ի <xliff:g id="BEGIN_PRIVACY_LINK"><a href="%1$s"></xliff:g>գաղտնիության քաղաքականությունը<xliff:g id="END_PRIVACY_LINK"></a></xliff:g> և <xliff:g id="BEGIN_TOS_LINK"><a href="%2$s"></xliff:g>օգտագործման պայմանները<xliff:g id="END_TOS_LINK"></a></xliff:g>։"</string>
+ <string name="taskbar_edu_search_disclosure" msgid="8734536088447779686">"Այս պրոդուկտն օգտագործում է էկրանի ընտրված հատվածը որոնման համար։ Կիրառվում են Google-ի <xliff:g id="BEGIN_PRIVACY_LINK"><a href="%1$s"></xliff:g>Գաղտնիության քաղաքականությունը<xliff:g id="END_PRIVACY_LINK"></a></xliff:g> և <xliff:g id="BEGIN_TOS_LINK"><a href="%2$s"></xliff:g>Օգտագործման պայմանները<xliff:g id="END_TOS_LINK"></a></xliff:g>։"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Փակել"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"Պատրաստ է"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"Սկիզբ"</string>
diff --git a/quickstep/res/values-sk/strings.xml b/quickstep/res/values-sk/strings.xml
index 0b40961..1737f07 100644
--- a/quickstep/res/values-sk/strings.xml
+++ b/quickstep/res/values-sk/strings.xml
@@ -117,7 +117,7 @@
<string name="taskbar_edu_features" msgid="3320337287472848162">"Panel aplikácií vám ponúka ďalšie možnosti"</string>
<string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Vždy zobrazovať panel aplikácií"</string>
<string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Ak chcete, aby sa panel aplikácií vždy zobrazoval v dolnej časti obrazovky, pridržte rozdeľovač"</string>
- <string name="taskbar_search_edu_title" msgid="5569194922234364530">"Ak chcete vyhľadávať, čo je na obrazovke, pridržte akčný kláves."</string>
+ <string name="taskbar_search_edu_title" msgid="5569194922234364530">"Ak chcete vyhľadávať, čo je na obrazovke, pridržte akčný kláves"</string>
<string name="taskbar_edu_search_disclosure" msgid="8734536088447779686">"Táto služba používa na účely vyhľadávania vybranú časť obrazovky. Uplatňujú sa <xliff:g id="BEGIN_PRIVACY_LINK"><a href="%1$s"></xliff:g>pravidlá ochrany súkromia<xliff:g id="END_PRIVACY_LINK"></a></xliff:g> a <xliff:g id="BEGIN_TOS_LINK"><a href="%2$s"></xliff:g>zmluvné podmienky<xliff:g id="END_TOS_LINK"></a></xliff:g> spoločnosti Google."</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Zavrieť"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"Hotovo"</string>
diff --git a/quickstep/res/values-sv/strings.xml b/quickstep/res/values-sv/strings.xml
index 2a1eea6..cec75d9 100644
--- a/quickstep/res/values-sv/strings.xml
+++ b/quickstep/res/values-sv/strings.xml
@@ -95,7 +95,7 @@
<string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Systemnavigeringsinställningar"</annotation></string>
<string name="action_share" msgid="2648470652637092375">"Dela"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Skärmbild"</string>
- <string name="action_split" msgid="2098009717623550676">"Delat"</string>
+ <string name="action_split" msgid="2098009717623550676">"Delad skärm"</string>
<string name="action_save_app_pair" msgid="5974823919237645229">"Spara app-par"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"Tryck på en annan app för att använda delad skärm"</string>
<string name="toast_contextual_split_select_app" msgid="433510957123687090">"Välj en annan app för att använda delad skärm"</string>
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index 7f09b6e..2021a0b 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -484,11 +484,4 @@
<dimen name="keyboard_quick_switch_no_recent_items_icon_size">24dp</dimen>
<dimen name="keyboard_quick_switch_no_recent_items_icon_margin">8dp</dimen>
- <!-- Desktop mode -->
- <dimen name="desktop_mode_floating_app_select_height">56dp</dimen>
- <dimen name="desktop_mode_floating_app_select_elevation">4dp</dimen>
- <dimen name="desktop_mode_floating_app_select_margin">16dp</dimen>
- <dimen name="desktop_mode_floating_app_select_text_size">14sp</dimen>
- <dimen name="desktop_mode_floating_app_select_text_margin">8dp</dimen>
-
</resources>
diff --git a/quickstep/res/values/strings.xml b/quickstep/res/values/strings.xml
index 278c66a..cf987c3 100644
--- a/quickstep/res/values/strings.xml
+++ b/quickstep/res/values/strings.xml
@@ -332,10 +332,4 @@
<!-- Accessibility label for quick switch tiles showing split tasks [CHAR LIMIT=NONE] -->
<string name="quick_switch_split_task"><xliff:g id="app_name_1" example="Chrome">%1$s</xliff:g> and <xliff:g id="app_name_2" example="Gmail">%2$s</xliff:g></string>
-
- <!-- ******* Desktop ******* -->
- <!-- Text shown in popup to choose a desktop app. [CHAR LIMIT=60] -->
- <string name="desktop_select_app_toast">Adding app to Desktop</string>
- <!-- Text shown on a button that closes the popup for choosing a desktop app. [CHAR_LIMIT=40] -->
- <string name="desktop_button_close_app_toast">Cancel</string>
</resources>
diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
index 72aaa90..0c499b8 100644
--- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
+++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
@@ -375,7 +375,7 @@
*/
protected boolean isLaunchingFromRecents(@NonNull View v,
@Nullable RemoteAnimationTarget[] targets) {
- return mLauncher.getStateManager().getState().overviewUi
+ return mLauncher.getStateManager().getState().isRecentsViewVisible
&& findTaskViewToLaunch(mLauncher.getOverviewPanel(), v, targets) != null;
}
diff --git a/quickstep/src/com/android/launcher3/statehandlers/DesktopVisibilityController.java b/quickstep/src/com/android/launcher3/statehandlers/DesktopVisibilityController.java
index 9eabb55..62cc0bb 100644
--- a/quickstep/src/com/android/launcher3/statehandlers/DesktopVisibilityController.java
+++ b/quickstep/src/com/android/launcher3/statehandlers/DesktopVisibilityController.java
@@ -35,7 +35,6 @@
import com.android.launcher3.util.DisplayController;
import com.android.quickstep.GestureState;
import com.android.quickstep.SystemUiProxy;
-import com.android.quickstep.views.DesktopAppSelectView;
import com.android.wm.shell.desktopmode.IDesktopTaskListener;
import java.util.HashSet;
@@ -49,8 +48,6 @@
private static final String TAG = "DesktopVisController";
private static final boolean DEBUG = false;
- private static final boolean IS_STASHING_ENABLED = SystemProperties.getBoolean(
- "persist.wm.debug.desktop_stashing", false);
private final Launcher mLauncher;
private final Set<DesktopVisibilityListener> mDesktopVisibilityListeners = new HashSet<>();
@@ -61,7 +58,6 @@
@Nullable
private IDesktopTaskListener mDesktopTaskListener;
- private DesktopAppSelectView mSelectAppToast;
public DesktopVisibilityController(Launcher launcher) {
mLauncher = launcher;
@@ -86,21 +82,7 @@
@Override
public void onStashedChanged(int displayId, boolean stashed) {
- if (!IS_STASHING_ENABLED) {
- return;
- }
- MAIN_EXECUTOR.execute(() -> {
- if (displayId == mLauncher.getDisplayId()) {
- if (DEBUG) {
- Log.d(TAG, "desktop stashed changed value=" + stashed);
- }
- if (stashed) {
- showSelectAppToast();
- } else {
- hideSelectAppToast();
- }
- }
- });
+ Log.w(TAG, "IDesktopTaskListener: onStashedChanged is deprecated");
}
};
SystemUiProxy.INSTANCE.get(mLauncher).setDesktopTaskListener(mDesktopTaskListener);
@@ -111,6 +93,7 @@
*/
public void unregisterSystemUiListener() {
SystemUiProxy.INSTANCE.get(mLauncher).setDesktopTaskListener(null);
+ mDesktopTaskListener = null;
}
/**
@@ -190,7 +173,7 @@
}
setBackgroundStateEnabled(state == BACKGROUND_APP);
// Desktop visibility tracks overview and background state separately
- setOverviewStateEnabled(state != BACKGROUND_APP && state.overviewUi);
+ setOverviewStateEnabled(state != BACKGROUND_APP && state.isRecentsViewVisible);
}
private void setOverviewStateEnabled(boolean overviewStateEnabled) {
@@ -303,15 +286,6 @@
}
/**
- * Handle launcher moving to home due to home gesture or home button press.
- */
- public void onHomeActionTriggered() {
- if (IS_STASHING_ENABLED && areDesktopTasksVisible()) {
- SystemUiProxy.INSTANCE.get(mLauncher).stashDesktopApps(mLauncher.getDisplayId());
- }
- }
-
- /**
* TODO: b/333533253 - Remove after flag rollout
*/
private void setLauncherViewsVisibility(int visibility) {
@@ -373,30 +347,6 @@
}
}
- private void showSelectAppToast() {
- if (mSelectAppToast != null) {
- return;
- }
- if (DEBUG) {
- Log.d(TAG, "show toast to select desktop apps");
- }
- Runnable onCloseCallback = () -> {
- SystemUiProxy.INSTANCE.get(mLauncher).hideStashedDesktopApps(mLauncher.getDisplayId());
- };
- mSelectAppToast = DesktopAppSelectView.show(mLauncher, onCloseCallback);
- }
-
- private void hideSelectAppToast() {
- if (mSelectAppToast == null) {
- return;
- }
- if (DEBUG) {
- Log.d(TAG, "hide toast to select desktop apps");
- }
- mSelectAppToast.hide();
- mSelectAppToast = null;
- }
-
/** A listener for when the user enters/exits Desktop Mode. */
public interface DesktopVisibilityListener {
/**
diff --git a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchTaskView.java b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchTaskView.java
index 48fc7d1..39b4f77 100644
--- a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchTaskView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchTaskView.java
@@ -186,7 +186,7 @@
@NonNull ImageView thumbnailView,
@ColorInt int backgroundColor,
@Nullable ThumbnailData thumbnailData) {
- Bitmap bm = thumbnailData == null ? null : thumbnailData.thumbnail;
+ Bitmap bm = thumbnailData == null ? null : thumbnailData.getThumbnail();
if (thumbnailView.getVisibility() != VISIBLE) {
thumbnailView.setVisibility(VISIBLE);
diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
index 4f02122..779009a 100644
--- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
@@ -51,6 +51,7 @@
import com.android.quickstep.util.GroupTask;
import com.android.quickstep.util.TISBindHelper;
import com.android.quickstep.views.RecentsView;
+import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags;
import java.io.PrintWriter;
import java.util.Arrays;
@@ -379,7 +380,7 @@
}
@Override
- public void updateStateForSysuiFlags(int sysuiFlags) {
+ public void updateStateForSysuiFlags(@SystemUiStateFlags long sysuiFlags) {
mTaskbarLauncherStateController.updateStateForSysuiFlags(sysuiFlags);
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
index abb763a..81581b8 100644
--- a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
@@ -45,6 +45,7 @@
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_QUICK_SETTINGS_EXPANDED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_PINNING;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SHORTCUT_HELPER_SHOWING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_VOICE_INTERACTION_WINDOW_SHOWING;
import android.animation.ArgbEvaluator;
@@ -105,6 +106,7 @@
import com.android.systemui.shared.rotation.RotationButton;
import com.android.systemui.shared.rotation.RotationButtonController;
import com.android.systemui.shared.system.QuickStepContract;
+import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -133,6 +135,7 @@
private static final int FLAG_VOICE_INTERACTION_WINDOW_SHOWING = 1 << 12;
private static final int FLAG_SMALL_SCREEN = 1 << 13;
private static final int FLAG_SLIDE_IN_VIEW_VISIBLE = 1 << 14;
+ private static final int FLAG_KEYBOARD_SHORTCUT_HELPER_SHOWING = 1 << 15;
/**
* Flags where a UI could be over Taskbar surfaces, so the color override should be disabled.
@@ -197,7 +200,8 @@
private TaskbarControllers mControllers;
private boolean mIsImeRenderingNavButtons;
private ImageView mA11yButton;
- private int mSysuiStateFlags;
+ @SystemUiStateFlags
+ private long mSysuiStateFlags;
private ImageView mBackButton;
private ImageView mHomeButton;
private MultiValueAlpha mBackButtonAlpha;
@@ -284,8 +288,9 @@
// - Notification shade is expanded
// - IME is showing (add separate translation for IME)
// - VoiceInteractionWindow (assistant) is showing
+ // - Keyboard shortcuts helper is showing
int flagsToRemoveTranslation = FLAG_NOTIFICATION_SHADE_EXPANDED | FLAG_IME_VISIBLE
- | FLAG_VOICE_INTERACTION_WINDOW_SHOWING;
+ | FLAG_VOICE_INTERACTION_WINDOW_SHOWING | FLAG_KEYBOARD_SHORTCUT_HELPER_SHOWING;
mPropertyHolders.add(new StatePropertyHolder(mNavButtonInAppDisplayProgressForSysui,
flags -> (flags & flagsToRemoveTranslation) != 0, AnimatedFloat.VALUE,
1, 0));
@@ -442,7 +447,7 @@
navButtonController.onButtonLongClick(BUTTON_SPACE, view));
}
- private void parseSystemUiFlags(int sysUiStateFlags) {
+ private void parseSystemUiFlags(@SystemUiStateFlags long sysUiStateFlags) {
mSysuiStateFlags = sysUiStateFlags;
boolean isImeVisible = (sysUiStateFlags & SYSUI_STATE_IME_SHOWING) != 0;
boolean isImeSwitcherShowing = (sysUiStateFlags & SYSUI_STATE_IME_SWITCHER_SHOWING) != 0;
@@ -450,12 +455,14 @@
boolean isHomeDisabled = (sysUiStateFlags & SYSUI_STATE_HOME_DISABLED) != 0;
boolean isRecentsDisabled = (sysUiStateFlags & SYSUI_STATE_OVERVIEW_DISABLED) != 0;
boolean isBackDisabled = (sysUiStateFlags & SYSUI_STATE_BACK_DISABLED) != 0;
- int shadeExpandedFlags = SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED
+ long shadeExpandedFlags = SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED
| SYSUI_STATE_QUICK_SETTINGS_EXPANDED;
boolean isNotificationShadeExpanded = (sysUiStateFlags & shadeExpandedFlags) != 0;
boolean isScreenPinningActive = (sysUiStateFlags & SYSUI_STATE_SCREEN_PINNING) != 0;
boolean isVoiceInteractionWindowShowing =
(sysUiStateFlags & SYSUI_STATE_VOICE_INTERACTION_WINDOW_SHOWING) != 0;
+ boolean isKeyboardShortcutHelperShowing =
+ (sysUiStateFlags & SYSUI_STATE_SHORTCUT_HELPER_SHOWING) != 0;
// TODO(b/202218289) we're getting IME as not visible on lockscreen from system
updateStateForFlag(FLAG_IME_VISIBLE, isImeVisible);
@@ -467,6 +474,7 @@
updateStateForFlag(FLAG_NOTIFICATION_SHADE_EXPANDED, isNotificationShadeExpanded);
updateStateForFlag(FLAG_SCREEN_PINNING_ACTIVE, isScreenPinningActive);
updateStateForFlag(FLAG_VOICE_INTERACTION_WINDOW_SHOWING, isVoiceInteractionWindowShowing);
+ updateStateForFlag(FLAG_KEYBOARD_SHORTCUT_HELPER_SHOWING, isKeyboardShortcutHelperShowing);
if (mA11yButton != null) {
// Only used in 3 button
@@ -477,7 +485,8 @@
}
}
- public void updateStateForSysuiFlags(int systemUiStateFlags, boolean skipAnim) {
+ public void updateStateForSysuiFlags(@SystemUiStateFlags long systemUiStateFlags,
+ boolean skipAnim) {
if (systemUiStateFlags == mSysuiStateFlags) {
return;
}
@@ -1053,6 +1062,8 @@
appendFlag(str, flags, FLAG_SCREEN_PINNING_ACTIVE, "FLAG_SCREEN_PINNING_ACTIVE");
appendFlag(str, flags, FLAG_VOICE_INTERACTION_WINDOW_SHOWING,
"FLAG_VOICE_INTERACTION_WINDOW_SHOWING");
+ appendFlag(str, flags, FLAG_KEYBOARD_SHORTCUT_HELPER_SHOWING,
+ "FLAG_KEYBOARD_SHORTCUT_HELPER_SHOWING");
return str.toString();
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java b/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java
index 36e054a..8d4c34d 100644
--- a/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java
@@ -42,6 +42,7 @@
import com.android.launcher3.util.MultiValueAlpha;
import com.android.quickstep.NavHandle;
import com.android.systemui.shared.navigationbar.RegionSamplingHelper;
+import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags;
import java.io.PrintWriter;
@@ -303,7 +304,7 @@
homeDisabled ? 0 : 1);
}
- public void updateStateForSysuiFlags(int systemUiStateFlags) {
+ public void updateStateForSysuiFlags(@SystemUiStateFlags long systemUiStateFlags) {
mTaskbarHidden = (systemUiStateFlags & SYSUI_STATE_NAV_BAR_HIDDEN) != 0;
updateRegionSamplingWindowVisibility();
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index af053e3..e77922a 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -137,6 +137,7 @@
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.rotation.RotationButtonController;
import com.android.systemui.shared.system.ActivityManagerWrapper;
+import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags;
import com.android.systemui.unfold.updates.RotationChangeProvider;
import com.android.systemui.unfold.util.ScopedUnfoldTransitionProgressProvider;
@@ -825,7 +826,8 @@
return mIsDestroyed;
}
- public void updateSysuiStateFlags(int systemUiStateFlags, boolean fromInit) {
+ public void updateSysuiStateFlags(@SystemUiStateFlags long systemUiStateFlags,
+ boolean fromInit) {
mControllers.navbarButtonsViewController.updateStateForSysuiFlags(systemUiStateFlags,
fromInit);
boolean isShadeVisible = (systemUiStateFlags & SYSUI_STATE_NOTIFICATION_PANEL_VISIBLE) != 0;
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
index 39f6fb2..4f5922c 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
@@ -74,12 +74,14 @@
import com.android.launcher3.popup.PopupContainerWithArrow;
import com.android.launcher3.shortcuts.DeepShortcutView;
import com.android.launcher3.shortcuts.ShortcutDragPreviewProvider;
+import com.android.launcher3.statehandlers.DesktopVisibilityController;
import com.android.launcher3.testing.TestLogging;
import com.android.launcher3.testing.shared.TestProtocol;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.IntSet;
import com.android.launcher3.util.ItemInfoMatcher;
import com.android.launcher3.views.BubbleTextHolder;
+import com.android.quickstep.LauncherActivityInterface;
import com.android.quickstep.util.LogUtils;
import com.android.quickstep.util.MultiValueUpdateListener;
import com.android.systemui.shared.recents.model.Task;
@@ -335,8 +337,13 @@
@Override
protected void callOnDragStart() {
super.callOnDragStart();
+ // TODO(297921594) clean it up when taskbar to desktop drag is implemented.
+ DesktopVisibilityController desktopController =
+ LauncherActivityInterface.INSTANCE.getDesktopVisibilityController();
+
// Pre-drag has ended, start the global system drag.
- if (mDisallowGlobalDrag) {
+ if (mDisallowGlobalDrag || (desktopController != null
+ && desktopController.areDesktopTasksVisible())) {
AbstractFloatingView.closeAllOpenViewsExcept(mActivity, TYPE_TASKBAR_ALL_APPS);
return;
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java
index 7f201b4..84874a9 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java
@@ -37,7 +37,7 @@
import androidx.core.graphics.Insets;
import androidx.core.view.WindowInsetsCompat;
-import com.android.app.viewcapture.SettingsAwareViewCapture;
+import com.android.app.viewcapture.ViewCaptureFactory;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.testing.TestLogging;
import com.android.launcher3.testing.shared.TestProtocol;
@@ -150,7 +150,7 @@
protected void onAttachedToWindow() {
super.onAttachedToWindow();
getViewTreeObserver().addOnComputeInternalInsetsListener(mTaskbarInsetsComputer);
- mViewCaptureCloseable = SettingsAwareViewCapture.getInstance(getContext())
+ mViewCaptureCloseable = ViewCaptureFactory.getInstance(getContext())
.startCapture(getRootView(), ".Taskbar");
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarForceVisibleImmersiveController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarForceVisibleImmersiveController.java
index 333c07b..6ac862e 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarForceVisibleImmersiveController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarForceVisibleImmersiveController.java
@@ -34,6 +34,7 @@
import com.android.launcher3.compat.AccessibilityManagerCompat;
import com.android.launcher3.util.MultiPropertyFactory;
import com.android.launcher3.util.TouchController;
+import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags;
/**
* Controller for taskbar when force visible in immersive mode is set.
@@ -83,7 +84,7 @@
}
/** Update values tracked via sysui flags. */
- public void updateSysuiFlags(int sysuiFlags) {
+ public void updateSysuiFlags(@SystemUiStateFlags long sysuiFlags) {
mIsImmersiveMode = (sysuiFlags & SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY) == 0;
if (mContext.isNavBarForceVisible()) {
if (mIsImmersiveMode) {
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarKeyguardController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarKeyguardController.java
index 03d08eb..eac4eaa 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarKeyguardController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarKeyguardController.java
@@ -17,6 +17,7 @@
import com.android.launcher3.AbstractFloatingView;
import com.android.systemui.shared.system.QuickStepContract;
+import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags;
import java.io.PrintWriter;
@@ -25,7 +26,7 @@
*/
public class TaskbarKeyguardController implements TaskbarControllers.LoggableTaskbarController {
- private static final int KEYGUARD_SYSUI_FLAGS = SYSUI_STATE_BOUNCER_SHOWING
+ private static final long KEYGUARD_SYSUI_FLAGS = SYSUI_STATE_BOUNCER_SHOWING
| SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING | SYSUI_STATE_DEVICE_DOZING
| SYSUI_STATE_OVERVIEW_DISABLED | SYSUI_STATE_HOME_DISABLED
| SYSUI_STATE_BACK_DISABLED | SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED
@@ -33,13 +34,13 @@
// If any of these SysUi flags (via QuickstepContract) is set, the device to be considered
// locked.
- public static final int MASK_ANY_SYSUI_LOCKED = SYSUI_STATE_BOUNCER_SHOWING
+ public static final long MASK_ANY_SYSUI_LOCKED = SYSUI_STATE_BOUNCER_SHOWING
| SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING
| SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED
| SYSUI_STATE_DEVICE_DREAMING;
private final TaskbarActivityContext mContext;
- private int mKeyguardSysuiFlags;
+ private long mKeyguardSysuiFlags;
private boolean mBouncerShowing;
private NavbarButtonsViewController mNavbarButtonsViewController;
private final KeyguardManager mKeyguardManager;
@@ -53,8 +54,8 @@
mNavbarButtonsViewController = navbarButtonUIController;
}
- public void updateStateForSysuiFlags(int systemUiStateFlags) {
- int interestingKeyguardFlags = systemUiStateFlags & KEYGUARD_SYSUI_FLAGS;
+ public void updateStateForSysuiFlags(@SystemUiStateFlags long systemUiStateFlags) {
+ long interestingKeyguardFlags = systemUiStateFlags & KEYGUARD_SYSUI_FLAGS;
if (interestingKeyguardFlags == mKeyguardSysuiFlags) {
// No change in keyguard relevant flags
return;
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
index 6ea52cb..ead1a8a 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
@@ -54,6 +54,7 @@
import com.android.quickstep.views.RecentsView;
import com.android.systemui.animation.ViewRootSync;
import com.android.systemui.shared.recents.model.ThumbnailData;
+import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags;
import java.io.PrintWriter;
import java.util.HashMap;
@@ -226,7 +227,7 @@
/** Initializes the controller instance, and applies the initial state immediately. */
public void init(TaskbarControllers controllers, QuickstepLauncher launcher,
- int sysuiStateFlags) {
+ @SystemUiStateFlags long sysuiStateFlags) {
mCanSyncViews = false;
mControllers = controllers;
@@ -325,11 +326,12 @@
}
/** SysUI flags updated, see QuickStepContract.SYSUI_STATE_* values. */
- public void updateStateForSysuiFlags(int systemUiStateFlags) {
+ public void updateStateForSysuiFlags(@SystemUiStateFlags long systemUiStateFlags) {
updateStateForSysuiFlags(systemUiStateFlags, /* applyState */ true);
}
- private void updateStateForSysuiFlags(int systemUiStateFlags, boolean applyState) {
+ private void updateStateForSysuiFlags(@SystemUiStateFlags long systemUiStateFlags,
+ boolean applyState) {
final boolean prevIsAwake = hasAnyFlag(FLAG_AWAKE);
final boolean currIsAwake = hasAnyFlag(systemUiStateFlags, SYSUI_STATE_AWAKE);
@@ -389,11 +391,11 @@
}
}
- private boolean hasAnyFlag(int flagMask) {
+ private boolean hasAnyFlag(long flagMask) {
return hasAnyFlag(mState, flagMask);
}
- private boolean hasAnyFlag(int flags, int flagMask) {
+ private boolean hasAnyFlag(long flags, long flagMask) {
return (flags & flagMask) != 0;
}
@@ -667,7 +669,7 @@
}
boolean isInOverviewUi() {
- return mLauncherState.overviewUi;
+ return mLauncherState.isRecentsViewVisible;
}
private void playStateTransitionAnim(AnimatorSet animatorSet, long duration,
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
index 42e6edb..e8dc177 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
@@ -73,6 +73,7 @@
import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.util.AssistUtils;
import com.android.systemui.shared.system.QuickStepContract;
+import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags;
import com.android.systemui.unfold.UnfoldTransitionProgressProvider;
import com.android.systemui.unfold.util.ScopedUnfoldTransitionProgressProvider;
@@ -491,7 +492,7 @@
}
}
- public void onSystemUiFlagsChanged(int systemUiStateFlags) {
+ public void onSystemUiFlagsChanged(@SystemUiStateFlags long systemUiStateFlags) {
if (DEBUG) {
Log.d(TAG, "SysUI flags changed: " + formatFlagChange(systemUiStateFlags,
mSharedState.sysuiStateFlags, QuickStepContract::getSystemUiStateString));
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java
index 13a68a0..d26a36d 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java
@@ -44,13 +44,12 @@
import com.android.launcher3.R;
import com.android.launcher3.logging.StatsLogManager;
-import com.android.launcher3.statehandlers.DesktopVisibilityController;
import com.android.launcher3.testing.TestLogging;
import com.android.launcher3.testing.shared.TestProtocol;
-import com.android.quickstep.LauncherActivityInterface;
import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.TaskUtils;
import com.android.quickstep.util.AssistUtils;
+import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
@@ -258,7 +257,7 @@
mLastScreenPinLongPress = 0;
}
- public void updateSysuiFlags(int sysuiFlags) {
+ public void updateSysuiFlags(@SystemUiStateFlags long sysuiFlags) {
mScreenPinned = (sysuiFlags & SYSUI_STATE_SCREEN_PINNING) != 0;
}
@@ -284,13 +283,6 @@
private void navigateHome() {
TaskUtils.closeSystemWindowsAsync(CLOSE_SYSTEM_WINDOWS_REASON_HOME_KEY);
-
- DesktopVisibilityController desktopVisibilityController =
- LauncherActivityInterface.INSTANCE.getDesktopVisibilityController();
- if (desktopVisibilityController != null) {
- desktopVisibilityController.onHomeActionTriggered();
- }
-
mCallbacks.onNavigateHome();
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarScrimViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarScrimViewController.java
index 712374d..92d9b23 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarScrimViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarScrimViewController.java
@@ -30,6 +30,7 @@
import com.android.launcher3.anim.AnimatedFloat;
import com.android.launcher3.util.DisplayController;
import com.android.quickstep.SystemUiProxy;
+import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags;
import java.io.PrintWriter;
@@ -45,7 +46,8 @@
private final TaskbarActivityContext mActivity;
private final TaskbarScrimView mScrimView;
private boolean mTaskbarVisible;
- private int mSysUiStateFlags;
+ @SystemUiStateFlags
+ private long mSysUiStateFlags;
// Alpha property for the scrim.
private final AnimatedFloat mScrimAlpha = new AnimatedFloat(this::updateScrimAlpha);
@@ -82,7 +84,7 @@
/**
* Updates the scrim state based on the flags.
*/
- public void updateStateForSysuiFlags(int stateFlags, boolean skipAnim) {
+ public void updateStateForSysuiFlags(@SystemUiStateFlags long stateFlags, boolean skipAnim) {
if (isBubbleBarEnabled() && DisplayController.isTransientTaskbar(mActivity)) {
// These scrims aren't used if bubble bar & transient taskbar are active.
return;
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarSharedState.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarSharedState.java
index e2c71bf..edaeb63 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarSharedState.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarSharedState.java
@@ -29,6 +29,8 @@
import android.os.IBinder;
import android.view.InsetsFrameProvider;
+import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags;
+
/**
* State shared across different taskbar instance
*/
@@ -39,7 +41,8 @@
private static int INDEX_RIGHT = 1;
// TaskbarManager#onSystemUiFlagsChanged
- public int sysuiStateFlags;
+ @SystemUiStateFlags
+ public long sysuiStateFlags;
// TaskbarManager#disableNavBarElements()
public int disableNavBarDisplayId;
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
index f764a83..1a3c497 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
@@ -71,7 +71,7 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.StringJoiner;
-import java.util.function.IntPredicate;
+import java.util.function.LongPredicate;
/**
* Coordinates between controllers such as TaskbarViewController and StashedHandleViewController to
@@ -229,7 +229,7 @@
/** Whether we are currently visually stashed (might change based on launcher state). */
private boolean mIsStashed = false;
- private int mState;
+ private long mState;
private @Nullable AnimatorSet mAnimator;
private boolean mIsSystemGestureInProgress;
@@ -240,7 +240,7 @@
private boolean mEnableBlockingTimeoutDuringTests = false;
// Evaluate whether the handle should be stashed
- private final IntPredicate mIsStashedPredicate = flags -> {
+ private final LongPredicate mIsStashedPredicate = flags -> {
boolean inApp = hasAnyFlag(flags, FLAGS_IN_APP);
boolean stashedInApp = hasAnyFlag(flags, FLAGS_STASHED_IN_APP);
boolean stashedLauncherState = hasAnyFlag(flags, FLAG_IN_STASHED_LAUNCHER_STATE);
@@ -388,11 +388,11 @@
return (hasAnyFlag(FLAG_IN_STASHED_LAUNCHER_STATE) && supportsVisualStashing());
}
- private boolean hasAnyFlag(int flagMask) {
+ private boolean hasAnyFlag(long flagMask) {
return hasAnyFlag(mState, flagMask);
}
- private boolean hasAnyFlag(int flags, int flagMask) {
+ private boolean hasAnyFlag(long flags, long flagMask) {
return (flags & flagMask) != 0;
}
@@ -929,7 +929,7 @@
}
/** Called when some system ui state has changed. (See SYSUI_STATE_... in QuickstepContract) */
- public void updateStateForSysuiFlags(int systemUiStateFlags, boolean skipAnim) {
+ public void updateStateForSysuiFlags(long systemUiStateFlags, boolean skipAnim) {
long animDuration = TASKBAR_STASH_DURATION;
long startDelay = 0;
@@ -1005,8 +1005,8 @@
* unstashed.
* @return Whether the flag state changed.
*/
- public boolean updateStateForFlag(int flag, boolean enabled) {
- int oldState = mState;
+ public boolean updateStateForFlag(long flag, boolean enabled) {
+ long oldState = mState;
if (enabled) {
mState |= flag;
} else {
@@ -1020,7 +1020,7 @@
*
* @param changedFlags The flags that have changed.
*/
- private void onStateChangeApplied(int changedFlags) {
+ private void onStateChangeApplied(long changedFlags) {
if (hasAnyFlag(changedFlags, FLAGS_STASHED_IN_APP)) {
mControllers.uiController.onStashedInAppChanged();
}
@@ -1151,7 +1151,7 @@
pw.println(prefix + "\tmIsImeSwitcherShowing=" + mIsImeSwitcherShowing);
}
- private static String getStateString(int flags) {
+ private static String getStateString(long flags) {
StringJoiner sj = new StringJoiner("|");
appendFlag(sj, flags, FLAGS_IN_APP, "FLAG_IN_APP");
appendFlag(sj, flags, FLAG_STASHED_IN_APP_SYSUI, "FLAG_STASHED_IN_APP_SYSUI");
@@ -1168,15 +1168,15 @@
}
private class StatePropertyHolder {
- private final IntPredicate mStashCondition;
+ private final LongPredicate mStashCondition;
private boolean mIsStashed;
private @StashAnimation int mLastStartedTransitionType = TRANSITION_DEFAULT;
- private int mPrevFlags;
+ private long mPrevFlags;
private long mLastUnlockTransitionTimeout = 0;
- StatePropertyHolder(IntPredicate stashCondition) {
+ StatePropertyHolder(LongPredicate stashCondition) {
mStashCondition = stashCondition;
}
@@ -1189,7 +1189,7 @@
* @return mAnimator if mIsStashed changed, or {@code null} otherwise.
*/
@Nullable
- public Animator createSetStateAnimator(int flags, long duration) {
+ public Animator createSetStateAnimator(long flags, long duration) {
boolean isStashed = mStashCondition.test(flags);
if (DEBUG) {
@@ -1201,7 +1201,7 @@
+ ", mIsStashed: " + mIsStashed);
}
- int changedFlags = mPrevFlags ^ flags;
+ long changedFlags = mPrevFlags ^ flags;
if (mPrevFlags != flags) {
onStateChangeApplied(changedFlags);
mPrevFlags = flags;
@@ -1248,7 +1248,7 @@
}
/** Calculates the tag for CUJ_TASKBAR_EXPAND and CUJ_TASKBAR_COLLAPSE jank traces. */
- private String computeTaskbarJankMonitorTag(int changedFlags) {
+ private String computeTaskbarJankMonitorTag(long changedFlags) {
if (hasAnyFlag(changedFlags, FLAG_IN_APP)) {
// moving in or out of the app
if (hasAnyFlag(FLAG_IN_APP)) {
@@ -1268,7 +1268,7 @@
return "";
}
- private @StashAnimation int computeTransitionType(int changedFlags) {
+ private @StashAnimation int computeTransitionType(long changedFlags) {
boolean hotseatHiddenDuringAppLaunch =
!mControllers.uiController.isHotseatIconOnTopWhenAligned()
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
index 6abd5a9..d0c494c 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
@@ -46,6 +46,7 @@
import com.android.quickstep.views.TaskView;
import com.android.quickstep.views.TaskView.TaskContainer;
import com.android.systemui.shared.recents.model.Task;
+import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags;
import java.io.PrintWriter;
import java.util.Collections;
@@ -140,7 +141,7 @@
/**
* SysUI flags updated, see QuickStepContract.SYSUI_STATE_* values.
*/
- public void updateStateForSysuiFlags(int sysuiFlags) {
+ public void updateStateForSysuiFlags(@SystemUiStateFlags long sysuiFlags) {
}
/**
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
index df7a7ba..e4ccc58 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
@@ -24,6 +24,8 @@
import static com.android.launcher3.config.FeatureFlags.ENABLE_ALL_APPS_SEARCH_IN_TASKBAR;
import static com.android.launcher3.config.FeatureFlags.enableTaskbarPinning;
import static com.android.launcher3.icons.IconNormalizer.ICON_VISIBLE_AREA_FACTOR;
+import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
+import static com.android.quickstep.RecentsAnimationDeviceState.QUICKSTEP_TOUCH_SLOP_RATIO_TWO_BUTTON;
import android.content.Context;
import android.content.res.Resources;
@@ -31,11 +33,13 @@
import android.graphics.Rect;
import android.os.Bundle;
import android.util.AttributeSet;
+import android.util.Log;
import android.view.DisplayCutout;
import android.view.InputDevice;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
+import android.view.ViewConfiguration;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.FrameLayout;
@@ -63,6 +67,9 @@
import com.android.launcher3.util.Themes;
import com.android.launcher3.views.ActivityContext;
import com.android.launcher3.views.IconButtonView;
+import com.android.quickstep.DeviceConfigWrapper;
+import com.android.quickstep.RecentsAnimationDeviceState;
+import com.android.quickstep.util.AssistStateManager;
import java.util.function.Predicate;
@@ -82,8 +89,10 @@
private final int mItemPadding;
private final int mFolderLeaveBehindColor;
private final boolean mIsRtl;
+ private final boolean mIsTransientTaskbar;
private final TaskbarActivityContext mActivityContext;
+ private final RecentsAnimationDeviceState mDeviceState;
// Initialized in init.
private TaskbarViewCallbacks mControllerCallbacks;
@@ -95,6 +104,11 @@
// Only non-null when device supports having an All Apps button.
private @Nullable IconButtonView mAllAppsButton;
+ private Runnable mAllAppsTouchRunnable;
+ private long mAllAppsButtonTouchDelayMs;
+ private boolean mAllAppsTouchTriggered;
+ private MotionEvent mCurrentDownEvent;
+ private float mTouchSlopSquared;
// Only non-null when device supports having an All Apps button.
private @Nullable IconButtonView mTaskbarDivider;
@@ -124,12 +138,11 @@
mActivityContext = ActivityContext.lookupContext(context);
mIconLayoutBounds = mActivityContext.getTransientTaskbarBounds();
Resources resources = getResources();
- boolean isTransientTaskbar = DisplayController.isTransientTaskbar(mActivityContext)
+ mIsTransientTaskbar = DisplayController.isTransientTaskbar(mActivityContext)
&& !mActivityContext.isPhoneMode();
mIsRtl = Utilities.isRtl(resources);
mTransientTaskbarMinWidth = resources.getDimension(R.dimen.transient_taskbar_min_width);
-
onDeviceProfileChanged(mActivityContext.getDeviceProfile());
int actualMargin = resources.getDimensionPixelSize(R.dimen.taskbar_icon_spacing);
@@ -159,7 +172,7 @@
mAllAppsButton = (IconButtonView) LayoutInflater.from(context)
.inflate(R.layout.taskbar_all_apps_button, this, false);
mAllAppsButton.setIconDrawable(resources.getDrawable(
- getAllAppsButton(isTransientTaskbar)));
+ getAllAppsButton(mIsTransientTaskbar)));
mAllAppsButton.setPadding(mItemPadding, mItemPadding, mItemPadding, mItemPadding);
mAllAppsButton.setForegroundTint(
mActivityContext.getColor(R.color.all_apps_button_color));
@@ -175,6 +188,13 @@
// TODO: Disable touch events on QSB otherwise it can crash.
mQsb = LayoutInflater.from(context).inflate(R.layout.search_container_hotseat, this, false);
+
+ // Default long press (touch) delay = 400ms
+ mAllAppsButtonTouchDelayMs = ViewConfiguration.getLongPressTimeout();
+ // Default touch slop
+ mDeviceState = new RecentsAnimationDeviceState(mContext);
+ mTouchSlopSquared = mDeviceState.getSquaredTouchSlop(
+ QUICKSTEP_TOUCH_SLOP_RATIO_TWO_BUTTON, 1);
}
@DrawableRes
@@ -265,11 +285,26 @@
mIconLongClickListener = mControllerCallbacks.getIconOnLongClickListener();
if (mAllAppsButton != null) {
- mAllAppsButton.setOnClickListener(mControllerCallbacks.getAllAppsButtonClickListener());
- mAllAppsButton.setOnLongClickListener(
- mControllerCallbacks.getAllAppsButtonLongClickListener());
+ mAllAppsButton.setOnClickListener(this::onAllAppsButtonClick);
+ mAllAppsButton.setOnLongClickListener(this::onAllAppsButtonLongClick);
+ mAllAppsButton.setOnTouchListener(this::onAllAppsButtonTouch);
mAllAppsButton.setHapticFeedbackEnabled(
mControllerCallbacks.isAllAppsButtonHapticFeedbackEnabled());
+ mAllAppsTouchRunnable = () -> {
+ mControllerCallbacks.triggerAllAppsButtonLongClick();
+ mAllAppsTouchTriggered = true;
+ };
+ AssistStateManager assistStateManager = AssistStateManager.INSTANCE.get(mContext);
+ if (DeviceConfigWrapper.get().getCustomLpaaThresholds()
+ && assistStateManager.getLPNHDurationMillis().isPresent()) {
+ mAllAppsButtonTouchDelayMs = assistStateManager.getLPNHDurationMillis().get();
+ }
+ if (DeviceConfigWrapper.get().getCustomLpaaThresholds()
+ && assistStateManager.getLPNHCustomSlopMultiplier().isPresent()) {
+ mTouchSlopSquared = mDeviceState.getSquaredTouchSlop(
+ QUICKSTEP_TOUCH_SLOP_RATIO_TWO_BUTTON,
+ assistStateManager.getLPNHCustomSlopMultiplier().get());
+ }
}
if (mTaskbarDivider != null && !mActivityContext.isThreeButtonNav()) {
mTaskbarDivider.setOnLongClickListener(
@@ -305,7 +340,6 @@
}
removeView(mQsb);
-
for (int i = 0; i < hotseatItemInfos.length; i++) {
ItemInfo hotseatItemInfo = hotseatItemInfos[i];
if (hotseatItemInfo == null) {
@@ -689,4 +723,63 @@
}
return mAllAppsButton;
}
+
+ private boolean onAllAppsButtonTouch(View view, MotionEvent ev) {
+ switch (ev.getAction()) {
+ case MotionEvent.ACTION_DOWN:
+ if (mCurrentDownEvent != null) {
+ mCurrentDownEvent.recycle();
+ }
+ mCurrentDownEvent = MotionEvent.obtain(ev);
+ mAllAppsTouchTriggered = false;
+ MAIN_EXECUTOR.getHandler().postDelayed(
+ mAllAppsTouchRunnable, mAllAppsButtonTouchDelayMs);
+ break;
+ case MotionEvent.ACTION_MOVE:
+ if (!MAIN_EXECUTOR.getHandler().hasCallbacks(mAllAppsTouchRunnable)
+ || mIsTransientTaskbar) {
+ break;
+ }
+ float dx = ev.getX() - mCurrentDownEvent.getX();
+ float dy = ev.getY() - mCurrentDownEvent.getY();
+ double distanceSquared = (dx * dx) + (dy * dy);
+ if (distanceSquared > mTouchSlopSquared) {
+ Log.d(TAG, "Touch slop out");
+ cancelAllAppsButtonTouch();
+ }
+ break;
+ case MotionEvent.ACTION_UP:
+ case MotionEvent.ACTION_CANCEL:
+ cancelAllAppsButtonTouch();
+ }
+ return false;
+ }
+
+ private void cancelAllAppsButtonTouch() {
+ MAIN_EXECUTOR.getHandler().removeCallbacks(mAllAppsTouchRunnable);
+ // ACTION_UP is first triggered, then click listener / long-click listener is triggered on
+ // the next frame, so we need to post twice and delay the reset.
+ if (mAllAppsButton != null) {
+ mAllAppsButton.post(() -> {
+ mAllAppsButton.post(() -> {
+ mAllAppsTouchTriggered = false;
+ });
+ });
+ }
+ }
+
+ private void onAllAppsButtonClick(View view) {
+ if (!mAllAppsTouchTriggered) {
+ mControllerCallbacks.triggerAllAppsButtonClick(view);
+ }
+ }
+
+ // Handle long click from Switch Access and Voice Access
+ private boolean onAllAppsButtonLongClick(View view) {
+ if (!MAIN_EXECUTOR.getHandler().hasCallbacks(mAllAppsTouchRunnable)
+ && !mAllAppsTouchTriggered) {
+ mControllerCallbacks.triggerAllAppsButtonLongClick();
+ }
+ return true;
+ }
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewCallbacks.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewCallbacks.java
index c841cac..3c646cb 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewCallbacks.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewCallbacks.java
@@ -46,20 +46,17 @@
return mActivity.getItemOnClickListener();
}
- public View.OnClickListener getAllAppsButtonClickListener() {
- return v -> {
- InteractionJankMonitorWrapper.begin(v, Cuj.CUJ_LAUNCHER_OPEN_ALL_APPS,
- /* tag= */ "TASKBAR_BUTTON");
- mActivity.getStatsLogManager().logger().log(LAUNCHER_TASKBAR_ALLAPPS_BUTTON_TAP);
- mControllers.taskbarAllAppsController.toggle();
- };
+ /** Trigger All Apps button click action. */
+ protected void triggerAllAppsButtonClick(View v) {
+ InteractionJankMonitorWrapper.begin(v, Cuj.CUJ_LAUNCHER_OPEN_ALL_APPS,
+ /* tag= */ "TASKBAR_BUTTON");
+ mActivity.getStatsLogManager().logger().log(LAUNCHER_TASKBAR_ALLAPPS_BUTTON_TAP);
+ mControllers.taskbarAllAppsController.toggle();
}
- public View.OnLongClickListener getAllAppsButtonLongClickListener() {
- return v -> {
- mActivity.getStatsLogManager().logger().log(LAUNCHER_TASKBAR_ALLAPPS_BUTTON_LONG_PRESS);
- return true;
- };
+ /** Trigger All Apps button long click action. */
+ protected void triggerAllAppsButtonLongClick() {
+ mActivity.getStatsLogManager().logger().log(LAUNCHER_TASKBAR_ALLAPPS_BUTTON_LONG_PRESS);
}
public boolean isAllAppsButtonHapticFeedbackEnabled() {
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java
index 5789f0c..46c2e25 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java
@@ -67,10 +67,10 @@
import com.android.launcher3.icons.BitmapInfo;
import com.android.launcher3.icons.BubbleIconFactory;
import com.android.launcher3.shortcuts.ShortcutRequest;
-import com.android.launcher3.taskbar.TaskbarControllers;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.Executors.SimpleThreadFactory;
import com.android.quickstep.SystemUiProxy;
+import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags;
import com.android.wm.shell.Flags;
import com.android.wm.shell.bubbles.IBubblesListener;
import com.android.wm.shell.common.bubbles.BubbleBarLocation;
@@ -117,7 +117,7 @@
|| SystemProperties.getBoolean("persist.wm.debug.bubble_bar", false);
}
- private static final int MASK_HIDE_BUBBLE_BAR = SYSUI_STATE_BOUNCER_SHOWING
+ private static final long MASK_HIDE_BUBBLE_BAR = SYSUI_STATE_BOUNCER_SHOWING
| SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING
| SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED
| SYSUI_STATE_IME_SHOWING
@@ -125,11 +125,11 @@
| SYSUI_STATE_QUICK_SETTINGS_EXPANDED
| SYSUI_STATE_IME_SWITCHER_SHOWING;
- private static final int MASK_HIDE_HANDLE_VIEW = SYSUI_STATE_BOUNCER_SHOWING
+ private static final long MASK_HIDE_HANDLE_VIEW = SYSUI_STATE_BOUNCER_SHOWING
| SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING
| SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED;
- private static final int MASK_SYSUI_LOCKED = SYSUI_STATE_BOUNCER_SHOWING
+ private static final long MASK_SYSUI_LOCKED = SYSUI_STATE_BOUNCER_SHOWING
| SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING
| SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED;
@@ -147,6 +147,7 @@
private BubbleBarItem mSelectedBubble;
private BubbleBarOverflow mOverflowBubble;
+ private ImeVisibilityChecker mImeVisibilityChecker;
private BubbleBarViewController mBubbleBarViewController;
private BubbleStashController mBubbleStashController;
private BubbleStashedHandleViewController mBubbleStashedHandleViewController;
@@ -215,7 +216,10 @@
mSystemUiProxy.setBubblesListener(null);
}
- public void init(TaskbarControllers controllers, BubbleControllers bubbleControllers) {
+ /** Initializes controllers. */
+ public void init(BubbleControllers bubbleControllers,
+ ImeVisibilityChecker imeVisibilityChecker) {
+ mImeVisibilityChecker = imeVisibilityChecker;
mBubbleBarViewController = bubbleControllers.bubbleBarViewController;
mBubbleStashController = bubbleControllers.bubbleStashController;
mBubbleStashedHandleViewController = bubbleControllers.bubbleStashedHandleViewController;
@@ -256,7 +260,7 @@
/**
* Updates the bubble bar, handle bar, and stash controllers based on sysui state flags.
*/
- public void updateStateForSysuiFlags(int flags) {
+ public void updateStateForSysuiFlags(@SystemUiStateFlags long flags) {
boolean hideBubbleBar = (flags & MASK_HIDE_BUBBLE_BAR) != 0;
mBubbleBarViewController.setHiddenForSysui(hideBubbleBar);
@@ -320,9 +324,9 @@
// enabling gesture nav. also suppress animation if the bubble bar is hidden for sysui e.g.
// the shade is open, or we're locked.
final boolean suppressAnimation =
- update.initialState || mBubbleBarViewController.isHiddenForSysui();
+ update.initialState || mBubbleBarViewController.isHiddenForSysui()
+ || mImeVisibilityChecker.isImeVisible();
- BubbleBarItem previouslySelectedBubble = mSelectedBubble;
BubbleBarBubble bubbleToSelect = null;
if (!update.removedBubbles.isEmpty()) {
for (int i = 0; i < update.removedBubbles.size(); i++) {
@@ -378,6 +382,7 @@
BubbleBarBubble bb = mBubbles.get(update.updatedBubble.getKey());
// If we're not stashed, we're visible so animate
bb.getView().updateDotVisibility(!mBubbleStashController.isStashed() /* animate */);
+ mBubbleBarViewController.animateBubbleNotification(bb, /* isExpanding= */ false);
}
if (update.bubbleKeysInOrder != null && !update.bubbleKeysInOrder.isEmpty()) {
// Create the new list
@@ -666,4 +671,10 @@
displayBounds.bottom = displaySize.y - translation;
return displayBounds;
}
+
+ /** Interface for checking whether the IME is visible. */
+ public interface ImeVisibilityChecker {
+ /** Whether the IME is visible. */
+ boolean isImeVisible();
+ }
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java
index f3ac1e4..43fe251 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java
@@ -394,21 +394,24 @@
* from the internal location that was used during bubble bar layout, translation values are
* calculated to position the bar at the desired location.
*
- * @param initialTranslation initial bubble bar translation at the start of drag
+ * @param initialTranslation initial bubble translation inside the bar at the start of drag
* @param location desired location of the bubble bar when drag is released
* @return point with x and y values representing translation on x and y-axis
*/
public PointF getDraggedBubbleReleaseTranslation(PointF initialTranslation,
BubbleBarLocation location) {
- // Start with bubble bar translation
- final PointF dragEndTranslation = new PointF(
- getBubbleBarDragReleaseTranslation(initialTranslation, location));
- // Apply individual bubble translation, as the order may have changed
- int viewIndex = indexOfChild(mDraggedBubbleView);
- dragEndTranslation.x += getExpandedBubbleTranslationX(viewIndex,
- getChildCount(),
- location.isOnLeft(isLayoutRtl()));
- return dragEndTranslation;
+ float dragEndTranslationX = initialTranslation.x;
+ boolean newLocationOnLeft = location.isOnLeft(isLayoutRtl());
+ if (getBubbleBarLocation().isOnLeft(isLayoutRtl()) != newLocationOnLeft) {
+ // Calculate translationX based on bar and bubble translations
+ float bubbleBarTx = getBubbleBarDragReleaseTranslation(initialTranslation, location).x;
+ float bubbleTx =
+ getExpandedBubbleTranslationX(
+ indexOfChild(mDraggedBubbleView), getChildCount(), newLocationOnLeft);
+ dragEndTranslationX = bubbleBarTx + bubbleTx;
+ }
+ // translationY does not change during drag and can be reused
+ return new PointF(dragEndTranslationX, initialTranslation.y);
}
private float getDistanceFromOtherSide() {
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java
index fbdb2ed..5f75b3b 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java
@@ -414,31 +414,31 @@
b.getView().setOnClickListener(mBubbleClickListener);
mBubbleDragController.setupBubbleView(b.getView());
- if (suppressAnimation) {
+ if (suppressAnimation || !(b instanceof BubbleBarBubble bubble)) {
return;
}
-
- if (!(b instanceof BubbleBarBubble bubble)) {
- return;
- }
-
- boolean isInApp = mTaskbarStashController.isInApp();
- // if this is the first bubble, animate to the initial state. one bubble is the overflow
- // so check for at most 2 children.
- if (mBarView.getChildCount() <= 2) {
- mBubbleBarViewAnimator.animateToInitialState(bubble, isInApp, isExpanding);
- return;
- }
-
- // only animate the new bubble if we're in an app and not auto expanding
- if (isInApp && !isExpanding && !isExpanded()) {
- mBubbleBarViewAnimator.animateBubbleInForStashed(bubble);
- }
+ animateBubbleNotification(bubble, isExpanding);
} else {
Log.w(TAG, "addBubble, bubble was null!");
}
}
+ /** Animates the bubble bar to notify the user about a bubble change. */
+ public void animateBubbleNotification(BubbleBarBubble bubble, boolean isExpanding) {
+ boolean isInApp = mTaskbarStashController.isInApp();
+ // if this is the first bubble, animate to the initial state. one bubble is the overflow
+ // so check for at most 2 children.
+ if (mBarView.getChildCount() <= 2) {
+ mBubbleBarViewAnimator.animateToInitialState(bubble, isInApp, isExpanding);
+ return;
+ }
+
+ // only animate the new bubble if we're in an app and not auto expanding
+ if (isInApp && !isExpanding && !isExpanded()) {
+ mBubbleBarViewAnimator.animateBubbleInForStashed(bubble);
+ }
+ }
+
/**
* Reorders the bubbles based on the provided list.
*/
@@ -506,12 +506,10 @@
/**
* Notifies SystemUI to expand the selected bubble when the bubble is released.
- * @param bubbleView dragged bubble view
*/
- public void onDragRelease(@NonNull BubbleView bubbleView, BubbleBarLocation location) {
- if (bubbleView.getBubble() == null) return;
+ public void onDragRelease(BubbleBarLocation location) {
// TODO(b/330585402): send new bubble bar bounds to shell for the animation
- mSystemUiProxy.stopBubbleDrag(bubbleView.getBubble().getKey(), location);
+ mSystemUiProxy.stopBubbleDrag(location);
}
/**
@@ -556,7 +554,7 @@
* @param bubble dismissed bubble item
*/
public void onDismissBubbleWhileDragging(@NonNull BubbleBarItem bubble) {
- mSystemUiProxy.removeBubble(bubble.getKey());
+ mSystemUiProxy.dragBubbleToDismiss(bubble.getKey());
}
/**
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleControllers.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleControllers.java
index 295477c..32d6375 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleControllers.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleControllers.java
@@ -64,7 +64,8 @@
* in constructors for now, as some controllers may still be waiting for init().
*/
public void init(TaskbarControllers taskbarControllers) {
- bubbleBarController.init(taskbarControllers, this);
+ bubbleBarController.init(this,
+ taskbarControllers.navbarButtonsViewController::isImeVisible);
bubbleBarViewController.init(taskbarControllers, this);
bubbleStashedHandleViewController.init(taskbarControllers, this);
bubbleStashController.init(taskbarControllers, this);
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleDragController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleDragController.java
index f4b393a..604ae89 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleDragController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleDragController.java
@@ -113,7 +113,7 @@
@Override
protected void onDragRelease() {
mBubblePinController.onDragEnd();
- mBubbleBarViewController.onDragRelease(bubbleView, mReleasedLocation);
+ mBubbleBarViewController.onDragRelease(mReleasedLocation);
}
@Override
diff --git a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayDragLayer.java b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayDragLayer.java
index 9c3e8af..773b0b9 100644
--- a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayDragLayer.java
+++ b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayDragLayer.java
@@ -30,7 +30,7 @@
import androidx.annotation.NonNull;
-import com.android.app.viewcapture.SettingsAwareViewCapture;
+import com.android.app.viewcapture.ViewCaptureFactory;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.testing.TestLogging;
import com.android.launcher3.testing.shared.TestProtocol;
@@ -59,7 +59,7 @@
protected void onAttachedToWindow() {
super.onAttachedToWindow();
getViewTreeObserver().addOnComputeInternalInsetsListener(this);
- mViewCaptureCloseable = SettingsAwareViewCapture.getInstance(getContext())
+ mViewCaptureCloseable = ViewCaptureFactory.getInstance(getContext())
.startCapture(getRootView(), ".TaskbarOverlay");
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
index 2eced74..14d391b 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
@@ -71,7 +71,7 @@
ADJACENT_PAGE_HORIZONTAL_OFFSET.set(mRecentsView, scaleAndOffset[1]);
TASK_SECONDARY_TRANSLATION.set(mRecentsView, 0f);
- getContentAlphaProperty().set(mRecentsView, state.overviewUi ? 1f : 0);
+ getContentAlphaProperty().set(mRecentsView, state.isRecentsViewVisible ? 1f : 0);
getTaskModalnessProperty().set(mRecentsView, state.getOverviewModalness());
RECENTS_GRID_PROGRESS.set(mRecentsView,
state.displayOverviewTasksAsGrid(mLauncher.getDeviceProfile()) ? 1f : 0f);
@@ -109,7 +109,8 @@
setter.setFloat(mRecentsView, TASK_SECONDARY_TRANSLATION, 0f,
config.getInterpolator(ANIM_OVERVIEW_TRANSLATE_Y, LINEAR));
- boolean exitingOverview = !FeatureFlags.enableSplitContextually() && !toState.overviewUi;
+ boolean exitingOverview =
+ !FeatureFlags.enableSplitContextually() && !toState.isRecentsViewVisible;
if (mRecentsView.isSplitSelectionActive() && exitingOverview) {
setter.add(mRecentsView.getSplitSelectController().getSplitAnimationController()
.createPlaceholderDismissAnim(mLauncher, LAUNCHER_SPLIT_SELECTION_EXIT_HOME,
@@ -124,7 +125,8 @@
);
}
- setter.setFloat(mRecentsView, getContentAlphaProperty(), toState.overviewUi ? 1 : 0,
+ setter.setFloat(mRecentsView, getContentAlphaProperty(),
+ toState.isRecentsViewVisible ? 1 : 0,
config.getInterpolator(ANIM_OVERVIEW_FADE, AGGRESSIVE_EASE_IN_OUT));
setter.setFloat(
@@ -145,7 +147,7 @@
private Interpolator getOverviewInterpolator(LauncherState fromState, LauncherState toState) {
return fromState == QUICK_SWITCH_FROM_HOME
? ACCELERATE_DECELERATE
- : toState.overviewUi ? INSTANT : FINAL_FRAME;
+ : toState.isRecentsViewVisible ? INSTANT : FINAL_FRAME;
}
abstract FloatProperty getTaskModalnessProperty();
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index b1bb198..69b0a71 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -103,7 +103,7 @@
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
-import com.android.app.viewcapture.SettingsAwareViewCapture;
+import com.android.app.viewcapture.ViewCaptureFactory;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Flags;
@@ -197,6 +197,8 @@
import com.android.systemui.unfold.progress.RemoteUnfoldTransitionReceiver;
import com.android.systemui.unfold.updates.RotationChangeProvider;
+import kotlin.Unit;
+
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -586,6 +588,7 @@
} else {
getStateManager().moveToRestState();
}
+ return Unit.INSTANCE;
});
} else {
getStateManager().goToState(NORMAL);
@@ -668,7 +671,7 @@
addMultiWindowModeChangedListener(mDepthController);
initUnfoldTransitionProgressProvider();
if (FeatureFlags.CONTINUOUS_VIEW_TREE_CAPTURE.get()) {
- mViewCapture = SettingsAwareViewCapture.getInstance(this).startCapture(getWindow());
+ mViewCapture = ViewCaptureFactory.getInstance(this).startCapture(getWindow());
}
getWindow().addPrivateFlags(PRIVATE_FLAG_OPTIMIZE_MEASURE);
QuickstepOnboardingPrefs.setup(this);
@@ -1477,4 +1480,9 @@
}
return super.onCreateView(parent, name, context, attrs);
}
+
+ @Override
+ public boolean isRecentsViewVisible() {
+ return getStateManager().getState().isRecentsViewVisible;
+ }
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
index 317e6f2..235ec7b 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
@@ -40,6 +40,7 @@
import com.android.launcher3.LauncherState;
import com.android.launcher3.Utilities;
+import com.android.launcher3.anim.AnimatedFloat;
import com.android.launcher3.anim.AnimatorListeners;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.anim.PropertySetter;
@@ -49,7 +50,6 @@
import com.android.quickstep.util.SplitAnimationTimings;
import com.android.quickstep.views.ClearAllButton;
import com.android.quickstep.views.LauncherRecentsView;
-import com.android.quickstep.views.OverviewActionsView;
import com.android.quickstep.views.RecentsView;
/**
@@ -67,7 +67,7 @@
@Override
public void setState(@NonNull LauncherState state) {
super.setState(state);
- if (state.overviewUi) {
+ if (state.isRecentsViewVisible) {
mRecentsView.updateEmptyMessage();
} else {
mRecentsView.resetTaskVisuals();
@@ -76,7 +76,7 @@
mRecentsView.setFullscreenProgress(state.getOverviewFullscreenProgress());
// In Overview, we may be layering app surfaces behind Launcher, so we need to notify
// DepthController to prevent optimizations which might occlude the layers behind
- mLauncher.getDepthController().setHasContentBehindLauncher(state.overviewUi);
+ mLauncher.getDepthController().setHasContentBehindLauncher(state.isRecentsViewVisible);
PendingAnimation builder =
new PendingAnimation(state.getTransitionDuration(mLauncher, true));
@@ -89,7 +89,7 @@
@NonNull StateAnimationConfig config, @NonNull PendingAnimation builder) {
super.setStateWithAnimationInternal(toState, config, builder);
- if (toState.overviewUi) {
+ if (toState.isRecentsViewVisible) {
// While animating into recents, update the visible task data as needed
builder.addOnFrameCallback(() -> mRecentsView.loadVisibleTaskData(FLAG_UPDATE_ALL));
mRecentsView.updateEmptyMessage();
@@ -107,7 +107,8 @@
// In Overview, we may be layering app surfaces behind Launcher, so we need to notify
// DepthController to prevent optimizations which might occlude the layers behind
builder.addListener(AnimatorListeners.forSuccessCallback(() ->
- mLauncher.getDepthController().setHasContentBehindLauncher(toState.overviewUi)));
+ mLauncher.getDepthController().setHasContentBehindLauncher(
+ toState.isRecentsViewVisible)));
handleSplitSelectionState(toState, builder, /* animate */true);
@@ -167,8 +168,8 @@
propertySetter.setFloat(mRecentsView.getClearAllButton(), ClearAllButton.VISIBILITY_ALPHA,
clearAllButtonAlpha, LINEAR);
float overviewButtonAlpha = state.areElementsVisible(mLauncher, OVERVIEW_ACTIONS) ? 1 : 0;
- propertySetter.setFloat(mLauncher.getActionsView().getVisibilityAlphaSetter(),
- OverviewActionsView.FLOAT_SETTER, overviewButtonAlpha, config.getInterpolator(
+ propertySetter.setFloat(mLauncher.getActionsView().getVisibilityAlpha(),
+ AnimatedFloat.VALUE, overviewButtonAlpha, config.getInterpolator(
ANIM_OVERVIEW_ACTIONS_FADE, LINEAR));
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/SystemApiWrapper.kt b/quickstep/src/com/android/launcher3/uioverrides/SystemApiWrapper.kt
index 535b4c2..146ff3d 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/SystemApiWrapper.kt
+++ b/quickstep/src/com/android/launcher3/uioverrides/SystemApiWrapper.kt
@@ -40,7 +40,7 @@
import com.android.quickstep.util.FadeOutRemoteTransition
/** A wrapper for the hidden API calls */
-class SystemApiWrapper(context: Context?) : ApiWrapper(context) {
+open class SystemApiWrapper(context: Context?) : ApiWrapper(context) {
override fun getPersons(si: ShortcutInfo) = si.persons ?: Utilities.EMPTY_PERSON_ARRAY
diff --git a/quickstep/src/com/android/launcher3/uioverrides/flags/DevOptionsUiHelper.kt b/quickstep/src/com/android/launcher3/uioverrides/flags/DevOptionsUiHelper.kt
index 3881e9a..dc6365b 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/flags/DevOptionsUiHelper.kt
+++ b/quickstep/src/com/android/launcher3/uioverrides/flags/DevOptionsUiHelper.kt
@@ -16,14 +16,28 @@
package com.android.launcher3.uioverrides.flags
+import android.app.PendingIntent
+import android.app.blob.BlobHandle.createWithSha256
+import android.app.blob.BlobStoreManager
import android.content.Context
+import android.content.IIntentReceiver
+import android.content.IIntentSender.Stub
import android.content.Intent
+import android.content.Intent.ACTION_CREATE_DOCUMENT
+import android.content.Intent.ACTION_OPEN_DOCUMENT
import android.content.pm.PackageManager
import android.net.Uri
+import android.os.Bundle
+import android.os.IBinder
+import android.os.ParcelFileDescriptor.AutoCloseOutputStream
import android.provider.DeviceConfig
import android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS
+import android.provider.Settings.Secure
import android.text.Html
import android.util.AttributeSet
+import android.util.Base64
+import android.util.Base64.NO_PADDING
+import android.util.Base64.NO_WRAP
import android.view.inputmethod.EditorInfo
import android.widget.TextView
import android.widget.Toast
@@ -33,11 +47,32 @@
import androidx.preference.PreferenceGroup
import androidx.preference.PreferenceViewHolder
import androidx.preference.SwitchPreference
+import com.android.launcher3.AutoInstallsLayout
import com.android.launcher3.ExtendedEditText
+import com.android.launcher3.LauncherAppState
import com.android.launcher3.LauncherPrefs
+import com.android.launcher3.LauncherSettings.Favorites.CONTAINER_DESKTOP
+import com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT
+import com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPLICATION
+import com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET
+import com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT
+import com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_FOLDER
+import com.android.launcher3.LauncherSettings.Settings.LAYOUT_DIGEST_KEY
+import com.android.launcher3.LauncherSettings.Settings.LAYOUT_DIGEST_LABEL
+import com.android.launcher3.LauncherSettings.Settings.LAYOUT_DIGEST_TAG
import com.android.launcher3.R
+import com.android.launcher3.model.data.FolderInfo
+import com.android.launcher3.model.data.ItemInfo
+import com.android.launcher3.model.data.LauncherAppWidgetInfo
+import com.android.launcher3.pm.UserCache
+import com.android.launcher3.proxy.ProxyActivityStarter
import com.android.launcher3.secondarydisplay.SecondaryDisplayLauncher
+import com.android.launcher3.shortcuts.ShortcutKey
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapperImpl
+import com.android.launcher3.util.Executors.MAIN_EXECUTOR
+import com.android.launcher3.util.Executors.MODEL_EXECUTOR
+import com.android.launcher3.util.Executors.ORDERED_BG_EXECUTOR
+import com.android.launcher3.util.LauncherLayoutBuilder
import com.android.launcher3.util.OnboardingPrefs.ALL_APPS_VISITED_COUNT
import com.android.launcher3.util.OnboardingPrefs.HOME_BOUNCE_COUNT
import com.android.launcher3.util.OnboardingPrefs.HOME_BOUNCE_SEEN
@@ -45,12 +80,17 @@
import com.android.launcher3.util.OnboardingPrefs.HOTSEAT_LONGPRESS_TIP_SEEN
import com.android.launcher3.util.OnboardingPrefs.TASKBAR_EDU_TOOLTIP_STEP
import com.android.launcher3.util.PluginManagerWrapper
+import com.android.launcher3.util.StartActivityParams
+import com.android.launcher3.util.UserIconInfo
import com.android.quickstep.util.DeviceConfigHelper
import com.android.quickstep.util.DeviceConfigHelper.Companion.NAMESPACE_LAUNCHER
import com.android.quickstep.util.DeviceConfigHelper.DebugInfo
import com.android.systemui.shared.plugins.PluginEnabler
import com.android.systemui.shared.plugins.PluginPrefs
+import java.io.OutputStreamWriter
+import java.security.MessageDigest
import java.util.Locale
+import java.util.concurrent.Executor
/** Helper class to generate UI for Device Config */
class DevOptionsUiHelper(c: Context, attr: AttributeSet?) : PreferenceGroup(c, attr) {
@@ -67,6 +107,9 @@
(holder.findViewById(R.id.filter_box) as TextView?)?.doAfterTextChanged {
val query: String = it.toString().lowercase(Locale.getDefault()).replace("_", " ")
filterPreferences(query, this)
+
+ // Always keep myself visible
+ this@DevOptionsUiHelper.isVisible = true
}
}
@@ -97,6 +140,7 @@
}
addIntentTargets()
addOnboardingPrefsCategory()
+ addLayoutSharePref()
}
private fun newCategory(titleText: String, subTitleText: String? = null) =
@@ -359,7 +403,7 @@
Preference(context).also {
it.title = title
it.summary = "Tap to reset"
- setOnPreferenceClickListener { _ ->
+ it.setOnPreferenceClickListener { _ ->
LauncherPrefs.getPrefs(context)
.edit()
.apply { keys.forEach { key -> remove(key) } }
@@ -370,6 +414,137 @@
}
)
+ private fun addLayoutSharePref() {
+ val model = LauncherAppState.getInstance(context).model
+ val category = newCategory("Workspace grid layout")
+ Preference(context).apply {
+ title = "Export"
+ intent =
+ createUriPickerIntent(ACTION_CREATE_DOCUMENT, MAIN_EXECUTOR) { uri ->
+ model.enqueueModelUpdateTask { _, dataModel, _ ->
+ val builder = LauncherLayoutBuilder()
+ dataModel.workspaceItems.forEach { info ->
+ val loc =
+ when (info.container) {
+ CONTAINER_DESKTOP ->
+ builder.atWorkspace(info.cellX, info.cellY, info.screenId)
+ CONTAINER_HOTSEAT -> builder.atHotseat(info.screenId)
+ else -> return@forEach
+ }
+ loc.addItem(info)
+ }
+ dataModel.appWidgets.forEach { info ->
+ builder.atWorkspace(info.cellX, info.cellY, info.screenId).addItem(info)
+ }
+
+ context.contentResolver.openOutputStream(uri).use { os ->
+ builder.build(OutputStreamWriter(os))
+ }
+
+ MAIN_EXECUTOR.execute {
+ Toast.makeText(context, "File saved", Toast.LENGTH_LONG).show()
+ }
+ }
+ }
+ category.addPreference(this)
+ }
+
+ Preference(context).apply {
+ title = "Import"
+ intent =
+ createUriPickerIntent(ACTION_OPEN_DOCUMENT, ORDERED_BG_EXECUTOR) { uri ->
+ val resolver = context.contentResolver
+ val data =
+ resolver.openInputStream(uri).use { stream ->
+ stream?.readAllBytes() ?: return@createUriPickerIntent
+ }
+
+ val digest = MessageDigest.getInstance("SHA-256").digest(data)
+ val handle = createWithSha256(digest, LAYOUT_DIGEST_LABEL, 0, LAYOUT_DIGEST_TAG)
+ val blobManager = context.getSystemService(BlobStoreManager::class.java)!!
+
+ blobManager.openSession(blobManager.createSession(handle)).use { session ->
+ AutoCloseOutputStream(session.openWrite(0, -1)).use { it.write(data) }
+ session.allowPublicAccess()
+
+ session.commit(ORDERED_BG_EXECUTOR) {
+ val key = Base64.encodeToString(digest, NO_WRAP or NO_PADDING)
+ Secure.putString(resolver, LAYOUT_DIGEST_KEY, key)
+
+ MODEL_EXECUTOR.submit { model.modelDbController.createEmptyDB() }.get()
+ MAIN_EXECUTOR.submit { model.forceReload() }.get()
+ MODEL_EXECUTOR.submit {}.get()
+ Secure.putString(resolver, LAYOUT_DIGEST_KEY, null)
+ }
+ }
+ }
+ category.addPreference(this)
+ }
+ }
+
+ private fun LauncherLayoutBuilder.ItemTarget.addItem(info: ItemInfo) {
+ val userType: String? =
+ when (UserCache.INSTANCE.get(context).getUserInfo(info.user).type) {
+ UserIconInfo.TYPE_WORK -> AutoInstallsLayout.USER_TYPE_WORK
+ UserIconInfo.TYPE_CLONED -> AutoInstallsLayout.USER_TYPE_CLONED
+ else -> null
+ }
+ when (info.itemType) {
+ ITEM_TYPE_APPLICATION ->
+ info.targetComponent?.let { c -> putApp(c.packageName, c.className, userType) }
+ ITEM_TYPE_DEEP_SHORTCUT ->
+ ShortcutKey.fromItemInfo(info).let { key ->
+ putShortcut(key.packageName, key.id, userType)
+ }
+ ITEM_TYPE_FOLDER ->
+ (info as FolderInfo).let { folderInfo ->
+ putFolder(folderInfo.title?.toString() ?: "").also { folderBuilder ->
+ folderInfo.getContents().forEach { folderContent ->
+ folderBuilder.addItem(folderContent)
+ }
+ }
+ }
+ ITEM_TYPE_APPWIDGET ->
+ putWidget(
+ (info as LauncherAppWidgetInfo).providerName.packageName,
+ info.providerName.className,
+ info.spanX,
+ info.spanY,
+ userType
+ )
+ }
+ }
+
+ private fun createUriPickerIntent(
+ action: String,
+ executor: Executor,
+ callback: (uri: Uri) -> Unit
+ ): Intent {
+ val pendingIntent =
+ PendingIntent(
+ object : Stub() {
+ override fun send(
+ code: Int,
+ intent: Intent,
+ resolvedType: String?,
+ allowlistToken: IBinder?,
+ finishedReceiver: IIntentReceiver?,
+ requiredPermission: String?,
+ options: Bundle?
+ ) {
+ intent.data?.let { uri -> executor.execute { callback(uri) } }
+ }
+ }
+ )
+ val params = StartActivityParams(pendingIntent, 0)
+ params.intent =
+ Intent(action)
+ .addCategory(Intent.CATEGORY_OPENABLE)
+ .setType("text/xml")
+ .putExtra(Intent.EXTRA_TITLE, "launcher_grid.xml")
+ return ProxyActivityStarter.getLaunchIntent(context, params)
+ }
+
private inner class CustomSwitchPref(
private val bindCallback: (holder: PreferenceViewHolder, pref: SwitchPreference) -> Unit
) : SwitchPreference(context) {
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java b/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java
index 7fa121d..2625646 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java
@@ -34,7 +34,7 @@
*/
public class BackgroundAppState extends OverviewState {
- private static final int STATE_FLAGS = FLAG_DISABLE_RESTORE | FLAG_OVERVIEW_UI
+ private static final int STATE_FLAGS = FLAG_DISABLE_RESTORE | FLAG_RECENTS_VIEW_VISIBLE
| FLAG_WORKSPACE_INACCESSIBLE | FLAG_NON_INTERACTIVE | FLAG_CLOSE_POPUPS;
public BackgroundAppState(int id) {
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java
index 3c291e6..932d241 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java
@@ -32,7 +32,7 @@
public class OverviewModalTaskState extends OverviewState {
private static final int STATE_FLAGS =
- FLAG_DISABLE_RESTORE | FLAG_OVERVIEW_UI | FLAG_WORKSPACE_INACCESSIBLE;
+ FLAG_DISABLE_RESTORE | FLAG_RECENTS_VIEW_VISIBLE | FLAG_WORKSPACE_INACCESSIBLE;
public OverviewModalTaskState(int id) {
super(id, LAUNCHER_STATE_OVERVIEW, STATE_FLAGS);
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java
index d0eef8e..7173298 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java
@@ -47,7 +47,7 @@
protected static final Rect sTempRect = new Rect();
private static final int STATE_FLAGS = FLAG_WORKSPACE_ICONS_CAN_BE_DRAGGED
- | FLAG_DISABLE_RESTORE | FLAG_OVERVIEW_UI | FLAG_WORKSPACE_INACCESSIBLE
+ | FLAG_DISABLE_RESTORE | FLAG_RECENTS_VIEW_VISIBLE | FLAG_WORKSPACE_INACCESSIBLE
| FLAG_CLOSE_POPUPS;
public OverviewState(int id) {
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java
index 3ed2d0b..11e0ed5 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java
@@ -118,7 +118,7 @@
if (!cameFromNavBar) {
return false;
}
- if (mStartState.overviewUi || mStartState == ALL_APPS) {
+ if (mStartState.isRecentsViewVisible || mStartState == ALL_APPS) {
return true;
}
int typeToClose = TYPE_ALL & ~TYPE_ALL_APPS_EDU;
@@ -145,7 +145,7 @@
private void initCurrentAnimation() {
long accuracy = (long) (getShiftRange() * 2);
final PendingAnimation builder = new PendingAnimation(accuracy);
- if (mStartState.overviewUi) {
+ if (mStartState.isRecentsViewVisible) {
RecentsView recentsView = mLauncher.getOverviewPanel();
AnimatorControllerWithResistance.createRecentsResistanceFromOverviewAnim(mLauncher,
builder);
@@ -194,7 +194,7 @@
RecentsView recentsView = mLauncher.getOverviewPanel();
recentsView.switchToScreenshot(null,
() -> recentsView.finishRecentsAnimation(true /* toRecents */, null));
- if (mStartState.overviewUi) {
+ if (mStartState.isRecentsViewVisible) {
Runnable onReachedHome = () -> {
StateManager.StateListener<LauncherState> listener =
new StateManager.StateListener<>() {
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java
index 42be52f..3325009 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java
@@ -249,7 +249,7 @@
}
private boolean handlingOverviewAnim() {
- int stateFlags = SystemUiProxy.INSTANCE.get(mLauncher).getLastSystemUiStateFlags();
+ long stateFlags = SystemUiProxy.INSTANCE.get(mLauncher).getLastSystemUiStateFlags();
return mDidTouchStartInNavBar && mStartState == NORMAL
&& (stateFlags & SYSUI_STATE_OVERVIEW_DISABLED) == 0;
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
index fc0df76..ab277b6 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
@@ -172,7 +172,7 @@
if ((ev.getEdgeFlags() & Utilities.EDGE_NAV_BAR) == 0) {
return false;
}
- int stateFlags = SystemUiProxy.INSTANCE.get(mLauncher).getLastSystemUiStateFlags();
+ long stateFlags = SystemUiProxy.INSTANCE.get(mLauncher).getLastSystemUiStateFlags();
if ((stateFlags & SYSUI_STATE_OVERVIEW_DISABLED) != 0) {
return false;
}
@@ -248,7 +248,7 @@
TASK_THUMBNAIL_SPLASH_ALPHA.set(mRecentsView, fromState.showTaskThumbnailSplash() ? 1f : 0);
mRecentsView.setContentAlpha(1);
mRecentsView.setFullscreenProgress(fromState.getOverviewFullscreenProgress());
- mLauncher.getActionsView().getVisibilityAlphaSetter().accept(
+ mLauncher.getActionsView().getVisibilityAlpha().updateValue(
(fromState.getVisibleElements(mLauncher) & OVERVIEW_ACTIONS) != 0 ? 1f : 0f);
mRecentsView.setTaskIconScaledDown(true);
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
index 16185f5..1a98db1 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
@@ -84,7 +84,7 @@
@Override
protected LauncherState getTargetState(LauncherState fromState, boolean isDragTowardPositive) {
- int stateFlags = SystemUiProxy.INSTANCE.get(mLauncher).getLastSystemUiStateFlags();
+ long stateFlags = SystemUiProxy.INSTANCE.get(mLauncher).getLastSystemUiStateFlags();
if ((stateFlags & SYSUI_STATE_OVERVIEW_DISABLED) != 0) {
return NORMAL;
}
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index 28ae3d2..10e327d 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -152,6 +152,8 @@
import com.android.wm.shell.common.TransactionPool;
import com.android.wm.shell.startingsurface.SplashScreenExitAnimationUtils;
+import kotlin.Unit;
+
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@@ -1173,12 +1175,6 @@
mStateCallback.setState(STATE_SCALED_CONTROLLER_HOME | STATE_CAPTURE_SCREENSHOT);
// Notify the SysUI to use fade-in animation when entering PiP
SystemUiProxy.INSTANCE.get(mContext).setPipAnimationTypeToAlpha();
- DesktopVisibilityController desktopVisibilityController =
- mContainerInterface.getDesktopVisibilityController();
- if (desktopVisibilityController != null) {
- // Notify the SysUI to stash desktop apps if they are visible
- desktopVisibilityController.onHomeActionTriggered();
- }
break;
case RECENTS:
mStateCallback.setState(STATE_SCALED_CONTROLLER_RECENTS | STATE_CAPTURE_SCREENSHOT
@@ -1474,7 +1470,8 @@
default:
event = IGNORE;
}
- StatsLogger logger = StatsLogManager.newInstance(mContext).logger()
+ StatsLogger logger = StatsLogManager.newInstance(
+ mContainer != null ? mContainer.asContext() : mContext).logger()
.withSrcState(LAUNCHER_STATE_BACKGROUND)
.withDstState(endTarget.containerType)
.withInputType(mGestureState.isTrackpadGesture()
@@ -2337,6 +2334,7 @@
mRecentsAnimationController.finish(true /* toRecents */, null);
}
}
+ return Unit.INSTANCE;
}, true /* freezeTaskList */);
} else {
mContainerInterface.onLaunchTaskFailed();
diff --git a/quickstep/src/com/android/quickstep/DesktopModeStatus.java b/quickstep/src/com/android/quickstep/DesktopModeStatus.java
deleted file mode 100644
index b1aae16..0000000
--- a/quickstep/src/com/android/quickstep/DesktopModeStatus.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2024 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.quickstep;
-
-import android.content.Context;
-import android.os.SystemProperties;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.window.flags.Flags;
-
-// TODO(b/335401172): Explore unifying logic across core and shell
-public class DesktopModeStatus {
-
- /**
- * Flag to indicate whether to restrict desktop mode to supported devices.
- */
- private static final boolean ENFORCE_DEVICE_RESTRICTIONS = SystemProperties.getBoolean(
- "persist.wm.debug.desktop_mode_enforce_device_restrictions", true);
-
- /**
- * Return {@code true} if desktop mode should be restricted to supported devices.
- */
- @VisibleForTesting
- public static boolean enforceDeviceRestrictions() {
- return ENFORCE_DEVICE_RESTRICTIONS;
- }
-
- /**
- * Return {@code true} if the current device supports desktop mode.
- */
- @VisibleForTesting
- public static boolean isDesktopModeSupported(Context context) {
- return context.getResources().getBoolean(
- com.android.internal.R.bool.config_isDesktopModeSupported);
- }
-
- /**
- * Return {@code true} if desktop mode can be entered on the current device.
- */
- public static boolean canEnterDesktopMode(Context context) {
- return Flags.enableDesktopWindowingMode()
- && (!enforceDeviceRestrictions() || isDesktopModeSupported(context));
- }
-}
diff --git a/quickstep/src/com/android/quickstep/DesktopSystemShortcut.kt b/quickstep/src/com/android/quickstep/DesktopSystemShortcut.kt
index e33ef7f..fdf4574 100644
--- a/quickstep/src/com/android/quickstep/DesktopSystemShortcut.kt
+++ b/quickstep/src/com/android/quickstep/DesktopSystemShortcut.kt
@@ -24,6 +24,7 @@
import com.android.quickstep.views.RecentsView
import com.android.quickstep.views.RecentsViewContainer
import com.android.quickstep.views.TaskView.TaskContainer
+import com.android.wm.shell.shared.DesktopModeStatus
/** A menu item, "Desktop", that allows the user to bring the current app into Desktop Windowing. */
class DesktopSystemShortcut(
diff --git a/quickstep/src/com/android/quickstep/DeviceConfigWrapper.kt b/quickstep/src/com/android/quickstep/DeviceConfigWrapper.kt
index 0f844e1..3549a12 100644
--- a/quickstep/src/com/android/quickstep/DeviceConfigWrapper.kt
+++ b/quickstep/src/com/android/quickstep/DeviceConfigWrapper.kt
@@ -37,6 +37,13 @@
"Server side control to customize LPH timeout and touch slop"
)
+ val customLpaaThresholds =
+ propReader.get(
+ "CUSTOM_LPAA_THRESHOLDS",
+ false,
+ "Server side control to customize LPAA timeout and touch slop"
+ )
+
val overrideLpnhLphThresholds =
propReader.get(
"OVERRIDE_LPNH_LPH_THRESHOLDS",
diff --git a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
index 7655c59..811b9fd 100644
--- a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
@@ -192,7 +192,7 @@
public RecentsView getVisibleRecentsView() {
QuickstepLauncher launcher = getVisibleLauncher();
RecentsView recentsView =
- launcher != null && launcher.getStateManager().getState().overviewUi
+ launcher != null && launcher.getStateManager().getState().isRecentsViewVisible
? launcher.getOverviewPanel() : null;
if (recentsView == null || (!launcher.hasBeenResumed()
&& recentsView.getRunningTaskViewId() == -1)) {
diff --git a/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java b/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
index 6a9f509..080e03a 100644
--- a/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
+++ b/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
@@ -304,9 +304,7 @@
// Disable if swiping to PIP
return null;
}
- if (sourceTaskView == null
- || sourceTaskView.getFirstTask() == null
- || sourceTaskView.getFirstTask().key.getComponent() == null) {
+ if (sourceTaskView == null || sourceTaskView.getFirstTask().key.getComponent() == null) {
// Disable if it's an invalid task
return null;
}
diff --git a/quickstep/src/com/android/quickstep/OverviewCommandHelper.java b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
index 68923ee..3091e3d 100644
--- a/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
+++ b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
@@ -16,6 +16,9 @@
package com.android.quickstep;
import static com.android.launcher3.PagedView.INVALID_PAGE;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_OVERVIEW_SHOW_OVERVIEW_FROM_3_BUTTON;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_OVERVIEW_SHOW_OVERVIEW_FROM_KEYBOARD_QUICK_SWITCH;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_OVERVIEW_SHOW_OVERVIEW_FROM_KEYBOARD_SHORTCUT;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.quickstep.util.ActiveGestureLog.INTENT_EXTRA_LOG_TRACE_ID;
@@ -34,6 +37,8 @@
import com.android.internal.jank.Cuj;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.logger.LauncherAtom;
+import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.statemanager.StatefulActivity;
import com.android.launcher3.taskbar.TaskbarUIController;
import com.android.launcher3.util.RunnableList;
@@ -171,7 +176,7 @@
RunnableList callbackList = null;
if (taskView != null) {
mWaitForToggleCommandComplete = true;
- taskView.setEndQuickswitchCuj(true);
+ taskView.setEndQuickSwitchCuj(true);
callbackList = taskView.launchTasks();
}
@@ -285,6 +290,7 @@
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
updateRecentsViewFocus(cmd);
+ logShowOverviewFrom(cmd.type);
}
@Override
public void onAnimationEnd(Animator animation) {
@@ -319,6 +325,7 @@
public void onRecentsAnimationStart(RecentsAnimationController controller,
RecentsAnimationTargets targets) {
updateRecentsViewFocus(cmd);
+ logShowOverviewFrom(cmd.type);
activityInterface.runOnInitBackgroundStateUI(() ->
interactionHandler.onGestureEnded(0, new PointF()));
cmd.removeListener(this);
@@ -420,6 +427,33 @@
return true;
}
+ private <T extends StatefulActivity<?> & RecentsViewContainer>
+ void logShowOverviewFrom(int cmdType) {
+ BaseActivityInterface<?, T> activityInterface =
+ mOverviewComponentObserver.getActivityInterface();
+ var container = activityInterface.getCreatedContainer();
+ if (container != null) {
+ StatsLogManager.LauncherEvent event;
+ switch (cmdType) {
+ case TYPE_SHOW -> event = LAUNCHER_OVERVIEW_SHOW_OVERVIEW_FROM_KEYBOARD_SHORTCUT;
+ case TYPE_HIDE ->
+ event = LAUNCHER_OVERVIEW_SHOW_OVERVIEW_FROM_KEYBOARD_QUICK_SWITCH;
+ case TYPE_TOGGLE -> event = LAUNCHER_OVERVIEW_SHOW_OVERVIEW_FROM_3_BUTTON;
+ default -> {
+ return;
+ }
+ }
+
+ StatsLogManager.newInstance(container.asContext())
+ .logger()
+ .withContainerInfo(LauncherAtom.ContainerInfo.newBuilder()
+ .setTaskSwitcherContainer(
+ LauncherAtom.TaskSwitcherContainer.getDefaultInstance())
+ .build())
+ .log(event);
+ }
+ }
+
public void dump(PrintWriter pw) {
pw.println("OverviewCommandHelper:");
pw.println(" mPendingCommands=" + mPendingCommands.size());
diff --git a/quickstep/src/com/android/quickstep/RecentsActivity.java b/quickstep/src/com/android/quickstep/RecentsActivity.java
index f57f4c8..97a0b3f 100644
--- a/quickstep/src/com/android/quickstep/RecentsActivity.java
+++ b/quickstep/src/com/android/quickstep/RecentsActivity.java
@@ -33,7 +33,6 @@
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.app.ActivityOptions;
-import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
@@ -507,4 +506,9 @@
public TISBindHelper getTISBindHelper() {
return mTISBindHelper;
}
+
+ @Override
+ public boolean isRecentsViewVisible() {
+ return getStateManager().getState().isRecentsViewVisible();
+ }
}
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
index 54466f3..34b50ca 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
@@ -91,7 +91,7 @@
static final String SUPPORT_ONE_HANDED_MODE = "ro.support_one_handed_mode";
// TODO: Move to quickstep contract
- private static final float QUICKSTEP_TOUCH_SLOP_RATIO_TWO_BUTTON = 3f;
+ public static final float QUICKSTEP_TOUCH_SLOP_RATIO_TWO_BUTTON = 3f;
private static final float QUICKSTEP_TOUCH_SLOP_RATIO_GESTURAL = 1.414f;
private final Context mContext;
@@ -108,7 +108,7 @@
private final ArrayList<Runnable> mOnDestroyActions = new ArrayList<>();
- private @SystemUiStateFlags int mSystemUiStateFlags = QuickStepContract.SYSUI_STATE_AWAKE;
+ private @SystemUiStateFlags long mSystemUiStateFlags = QuickStepContract.SYSUI_STATE_AWAKE;
private NavigationMode mMode = THREE_BUTTONS;
private NavBarPosition mNavBarPosition;
@@ -352,7 +352,7 @@
/**
* Updates the system ui state flags from SystemUI.
*/
- public void setSystemUiFlags(int stateFlags) {
+ public void setSystemUiFlags(@SystemUiStateFlags long stateFlags) {
mSystemUiStateFlags = stateFlags;
}
@@ -360,7 +360,8 @@
* @return the system ui state flags.
*/
// TODO(141886704): See if we can remove this
- public int getSystemUiStateFlags() {
+ @SystemUiStateFlags
+ public long getSystemUiStateFlags() {
return mSystemUiStateFlags;
}
@@ -609,6 +610,16 @@
return touchSlop * touchSlop;
}
+ /**
+ * Returns the squared touch slop using the given base slop multiplier {@code slopMultiplier}
+ * and custom slop multiplier {@code customSlopMultiplier}.
+ */
+ public float getSquaredTouchSlop(float slopMultiplier, float customSlopMultiplier) {
+ float systemTouchSlop = ViewConfiguration.get(mContext).getScaledTouchSlop();
+ float touchSlop = customSlopMultiplier * slopMultiplier * systemTouchSlop;
+ return touchSlop * touchSlop;
+ }
+
public String getSystemUiStateString() {
return QuickStepContract.getSystemUiStateString(mSystemUiStateFlags);
}
diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java
index 4d3fe41..da1d322 100644
--- a/quickstep/src/com/android/quickstep/SystemUiProxy.java
+++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java
@@ -72,6 +72,7 @@
import com.android.quickstep.util.unfold.ProxyUnfoldTransitionProvider;
import com.android.systemui.shared.recents.ISystemUiProxy;
import com.android.systemui.shared.recents.model.ThumbnailData;
+import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags;
import com.android.systemui.shared.system.RecentsAnimationControllerCompat;
import com.android.systemui.shared.system.RecentsAnimationListener;
import com.android.systemui.shared.system.smartspace.ILauncherUnlockAnimationController;
@@ -172,7 +173,8 @@
private final Handler mAsyncHandler;
// TODO(141886704): Find a way to remove this
- private int mLastSystemUiStateFlags;
+ @SystemUiStateFlags
+ private long mLastSystemUiStateFlags;
/**
* This is a singleton pending intent that is used to start recents via Shell (which is a
@@ -324,12 +326,13 @@
}
// TODO(141886704): Find a way to remove this
- public void setLastSystemUiStateFlags(int stateFlags) {
+ public void setLastSystemUiStateFlags(@SystemUiStateFlags long stateFlags) {
mLastSystemUiStateFlags = stateFlags;
}
// TODO(141886704): Find a way to remove this
- public int getLastSystemUiStateFlags() {
+ @SystemUiStateFlags
+ public long getLastSystemUiStateFlags() {
return mLastSystemUiStateFlags;
}
@@ -575,6 +578,17 @@
}
}
+ @Override
+ public void toggleQuickSettingsPanel() {
+ if (mSystemUiProxy != null) {
+ try {
+ mSystemUiProxy.toggleQuickSettingsPanel();
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed call toggleQuickSettingsPanel", e);
+ }
+ }
+ }
+
//
// Pip
//
@@ -760,19 +774,6 @@
}
/**
- * Tells SysUI to remove the bubble with the provided key.
- * @param key the key of the bubble to show.
- */
- public void removeBubble(String key) {
- if (mBubbles == null) return;
- try {
- mBubbles.removeBubble(key);
- } catch (RemoteException e) {
- Log.w(TAG, "Failed call removeBubble");
- }
- }
-
- /**
* Tells SysUI to remove all bubbles.
*/
public void removeAllBubbles() {
@@ -814,19 +815,31 @@
/**
* Tells SysUI when the bubble stops being dragged.
* Should be called only when the bubble bar is expanded.
- * @param bubbleKey key of the bubble being dragged
* @param location location of the bubble bar
*/
- public void stopBubbleDrag(@Nullable String bubbleKey, BubbleBarLocation location) {
+ public void stopBubbleDrag(BubbleBarLocation location) {
if (mBubbles == null) return;
try {
- mBubbles.stopBubbleDrag(bubbleKey, location);
+ mBubbles.stopBubbleDrag(location);
} catch (RemoteException e) {
Log.w(TAG, "Failed call stopBubbleDrag");
}
}
/**
+ * Tells SysUI to dismiss the bubble with the provided key.
+ * @param key the key of the bubble to dismiss.
+ */
+ public void dragBubbleToDismiss(String key) {
+ if (mBubbles == null) return;
+ try {
+ mBubbles.dragBubbleToDismiss(key);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed call dragBubbleToDismiss");
+ }
+ }
+
+ /**
* Tells SysUI to show user education relative to the reference point provided.
* @param position the bubble bar top center position in Screen coordinates.
*/
@@ -1429,28 +1442,6 @@
}
}
- /** Call shell to stash desktop apps */
- public void stashDesktopApps(int displayId) {
- if (mDesktopMode != null) {
- try {
- mDesktopMode.stashDesktopApps(displayId);
- } catch (RemoteException e) {
- Log.w(TAG, "Failed call stashDesktopApps", e);
- }
- }
- }
-
- /** Call shell to hide desktop apps that may be stashed */
- public void hideStashedDesktopApps(int displayId) {
- if (mDesktopMode != null) {
- try {
- mDesktopMode.hideStashedDesktopApps(displayId);
- } catch (RemoteException e) {
- Log.w(TAG, "Failed call hideStashedDesktopApps", e);
- }
- }
- }
-
/**
* If task with the given id is on the desktop, bring it to front
*/
diff --git a/quickstep/src/com/android/quickstep/TaskShortcutFactory.java b/quickstep/src/com/android/quickstep/TaskShortcutFactory.java
index a53d91f..537f432 100644
--- a/quickstep/src/com/android/quickstep/TaskShortcutFactory.java
+++ b/quickstep/src/com/android/quickstep/TaskShortcutFactory.java
@@ -42,10 +42,8 @@
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Flags;
import com.android.launcher3.R;
-import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.logging.StatsLogManager.LauncherEvent;
import com.android.launcher3.model.WellbeingModel;
-import com.android.launcher3.model.data.ItemInfoWithIcon;
import com.android.launcher3.popup.SystemShortcut;
import com.android.launcher3.popup.SystemShortcut.AppInfo;
import com.android.launcher3.util.InstantAppResolver;
@@ -463,8 +461,7 @@
boolean isGridOnlyOverview = isTablet && Flags.enableGridOnlyOverview();
// Extra conditions if it's not grid-only overview
if (!isGridOnlyOverview) {
- RecentsOrientedState orientedState =
- taskContainer.getTaskView().getRecentsView().getPagedViewOrientedState();
+ RecentsOrientedState orientedState = taskContainer.getTaskView().getOrientedState();
boolean isFakeLandscape = !orientedState.isRecentsActivityRotationAllowed()
&& orientedState.getTouchRotation() != ROTATION_0;
if (!isFakeLandscape) {
@@ -493,8 +490,7 @@
boolean isGridOnlyOverview = isTablet && Flags.enableGridOnlyOverview();
// Extra conditions if it's not grid-only overview
if (!isGridOnlyOverview) {
- RecentsOrientedState orientedState =
- taskContainer.getTaskView().getRecentsView().getPagedViewOrientedState();
+ RecentsOrientedState orientedState = taskContainer.getTaskView().getOrientedState();
boolean isFakeLandscape = !orientedState.isRecentsActivityRotationAllowed()
&& orientedState.getTouchRotation() != ROTATION_0;
if (!isFakeLandscape) {
diff --git a/quickstep/src/com/android/quickstep/TaskThumbnailCache.java b/quickstep/src/com/android/quickstep/TaskThumbnailCache.java
index b7cbb47..7ebb767 100644
--- a/quickstep/src/com/android/quickstep/TaskThumbnailCache.java
+++ b/quickstep/src/com/android/quickstep/TaskThumbnailCache.java
@@ -148,12 +148,12 @@
* @param callback The callback to receive the task after its data has been populated.
* @return A cancelable handle to the request
*/
- public CancellableTask updateThumbnailInBackground(
+ public CancellableTask<ThumbnailData> updateThumbnailInBackground(
Task task, Consumer<ThumbnailData> callback) {
Preconditions.assertUIThread();
boolean lowResolution = !mHighResLoadingState.isEnabled();
- if (task.thumbnail != null && task.thumbnail.thumbnail != null
+ if (task.thumbnail != null && task.thumbnail.getThumbnail() != null
&& (!task.thumbnail.reducedResolution || lowResolution)) {
// Nothing to load, the thumbnail is already high-resolution or matches what the
// request, so just callback
@@ -184,12 +184,12 @@
return newSize > oldSize;
}
- private CancellableTask updateThumbnailInBackground(TaskKey key, boolean lowResolution,
- Consumer<ThumbnailData> callback) {
+ private CancellableTask<ThumbnailData> updateThumbnailInBackground(TaskKey key,
+ boolean lowResolution, Consumer<ThumbnailData> callback) {
Preconditions.assertUIThread();
ThumbnailData cachedThumbnail = mCache.getAndInvalidateIfModified(key);
- if (cachedThumbnail != null && cachedThumbnail.thumbnail != null
+ if (cachedThumbnail != null && cachedThumbnail.getThumbnail() != null
&& (!cachedThumbnail.reducedResolution || lowResolution)) {
// Already cached, lets use that thumbnail
callback.accept(cachedThumbnail);
@@ -200,7 +200,7 @@
() -> {
ThumbnailData thumbnailData = ActivityManagerWrapper.getInstance()
.getTaskThumbnail(key.id, lowResolution);
- return thumbnailData.thumbnail != null ? thumbnailData
+ return thumbnailData.getThumbnail() != null ? thumbnailData
: ActivityManagerWrapper.getInstance().takeTaskThumbnail(key.id);
},
MAIN_EXECUTOR,
@@ -210,7 +210,7 @@
if (enableGridOnlyOverview() && result.reducedResolution
&& getHighResLoadingState().isEnabled()) {
ThumbnailData newCachedThumbnail = mCache.getAndInvalidateIfModified(key);
- if (newCachedThumbnail != null && newCachedThumbnail.thumbnail != null
+ if (newCachedThumbnail != null && newCachedThumbnail.getThumbnail() != null
&& !newCachedThumbnail.reducedResolution) {
return;
}
diff --git a/quickstep/src/com/android/quickstep/TaskViewUtils.java b/quickstep/src/com/android/quickstep/TaskViewUtils.java
index d2560e6..ecd84f8 100644
--- a/quickstep/src/com/android/quickstep/TaskViewUtils.java
+++ b/quickstep/src/com/android/quickstep/TaskViewUtils.java
@@ -165,8 +165,8 @@
@NonNull RemoteAnimationTarget[] nonAppTargets,
@Nullable DepthController depthController,
PendingAnimation out) {
- boolean isQuickSwitch = v.isEndQuickswitchCuj();
- v.setEndQuickswitchCuj(false);
+ boolean isQuickSwitch = v.isEndQuickSwitchCuj();
+ v.setEndQuickSwitchCuj(false);
final RemoteAnimationTargets targets =
new RemoteAnimationTargets(appTargets, wallpaperTargets, nonAppTargets,
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index f94a29c..4599f18 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -129,6 +129,7 @@
import com.android.systemui.shared.system.InputChannelCompat.InputEventReceiver;
import com.android.systemui.shared.system.InputConsumerController;
import com.android.systemui.shared.system.InputMonitorCompat;
+import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags;
import com.android.systemui.shared.system.smartspace.ISysuiUnlockAnimationController;
import com.android.systemui.unfold.progress.IUnfoldAnimation;
import com.android.wm.shell.back.IBackAnimation;
@@ -301,9 +302,9 @@
}
@BinderThread
- public void onSystemUiStateChanged(int stateFlags) {
+ public void onSystemUiStateChanged(@SystemUiStateFlags long stateFlags) {
MAIN_EXECUTOR.execute(() -> executeForTouchInteractionService(tis -> {
- int lastFlags = tis.mDeviceState.getSystemUiStateFlags();
+ long lastFlags = tis.mDeviceState.getSystemUiStateFlags();
tis.mDeviceState.setSystemUiFlags(stateFlags);
tis.onSystemUiFlagsChanged(lastFlags);
}));
@@ -636,14 +637,14 @@
}
@UiThread
- private void onSystemUiFlagsChanged(int lastSysUIFlags) {
+ private void onSystemUiFlagsChanged(@SystemUiStateFlags long lastSysUIFlags) {
if (LockedUserState.get(this).isUserUnlocked()) {
- int systemUiStateFlags = mDeviceState.getSystemUiStateFlags();
+ long systemUiStateFlags = mDeviceState.getSystemUiStateFlags();
SystemUiProxy.INSTANCE.get(this).setLastSystemUiStateFlags(systemUiStateFlags);
mOverviewComponentObserver.onSystemUiStateChanged();
mTaskbarManager.onSystemUiFlagsChanged(systemUiStateFlags);
- int isShadeExpandedFlag =
+ long isShadeExpandedFlag =
SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED | SYSUI_STATE_QUICK_SETTINGS_EXPANDED;
boolean wasExpanded = (lastSysUIFlags & isShadeExpandedFlag) != 0;
boolean isExpanded = (systemUiStateFlags & isShadeExpandedFlag) != 0;
diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java
index 1bf129c..94764a5 100644
--- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java
+++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java
@@ -42,13 +42,13 @@
import androidx.annotation.NonNull;
+import com.android.launcher3.anim.AnimatedFloat;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.anim.PropertySetter;
import com.android.launcher3.statemanager.StateManager.StateHandler;
import com.android.launcher3.states.StateAnimationConfig;
import com.android.quickstep.RecentsActivity;
import com.android.quickstep.views.ClearAllButton;
-import com.android.quickstep.views.OverviewActionsView;
import com.android.quickstep.views.RecentsView;
/**
@@ -96,8 +96,8 @@
setter.setFloat(mRecentsView.getClearAllButton(), ClearAllButton.VISIBILITY_ALPHA,
clearAllButtonAlpha, LINEAR);
float overviewButtonAlpha = state.hasOverviewActions() ? 1 : 0;
- setter.setFloat(mActivity.getActionsView().getVisibilityAlphaSetter(),
- OverviewActionsView.FLOAT_SETTER, overviewButtonAlpha, LINEAR);
+ setter.setFloat(mActivity.getActionsView().getVisibilityAlpha(),
+ AnimatedFloat.VALUE, overviewButtonAlpha, LINEAR);
float[] scaleAndOffset = state.getOverviewScaleAndOffset(mActivity);
setter.setFloat(mRecentsView, RECENTS_SCALE_PROPERTY, scaleAndOffset[0],
@@ -136,7 +136,7 @@
}
private Interpolator getOverviewInterpolator(RecentsState toState) {
- return toState.overviewUi() ? INSTANT : FINAL_FRAME;
+ return toState.isRecentsViewVisible() ? INSTANT : FINAL_FRAME;
}
/**
diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
index b79586b..096ed2c 100644
--- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
+++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
@@ -247,7 +247,7 @@
}
// Set border after select mode changes to avoid showing border during state transition
- if (!toState.overviewUi() || toState == MODAL_TASK) {
+ if (!toState.isRecentsViewVisible() || toState == MODAL_TASK) {
setTaskBorderEnabled(false);
}
@@ -267,7 +267,7 @@
setOverviewSelectEnabled(false);
}
- if (finalState.overviewUi() && finalState != MODAL_TASK) {
+ if (finalState.isRecentsViewVisible() && finalState != MODAL_TASK) {
setTaskBorderEnabled(true);
}
@@ -298,7 +298,7 @@
public boolean onTouchEvent(MotionEvent ev) {
boolean result = super.onTouchEvent(ev);
// Do not let touch escape to siblings below this view.
- return result || mContainer.getStateManager().getState().overviewUi();
+ return result || mContainer.getStateManager().getState().isRecentsViewVisible();
}
@Override
diff --git a/quickstep/src/com/android/quickstep/fallback/RecentsState.java b/quickstep/src/com/android/quickstep/fallback/RecentsState.java
index 84937a2..ca9753f 100644
--- a/quickstep/src/com/android/quickstep/fallback/RecentsState.java
+++ b/quickstep/src/com/android/quickstep/fallback/RecentsState.java
@@ -26,7 +26,6 @@
import com.android.launcher3.R;
import com.android.launcher3.statemanager.BaseState;
import com.android.launcher3.util.Themes;
-import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.RecentsViewContainer;
/**
@@ -41,22 +40,23 @@
private static final int FLAG_SHOW_AS_GRID = BaseState.getFlag(4);
private static final int FLAG_SCRIM = BaseState.getFlag(5);
private static final int FLAG_LIVE_TILE = BaseState.getFlag(6);
- private static final int FLAG_OVERVIEW_UI = BaseState.getFlag(7);
+ private static final int FLAG_RECENTS_VIEW_VISIBLE = BaseState.getFlag(7);
private static final int FLAG_TASK_THUMBNAIL_SPLASH = BaseState.getFlag(8);
public static final RecentsState DEFAULT = new RecentsState(0,
FLAG_DISABLE_RESTORE | FLAG_CLEAR_ALL_BUTTON | FLAG_OVERVIEW_ACTIONS | FLAG_SHOW_AS_GRID
- | FLAG_SCRIM | FLAG_LIVE_TILE | FLAG_OVERVIEW_UI);
+ | FLAG_SCRIM | FLAG_LIVE_TILE | FLAG_RECENTS_VIEW_VISIBLE);
public static final RecentsState MODAL_TASK = new ModalState(1,
FLAG_DISABLE_RESTORE | FLAG_CLEAR_ALL_BUTTON | FLAG_OVERVIEW_ACTIONS | FLAG_MODAL
- | FLAG_SHOW_AS_GRID | FLAG_SCRIM | FLAG_LIVE_TILE | FLAG_OVERVIEW_UI);
+ | FLAG_SHOW_AS_GRID | FLAG_SCRIM | FLAG_LIVE_TILE | FLAG_RECENTS_VIEW_VISIBLE);
public static final RecentsState BACKGROUND_APP = new BackgroundAppState(2,
- FLAG_DISABLE_RESTORE | FLAG_NON_INTERACTIVE | FLAG_FULL_SCREEN | FLAG_OVERVIEW_UI
+ FLAG_DISABLE_RESTORE | FLAG_NON_INTERACTIVE | FLAG_FULL_SCREEN
+ | FLAG_RECENTS_VIEW_VISIBLE
| FLAG_TASK_THUMBNAIL_SPLASH);
public static final RecentsState HOME = new RecentsState(3, 0);
public static final RecentsState BG_LAUNCHER = new LauncherState(4, 0);
public static final RecentsState OVERVIEW_SPLIT_SELECT = new RecentsState(5,
- FLAG_SHOW_AS_GRID | FLAG_SCRIM | FLAG_OVERVIEW_UI | FLAG_CLOSE_POPUPS
+ FLAG_SHOW_AS_GRID | FLAG_SCRIM | FLAG_RECENTS_VIEW_VISIBLE | FLAG_CLOSE_POPUPS
| FLAG_DISABLE_RESTORE);
public final int ordinal;
@@ -152,8 +152,8 @@
/**
* True if the state has overview panel visible.
*/
- public boolean overviewUi() {
- return hasFlag(FLAG_OVERVIEW_UI);
+ public boolean isRecentsViewVisible() {
+ return hasFlag(FLAG_RECENTS_VIEW_VISIBLE);
}
private static class ModalState extends RecentsState {
diff --git a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
index 3cae4dc..1d4160d 100644
--- a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
+++ b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
@@ -16,6 +16,10 @@
package com.android.quickstep.logging;
+import static android.view.Surface.ROTATION_180;
+import static android.view.Surface.ROTATION_270;
+import static android.view.Surface.ROTATION_90;
+
import static androidx.core.util.Preconditions.checkNotNull;
import static androidx.core.util.Preconditions.checkState;
@@ -26,10 +30,17 @@
import static com.android.launcher3.logger.LauncherAtom.ContainerInfo.ContainerCase.SEARCH_RESULT_CONTAINER;
import static com.android.launcher3.logger.LauncherAtomExtensions.ExtendedContainers.ContainerCase.DEVICE_SEARCH_RESULT_CONTAINER;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_WORKSPACE_SNAPSHOT;
+import static com.android.systemui.shared.system.SysUiStatsLog.LAUNCHER_UICHANGED__DISPLAY_ROTATION__ROTATION_0;
+import static com.android.systemui.shared.system.SysUiStatsLog.LAUNCHER_UICHANGED__DISPLAY_ROTATION__ROTATION_90;
+import static com.android.systemui.shared.system.SysUiStatsLog.LAUNCHER_UICHANGED__DISPLAY_ROTATION__ROTATION_180;
+import static com.android.systemui.shared.system.SysUiStatsLog.LAUNCHER_UICHANGED__DISPLAY_ROTATION__ROTATION_270;
import static com.android.systemui.shared.system.SysUiStatsLog.LAUNCHER_UICHANGED__DST_STATE__ALLAPPS;
import static com.android.systemui.shared.system.SysUiStatsLog.LAUNCHER_UICHANGED__DST_STATE__BACKGROUND;
import static com.android.systemui.shared.system.SysUiStatsLog.LAUNCHER_UICHANGED__DST_STATE__HOME;
import static com.android.systemui.shared.system.SysUiStatsLog.LAUNCHER_UICHANGED__DST_STATE__OVERVIEW;
+import static com.android.systemui.shared.system.SysUiStatsLog.LAUNCHER_UICHANGED__RECENTS_ORIENTATION_HANDLER__PORTRAIT;
+import static com.android.systemui.shared.system.SysUiStatsLog.LAUNCHER_UICHANGED__RECENTS_ORIENTATION_HANDLER__LANDSCAPE;
+import static com.android.systemui.shared.system.SysUiStatsLog.LAUNCHER_UICHANGED__RECENTS_ORIENTATION_HANDLER__SEASCAPE;
import android.content.Context;
import android.text.TextUtils;
@@ -59,6 +70,7 @@
import com.android.launcher3.logging.InstanceId;
import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.Executors;
import com.android.launcher3.util.LogConfig;
import com.android.launcher3.views.ActivityContext;
@@ -226,10 +238,15 @@
private int mInputType = SysUiStatsLog.LAUNCHER_UICHANGED__INPUT_TYPE__UNKNOWN;
private Optional<Integer> mFeatures = Optional.empty();
private Optional<String> mPackageName = Optional.empty();
+ /**
+ * Indicates the current rotation of the display. Uses {@link android.view.Surface values.}
+ */
+ private final int mDisplayRotation;
StatsCompatLogger(Context context, ActivityContext activityContext) {
mContext = context;
mActivityContext = Optional.ofNullable(activityContext);
+ mDisplayRotation = DisplayController.INSTANCE.get(mContext).getInfo().rotation;
}
@Override
@@ -502,7 +519,28 @@
getSearchAttributes(atomInfo) /* searchAttributes */,
getAttributes(atomInfo) /* attributes */,
inputType /* input_type */,
- atomInfo.getUserType() /* user_type */);
+ atomInfo.getUserType() /* user_type */,
+ getDisplayRotation() /* display_rotation */,
+ getRecentsOrientationHandler(atomInfo) /* recents_orientation_handler */);
+ }
+
+ private int getDisplayRotation() {
+ return switch (mDisplayRotation) {
+ case ROTATION_90 -> LAUNCHER_UICHANGED__DISPLAY_ROTATION__ROTATION_90;
+ case ROTATION_180 -> LAUNCHER_UICHANGED__DISPLAY_ROTATION__ROTATION_180;
+ case ROTATION_270 -> LAUNCHER_UICHANGED__DISPLAY_ROTATION__ROTATION_270;
+ default -> LAUNCHER_UICHANGED__DISPLAY_ROTATION__ROTATION_0;
+ };
+ }
+
+ private int getRecentsOrientationHandler(LauncherAtom.ItemInfo itemInfo) {
+ var orientationHandler =
+ itemInfo.getContainerInfo().getTaskSwitcherContainer().getOrientationHandler();
+ return switch (orientationHandler) {
+ case PORTRAIT -> LAUNCHER_UICHANGED__RECENTS_ORIENTATION_HANDLER__PORTRAIT;
+ case LANDSCAPE -> LAUNCHER_UICHANGED__RECENTS_ORIENTATION_HANDLER__LANDSCAPE;
+ case SEASCAPE -> LAUNCHER_UICHANGED__RECENTS_ORIENTATION_HANDLER__SEASCAPE;
+ };
}
}
diff --git a/quickstep/src/com/android/quickstep/orientation/LandscapePagedViewHandler.kt b/quickstep/src/com/android/quickstep/orientation/LandscapePagedViewHandler.kt
index 1640104..8f8cc6e 100644
--- a/quickstep/src/com/android/quickstep/orientation/LandscapePagedViewHandler.kt
+++ b/quickstep/src/com/android/quickstep/orientation/LandscapePagedViewHandler.kt
@@ -42,6 +42,7 @@
import com.android.launcher3.LauncherAnimUtils
import com.android.launcher3.R
import com.android.launcher3.Utilities
+import com.android.launcher3.logger.LauncherAtom.TaskSwitcherContainer
import com.android.launcher3.touch.PagedOrientationHandler.ChildBounds
import com.android.launcher3.touch.PagedOrientationHandler.Float2DAction
import com.android.launcher3.touch.PagedOrientationHandler.Int2DAction
@@ -611,6 +612,9 @@
override fun getFloatingTaskPrimaryTranslation(floatingTask: View, dp: DeviceProfile): Float =
floatingTask.translationY
+ override fun getHandlerTypeForLogging(): TaskSwitcherContainer.OrientationHandler =
+ TaskSwitcherContainer.OrientationHandler.LANDSCAPE
+
/**
* Retrieves split icons position
*
diff --git a/quickstep/src/com/android/quickstep/orientation/PortraitPagedViewHandler.java b/quickstep/src/com/android/quickstep/orientation/PortraitPagedViewHandler.java
index 1be908b..f6284d5 100644
--- a/quickstep/src/com/android/quickstep/orientation/PortraitPagedViewHandler.java
+++ b/quickstep/src/com/android/quickstep/orientation/PortraitPagedViewHandler.java
@@ -46,9 +46,12 @@
import android.widget.FrameLayout;
import android.widget.LinearLayout;
+import androidx.annotation.NonNull;
+
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
+import com.android.launcher3.logger.LauncherAtom;
import com.android.launcher3.touch.DefaultPagedViewHandler;
import com.android.launcher3.touch.SingleAxisSwipeDetector;
import com.android.launcher3.util.SplitConfigurationOptions;
@@ -802,4 +805,10 @@
? floatingTask.getTranslationX()
: floatingTask.getTranslationY();
}
+
+ @NonNull
+ @Override
+ public LauncherAtom.TaskSwitcherContainer.OrientationHandler getHandlerTypeForLogging() {
+ return LauncherAtom.TaskSwitcherContainer.OrientationHandler.PORTRAIT;
+ }
}
diff --git a/quickstep/src/com/android/quickstep/orientation/RecentsPagedOrientationHandler.kt b/quickstep/src/com/android/quickstep/orientation/RecentsPagedOrientationHandler.kt
index 6c82890..5bc1be8 100644
--- a/quickstep/src/com/android/quickstep/orientation/RecentsPagedOrientationHandler.kt
+++ b/quickstep/src/com/android/quickstep/orientation/RecentsPagedOrientationHandler.kt
@@ -26,6 +26,7 @@
import android.widget.FrameLayout
import android.widget.LinearLayout
import com.android.launcher3.DeviceProfile
+import com.android.launcher3.logger.LauncherAtom
import com.android.launcher3.touch.PagedOrientationHandler
import com.android.launcher3.touch.PagedOrientationHandler.Float2DAction
import com.android.launcher3.touch.PagedOrientationHandler.Int2DAction
@@ -371,6 +372,8 @@
*/
fun getFloatingTaskPrimaryTranslation(floatingTask: View, dp: DeviceProfile): Float
+ fun getHandlerTypeForLogging(): LauncherAtom.TaskSwitcherContainer.OrientationHandler
+
companion object {
@JvmField val PORTRAIT: RecentsPagedOrientationHandler = PortraitPagedViewHandler()
@JvmField val LANDSCAPE: RecentsPagedOrientationHandler = LandscapePagedViewHandler()
diff --git a/quickstep/src/com/android/quickstep/orientation/SeascapePagedViewHandler.kt b/quickstep/src/com/android/quickstep/orientation/SeascapePagedViewHandler.kt
index 5bebf8c..46e4b0c 100644
--- a/quickstep/src/com/android/quickstep/orientation/SeascapePagedViewHandler.kt
+++ b/quickstep/src/com/android/quickstep/orientation/SeascapePagedViewHandler.kt
@@ -32,6 +32,7 @@
import com.android.launcher3.Flags
import com.android.launcher3.R
import com.android.launcher3.Utilities
+import com.android.launcher3.logger.LauncherAtom
import com.android.launcher3.touch.SingleAxisSwipeDetector
import com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT
import com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT
@@ -395,4 +396,8 @@
iconView.layoutParams = layoutParams
}
}
+
+ @Override
+ override fun getHandlerTypeForLogging(): LauncherAtom.TaskSwitcherContainer.OrientationHandler =
+ LauncherAtom.TaskSwitcherContainer.OrientationHandler.SEASCAPE
}
diff --git a/quickstep/src/com/android/quickstep/task/thumbnail/TaskThumbnailView.kt b/quickstep/src/com/android/quickstep/task/thumbnail/TaskThumbnailView.kt
index b466f3f..8762976 100644
--- a/quickstep/src/com/android/quickstep/task/thumbnail/TaskThumbnailView.kt
+++ b/quickstep/src/com/android/quickstep/task/thumbnail/TaskThumbnailView.kt
@@ -46,7 +46,7 @@
RecentsViewContainer.containerFromContext<RecentsViewContainer>(context)
.getOverviewPanel<RecentsView<*, *>>()
.mRecentsViewData,
- (parent as TaskView).mTaskViewData
+ (parent as TaskView).taskViewData
)
}
diff --git a/quickstep/src/com/android/quickstep/util/BorderAnimator.kt b/quickstep/src/com/android/quickstep/util/BorderAnimator.kt
index 44eb070..85238ed 100644
--- a/quickstep/src/com/android/quickstep/util/BorderAnimator.kt
+++ b/quickstep/src/com/android/quickstep/util/BorderAnimator.kt
@@ -86,7 +86,7 @@
fun createSimpleBorderAnimator(
@Px borderRadiusPx: Int,
@Px borderWidthPx: Int,
- boundsBuilder: (rect: Rect?) -> Unit,
+ boundsBuilder: (Rect) -> Unit,
targetView: View,
@ColorInt borderColor: Int = DEFAULT_BORDER_COLOR,
appearanceDurationMs: Long = DEFAULT_APPEARANCE_ANIMATION_DURATION_MS,
@@ -250,7 +250,7 @@
/** BorderAnimationParams that simply draws the border outside the bounds of the target view. */
private class SimpleParams(
@Px borderWidthPx: Int,
- boundsBuilder: (rect: Rect?) -> Unit,
+ boundsBuilder: (Rect) -> Unit,
targetView: View,
) : BorderAnimationParams(borderWidthPx, boundsBuilder, targetView) {
override val alignmentAdjustmentInset = 0
diff --git a/quickstep/src/com/android/quickstep/util/RectFSpringAnim.java b/quickstep/src/com/android/quickstep/util/RectFSpringAnim.java
index 5505bb3..769ccc0 100644
--- a/quickstep/src/com/android/quickstep/util/RectFSpringAnim.java
+++ b/quickstep/src/com/android/quickstep/util/RectFSpringAnim.java
@@ -565,7 +565,11 @@
final float bottomThreshold = deviceProfile.heightPx - padding.bottom;
if (targetRect.bottom > bottomThreshold) {
- tracking = TRACKING_BOTTOM;
+ if (enableScalingRevealHomeAnimation()) {
+ tracking = TRACKING_CENTER;
+ } else {
+ tracking = TRACKING_BOTTOM;
+ }
} else if (targetRect.top < topThreshold) {
tracking = TRACKING_TOP;
} else {
diff --git a/quickstep/src/com/android/quickstep/util/ScalingWorkspaceRevealAnim.kt b/quickstep/src/com/android/quickstep/util/ScalingWorkspaceRevealAnim.kt
index 1bf77f1..4513fa2 100644
--- a/quickstep/src/com/android/quickstep/util/ScalingWorkspaceRevealAnim.kt
+++ b/quickstep/src/com/android/quickstep/util/ScalingWorkspaceRevealAnim.kt
@@ -17,11 +17,12 @@
package com.android.quickstep.util
import android.graphics.Matrix
+import android.graphics.Path
import android.graphics.RectF
import android.view.View
+import android.view.animation.PathInterpolator
import androidx.core.graphics.transform
import com.android.app.animation.Interpolators
-import com.android.app.animation.Interpolators.EMPHASIZED
import com.android.app.animation.Interpolators.LINEAR
import com.android.launcher3.LauncherAnimUtils.HOTSEAT_SCALE_PROPERTY_FACTORY
import com.android.launcher3.LauncherAnimUtils.SCALE_INDEX_WORKSPACE_STATE
@@ -53,6 +54,19 @@
private const val MIN_ALPHA = 0f
private const val MAX_SIZE = 1f
private const val MIN_SIZE = 0.85f
+
+ /**
+ * Custom interpolator for both the home and wallpaper scaling. Necessary because EMPHASIZED
+ * is too aggressive, but EMPHASIZED_DECELERATE is too soft.
+ */
+ private val SCALE_INTERPOLATOR =
+ PathInterpolator(
+ Path().apply {
+ moveTo(0f, 0f)
+ cubicTo(0.045f, 0.0356f, 0.0975f, 0.2055f, 0.15f, 0.3952f)
+ cubicTo(0.235f, 0.6855f, 0.235f, 1f, 1f, 1f)
+ }
+ )
}
private val animation = PendingAnimation(SCALE_DURATION_MS)
@@ -78,20 +92,20 @@
val hotseat = launcher.hotseat
// Scale the Workspace and Hotseat around the same pivot.
+ workspace.setPivotToScaleWithSelf(hotseat)
animation.addFloat(
workspace,
WORKSPACE_SCALE_PROPERTY_FACTORY[SCALE_INDEX_WORKSPACE_STATE],
MIN_SIZE,
MAX_SIZE,
- EMPHASIZED,
+ SCALE_INTERPOLATOR,
)
- workspace.setPivotToScaleWithSelf(hotseat)
animation.addFloat(
hotseat,
HOTSEAT_SCALE_PROPERTY_FACTORY[SCALE_INDEX_WORKSPACE_STATE],
MIN_SIZE,
MAX_SIZE,
- EMPHASIZED,
+ SCALE_INTERPOLATOR,
)
// Fade in quickly at the beginning of the animation, so the content doesn't look like it's
@@ -114,11 +128,11 @@
// Match the Wallpaper animation to the rest of the content.
val depthController = (launcher as? QuickstepLauncher)?.depthController
- transitionConfig.setInterpolator(StateAnimationConfig.ANIM_DEPTH, EMPHASIZED)
+ transitionConfig.setInterpolator(StateAnimationConfig.ANIM_DEPTH, SCALE_INTERPOLATOR)
depthController?.setStateWithAnimation(LauncherState.NORMAL, transitionConfig, animation)
// Make sure that the contrast scrim animates correctly if needed.
- transitionConfig.setInterpolator(StateAnimationConfig.ANIM_SCRIM_FADE, EMPHASIZED)
+ transitionConfig.setInterpolator(StateAnimationConfig.ANIM_SCRIM_FADE, SCALE_INTERPOLATOR)
launcher.workspace.stateTransitionAnimation.setScrim(
animation,
LauncherState.NORMAL,
diff --git a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
index df1879e..7e7c794 100644
--- a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
+++ b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
@@ -983,6 +983,7 @@
void onDestroy() {
SystemUiProxy.INSTANCE.get(mLauncher).unregisterSplitSelectListener(
mSplitSelectListener);
+ mSplitSelectListener = null;
}
/**
diff --git a/quickstep/src/com/android/quickstep/util/SplitWithKeyboardShortcutController.java b/quickstep/src/com/android/quickstep/util/SplitWithKeyboardShortcutController.java
index 85d4f4b..5e42b90 100644
--- a/quickstep/src/com/android/quickstep/util/SplitWithKeyboardShortcutController.java
+++ b/quickstep/src/com/android/quickstep/util/SplitWithKeyboardShortcutController.java
@@ -136,7 +136,7 @@
RectF startingTaskRect = new RectF();
final FloatingTaskView floatingTaskView = FloatingTaskView.getFloatingTaskView(
mLauncher, mLauncher.getDragLayer(),
- controller.screenshotTask(runningTaskInfo.taskId).thumbnail,
+ controller.screenshotTask(runningTaskInfo.taskId).getThumbnail(),
null /* icon */, startingTaskRect);
RecentsModel.INSTANCE.get(mLauncher.getApplicationContext())
.getIconCache()
diff --git a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
index 9da4985..49f4e5f 100644
--- a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
+++ b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
@@ -551,7 +551,7 @@
* TaskView
*/
public float getCurrentCornerRadius() {
- float visibleRadius = mCurrentFullscreenParams.mCurrentDrawnCornerRadius;
+ float visibleRadius = mCurrentFullscreenParams.getCurrentDrawnCornerRadius();
mTempPoint[0] = visibleRadius;
mTempPoint[1] = 0;
mInversePositionMatrix.mapVectors(mTempPoint);
diff --git a/quickstep/src/com/android/quickstep/views/DesktopAppSelectView.java b/quickstep/src/com/android/quickstep/views/DesktopAppSelectView.java
deleted file mode 100644
index 6a9a268..0000000
--- a/quickstep/src/com/android/quickstep/views/DesktopAppSelectView.java
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright (C) 2023 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.quickstep.views;
-
-import static com.android.app.animation.Interpolators.EMPHASIZED_DECELERATE;
-import static com.android.app.animation.Interpolators.LINEAR;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.AnimatorSet;
-import android.animation.ObjectAnimator;
-import android.animation.ValueAnimator;
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.View;
-import android.widget.LinearLayout;
-
-import androidx.annotation.Nullable;
-
-import com.android.launcher3.Launcher;
-import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
-import com.android.launcher3.uioverrides.QuickstepLauncher;
-
-/**
- * Floating view show on launcher home screen that notifies the user that an app will be launched to
- * the desktop.
- */
-public class DesktopAppSelectView extends LinearLayout {
-
- private static final int SHOW_INITIAL_HEIGHT_DP = 7;
- private static final int SHOW_CONTAINER_SCALE_DURATION = 333;
- private static final int SHOW_CONTAINER_ALPHA_DURATION = 83;
- private static final int SHOW_CONTENT_ALPHA_DELAY = 67;
- private static final int SHOW_CONTENT_ALPHA_DURATION = 83;
- private static final int HIDE_DURATION = 83;
-
- private final RecentsViewContainer mContainer;
-
- private View mText;
- private View mCloseButton;
- @Nullable
- private Runnable mOnCloseCallback;
- private AnimatorSet mShowAnimation;
- private Animator mHideAnimation;
-
- public DesktopAppSelectView(Context context) {
- this(context, null);
- }
-
- public DesktopAppSelectView(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public DesktopAppSelectView(Context context, AttributeSet attrs, int defStyleAttr) {
- this(context, attrs, defStyleAttr, 0);
- }
-
- public DesktopAppSelectView(Context context, AttributeSet attrs, int defStyleAttr,
- int defStyleRes) {
- super(context, attrs, defStyleAttr, defStyleRes);
- mContainer = RecentsViewContainer.containerFromContext(context);
- }
-
- /**
- * Show the popup on launcher home screen
- *
- * @param onCloseCallback optional callback that is called when user clicks the close button
- * @return the created view
- */
- public static DesktopAppSelectView show(Launcher launcher, @Nullable Runnable onCloseCallback) {
- DesktopAppSelectView view = (DesktopAppSelectView) launcher.getLayoutInflater().inflate(
- R.layout.floating_desktop_app_select, launcher.getDragLayer(), false);
- view.setOnCloseClickCallback(onCloseCallback);
- view.show();
- return view;
- }
-
- @Override
- protected void onFinishInflate() {
- super.onFinishInflate();
- mText = findViewById(R.id.desktop_app_select_text);
- mCloseButton = findViewById(R.id.close_button);
- mCloseButton.setOnClickListener(v -> {
- if (mHideAnimation == null) {
- hide();
- if (mOnCloseCallback != null) {
- mOnCloseCallback.run();
- }
- }
- });
- }
-
- private void show() {
- mContainer.getDragLayer().addView(this);
-
- // Set up initial values
- getBackground().setAlpha(0);
- mText.setAlpha(0);
- mCloseButton.setAlpha(0);
- int initialHeightPx = Utilities.dpToPx(SHOW_INITIAL_HEIGHT_DP);
- int finalHeight = getResources().getDimensionPixelSize(
- R.dimen.desktop_mode_floating_app_select_height);
- float initialScale = initialHeightPx / (float) finalHeight;
- setScaleY(initialScale);
- setPivotY(0);
-
- // Animate the container
- ValueAnimator containerBackground = ValueAnimator.ofInt(0, 255);
- containerBackground.addUpdateListener(
- animation -> getBackground().setAlpha((Integer) animation.getAnimatedValue()));
- containerBackground.setDuration(SHOW_CONTAINER_ALPHA_DURATION);
- containerBackground.setInterpolator(LINEAR);
-
- ObjectAnimator containerSize = ObjectAnimator.ofFloat(this, SCALE_Y, 1f);
- containerSize.setDuration(SHOW_CONTAINER_SCALE_DURATION);
- containerSize.setInterpolator(EMPHASIZED_DECELERATE);
-
- // Animate the contents
- ObjectAnimator textAlpha = ObjectAnimator.ofFloat(mText, ALPHA, 1);
- ObjectAnimator buttonAlpha = ObjectAnimator.ofFloat(mCloseButton, ALPHA, 1);
- AnimatorSet contentAlpha = new AnimatorSet();
- contentAlpha.playTogether(textAlpha, buttonAlpha);
- contentAlpha.setStartDelay(SHOW_CONTENT_ALPHA_DELAY);
- contentAlpha.setDuration(SHOW_CONTENT_ALPHA_DURATION);
- contentAlpha.setInterpolator(LINEAR);
-
- // Start the animation
- mShowAnimation = new AnimatorSet();
- mShowAnimation.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- super.onAnimationEnd(animation);
- mShowAnimation = null;
- }
- });
- mShowAnimation.playTogether(containerBackground, containerSize, contentAlpha);
- mShowAnimation.start();
- }
-
- /**
- * Hide the floating view
- */
- public void hide() {
- if (mShowAnimation != null) {
- mShowAnimation.cancel();
- }
- mHideAnimation = ObjectAnimator.ofFloat(this, ALPHA, 0);
- mHideAnimation.setDuration(HIDE_DURATION).setInterpolator(LINEAR);
- mHideAnimation.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- super.onAnimationEnd(animation);
- mContainer.getDragLayer().removeView(DesktopAppSelectView.this);
- mHideAnimation = null;
- }
- });
- mHideAnimation.start();
- }
-
- /**
- * Add a callback that is called when close button is clicked
- */
- public void setOnCloseClickCallback(@Nullable Runnable callback) {
- mOnCloseCallback = callback;
- }
-}
diff --git a/quickstep/src/com/android/quickstep/views/DesktopTaskView.kt b/quickstep/src/com/android/quickstep/views/DesktopTaskView.kt
index b7c0236..3935c67 100644
--- a/quickstep/src/com/android/quickstep/views/DesktopTaskView.kt
+++ b/quickstep/src/com/android/quickstep/views/DesktopTaskView.kt
@@ -27,34 +27,30 @@
import android.view.View
import android.view.ViewGroup
import androidx.core.view.updateLayoutParams
-import com.android.launcher3.LauncherState
import com.android.launcher3.R
-import com.android.launcher3.Utilities
import com.android.launcher3.util.CancellableTask
import com.android.launcher3.util.RunnableList
import com.android.launcher3.util.SplitConfigurationOptions
import com.android.launcher3.util.ViewPool
+import com.android.launcher3.util.rects.set
import com.android.quickstep.BaseContainerInterface
import com.android.quickstep.RecentsModel
+import com.android.quickstep.TaskOverlayFactory
import com.android.quickstep.util.RecentsOrientedState
import com.android.systemui.shared.recents.model.Task
import com.android.systemui.shared.recents.model.ThumbnailData
-import com.android.systemui.shared.system.QuickStepContract
-import java.util.function.Consumer
/** TaskView that contains all tasks that are part of the desktop. */
// TODO(b/249371338): TaskView needs to be refactored to have better support for N tasks.
-class DesktopTaskView @JvmOverloads constructor(context: Context?, attrs: AttributeSet? = null) :
+class DesktopTaskView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
TaskView(context, attrs) {
private val pendingThumbnailRequests = mutableListOf<CancellableTask<*>>()
private val snapshotDrawParams =
object : FullscreenDrawParams(context) {
+ // DesktopTaskView thumbnail's corner radius is independent of fullscreenProgress.
override fun computeTaskCornerRadius(context: Context) =
- QuickStepContract.getWindowCornerRadius(context)
-
- override fun computeWindowCornerRadius(context: Context) =
- QuickStepContract.getWindowCornerRadius(context)
+ computeWindowCornerRadius(context)
}
private val taskThumbnailViewPool =
ViewPool<TaskThumbnailViewDeprecated>(
@@ -69,15 +65,11 @@
private lateinit var backgroundView: View
private var childCountAtInflation = 0
- init {
- mTaskContainers = ArrayList()
- }
-
override fun onFinishInflate() {
super.onFinishInflate()
backgroundView = findViewById(R.id.background)!!
- val topMarginPx = mContainer.deviceProfile.overviewTaskThumbnailTopMarginPx
+ val topMarginPx = container.deviceProfile.overviewTaskThumbnailTopMarginPx
backgroundView.updateLayoutParams<LayoutParams> { topMargin = topMarginPx }
val outerRadii = FloatArray(8) { taskCornerRadius }
@@ -88,179 +80,25 @@
val iconBackground = resources.getDrawable(R.drawable.bg_circle, context.theme)
val icon = resources.getDrawable(R.drawable.ic_desktop, context.theme)
- setIcon(mIconView, LayerDrawable(arrayOf(iconBackground, icon)))
+ setIcon(iconView, LayerDrawable(arrayOf(iconBackground, icon)))
childCountAtInflation = childCount
}
- override fun getThumbnailBounds(bounds: Rect, relativeToDragLayer: Boolean) {
- if (relativeToDragLayer) {
- mContainer.dragLayer.getDescendantRectRelativeToSelf(backgroundView, bounds)
- } else {
- bounds.set(
- backgroundView.left,
- backgroundView.top,
- backgroundView.right,
- backgroundView.bottom
- )
- }
- }
-
- override fun bind(task: Task, orientedState: RecentsOrientedState) {
- bind(listOf(task), orientedState)
- }
-
- /** Updates this desktop task to the gives task list defined in `tasks` */
- fun bind(tasks: List<Task>, orientedState: RecentsOrientedState) {
- if (DEBUG) {
- val sb = StringBuilder()
- sb.append("bind tasks=").append(tasks.size).append("\n")
- tasks.forEach { sb.append(" key=${it.key}\n") }
- Log.d(TAG, sb.toString())
- }
- cancelPendingLoadTasks()
-
- (mTaskContainers as ArrayList).ensureCapacity(tasks.size)
- tasks.forEachIndexed { index, task ->
- val thumbnailView: TaskThumbnailViewDeprecated
- if (index >= mTaskContainers.size) {
- thumbnailView = taskThumbnailViewPool.view
- // Add thumbnailView from to position after the initial child views.
- addView(
- thumbnailView,
- childCountAtInflation,
- LayoutParams(
- ViewGroup.LayoutParams.WRAP_CONTENT,
- ViewGroup.LayoutParams.WRAP_CONTENT
- )
- )
- } else {
- thumbnailView = mTaskContainers[index].thumbnailView
- }
- thumbnailView.bind(task)
- val taskContainer =
- TaskContainer(
- task,
- thumbnailView,
- mIconView,
- SplitConfigurationOptions.STAGE_POSITION_UNDEFINED,
- null
- )
- if (index >= mTaskContainers.size) {
- mTaskContainers.add(taskContainer)
- } else {
- mTaskContainers[index] = taskContainer
- }
- }
- while (mTaskContainers.size > tasks.size) {
- mTaskContainers.removeLast().apply {
- removeView(thumbnailView)
- taskThumbnailViewPool.recycle(thumbnailView)
- }
- }
-
- setOrientationState(orientedState)
- }
-
- override fun onTaskListVisibilityChanged(visible: Boolean, changes: Int) {
- cancelPendingLoadTasks()
- if (needsUpdate(changes, FLAG_UPDATE_THUMBNAIL)) {
- mTaskContainers.forEach {
- if (visible) {
- RecentsModel.INSTANCE.get(context)
- .thumbnailCache
- .updateThumbnailInBackground(it.task) { thumbnailData: ThumbnailData ->
- it.thumbnailView.setThumbnail(it.task, thumbnailData)
- }
- ?.apply { pendingThumbnailRequests.add(this) }
- } else {
- it.thumbnailView.setThumbnail(null, null)
- // Reset the task thumbnail ref
- it.task.thumbnail = null
- }
- }
- }
- }
-
- // thumbnailView is laid out differently and is handled in onMeasure
- override fun setThumbnailOrientation(orientationState: RecentsOrientedState) {}
-
- override fun cancelPendingLoadTasks() {
- pendingThumbnailRequests.forEach { it.cancel() }
- pendingThumbnailRequests.clear()
- }
-
- override fun launchTaskAnimated(): RunnableList? {
- val recentsView = recentsView
- if (recentsView == null) {
- Log.d(TAG, "launchTaskAnimated - recentsView is null")
- return null
- }
-
- val endCallback = RunnableList()
- val desktopController = recentsView.desktopRecentsController
- if (desktopController == null) {
- Log.d(
- TAG,
- "launchTaskAnimated - recentsController is null: ${taskIds.contentToString()}"
- )
- } else {
- desktopController.launchDesktopFromRecents(this) { endCallback.executeAllAndDestroy() }
- Log.d(
- TAG,
- "launchTaskAnimated - launchDesktopFromRecents: ${taskIds.contentToString()}"
- )
- }
-
- // Callbacks get run from recentsView for case when recents animation already running
- recentsView.addSideTaskLaunchCallback(endCallback)
- return endCallback
- }
-
- override fun launchTask(callback: Consumer<Boolean>, isQuickswitch: Boolean) {
- launchTasks()
- callback.accept(true)
- }
-
- public override fun refreshThumbnails(thumbnailDatas: HashMap<Int, ThumbnailData>?) {
- // Sets new thumbnails based on the incoming data and refreshes the rest.
- thumbnailDatas?.let {
- mTaskContainers.forEach {
- val thumbnailData = thumbnailDatas[it.task.key.id]
- if (thumbnailData != null) {
- it.thumbnailView.setThumbnail(it.task, thumbnailData)
- } else {
- // Refresh the rest that were not updated.
- it.thumbnailView.refresh()
- }
- }
- }
- }
-
- override fun onRecycle() {
- resetPersistentViewTransforms()
- // Clear any references to the thumbnail (it will be re-read either from the cache or the
- // system on next bind)
- mTaskContainers.forEach { it.thumbnailView.setThumbnail(it.task, null) }
- setOverlayEnabled(false)
- onTaskListVisibilityChanged(false)
- visibility = VISIBLE
- }
-
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
val containerWidth = MeasureSpec.getSize(widthMeasureSpec)
var containerHeight = MeasureSpec.getSize(heightMeasureSpec)
setMeasuredDimension(containerWidth, containerHeight)
- if (mTaskContainers.isEmpty()) {
+ if (taskContainers.isEmpty()) {
return
}
- val thumbnailTopMarginPx = mContainer.deviceProfile.overviewTaskThumbnailTopMarginPx
+ val thumbnailTopMarginPx = container.deviceProfile.overviewTaskThumbnailTopMarginPx
containerHeight -= thumbnailTopMarginPx
- BaseContainerInterface.getTaskDimension(mContext, mContainer.deviceProfile, tempPointF)
+ BaseContainerInterface.getTaskDimension(mContext, container.deviceProfile, tempPointF)
val windowWidth = tempPointF.x.toInt()
val windowHeight = tempPointF.y.toInt()
val scaleWidth = containerWidth / windowWidth.toFloat()
@@ -274,7 +112,7 @@
}
// Desktop tile is a shrunk down version of launcher and freeform task thumbnails.
- mTaskContainers.forEach {
+ taskContainers.forEach {
// Default to quarter of the desktop if we did not get app bounds.
val taskSize =
it.task.appBounds
@@ -309,54 +147,191 @@
}
}
- // TODO(b/330685808) support overlay for Screenshot action
- override fun setOverlayEnabled(overlayEnabled: Boolean) {}
+ override fun onRecycle() {
+ resetPersistentViewTransforms()
+ // Clear any references to the thumbnail (it will be re-read either from the cache or the
+ // system on next bind)
+ taskContainers.forEach { it.thumbnailView.setThumbnail(it.task, null) }
+ setOverlayEnabled(false)
+ onTaskListVisibilityChanged(false)
+ visibility = VISIBLE
+ }
- override fun setFullscreenProgress(progress: Float) {
- // TODO(b/249371338): this copies parent implementation and makes it work for N thumbs
- val boundProgress = Utilities.boundToRange(progress, 0f, 1f)
- mFullscreenProgress = boundProgress
- mIconView.setVisibility(if (boundProgress < 1) VISIBLE else INVISIBLE)
- // Don't show background while we are transitioning to/from fullscreen
- backgroundView.visibility = if (mFullscreenProgress > 0) INVISIBLE else VISIBLE
- mTaskContainers.forEach {
- it.thumbnailView.taskOverlay.setFullscreenProgress(boundProgress)
+ override fun bind(
+ task: Task,
+ orientedState: RecentsOrientedState,
+ taskOverlayFactory: TaskOverlayFactory
+ ) {
+ bind(listOf(task), orientedState, taskOverlayFactory)
+ }
+
+ /** Updates this desktop task to the gives task list defined in `tasks` */
+ fun bind(
+ tasks: List<Task>,
+ orientedState: RecentsOrientedState,
+ taskOverlayFactory: TaskOverlayFactory
+ ) {
+ if (DEBUG) {
+ val sb = StringBuilder()
+ sb.append("bind tasks=").append(tasks.size).append("\n")
+ tasks.forEach { sb.append(" key=${it.key}\n") }
+ Log.d(TAG, sb.toString())
}
- // Animate icons and DWB banners in/out, except in QuickSwitch state, when tiles are
- // oversized and banner would look disproportionately large.
- if (
- mContainer.getOverviewPanel<RecentsView<*, *>>().getStateManager().state !=
- LauncherState.BACKGROUND_APP
- ) {
- setIconsAndBannersTransitionProgress(boundProgress, true)
+ cancelPendingLoadTasks()
+
+ if (!isTaskContainersInitialized()) {
+ taskContainers = arrayListOf()
}
- updateSnapshotRadius()
+ val taskContainers = taskContainers as ArrayList
+ taskContainers.ensureCapacity(tasks.size)
+ tasks.forEachIndexed { index, task ->
+ val thumbnailView: TaskThumbnailViewDeprecated
+ if (index >= taskContainers.size) {
+ thumbnailView = taskThumbnailViewPool.view
+ // Add thumbnailView from to position after the initial child views.
+ addView(
+ thumbnailView,
+ childCountAtInflation,
+ LayoutParams(
+ ViewGroup.LayoutParams.WRAP_CONTENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT
+ )
+ )
+ } else {
+ thumbnailView = taskContainers[index].thumbnailView
+ }
+ thumbnailView.bind(task, taskOverlayFactory)
+ val taskContainer =
+ TaskContainer(
+ task,
+ thumbnailView,
+ iconView,
+ SplitConfigurationOptions.STAGE_POSITION_UNDEFINED,
+ null
+ )
+ if (index >= taskContainers.size) {
+ taskContainers.add(taskContainer)
+ } else {
+ taskContainers[index] = taskContainer
+ }
+ }
+ repeat(taskContainers.size - tasks.size) {
+ taskContainers.removeLast().apply {
+ removeView(thumbnailView)
+ taskThumbnailViewPool.recycle(thumbnailView)
+ }
+ }
+
+ setOrientationState(orientedState)
}
- override fun updateSnapshotRadius() {
- super.updateSnapshotRadius()
- updateFullscreenParams(snapshotDrawParams)
- mTaskContainers.forEach { it.thumbnailView.setFullscreenParams(snapshotDrawParams) }
+ // thumbnailView is laid out differently and is handled in onMeasure
+ override fun setThumbnailOrientation(orientationState: RecentsOrientedState) {}
+
+ override fun onTaskListVisibilityChanged(visible: Boolean, changes: Int) {
+ cancelPendingLoadTasks()
+ if (needsUpdate(changes, FLAG_UPDATE_THUMBNAIL)) {
+ taskContainers.forEach {
+ if (visible) {
+ RecentsModel.INSTANCE.get(context)
+ .thumbnailCache
+ .updateThumbnailInBackground(it.task) { thumbnailData: ThumbnailData ->
+ it.thumbnailView.setThumbnail(it.task, thumbnailData)
+ }
+ ?.apply { pendingThumbnailRequests.add(this) }
+ } else {
+ it.thumbnailView.setThumbnail(null, null)
+ // Reset the task thumbnail ref
+ it.task.thumbnail = null
+ }
+ }
+ }
}
- override fun setColorTint(amount: Float, tintColor: Int) {
- mTaskContainers.forEach { it.thumbnailView.dimAlpha = amount }
+ override fun cancelPendingLoadTasks() {
+ pendingThumbnailRequests.forEach { it.cancel() }
+ pendingThumbnailRequests.clear()
}
- override fun applyThumbnailSplashAlpha() {
- mTaskContainers.forEach { it.thumbnailView.setSplashAlpha(mTaskThumbnailSplashAlpha) }
+ override fun getThumbnailBounds(bounds: Rect, relativeToDragLayer: Boolean) {
+ if (relativeToDragLayer) {
+ container.dragLayer.getDescendantRectRelativeToSelf(backgroundView, bounds)
+ } else {
+ bounds.set(backgroundView)
+ }
}
- public override fun setThumbnailVisibility(visibility: Int, taskId: Int) {
- mTaskContainers.forEach { it.thumbnailView.visibility = visibility }
+ override fun launchTaskAnimated(): RunnableList? {
+ val recentsView = recentsView ?: return null
+ val endCallback = RunnableList()
+ val desktopController = recentsView.desktopRecentsController
+ checkNotNull(desktopController) { "recentsController is null" }
+ desktopController.launchDesktopFromRecents(this) { endCallback.executeAllAndDestroy() }
+ Log.d(TAG, "launchTaskAnimated - launchDesktopFromRecents: ${taskIds.contentToString()}")
+
+ // Callbacks get run from recentsView for case when recents animation already running
+ recentsView.addSideTaskLaunchCallback(endCallback)
+ return endCallback
+ }
+
+ override fun launchTask(callback: (launched: Boolean) -> Unit, isQuickSwitch: Boolean) {
+ launchTasks()
+ callback(true)
+ }
+
+ override fun refreshThumbnails(thumbnailDatas: HashMap<Int, ThumbnailData?>?) {
+ // Sets new thumbnails based on the incoming data and refreshes the rest.
+ thumbnailDatas?.let {
+ taskContainers.forEach {
+ val thumbnailData = thumbnailDatas[it.task.key.id]
+ if (thumbnailData != null) {
+ it.thumbnailView.setThumbnail(it.task, thumbnailData)
+ } else {
+ // Refresh the rest that were not updated.
+ it.thumbnailView.refresh()
+ }
+ }
+ }
}
// Desktop tile can't be in split screen
override fun confirmSecondSplitSelectApp(): Boolean = false
+ override fun setColorTint(amount: Float, tintColor: Int) {
+ taskContainers.forEach { it.thumbnailView.dimAlpha = amount }
+ }
+
+ override fun setThumbnailVisibility(visibility: Int, taskId: Int) {
+ taskContainers.forEach { it.thumbnailView.visibility = visibility }
+ }
+
+ // TODO(b/330685808) support overlay for Screenshot action
+ override fun setOverlayEnabled(overlayEnabled: Boolean) {}
+
+ override fun onFullscreenProgressChanged(fullscreenProgress: Float) {
+ // TODO(b/249371338): this copies parent implementation and makes it work for N thumbs
+ iconView.setVisibility(if (fullscreenProgress < 1) VISIBLE else INVISIBLE)
+ // Don't show background while we are transitioning to/from fullscreen
+ backgroundView.visibility = if (fullscreenProgress > 0) INVISIBLE else VISIBLE
+ taskContainers.forEach {
+ it.thumbnailView.taskOverlay.setFullscreenProgress(fullscreenProgress)
+ }
+ setIconsAndBannersFullscreenProgress(fullscreenProgress)
+ updateSnapshotRadius()
+ }
+
+ override fun updateSnapshotRadius() {
+ updateFullscreenParams(snapshotDrawParams)
+ taskContainers.forEach { it.thumbnailView.setFullscreenParams(snapshotDrawParams) }
+ }
+
+ override fun applyThumbnailSplashAlpha() {
+ taskContainers.forEach { it.thumbnailView.setSplashAlpha(taskThumbnailSplashAlpha) }
+ }
+
companion object {
private const val TAG = "DesktopTaskView"
- private const val DEBUG = true
+ private const val DEBUG = false
private val ORIGIN = Point(0, 0)
}
}
diff --git a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
deleted file mode 100644
index 1ccb764..0000000
--- a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
+++ /dev/null
@@ -1,560 +0,0 @@
-package com.android.quickstep.views;
-
-import static android.app.ActivityTaskManager.INVALID_TASK_ID;
-
-import static com.android.launcher3.Flags.enableOverviewIconMenu;
-import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT;
-import static com.android.quickstep.util.SplitScreenUtils.convertLauncherSplitBoundsToShell;
-
-import android.app.ActivityTaskManager;
-import android.content.Context;
-import android.graphics.Point;
-import android.graphics.PointF;
-import android.graphics.Rect;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.util.Pair;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewStub;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import com.android.internal.jank.Cuj;
-import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
-import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.util.CancellableTask;
-import com.android.launcher3.util.RunnableList;
-import com.android.launcher3.util.SplitConfigurationOptions;
-import com.android.launcher3.util.SplitConfigurationOptions.SplitBounds;
-import com.android.launcher3.util.TransformingTouchDelegate;
-import com.android.launcher3.views.BaseDragLayer;
-import com.android.quickstep.RecentsModel;
-import com.android.quickstep.TaskIconCache;
-import com.android.quickstep.TaskThumbnailCache;
-import com.android.quickstep.util.RecentsOrientedState;
-import com.android.quickstep.util.SplitSelectStateController;
-import com.android.systemui.shared.recents.model.Task;
-import com.android.systemui.shared.recents.model.ThumbnailData;
-import com.android.systemui.shared.recents.utilities.PreviewPositionHelper;
-import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
-import com.android.wm.shell.common.split.SplitScreenConstants.PersistentSnapPosition;
-
-import kotlin.Unit;
-
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Optional;
-import java.util.function.Consumer;
-
-/**
- * TaskView that contains and shows thumbnails for not one, BUT TWO(!!) tasks
- *
- * That's right. If you call within the next 5 minutes we'll go ahead and double your order and
- * send you !! TWO !! Tasks along with their TaskThumbnailViews complimentary. On. The. House.
- * And not only that, we'll even clean up your thumbnail request if you don't like it.
- * All the benefits of one TaskView, except DOUBLED!
- *
- * (Icon loading sold separately, fees may apply. Shipping & Handling for Overlays not included).
- */
-public class GroupedTaskView extends TaskView {
-
- private static final String TAG = "GroupedTaskView";
- // TODO(b/336612373): Support new TTV for GroupedTaskView
- private TaskThumbnailViewDeprecated mSnapshotView2;
- private TaskViewIcon mIconView2;
- @Nullable
- private CancellableTask<ThumbnailData> mThumbnailLoadRequest2;
- @Nullable
- private CancellableTask mIconLoadRequest2;
- private final float[] mIcon2CenterCoords = new float[2];
- private TransformingTouchDelegate mIcon2TouchDelegate;
- @Nullable
- private SplitBounds mSplitBoundsConfig;
- private final DigitalWellBeingToast mDigitalWellBeingToast2;
-
- public GroupedTaskView(Context context) {
- this(context, null);
- }
-
- public GroupedTaskView(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public GroupedTaskView(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- mDigitalWellBeingToast2 = new DigitalWellBeingToast(mContainer, this);
- }
-
- /**
- * Returns the second task bound to this TaskView.
- *
- * @deprecated Use {@link #mTaskContainers} instead.
- */
- @Deprecated
- @Nullable
- private Task getSecondTask() {
- return mTaskContainers.size() > 1 ? mTaskContainers.get(1).getTask() : null;
- }
-
- @Override
- public Unit getThumbnailBounds(@NonNull Rect bounds, boolean relativeToDragLayer) {
- if (mSplitBoundsConfig == null) {
- super.getThumbnailBounds(bounds, relativeToDragLayer);
- return Unit.INSTANCE;
- }
- if (relativeToDragLayer) {
- Rect firstThumbnailBounds = new Rect();
- Rect secondThumbnailBounds = new Rect();
- BaseDragLayer dragLayer = mContainer.getDragLayer();
- dragLayer.getDescendantRectRelativeToSelf(
- mTaskThumbnailViewDeprecated, firstThumbnailBounds);
- dragLayer.getDescendantRectRelativeToSelf(mSnapshotView2, secondThumbnailBounds);
-
- bounds.set(firstThumbnailBounds);
- bounds.union(secondThumbnailBounds);
- } else {
- bounds.set(getSnapshotViewBounds(mTaskThumbnailViewDeprecated));
- bounds.union(getSnapshotViewBounds(mSnapshotView2));
- }
- return Unit.INSTANCE;
- }
-
- private Rect getSnapshotViewBounds(@NonNull View snapshotView) {
- int snapshotViewX = Math.round(snapshotView.getX());
- int snapshotViewY = Math.round(snapshotView.getY());
- return new Rect(snapshotViewX,
- snapshotViewY,
- snapshotViewX + snapshotView.getWidth(),
- snapshotViewY + snapshotView.getHeight());
- }
-
- @Override
- protected void onFinishInflate() {
- super.onFinishInflate();
- mSnapshotView2 = findViewById(R.id.bottomright_snapshot);
- ViewStub iconViewStub2 = findViewById(R.id.bottomRight_icon);
- if (enableOverviewIconMenu()) {
- iconViewStub2.setLayoutResource(R.layout.icon_app_chip_view);
- } else {
- iconViewStub2.setLayoutResource(R.layout.icon_view);
- }
- mIconView2 = (TaskViewIcon) iconViewStub2.inflate();
- mIcon2TouchDelegate = new TransformingTouchDelegate(mIconView2.asView());
- }
-
- public void bind(Task primary, Task secondary, RecentsOrientedState orientedState,
- @Nullable SplitBounds splitBoundsConfig) {
- super.bind(primary, orientedState);
- mTaskContainers = Arrays.asList(
- mTaskContainers.get(0),
- new TaskContainer(secondary, findViewById(R.id.bottomright_snapshot),
- mIconView2, STAGE_POSITION_BOTTOM_OR_RIGHT, mDigitalWellBeingToast2));
- mTaskContainers.get(0).setStagePosition(
- SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT);
- mSnapshotView2.bind(secondary);
- mSplitBoundsConfig = splitBoundsConfig;
- if (mSplitBoundsConfig == null) {
- return;
- }
- mTaskThumbnailViewDeprecated.getPreviewPositionHelper().setSplitBounds(
- convertLauncherSplitBoundsToShell(splitBoundsConfig),
- PreviewPositionHelper.STAGE_POSITION_TOP_OR_LEFT);
- mSnapshotView2.getPreviewPositionHelper().setSplitBounds(
- convertLauncherSplitBoundsToShell(splitBoundsConfig),
- PreviewPositionHelper.STAGE_POSITION_BOTTOM_OR_RIGHT);
- }
-
- /**
- * Sets up an on-click listener and the visibility for show_windows icon on top of each task.
- */
- @Override
- public void setUpShowAllInstancesListener() {
- // sets up the listener for the left/top task
- super.setUpShowAllInstancesListener();
- if (mTaskContainers.size() < 2) {
- return;
- }
-
- // right/bottom task's base package name
- String taskPackageName = mTaskContainers.get(1).getTask().key.getPackageName();
-
- // icon of the right/bottom task
- View showWindowsView = findViewById(R.id.show_windows_right);
- updateFilterCallback(showWindowsView, getFilterUpdateCallback(taskPackageName));
- }
-
- @Override
- public void onTaskListVisibilityChanged(boolean visible, int changes) {
- super.onTaskListVisibilityChanged(visible, changes);
- if (visible) {
- RecentsModel model = RecentsModel.INSTANCE.get(getContext());
- TaskThumbnailCache thumbnailCache = model.getThumbnailCache();
- TaskIconCache iconCache = model.getIconCache();
-
- if (needsUpdate(changes, FLAG_UPDATE_THUMBNAIL)) {
- mThumbnailLoadRequest2 = thumbnailCache.updateThumbnailInBackground(
- getSecondTask(),
- thumbnailData -> mSnapshotView2.setThumbnail(getSecondTask(),
- thumbnailData
- ));
- }
-
- if (needsUpdate(changes, FLAG_UPDATE_ICON)) {
- mIconLoadRequest2 = iconCache.updateIconInBackground(getSecondTask(),
- (task) -> {
- setIcon(mIconView2, task.icon);
- if (enableOverviewIconMenu()) {
- setText(mIconView2, task.title);
- }
- mDigitalWellBeingToast2.initialize(getSecondTask());
- mDigitalWellBeingToast2.setSplitConfiguration(mSplitBoundsConfig);
- mDigitalWellBeingToast.setSplitConfiguration(mSplitBoundsConfig);
- });
- }
- } else {
- if (needsUpdate(changes, FLAG_UPDATE_THUMBNAIL)) {
- mSnapshotView2.setThumbnail(null, null);
- // Reset the task thumbnail reference as well (it will be fetched from the cache or
- // reloaded next time we need it)
- getSecondTask().thumbnail = null;
- }
- if (needsUpdate(changes, FLAG_UPDATE_ICON)) {
- setIcon(mIconView2, null);
- if (enableOverviewIconMenu()) {
- setText(mIconView2, null);
- }
- }
- }
- }
-
- public void updateSplitBoundsConfig(SplitBounds splitBounds) {
- mSplitBoundsConfig = splitBounds;
- invalidate();
- }
-
- @Nullable
- public SplitBounds getSplitBoundsConfig() {
- return mSplitBoundsConfig;
- }
-
- /**
- * Returns the {@link PersistentSnapPosition} of this pair of tasks.
- */
- public @PersistentSnapPosition int getSnapPosition() {
- if (mSplitBoundsConfig == null) {
- throw new IllegalStateException("mSplitBoundsConfig is null");
- }
-
- return mSplitBoundsConfig.snapPosition;
- }
-
- @Override
- public boolean offerTouchToChildren(MotionEvent event) {
- computeAndSetIconTouchDelegate(mIconView2, mIcon2CenterCoords, mIcon2TouchDelegate);
- if (mIcon2TouchDelegate.onTouchEvent(event)) {
- return true;
- }
-
- return super.offerTouchToChildren(event);
- }
-
- @Override
- protected void cancelPendingLoadTasks() {
- super.cancelPendingLoadTasks();
- if (mThumbnailLoadRequest2 != null) {
- mThumbnailLoadRequest2.cancel();
- mThumbnailLoadRequest2 = null;
- }
- if (mIconLoadRequest2 != null) {
- mIconLoadRequest2.cancel();
- mIconLoadRequest2 = null;
- }
- }
-
- @Nullable
- @Override
- public RunnableList launchTaskAnimated() {
- if (mTaskContainers.isEmpty()) {
- return null;
- }
-
- RunnableList endCallback = new RunnableList();
- RecentsView recentsView = getRecentsView();
- // Callbacks run from remote animation when recents animation not currently running
- InteractionJankMonitorWrapper.begin(this, Cuj.CUJ_SPLIT_SCREEN_ENTER,
- "Enter form GroupedTaskView");
- launchTaskInternal(success -> {
- endCallback.executeAllAndDestroy();
- InteractionJankMonitorWrapper.end(Cuj.CUJ_SPLIT_SCREEN_ENTER);
- }, false /* freezeTaskList */, true /*launchingExistingTaskview*/);
-
- // Callbacks get run from recentsView for case when recents animation already running
- recentsView.addSideTaskLaunchCallback(endCallback);
- return endCallback;
- }
-
- @Override
- public void launchTask(@NonNull Consumer<Boolean> callback, boolean isQuickswitch) {
- launchTaskInternal(callback, isQuickswitch, false /*launchingExistingTaskview*/);
- }
-
- /**
- * @param launchingExistingTaskView {@link SplitSelectStateController#launchExistingSplitPair}
- * uses existence of GroupedTaskView as control flow of how to animate in the incoming task. If
- * we're launching from overview (from overview thumbnails) then pass in {@code true},
- * otherwise pass in {@code false} for case like quickswitching from home to task
- */
- private void launchTaskInternal(@NonNull Consumer<Boolean> callback, boolean isQuickswitch,
- boolean launchingExistingTaskView) {
- getRecentsView().getSplitSelectController().launchExistingSplitPair(
- launchingExistingTaskView ? this : null, getFirstTask().key.id,
- getSecondTask().key.id, SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT,
- callback, isQuickswitch, getSnapPosition());
- Log.d(TAG, "launchTaskInternal - launchExistingSplitPair: " + Arrays.toString(
- getTaskIds()));
- }
-
- @Override
- void refreshThumbnails(@Nullable HashMap<Integer, ThumbnailData> thumbnailDatas) {
- super.refreshThumbnails(thumbnailDatas);
- if (getSecondTask() != null && thumbnailDatas != null) {
- final ThumbnailData thumbnailData = thumbnailDatas.get(getSecondTask().key.id);
- if (thumbnailData != null) {
- mSnapshotView2.setThumbnail(getSecondTask(), thumbnailData);
- return;
- }
- }
-
- mSnapshotView2.refresh();
- }
-
- /**
- * Returns taskId that split selection was initiated with,
- * {@link ActivityTaskManager#INVALID_TASK_ID} if no tasks in this TaskView are part of
- * split selection
- */
- protected int getThisTaskCurrentlyInSplitSelection() {
- int initialTaskId = getRecentsView().getSplitSelectController().getInitialTaskId();
- return containsTaskId(initialTaskId) ? initialTaskId : INVALID_TASK_ID;
- }
-
- @Override
- protected int getLastSelectedChildTaskIndex() {
- SplitSelectStateController splitSelectController =
- getRecentsView().getSplitSelectController();
- if (splitSelectController.isDismissingFromSplitPair()) {
- // return the container index of the task that wasn't initially selected to split with
- // because that is the only remaining app that can be selected. The coordinate checks
- // below aren't reliable since both of those views may be gone/transformed
- int initSplitTaskId = getThisTaskCurrentlyInSplitSelection();
- if (initSplitTaskId != INVALID_TASK_ID) {
- return initSplitTaskId == getFirstTask().key.id ? 1 : 0;
- }
- }
-
- // Check which of the two apps was selected
- if (isCoordInView(mIconView2.asView(), mLastTouchDownPosition)
- || isCoordInView(mSnapshotView2, mLastTouchDownPosition)) {
- return 1;
- }
- return super.getLastSelectedChildTaskIndex();
- }
-
- private boolean isCoordInView(View v, PointF position) {
- float[] localPos = new float[]{position.x, position.y};
- Utilities.mapCoordInSelfToDescendant(v, this, localPos);
- return Utilities.pointInView(v, localPos[0], localPos[1], 0f /* slop */);
- }
-
- @Override
- public void onRecycle() {
- super.onRecycle();
- mSnapshotView2.setThumbnail(getSecondTask(), null);
- mSplitBoundsConfig = null;
- }
-
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- int widthSize = MeasureSpec.getSize(widthMeasureSpec);
- int heightSize = MeasureSpec.getSize(heightMeasureSpec);
- setMeasuredDimension(widthSize, heightSize);
- if (mSplitBoundsConfig == null || mTaskThumbnailViewDeprecated == null
- || mSnapshotView2 == null) {
- return;
- }
- int initSplitTaskId = getThisTaskCurrentlyInSplitSelection();
- if (initSplitTaskId == INVALID_TASK_ID) {
- getPagedOrientationHandler().measureGroupedTaskViewThumbnailBounds(
- mTaskThumbnailViewDeprecated,
- mSnapshotView2, widthSize, heightSize, mSplitBoundsConfig,
- mContainer.getDeviceProfile(), getLayoutDirection() == 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
- mTaskThumbnailViewDeprecated.applySplitSelectTranslateX(
- mTaskThumbnailViewDeprecated.getTranslationX());
- mTaskThumbnailViewDeprecated.applySplitSelectTranslateY(
- mTaskThumbnailViewDeprecated.getTranslationY());
- mSnapshotView2.applySplitSelectTranslateX(mSnapshotView2.getTranslationX());
- mSnapshotView2.applySplitSelectTranslateY(mSnapshotView2.getTranslationY());
- } else {
- // Currently being split with this taskView, let the non-split selected thumbnail
- // take up full thumbnail area
- Optional<TaskContainer> nonSplitContainer = mTaskContainers.stream().filter(
- container -> container.getTask().key.id != initSplitTaskId).findAny();
- nonSplitContainer.ifPresent(
- taskIdAttributeContainer -> taskIdAttributeContainer.getThumbnailView().measure(
- widthMeasureSpec, MeasureSpec.makeMeasureSpec(
- heightSize - mContainer.getDeviceProfile()
- .overviewTaskThumbnailTopMarginPx,
- MeasureSpec.EXACTLY)));
- }
- if (!enableOverviewIconMenu()) {
- updateIconPlacement();
- }
- }
-
- @Override
- public void setOverlayEnabled(boolean overlayEnabled) {
- if (FeatureFlags.enableAppPairs()) {
- super.setOverlayEnabled(overlayEnabled);
- } else {
- // Intentional no-op to prevent setting smart actions overlay on thumbnails
- }
- }
-
- @Override
- public void setOrientationState(RecentsOrientedState orientationState) {
- DeviceProfile deviceProfile = mContainer.getDeviceProfile();
- if (enableOverviewIconMenu() && mSplitBoundsConfig != null) {
- ViewGroup.LayoutParams layoutParams = getLayoutParams();
- Pair<Point, Point> groupedTaskViewSizes =
- orientationState.getOrientationHandler().getGroupedTaskViewSizes(
- deviceProfile,
- mSplitBoundsConfig,
- layoutParams.width,
- layoutParams.height
- );
- int iconViewMarginStart = getResources().getDimensionPixelSize(
- R.dimen.task_thumbnail_icon_menu_expanded_top_start_margin);
- int iconViewBackgroundMarginStart = getResources().getDimensionPixelSize(
- R.dimen.task_thumbnail_icon_menu_background_margin_top_start);
- int iconMargins = (iconViewMarginStart + iconViewBackgroundMarginStart) * 2;
- ((IconAppChipView) mIconView).setMaxWidth(groupedTaskViewSizes.first.x - iconMargins);
- ((IconAppChipView) mIconView2).setMaxWidth(groupedTaskViewSizes.second.x - iconMargins);
- }
- // setMaxWidth() needs to be called before mIconView.setIconOrientation which is called in
- // the super below.
- super.setOrientationState(orientationState);
-
- boolean isGridTask = deviceProfile.isTablet && !isFocusedTask();
- mIconView2.setIconOrientation(orientationState, isGridTask);
- updateIconPlacement();
- updateSecondaryDwbPlacement();
- }
-
- private void updateIconPlacement() {
- if (mSplitBoundsConfig == null) {
- return;
- }
-
- DeviceProfile deviceProfile = mContainer.getDeviceProfile();
- int taskIconHeight = deviceProfile.overviewTaskIconSizePx;
- boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
-
- if (enableOverviewIconMenu()) {
- ViewGroup.LayoutParams layoutParams = getLayoutParams();
- Pair<Point, Point> groupedTaskViewSizes =
- getPagedOrientationHandler()
- .getGroupedTaskViewSizes(
- deviceProfile,
- mSplitBoundsConfig,
- layoutParams.width,
- layoutParams.height
- );
-
- getPagedOrientationHandler().setSplitIconParams(mIconView.asView(), mIconView2.asView(),
- taskIconHeight, groupedTaskViewSizes.first.x, groupedTaskViewSizes.first.y,
- getLayoutParams().height, getLayoutParams().width, isRtl, deviceProfile,
- mSplitBoundsConfig);
- } else {
- getPagedOrientationHandler().setSplitIconParams(mIconView.asView(), mIconView2.asView(),
- taskIconHeight, mTaskThumbnailViewDeprecated.getMeasuredWidth(),
- mTaskThumbnailViewDeprecated.getMeasuredHeight(), getMeasuredHeight(),
- getMeasuredWidth(),
- isRtl, deviceProfile, mSplitBoundsConfig);
- }
- }
-
- private void updateSecondaryDwbPlacement() {
- if (getSecondTask() == null) {
- return;
- }
- mDigitalWellBeingToast2.initialize(getSecondTask());
- }
-
- @Override
- protected void updateSnapshotRadius() {
- super.updateSnapshotRadius();
- mSnapshotView2.setFullscreenParams(mCurrentFullscreenParams);
- }
-
- @Override
- protected void setIconsAndBannersTransitionProgress(float progress, boolean invert) {
- super.setIconsAndBannersTransitionProgress(progress, invert);
- // Value set by super call
- float scale = mIconView.getAlpha();
- mIconView2.setContentAlpha(scale);
- mDigitalWellBeingToast2.updateBannerOffset(1f - scale);
- }
-
- @Override
- public void setColorTint(float amount, int tintColor) {
- super.setColorTint(amount, tintColor);
- mIconView2.setIconColorTint(tintColor, amount);
- mSnapshotView2.setDimAlpha(amount);
- mDigitalWellBeingToast2.setBannerColorTint(tintColor, amount);
- }
-
- @Override
- protected void applyThumbnailSplashAlpha() {
- super.applyThumbnailSplashAlpha();
- mSnapshotView2.setSplashAlpha(mTaskThumbnailSplashAlpha);
- }
-
- @Override
- protected void refreshTaskThumbnailSplash() {
- super.refreshTaskThumbnailSplash();
- mSnapshotView2.refreshSplashView();
- }
-
- @Override
- protected void resetViewTransforms() {
- super.resetViewTransforms();
- mSnapshotView2.resetViewTransforms();
- }
-
- /**
- * Sets visibility for thumbnails and associated elements (DWB banners).
- * IconView is unaffected.
- *
- * When setting INVISIBLE, sets the visibility for the last selected child task.
- * When setting VISIBLE (as a reset), sets the visibility for both tasks.
- */
- @Override
- void setThumbnailVisibility(int visibility, int taskId) {
- for (TaskContainer container : mTaskContainers) {
- if (visibility == VISIBLE || container.getTask().key.id == taskId) {
- container.getThumbnailView().setVisibility(visibility);
- container.getDigitalWellBeingToast().setBannerVisibility(visibility);
- }
- }
- }
-}
diff --git a/quickstep/src/com/android/quickstep/views/GroupedTaskView.kt b/quickstep/src/com/android/quickstep/views/GroupedTaskView.kt
new file mode 100644
index 0000000..f6ae038
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/views/GroupedTaskView.kt
@@ -0,0 +1,521 @@
+/*
+ * Copyright (C) 2024 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.quickstep.views
+
+import android.app.ActivityTaskManager.INVALID_TASK_ID
+import android.content.Context
+import android.graphics.PointF
+import android.graphics.Rect
+import android.util.AttributeSet
+import android.util.Log
+import android.view.MotionEvent
+import android.view.View
+import android.view.ViewStub
+import com.android.internal.jank.Cuj
+import com.android.launcher3.Flags.enableOverviewIconMenu
+import com.android.launcher3.R
+import com.android.launcher3.Utilities
+import com.android.launcher3.config.FeatureFlags
+import com.android.launcher3.util.CancellableTask
+import com.android.launcher3.util.RunnableList
+import com.android.launcher3.util.SplitConfigurationOptions
+import com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT
+import com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT
+import com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_UNDEFINED
+import com.android.launcher3.util.TransformingTouchDelegate
+import com.android.quickstep.RecentsModel
+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.model.ThumbnailData
+import com.android.systemui.shared.recents.utilities.PreviewPositionHelper
+import com.android.systemui.shared.system.InteractionJankMonitorWrapper
+import com.android.wm.shell.common.split.SplitScreenConstants.PersistentSnapPosition
+
+/**
+ * TaskView that contains and shows thumbnails for not one, BUT TWO(!!) tasks
+ *
+ * That's right. If you call within the next 5 minutes we'll go ahead and double your order and send
+ * you !! TWO !! Tasks along with their TaskThumbnailViews complimentary. On. The. House. And not
+ * only that, we'll even clean up your thumbnail request if you don't like it. All the benefits of
+ * one TaskView, except DOUBLED!
+ *
+ * (Icon loading sold separately, fees may apply. Shipping & Handling for Overlays not included).
+ */
+class GroupedTaskView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
+ TaskView(context, attrs) {
+ // TODO(b/336612373): Support new TTV for GroupedTaskView
+ private val icon2CenterCoordinates = FloatArray(2)
+ private val digitalWellBeingToast2: DigitalWellBeingToast =
+ DigitalWellBeingToast(container, this)
+
+ private lateinit var snapshotView2: TaskThumbnailViewDeprecated
+ private lateinit var iconView2: TaskViewIcon
+ private lateinit var icon2TouchDelegate: TransformingTouchDelegate
+
+ var splitBoundsConfig: SplitConfigurationOptions.SplitBounds? = null
+ private set
+ private var thumbnailLoadRequest2: CancellableTask<ThumbnailData>? = null
+ private var iconLoadRequest2: CancellableTask<*>? = null
+
+ @get:PersistentSnapPosition
+ val snapPosition: Int
+ /** Returns the [PersistentSnapPosition] of this pair of tasks. */
+ get() = splitBoundsConfig?.snapPosition ?: STAGE_POSITION_UNDEFINED
+
+ @get:Deprecated("Use {@link #mTaskContainers} instead.")
+ private val secondTask: Task
+ /** Returns the second task bound to this TaskView. */
+ get() = taskContainers[1].task
+
+ override fun onFinishInflate() {
+ super.onFinishInflate()
+ snapshotView2 = findViewById(R.id.bottomright_snapshot)!!
+ val iconViewStub2 =
+ findViewById<ViewStub>(R.id.bottomRight_icon)!!.apply {
+ layoutResource =
+ if (enableOverviewIconMenu()) R.layout.icon_app_chip_view
+ else R.layout.icon_view
+ }
+ iconView2 = iconViewStub2.inflate() as TaskViewIcon
+ icon2TouchDelegate = TransformingTouchDelegate(iconView2.asView())
+ }
+
+ override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec)
+ val widthSize = MeasureSpec.getSize(widthMeasureSpec)
+ val heightSize = MeasureSpec.getSize(heightMeasureSpec)
+ setMeasuredDimension(widthSize, heightSize)
+ val splitBoundsConfig = splitBoundsConfig ?: return
+ val initSplitTaskId = getThisTaskCurrentlyInSplitSelection()
+ if (initSplitTaskId == INVALID_TASK_ID) {
+ pagedOrientationHandler.measureGroupedTaskViewThumbnailBounds(
+ taskThumbnailViewDeprecated,
+ snapshotView2,
+ 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
+ taskThumbnailViewDeprecated.applySplitSelectTranslateX(
+ taskThumbnailViewDeprecated.translationX
+ )
+ taskThumbnailViewDeprecated.applySplitSelectTranslateY(
+ taskThumbnailViewDeprecated.translationY
+ )
+ snapshotView2.applySplitSelectTranslateX(snapshotView2.translationX)
+ snapshotView2.applySplitSelectTranslateY(snapshotView2.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 }
+ ?.thumbnailView
+ ?.measure(
+ widthMeasureSpec,
+ MeasureSpec.makeMeasureSpec(
+ heightSize - container.deviceProfile.overviewTaskThumbnailTopMarginPx,
+ MeasureSpec.EXACTLY
+ )
+ )
+ }
+ if (!enableOverviewIconMenu()) {
+ updateIconPlacement()
+ }
+ }
+
+ override fun onRecycle() {
+ super.onRecycle()
+ snapshotView2.setThumbnail(secondTask, null)
+ splitBoundsConfig = null
+ }
+
+ fun bind(
+ primaryTask: Task,
+ secondaryTask: Task,
+ orientedState: RecentsOrientedState,
+ taskOverlayFactory: TaskOverlayFactory,
+ splitBoundsConfig: SplitConfigurationOptions.SplitBounds?,
+ ) {
+ cancelPendingLoadTasks()
+ setupTaskContainers(primaryTask, taskOverlayFactory)
+ taskContainers =
+ listOf(
+ taskContainers[0].apply { stagePosition = STAGE_POSITION_TOP_OR_LEFT },
+ TaskContainer(
+ secondaryTask,
+ findViewById(R.id.bottomright_snapshot)!!,
+ iconView2,
+ STAGE_POSITION_BOTTOM_OR_RIGHT,
+ digitalWellBeingToast2
+ )
+ )
+ snapshotView2.bind(secondaryTask, taskOverlayFactory)
+ this.splitBoundsConfig = splitBoundsConfig
+ this.splitBoundsConfig?.let {
+ taskThumbnailViewDeprecated.previewPositionHelper.setSplitBounds(
+ convertLauncherSplitBoundsToShell(it),
+ PreviewPositionHelper.STAGE_POSITION_TOP_OR_LEFT
+ )
+ snapshotView2.previewPositionHelper.setSplitBounds(
+ convertLauncherSplitBoundsToShell(it),
+ PreviewPositionHelper.STAGE_POSITION_BOTTOM_OR_RIGHT
+ )
+ }
+ setOrientationState(orientedState)
+ }
+
+ override fun setOrientationState(orientationState: RecentsOrientedState) {
+ if (enableOverviewIconMenu()) {
+ splitBoundsConfig?.let {
+ val groupedTaskViewSizes =
+ orientationState.orientationHandler.getGroupedTaskViewSizes(
+ container.deviceProfile,
+ it,
+ layoutParams.width,
+ layoutParams.height
+ )
+ val iconViewMarginStart =
+ resources.getDimensionPixelSize(
+ R.dimen.task_thumbnail_icon_menu_expanded_top_start_margin
+ )
+ val iconViewBackgroundMarginStart =
+ resources.getDimensionPixelSize(
+ R.dimen.task_thumbnail_icon_menu_background_margin_top_start
+ )
+ val iconMargins = (iconViewMarginStart + iconViewBackgroundMarginStart) * 2
+ // setMaxWidth() needs to be called before mIconView.setIconOrientation which is
+ // called in the super below.
+ (iconView as IconAppChipView).setMaxWidth(
+ groupedTaskViewSizes.first.x - iconMargins
+ )
+ (iconView2 as IconAppChipView).setMaxWidth(
+ groupedTaskViewSizes.second.x - iconMargins
+ )
+ }
+ }
+ super.setOrientationState(orientationState)
+ iconView2.setIconOrientation(orientationState, isGridTask)
+ updateIconPlacement()
+ }
+
+ override fun setThumbnailOrientation(orientationState: RecentsOrientedState) {
+ super.setThumbnailOrientation(orientationState)
+ digitalWellBeingToast2.initialize(secondTask)
+ }
+
+ private fun updateIconPlacement() {
+ val splitBoundsConfig = splitBoundsConfig ?: return
+ val taskIconHeight = container.deviceProfile.overviewTaskIconSizePx
+ val isRtl = layoutDirection == LAYOUT_DIRECTION_RTL
+ if (enableOverviewIconMenu()) {
+ val groupedTaskViewSizes =
+ pagedOrientationHandler.getGroupedTaskViewSizes(
+ container.deviceProfile,
+ splitBoundsConfig,
+ layoutParams.width,
+ layoutParams.height
+ )
+ pagedOrientationHandler.setSplitIconParams(
+ iconView.asView(),
+ iconView2.asView(),
+ taskIconHeight,
+ groupedTaskViewSizes.first.x,
+ groupedTaskViewSizes.first.y,
+ layoutParams.height,
+ layoutParams.width,
+ isRtl,
+ container.deviceProfile,
+ splitBoundsConfig
+ )
+ } else {
+ pagedOrientationHandler.setSplitIconParams(
+ iconView.asView(),
+ iconView2.asView(),
+ taskIconHeight,
+ taskThumbnailViewDeprecated.measuredWidth,
+ taskThumbnailViewDeprecated.measuredHeight,
+ measuredHeight,
+ measuredWidth,
+ isRtl,
+ container.deviceProfile,
+ splitBoundsConfig
+ )
+ }
+ }
+
+ override fun onTaskListVisibilityChanged(visible: Boolean, changes: Int) {
+ super.onTaskListVisibilityChanged(visible, changes)
+ val model = RecentsModel.INSTANCE.get(context)
+ if (needsUpdate(changes, FLAG_UPDATE_THUMBNAIL)) {
+ if (visible) {
+ thumbnailLoadRequest2 =
+ model.thumbnailCache.updateThumbnailInBackground(secondTask) {
+ snapshotView2.setThumbnail(secondTask, it)
+ }
+ } else {
+ snapshotView2.setThumbnail(null, null)
+ // Reset the task thumbnail reference as well (it will be fetched from the cache or
+ // reloaded next time we need it)
+ secondTask.thumbnail = null
+ }
+ }
+ if (needsUpdate(changes, FLAG_UPDATE_ICON)) {
+ if (visible) {
+ iconLoadRequest2 =
+ model.iconCache.updateIconInBackground(secondTask) {
+ setIcon(iconView2, it.icon)
+ if (enableOverviewIconMenu()) {
+ setText(iconView2, it.title)
+ }
+ digitalWellBeingToast2.initialize(secondTask)
+ digitalWellBeingToast2.setSplitConfiguration(splitBoundsConfig)
+ digitalWellBeingToast.setSplitConfiguration(splitBoundsConfig)
+ }
+ } else {
+ setIcon(iconView2, null)
+ if (enableOverviewIconMenu()) {
+ setText(iconView2, null)
+ }
+ }
+ }
+ }
+
+ override fun cancelPendingLoadTasks() {
+ super.cancelPendingLoadTasks()
+ thumbnailLoadRequest2?.cancel()
+ thumbnailLoadRequest2 = null
+ iconLoadRequest2?.cancel()
+ iconLoadRequest2 = null
+ }
+
+ override fun getThumbnailBounds(bounds: Rect, relativeToDragLayer: Boolean) {
+ splitBoundsConfig ?: return super.getThumbnailBounds(bounds, relativeToDragLayer)
+ if (relativeToDragLayer) {
+ val firstThumbnailBounds = Rect()
+ val secondThumbnailBounds = Rect()
+ with(container.dragLayer) {
+ getDescendantRectRelativeToSelf(snapshotView, firstThumbnailBounds)
+ getDescendantRectRelativeToSelf(snapshotView2, secondThumbnailBounds)
+ }
+ bounds.set(firstThumbnailBounds)
+ bounds.union(secondThumbnailBounds)
+ } else {
+ bounds.set(getSnapshotViewBounds(snapshotView))
+ bounds.union(getSnapshotViewBounds(snapshotView2))
+ }
+ }
+
+ private fun getSnapshotViewBounds(snapshotView: View): Rect {
+ val snapshotViewX = Math.round(snapshotView.x)
+ val snapshotViewY = Math.round(snapshotView.y)
+ return Rect(
+ snapshotViewX,
+ snapshotViewY,
+ snapshotViewX + snapshotView.width,
+ snapshotViewY + snapshotView.height
+ )
+ }
+
+ /**
+ * Sets up an on-click listener and the visibility for show_windows icon on top of each task.
+ */
+ override fun setUpShowAllInstancesListener() {
+ // sets up the listener for the left/top task
+ super.setUpShowAllInstancesListener()
+ // right/bottom task's base package name
+ val taskPackageName = taskContainers[1].task.key.packageName
+ // icon of the right/bottom task
+ val showWindowsView = findViewById<View>(R.id.show_windows_right)!!
+ updateFilterCallback(showWindowsView, getFilterUpdateCallback(taskPackageName))
+ }
+
+ fun updateSplitBoundsConfig(splitBounds: SplitConfigurationOptions.SplitBounds?) {
+ splitBoundsConfig = splitBounds
+ invalidate()
+ }
+
+ override fun offerTouchToChildren(event: MotionEvent): Boolean {
+ computeAndSetIconTouchDelegate(iconView2, icon2CenterCoordinates, icon2TouchDelegate)
+ return if (icon2TouchDelegate.onTouchEvent(event)) {
+ true
+ } else super.offerTouchToChildren(event)
+ }
+
+ override fun launchTaskAnimated(): RunnableList? {
+ if (taskContainers.isEmpty()) {
+ Log.d(TAG, "launchTaskAnimated - task is not bound")
+ return null
+ }
+ val recentsView = recentsView ?: return null
+ val endCallback = RunnableList()
+ // Callbacks run from remote animation when recents animation not currently running
+ InteractionJankMonitorWrapper.begin(
+ this,
+ Cuj.CUJ_SPLIT_SCREEN_ENTER,
+ "Enter form GroupedTaskView"
+ )
+ launchTaskInternal(isQuickSwitch = false, launchingExistingTaskView = true) {
+ endCallback.executeAllAndDestroy()
+ InteractionJankMonitorWrapper.end(Cuj.CUJ_SPLIT_SCREEN_ENTER)
+ }
+
+ // Callbacks get run from recentsView for case when recents animation already running
+ recentsView.addSideTaskLaunchCallback(endCallback)
+ return endCallback
+ }
+
+ override fun launchTask(callback: (launched: Boolean) -> Unit, isQuickSwitch: Boolean) {
+ launchTaskInternal(isQuickSwitch, false, callback /*launchingExistingTaskview*/)
+ }
+
+ /**
+ * @param launchingExistingTaskView [SplitSelectStateController.launchExistingSplitPair] uses
+ * existence of GroupedTaskView as control flow of how to animate in the incoming task. If
+ * we're launching from overview (from overview thumbnails) then pass in `true`, otherwise
+ * pass in `false` for case like quickswitching from home to task
+ */
+ private fun launchTaskInternal(
+ isQuickSwitch: Boolean,
+ launchingExistingTaskView: Boolean,
+ callback: (launched: Boolean) -> Unit
+ ) {
+ recentsView?.let {
+ it.splitSelectController.launchExistingSplitPair(
+ if (launchingExistingTaskView) this else null,
+ taskContainers[0].task.key.id,
+ taskContainers[1].task.key.id,
+ STAGE_POSITION_TOP_OR_LEFT,
+ callback,
+ isQuickSwitch,
+ snapPosition
+ )
+ Log.d(TAG, "launchTaskInternal - launchExistingSplitPair: ${taskIds.contentToString()}")
+ }
+ }
+
+ override fun refreshThumbnails(thumbnailDatas: HashMap<Int, ThumbnailData?>?) {
+ super.refreshThumbnails(thumbnailDatas)
+ thumbnailDatas?.get(secondTask.key.id)?.let { snapshotView2.setThumbnail(secondTask, it) }
+ ?: { snapshotView2.refresh() }
+ }
+
+ /**
+ * Returns taskId that split selection was initiated with, [INVALID_TASK_ID] if no tasks in this
+ * TaskView are part of split selection
+ */
+ private fun getThisTaskCurrentlyInSplitSelection(): Int {
+ val initialTaskId = recentsView?.splitSelectController?.initialTaskId
+ return if (initialTaskId != null && containsTaskId(initialTaskId)) initialTaskId
+ else INVALID_TASK_ID
+ }
+
+ override fun getLastSelectedChildTaskIndex(): Int {
+ if (recentsView?.splitSelectController?.isDismissingFromSplitPair == true) {
+ // return the container index of the task that wasn't initially selected to split
+ // with because that is the only remaining app that can be selected. The coordinate
+ // checks below aren't reliable since both of those views may be gone/transformed
+ val initSplitTaskId = getThisTaskCurrentlyInSplitSelection()
+ if (initSplitTaskId != INVALID_TASK_ID) {
+ return if (initSplitTaskId == firstTask.key.id) 1 else 0
+ }
+ }
+
+ // Check which of the two apps was selected
+ if (
+ iconView2.asView().containsPoint(mLastTouchDownPosition) ||
+ snapshotView2.containsPoint(mLastTouchDownPosition)
+ ) {
+ return 1
+ }
+ return super.getLastSelectedChildTaskIndex()
+ }
+
+ private fun View.containsPoint(position: PointF): Boolean {
+ val localPos = floatArrayOf(position.x, position.y)
+ Utilities.mapCoordInSelfToDescendant(this, this@GroupedTaskView, localPos)
+ return Utilities.pointInView(this, localPos[0], localPos[1], 0f /* slop */)
+ }
+
+ override fun setIconsAndBannersTransitionProgress(progress: Float, invert: Boolean) {
+ super.setIconsAndBannersTransitionProgress(progress, invert)
+ getIconContentScale(invert).let {
+ iconView2.setContentAlpha(it)
+ digitalWellBeingToast2.updateBannerOffset(1f - it)
+ }
+ }
+
+ override fun setColorTint(amount: Float, tintColor: Int) {
+ super.setColorTint(amount, tintColor)
+ iconView2.setIconColorTint(tintColor, amount)
+ snapshotView2.dimAlpha = amount
+ digitalWellBeingToast2.setBannerColorTint(tintColor, amount)
+ }
+
+ /**
+ * Sets visibility for thumbnails and associated elements (DWB banners). IconView is unaffected.
+ *
+ * When setting INVISIBLE, sets the visibility for the last selected child task. When setting
+ * VISIBLE (as a reset), sets the visibility for both tasks.
+ */
+ override fun setThumbnailVisibility(visibility: Int, taskId: Int) {
+ taskContainers.forEach {
+ if (visibility == VISIBLE || it.task.key.id == taskId) {
+ it.thumbnailView.visibility = visibility
+ it.digitalWellBeingToast?.setBannerVisibility(visibility)
+ }
+ }
+ }
+
+ override fun setOverlayEnabled(overlayEnabled: Boolean) {
+ if (FeatureFlags.enableAppPairs()) {
+ super.setOverlayEnabled(overlayEnabled)
+ } else {
+ // Intentional no-op to prevent setting smart actions overlay on thumbnails
+ }
+ }
+
+ override fun refreshTaskThumbnailSplash() {
+ super.refreshTaskThumbnailSplash()
+ snapshotView2.refreshSplashView()
+ }
+
+ override fun updateSnapshotRadius() {
+ super.updateSnapshotRadius()
+ snapshotView2.setFullscreenParams(currentFullscreenParams)
+ }
+
+ override fun applyThumbnailSplashAlpha() {
+ super.applyThumbnailSplashAlpha()
+ snapshotView2.setSplashAlpha(taskThumbnailSplashAlpha)
+ }
+
+ override fun resetViewTransforms() {
+ super.resetViewTransforms()
+ snapshotView2.resetViewTransforms()
+ }
+
+ companion object {
+ private const val TAG = "GroupedTaskView"
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
index 8d1907f..5284b44 100644
--- a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
@@ -56,6 +56,8 @@
import com.android.quickstep.util.SplitSelectStateController;
import com.android.systemui.shared.recents.model.Task;
+import kotlin.Unit;
+
/**
* {@link RecentsView} used in Launcher activity
*/
@@ -107,7 +109,7 @@
}
@Override
- protected void onTaskLaunchAnimationEnd(boolean success) {
+ protected Unit onTaskLaunchAnimationEnd(boolean success) {
if (success) {
getStateManager().moveToRestState();
} else {
@@ -115,6 +117,7 @@
mContainer.getAllAppsController().setState(state);
}
super.onTaskLaunchAnimationEnd(success);
+ return Unit.INSTANCE;
}
@Override
@@ -143,7 +146,7 @@
@Override
public void onStateTransitionStart(LauncherState toState) {
- setOverviewStateEnabled(toState.overviewUi);
+ setOverviewStateEnabled(toState.isRecentsViewVisible);
setOverviewGridEnabled(toState.displayOverviewTasksAsGrid(mContainer.getDeviceProfile()));
setOverviewFullscreenEnabled(toState.getOverviewFullscreenProgress() == 1);
@@ -154,7 +157,7 @@
}
// Set border after select mode changes to avoid showing border during state transition
- if (!toState.overviewUi || toState == OVERVIEW_MODAL_TASK) {
+ if (!toState.isRecentsViewVisible || toState == OVERVIEW_MODAL_TASK) {
setTaskBorderEnabled(false);
}
@@ -178,7 +181,7 @@
setOverviewSelectEnabled(false);
}
- if (finalState.overviewUi && finalState != OVERVIEW_MODAL_TASK) {
+ if (finalState.isRecentsViewVisible && finalState != OVERVIEW_MODAL_TASK) {
setTaskBorderEnabled(true);
}
@@ -203,7 +206,7 @@
public boolean onTouchEvent(MotionEvent ev) {
boolean result = super.onTouchEvent(ev);
// Do not let touch escape to siblings below this view.
- return result || getStateManager().getState().overviewUi;
+ return result || getStateManager().getState().isRecentsViewVisible;
}
@Override
diff --git a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
index ba60141..83a2ceb 100644
--- a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
+++ b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
@@ -20,7 +20,6 @@
import android.content.res.Configuration;
import android.graphics.Rect;
import android.util.AttributeSet;
-import android.util.FloatProperty;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
@@ -34,36 +33,22 @@
import com.android.launcher3.Flags;
import com.android.launcher3.Insettable;
import com.android.launcher3.R;
+import com.android.launcher3.anim.AnimatedFloat;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.MultiValueAlpha;
import com.android.launcher3.util.NavigationMode;
import com.android.quickstep.TaskOverlayFactory.OverlayUICallbacks;
-import com.android.quickstep.util.AppPairsController;
import com.android.quickstep.util.LayoutUtils;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Arrays;
-import java.util.function.Consumer;
/**
* View for showing action buttons in Overview
*/
public class OverviewActionsView<T extends OverlayUICallbacks> extends FrameLayout
implements OnClickListener, Insettable {
- public static final FloatProperty<Consumer<Float>> FLOAT_SETTER =
- new FloatProperty<>("floatSetter") {
- @Override
- public void setValue(Consumer<Float> consumer, float v) {
- consumer.accept(v);
- }
-
- @Override
- public Float get(Consumer<Float> consumer) {
- return -1f;
- }
- };
-
private final Rect mInsets = new Rect();
@IntDef(flag = true, value = {
@@ -110,7 +95,13 @@
public @interface SplitButtonHiddenFlags { }
public static final int FLAG_SMALL_SCREEN_HIDE_SPLIT = 1 << 0;
- /** Holds MultiValueAlpha values for all actions buttons */
+ /**
+ * Holds an AnimatedFloat for each alpha property, used to set or animate alpha values in
+ * {@link #mMultiValueAlphas}.
+ */
+ private final AnimatedFloat[] mAlphaProperties = new AnimatedFloat[NUM_ALPHAS];
+
+ /** Holds MultiValueAlpha values for all actions bars */
private final MultiValueAlpha[] mMultiValueAlphas = new MultiValueAlpha[2];
/** Index used for single-task actions in the mMultiValueAlphas array */
private static final int ACTIONS_ALPHAS = 0;
@@ -161,11 +152,21 @@
// These will take up the same space on the screen and alternate visibility as needed.
mActionButtons = findViewById(R.id.action_buttons);
mGroupActionButtons = findViewById(R.id.group_action_buttons);
- // Initialize a list to set alpha on mActionButtons and mGroupActionButtons simultaneously.
+ // Initialize a list to hold alphas for mActionButtons and mGroupActionButtons.
mMultiValueAlphas[ACTIONS_ALPHAS] = new MultiValueAlpha(mActionButtons, NUM_ALPHAS);
mMultiValueAlphas[GROUP_ACTIONS_ALPHAS] =
new MultiValueAlpha(mGroupActionButtons, NUM_ALPHAS);
Arrays.stream(mMultiValueAlphas).forEach(a -> a.setUpdateVisibility(true));
+ // To control alpha simultaneously on mActionButtons and mGroupActionButtons, we set up an
+ // AnimatedFloat for each alpha property.
+ for (int i = 0; i < NUM_ALPHAS; i++) {
+ final int index = i;
+ mAlphaProperties[index] = new AnimatedFloat(() -> {
+ for (MultiValueAlpha multiValueAlpha : mMultiValueAlphas) {
+ multiValueAlpha.get(index).setValue(mAlphaProperties[index].value);
+ }
+ }, 1f /* initialValue */);
+ }
// The screenshot button is implemented as a Button in launcher3 and NexusLauncher, but is
// an ImageButton in go launcher (does not share a common class with Button). Take care when
@@ -222,7 +223,7 @@
mHiddenFlags &= ~visibilityFlags;
}
boolean isHidden = mHiddenFlags != 0;
- setActionsAlpha(INDEX_HIDDEN_FLAGS_ALPHA, isHidden ? 0 : 1);
+ mAlphaProperties[INDEX_HIDDEN_FLAGS_ALPHA].updateValue(isHidden ? 0 : 1);
}
/**
@@ -310,28 +311,24 @@
}
}
- private void setActionsAlpha(int index, float value) {
- Arrays.stream(mMultiValueAlphas).forEach(a -> a.get(index).setValue(value));
+ public AnimatedFloat getContentAlpha() {
+ return mAlphaProperties[INDEX_CONTENT_ALPHA];
}
- public Consumer<Float> getContentAlphaSetter() {
- return v -> setActionsAlpha(INDEX_CONTENT_ALPHA, v);
+ public AnimatedFloat getVisibilityAlpha() {
+ return mAlphaProperties[INDEX_VISIBILITY_ALPHA];
}
- public Consumer<Float> getVisibilityAlphaSetter() {
- return v -> setActionsAlpha(INDEX_VISIBILITY_ALPHA, v);
+ public AnimatedFloat getFullscreenAlpha() {
+ return mAlphaProperties[INDEX_FULLSCREEN_ALPHA];
}
- public Consumer<Float> getFullscreenAlphaSetter() {
- return v -> setActionsAlpha(INDEX_FULLSCREEN_ALPHA, v);
+ public AnimatedFloat getShareTargetAlpha() {
+ return mAlphaProperties[INDEX_SHARE_TARGET_ALPHA];
}
- public Consumer<Float> getShareTargetAlphaSetter() {
- return v -> setActionsAlpha(INDEX_SHARE_TARGET_ALPHA, v);
- }
-
- public Consumer<Float> getIndexScrollAlphaSetter() {
- return v -> setActionsAlpha(INDEX_SCROLL_ALPHA, v);
+ public AnimatedFloat getIndexScrollAlpha() {
+ return mAlphaProperties[INDEX_SCROLL_ALPHA];
}
/**
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index a242e1d..3c0445f 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -45,6 +45,7 @@
import static com.android.launcher3.Utilities.squaredHypot;
import static com.android.launcher3.Utilities.squaredTouchSlop;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_OVERVIEW_ACTIONS_SPLIT;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_OVERVIEW_ORIENTATION_CHANGED;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_CLEAR_ALL;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_DISMISS_SWIPE_UP;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_LAUNCH_SWIPE_DOWN;
@@ -145,6 +146,7 @@
import com.android.launcher3.compat.AccessibilityManagerCompat;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.desktop.DesktopRecentsTransitionController;
+import com.android.launcher3.logger.LauncherAtom;
import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.statehandlers.DepthController;
@@ -168,7 +170,6 @@
import com.android.launcher3.util.VibratorWrapper;
import com.android.launcher3.util.ViewPool;
import com.android.quickstep.BaseContainerInterface;
-import com.android.quickstep.DesktopModeStatus;
import com.android.quickstep.GestureState;
import com.android.quickstep.OverviewCommandHelper;
import com.android.quickstep.RecentsAnimationController;
@@ -216,6 +217,9 @@
import com.android.systemui.shared.system.TaskStackChangeListener;
import com.android.systemui.shared.system.TaskStackChangeListeners;
import com.android.wm.shell.common.pip.IPipAnimationListener;
+import com.android.wm.shell.shared.DesktopModeStatus;
+
+import kotlin.Unit;
import java.util.ArrayList;
import java.util.Arrays;
@@ -1014,11 +1018,10 @@
for (int i = 0; i < getTaskViewCount(); i++) {
TaskView tv = requireTaskViewAt(i);
Task task = tv.getFirstTask();
- if (task != null && task.key != null && pkg.equals(task.key.getPackageName())
- && task.key.userId == user.getIdentifier()) {
+ if (pkg.equals(task.key.getPackageName()) && task.key.userId == user.getIdentifier()) {
task.icon = null;
TaskViewIcon firstIconView = tv.getFirstIconView();
- if (firstIconView != null && firstIconView.getDrawable() != null) {
+ if (firstIconView.getDrawable() != null) {
tv.onTaskListVisibilityChanged(true /* visible */);
}
}
@@ -1738,7 +1741,7 @@
int[] currentTaskIds;
TaskView currentTaskView = getTaskViewAt(mCurrentPage);
- if (currentTaskView != null && currentTaskView.getFirstTask() != null) {
+ if (currentTaskView != null) {
currentTaskIds = currentTaskView.getTaskIds();
} else {
currentTaskIds = new int[0];
@@ -1768,12 +1771,12 @@
// If we are entering Overview as a result of initiating a split from somewhere else
// (e.g. split from Home), we need to make sure the staged app is not drawn as a thumbnail.
- int stagedTaskIdToBeRemovedFromGrid;
+ int stagedTaskIdToBeRemoved;
if (isSplitSelectionActive()) {
- stagedTaskIdToBeRemovedFromGrid = mSplitSelectStateController.getInitialTaskId();
+ stagedTaskIdToBeRemoved = mSplitSelectStateController.getInitialTaskId();
updateCurrentTaskActionsVisibility();
} else {
- stagedTaskIdToBeRemovedFromGrid = INVALID_TASK_ID;
+ stagedTaskIdToBeRemoved = INVALID_TASK_ID;
}
// update the map of instance counts
mFilterState.updateInstanceCountMap(taskGroups);
@@ -1785,46 +1788,36 @@
// taskGroups backwards populates the thumbnail grid from least recent to most recent.
for (int i = taskGroups.size() - 1; i >= 0; i--) {
GroupTask groupTask = taskGroups.get(i);
- boolean isRemovalNeeded = stagedTaskIdToBeRemovedFromGrid != INVALID_TASK_ID
- && groupTask.containsTask(stagedTaskIdToBeRemovedFromGrid);
+ boolean isRemovalNeeded = stagedTaskIdToBeRemoved != INVALID_TASK_ID
+ && groupTask.containsTask(stagedTaskIdToBeRemoved);
- TaskView taskView;
- if (isRemovalNeeded && groupTask.hasMultipleTasks()) {
- // If we need to remove half of a pair of tasks, force a TaskView with Type.SINGLE
- // to be a temporary container for the remaining task.
- taskView = getTaskViewFromPool(TaskView.Type.SINGLE);
- } else {
- taskView = getTaskViewFromPool(groupTask.taskViewType);
+ if (isRemovalNeeded && !groupTask.hasMultipleTasks()) {
+ // If the task we need to remove is not part of a pair, avoiding creating the
+ // TaskView.
+ continue;
}
- addView(taskView);
-
- if (isRemovalNeeded && groupTask.hasMultipleTasks()) {
- if (groupTask.task1.key.id == stagedTaskIdToBeRemovedFromGrid) {
- taskView.bind(groupTask.task2, mOrientationState);
- } else {
- taskView.bind(groupTask.task1, mOrientationState);
- }
- } else if (isRemovalNeeded) {
- // If the task we need to remove is not part of a pair, bind it to the TaskView
- // first (to prevent problems), then remove the whole thing.
- taskView.bind(groupTask.task1, mOrientationState);
- removeView(taskView);
- } else if (taskView instanceof GroupedTaskView) {
+ // If we need to remove half of a pair of tasks, force a TaskView with Type.SINGLE
+ // to be a temporary container for the remaining task.
+ TaskView taskView = getTaskViewFromPool(
+ isRemovalNeeded ? TaskView.Type.SINGLE : groupTask.taskViewType);
+ if (taskView instanceof GroupedTaskView) {
boolean firstTaskIsLeftTopTask =
groupTask.mSplitBounds.leftTopTaskId == groupTask.task1.key.id;
Task leftTopTask = firstTaskIsLeftTopTask ? groupTask.task1 : groupTask.task2;
Task rightBottomTask = firstTaskIsLeftTopTask ? groupTask.task2 : groupTask.task1;
-
((GroupedTaskView) taskView).bind(leftTopTask, rightBottomTask, mOrientationState,
- groupTask.mSplitBounds);
+ mTaskOverlayFactory, groupTask.mSplitBounds);
} else if (taskView instanceof DesktopTaskView) {
((DesktopTaskView) taskView).bind(((DesktopTask) groupTask).tasks,
- mOrientationState);
+ mOrientationState, mTaskOverlayFactory);
mDesktopTaskView = (DesktopTaskView) taskView;
} else {
- taskView.bind(groupTask.task1, mOrientationState);
+ Task task = groupTask.task1.key.id == stagedTaskIdToBeRemoved ? groupTask.task2
+ : groupTask.task1;
+ taskView.bind(task, mOrientationState, mTaskOverlayFactory);
}
+ addView(taskView);
// enables instance filtering if the feature flag for it is on
if (FeatureFlags.ENABLE_MULTI_INSTANCE.get()) {
@@ -2029,7 +2022,7 @@
mClearAllButton.setFullscreenProgress(fullscreenProgress);
// Fade out the actions view quickly (0.1 range)
- mActionsView.getFullscreenAlphaSetter().accept(
+ mActionsView.getFullscreenAlpha().updateValue(
mapToRange(fullscreenProgress, 0, 0.1f, 1f, 0f, LINEAR));
}
@@ -2085,12 +2078,17 @@
: View.LAYOUT_DIRECTION_RTL);
mClearAllButton.setRotation(getPagedOrientationHandler().getDegreesRotated());
- if (forceRecreateDragLayerControllers
- || !getPagedOrientationHandler().equals(oldOrientationHandler)) {
+ boolean isOrientationHandlerChanged =
+ !getPagedOrientationHandler().equals(oldOrientationHandler);
+ if (forceRecreateDragLayerControllers || isOrientationHandlerChanged) {
// Changed orientations, update controllers so they intercept accordingly.
mContainer.getDragLayer().recreateControllers();
onOrientationChanged();
resetTaskVisuals();
+ // Log fake orientation changed.
+ if (isOrientationHandlerChanged) {
+ logOrientationChanged();
+ }
}
boolean isInLandscape = mOrientationState.getTouchRotation() != ROTATION_0
@@ -2175,7 +2173,8 @@
}
for (int i = 0; i < taskCount; i++) {
TaskView taskView = requireTaskViewAt(i);
- taskView.updateTaskSize();
+ taskView.updateTaskSize(mLastComputedTaskSize, mLastComputedGridTaskSize,
+ mLastComputedCarouselTaskSize);
taskView.setNonGridTranslationX(accumulatedTranslationX);
taskView.setNonGridPivotTranslationX(translateXToMiddle);
// Compensate space caused by TaskView scaling.
@@ -2280,8 +2279,8 @@
}
private void animateActionsViewAlpha(float alphaValue, long duration) {
- mActionsViewAlphaAnimator = ObjectAnimator.ofFloat(mActionsView.getVisibilityAlphaSetter(),
- OverviewActionsView.FLOAT_SETTER, alphaValue);
+ mActionsViewAlphaAnimator = ObjectAnimator.ofFloat(mActionsView.getVisibilityAlpha(),
+ AnimatedFloat.VALUE, alphaValue);
mActionsViewAlphaAnimatorFinalValue = alphaValue;
mActionsViewAlphaAnimator.setDuration(duration);
// Set autocancel to prevent race-conditiony setting of alpha from other animations
@@ -2300,7 +2299,7 @@
mClearAllButton.onRecentsViewScroll(scroll, mOverviewGridEnabled);
// Clear all button alpha was set by the previous line.
- mActionsView.getIndexScrollAlphaSetter().accept(1 - mClearAllButton.getScrollAlpha());
+ mActionsView.getIndexScrollAlpha().updateValue(1 - mClearAllButton.getScrollAlpha());
}
@Override
@@ -2794,26 +2793,24 @@
if (needDesktopTask) {
taskView = getTaskViewFromPool(TaskView.Type.DESKTOP);
mTmpRunningTasks = Arrays.copyOf(runningTasks, runningTasks.length);
- addView(taskView, 0);
((DesktopTaskView) taskView).bind(Arrays.asList(mTmpRunningTasks),
- mOrientationState);
+ mOrientationState, mTaskOverlayFactory);
} else if (needGroupTaskView) {
taskView = getTaskViewFromPool(TaskView.Type.GROUPED);
mTmpRunningTasks = new Task[]{runningTasks[0], runningTasks[1]};
- addView(taskView, 0);
// When we create a placeholder task view mSplitBoundsConfig will be null, but with
// the actual app running we won't need to show the thumbnail until all the tasks
// load later anyways
((GroupedTaskView)taskView).bind(mTmpRunningTasks[0], mTmpRunningTasks[1],
- mOrientationState, mSplitBoundsConfig);
+ mOrientationState, mTaskOverlayFactory, mSplitBoundsConfig);
} else {
taskView = getTaskViewFromPool(TaskView.Type.SINGLE);
- addView(taskView, 0);
// The temporary running task is only used for the duration between the start of the
// gesture and the task list is loaded and applied
mTmpRunningTasks = new Task[]{runningTasks[0]};
- taskView.bind(mTmpRunningTasks[0], mOrientationState);
+ taskView.bind(mTmpRunningTasks[0], mOrientationState, mTaskOverlayFactory);
}
+ addView(taskView, 0);
runningTaskViewId = taskView.getTaskViewId();
if (wasEmpty) {
addView(mClearAllButton);
@@ -2911,7 +2908,7 @@
mRunningTaskShowScreenshot = showScreenshot;
TaskView runningTaskView = getRunningTaskView();
if (runningTaskView != null) {
- runningTaskView.setShowScreenshot(mRunningTaskShowScreenshot);
+ runningTaskView.setShouldShowScreenshot(mRunningTaskShowScreenshot);
}
}
@@ -3755,7 +3752,7 @@
if (taskView == nextFocusedTaskView) {
// Enlarge the task to be focused next, and translate into focus position.
float scale = mTaskWidth / (float) mLastComputedGridTaskSize.width();
- anim.setFloat(taskView, TaskView.SNAPSHOT_SCALE, scale,
+ anim.setFloat(taskView, TaskView.DISMISS_SCALE, scale,
clampToProgress(LINEAR, animationStartProgress,
dismissTranslationInterpolationEnd));
anim.setFloat(taskView, taskView.getPrimaryDismissTranslationProperty(),
@@ -3826,19 +3823,17 @@
if (success) {
if (shouldRemoveTask) {
- if (dismissedTaskView.getFirstTask() != null) {
- if (dismissedTaskView.isRunningTask()) {
- finishRecentsAnimation(true /* toRecents */, false /* shouldPip */,
- () -> removeTaskInternal(dismissedTaskViewId));
- } else {
- removeTaskInternal(dismissedTaskViewId);
- }
- announceForAccessibility(
- getResources().getString(R.string.task_view_closed));
- mContainer.getStatsLogManager().logger()
- .withItemInfo(dismissedTaskView.getItemInfo())
- .log(LAUNCHER_TASK_DISMISS_SWIPE_UP);
+ if (dismissedTaskView.isRunningTask()) {
+ finishRecentsAnimation(true /* toRecents */, false /* shouldPip */,
+ () -> removeTaskInternal(dismissedTaskViewId));
+ } else {
+ removeTaskInternal(dismissedTaskViewId);
}
+ announceForAccessibility(
+ getResources().getString(R.string.task_view_closed));
+ mContainer.getStatsLogManager().logger()
+ .withItemInfo(dismissedTaskView.getItemInfo())
+ .log(LAUNCHER_TASK_DISMISS_SWIPE_UP);
}
int pageToSnapTo = mCurrentPage;
@@ -3887,7 +3882,8 @@
taskViewIdArray.removeValue(
finalNextFocusedTaskView.getTaskViewId());
}
- if (snappedIndex < taskViewIdArray.size()) {
+ if (snappedIndex >= 0
+ && snappedIndex < taskViewIdArray.size()) {
taskViewIdToSnapTo = taskViewIdArray.get(snappedIndex);
} else if (snappedIndex == taskViewIdArray.size()) {
// If the snapped task is the last item from the
@@ -4309,7 +4305,7 @@
int alphaInt = Math.round(alpha * 255);
mEmptyMessagePaint.setAlpha(alphaInt);
mEmptyIcon.setAlpha(alphaInt);
- mActionsView.getContentAlphaSetter().accept(mContentAlpha);
+ mActionsView.getContentAlpha().updateValue(mContentAlpha);
if (alpha > 0) {
setVisibility(VISIBLE);
@@ -4355,7 +4351,10 @@
public void updateRecentsRotation() {
final int rotation = TraceHelper.allowIpcs(
"RecentsView.updateRecentsRotation", () -> mContainer.getDisplay().getRotation());
- mOrientationState.setRecentsRotation(rotation);
+ // Log real orientation change.
+ if (mOrientationState.setRecentsRotation(rotation)) {
+ logOrientationChanged();
+ }
}
public void setLayoutRotation(int touchRotation, int displayRotation) {
@@ -5280,11 +5279,8 @@
} else {
tv.launchTask(this::onTaskLaunchAnimationEnd);
}
- Task task = tv.getFirstTask();
- if (task != null) {
- mContainer.getStatsLogManager().logger().withItemInfo(tv.getItemInfo())
- .log(LAUNCHER_TASK_LAUNCH_SWIPE_DOWN);
- }
+ mContainer.getStatsLogManager().logger().withItemInfo(tv.getItemInfo())
+ .log(LAUNCHER_TASK_LAUNCH_SWIPE_DOWN);
} else {
onTaskLaunchAnimationEnd(false);
}
@@ -5293,10 +5289,11 @@
return mPendingAnimation;
}
- protected void onTaskLaunchAnimationEnd(boolean success) {
+ protected Unit onTaskLaunchAnimationEnd(boolean success) {
if (success) {
resetTaskVisuals();
}
+ return Unit.INSTANCE;
}
@Override
@@ -5912,7 +5909,7 @@
return;
}
- taskView.setShowScreenshot(true);
+ taskView.setShouldShowScreenshot(true);
for (TaskContainer container : taskView.getTaskContainers()) {
if (container == null) {
continue;
@@ -5941,7 +5938,7 @@
Runnable onFinishRunnable) {
final TaskView taskView = getRunningTaskView();
if (taskView != null) {
- taskView.setShowScreenshot(true);
+ taskView.setShouldShowScreenshot(true);
taskView.refreshThumbnails(thumbnailDatas);
ViewUtils.postFrameDrawn(taskView, onFinishRunnable);
} else {
@@ -6301,6 +6298,24 @@
successCallback.run();
}
+ // Logs when the orientation of Overview changes. We log both real and fake orientation changes.
+ private void logOrientationChanged() {
+ // Only log when Overview is showing.
+ if (mOverviewStateEnabled) {
+ mContainer.getStatsLogManager()
+ .logger()
+ .withContainerInfo(
+ LauncherAtom.ContainerInfo.newBuilder()
+ .setTaskSwitcherContainer(
+ LauncherAtom.TaskSwitcherContainer.newBuilder()
+ .setOrientationHandler(
+ getPagedOrientationHandler()
+ .getHandlerTypeForLogging()))
+ .build())
+ .log(LAUNCHER_OVERVIEW_ORIENTATION_CHANGED);
+ }
+ }
+
public interface TaskLaunchListener {
void onTaskLaunched();
}
diff --git a/src/com/android/quickstep/views/RecentsViewContainer.java b/quickstep/src/com/android/quickstep/views/RecentsViewContainer.java
similarity index 80%
rename from src/com/android/quickstep/views/RecentsViewContainer.java
rename to quickstep/src/com/android/quickstep/views/RecentsViewContainer.java
index 0c3f4f1..060c71e 100644
--- a/src/com/android/quickstep/views/RecentsViewContainer.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsViewContainer.java
@@ -27,6 +27,7 @@
import android.view.Window;
import com.android.launcher3.BaseActivity;
+import com.android.launcher3.logger.LauncherAtom;
import com.android.launcher3.util.SystemUiController;
import com.android.launcher3.views.ActivityContext;
import com.android.launcher3.views.ScrimView;
@@ -165,4 +166,36 @@
* Begins transition from overview back to homescreen
*/
void returnToHomescreen();
+
+ /**
+ * True if the overview panel is visible.
+ * @return Boolean
+ */
+ boolean isRecentsViewVisible();
+
+ /**
+ * Overwrites any logged item in Launcher that doesn't have a container with the
+ * {@link com.android.launcher3.touch.PagedOrientationHandler} in use for Overview.
+ *
+ * @param itemInfoBuilder {@link LauncherAtom.ItemInfo.Builder}
+ */
+ default void applyOverwritesToLogItem(LauncherAtom.ItemInfo.Builder itemInfoBuilder) {
+ if (!itemInfoBuilder.getContainerInfo().hasTaskSwitcherContainer()) {
+ return;
+ }
+
+ if (!isRecentsViewVisible()) {
+ return;
+ }
+
+ RecentsView<?, ?> recentsView = getOverviewPanel();
+ var orientationForLogging =
+ recentsView.getPagedOrientationHandler().getHandlerTypeForLogging();
+ itemInfoBuilder.setContainerInfo(
+ LauncherAtom.ContainerInfo.newBuilder()
+ .setTaskSwitcherContainer(
+ LauncherAtom.TaskSwitcherContainer.newBuilder()
+ .setOrientationHandler(orientationForLogging))
+ .build());
+ }
}
diff --git a/quickstep/src/com/android/quickstep/views/TaskMenuViewWithArrow.kt b/quickstep/src/com/android/quickstep/views/TaskMenuViewWithArrow.kt
index 7adc32e..659cc0c 100644
--- a/quickstep/src/com/android/quickstep/views/TaskMenuViewWithArrow.kt
+++ b/quickstep/src/com/android/quickstep/views/TaskMenuViewWithArrow.kt
@@ -43,10 +43,7 @@
companion object {
const val TAG = "TaskMenuViewWithArrow"
- fun <T> showForTask(
- taskContainer: TaskContainer,
- alignedOptionIndex: Int = 0
- ): Boolean where T : RecentsViewContainer, T : Context {
+ fun showForTask(taskContainer: TaskContainer, alignedOptionIndex: Int = 0): Boolean {
val container: RecentsViewContainer =
RecentsViewContainer.containerFromContext(taskContainer.taskView.context)
val taskMenuViewWithArrow =
@@ -54,7 +51,7 @@
R.layout.task_menu_with_arrow,
container.dragLayer,
false
- ) as TaskMenuViewWithArrow<T>
+ ) as TaskMenuViewWithArrow<*>
return taskMenuViewWithArrow.populateAndShowForTask(taskContainer, alignedOptionIndex)
}
diff --git a/quickstep/src/com/android/quickstep/views/TaskThumbnailViewDeprecated.java b/quickstep/src/com/android/quickstep/views/TaskThumbnailViewDeprecated.java
index 21c6ca8..fed6af5 100644
--- a/quickstep/src/com/android/quickstep/views/TaskThumbnailViewDeprecated.java
+++ b/quickstep/src/com/android/quickstep/views/TaskThumbnailViewDeprecated.java
@@ -54,6 +54,7 @@
import com.android.launcher3.util.SystemUiController;
import com.android.launcher3.util.SystemUiController.SystemUiControllerFlags;
import com.android.launcher3.util.ViewPool;
+import com.android.quickstep.TaskOverlayFactory;
import com.android.quickstep.TaskOverlayFactory.TaskOverlay;
import com.android.quickstep.orientation.RecentsPagedOrientationHandler;
import com.android.quickstep.views.TaskView.FullscreenDrawParams;
@@ -128,6 +129,7 @@
};
private final RecentsViewContainer mContainer;
+ private TaskOverlayFactory mTaskOverlayFactory;
@Nullable
private TaskOverlay mOverlay;
private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
@@ -188,7 +190,8 @@
/**
* Updates the thumbnail to draw the provided task
*/
- public void bind(Task task) {
+ public void bind(Task task, TaskOverlayFactory taskOverlayFactory) {
+ mTaskOverlayFactory = taskOverlayFactory;
getTaskOverlay().reset();
mTask = task;
int color = task == null ? Color.BLACK : task.colorBackground | 0xFF000000;
@@ -199,6 +202,17 @@
}
/**
+ * Sets TaskOverlayFactory without binding a task.
+ *
+ * @deprecated Should only be used when using new
+ * {@link com.android.quickstep.task.thumbnail.TaskThumbnailView}.
+ */
+ @Deprecated
+ public void setTaskOverlayFactory(TaskOverlayFactory taskOverlayFactory) {
+ mTaskOverlayFactory = taskOverlayFactory;
+ }
+
+ /**
* Updates the thumbnail.
*
* @param refreshNow whether the {@code thumbnailData} will be used to redraw immediately.
@@ -212,8 +226,8 @@
boolean refreshNow) {
mTask = task;
boolean thumbnailWasNull = mThumbnailData == null;
- mThumbnailData =
- (thumbnailData != null && thumbnailData.thumbnail != null) ? thumbnailData : null;
+ mThumbnailData = (thumbnailData != null && thumbnailData.getThumbnail() != null)
+ ? thumbnailData : null;
if (mTask != null) {
updateSplashView(mTask.icon);
}
@@ -238,8 +252,8 @@
* @param shouldRefreshOverlay whether to re-initialize overlay
*/
private void refresh(boolean shouldRefreshOverlay) {
- if (mThumbnailData != null && mThumbnailData.thumbnail != null) {
- Bitmap bm = mThumbnailData.thumbnail;
+ if (mThumbnailData != null && mThumbnailData.getThumbnail() != null) {
+ Bitmap bm = mThumbnailData.getThumbnail();
bm.prepareToDraw();
mBitmapShader = new BitmapShader(bm, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
mPaint.setShader(mBitmapShader);
@@ -281,7 +295,7 @@
public TaskOverlay getTaskOverlay() {
if (mOverlay == null) {
- mOverlay = getTaskView().getRecentsView().getTaskOverlayFactory().createOverlay(this);
+ mOverlay = mTaskOverlayFactory.createOverlay(this);
}
return mOverlay;
}
@@ -303,8 +317,10 @@
}
RectF bitmapRect = new RectF(
- 0, 0,
- mThumbnailData.thumbnail.getWidth(), mThumbnailData.thumbnail.getHeight());
+ 0,
+ 0,
+ mThumbnailData.getThumbnail().getWidth(),
+ mThumbnailData.getThumbnail().getHeight());
RectF viewRect = new RectF(0, 0, getMeasuredWidth(), getMeasuredHeight());
// The position helper matrix tells us how to transform the bitmap to fit the view, the
@@ -348,7 +364,7 @@
canvas.save();
// Draw the insets if we're being drawn fullscreen (we do this for quick switch).
drawOnCanvas(canvas, 0, 0, getMeasuredWidth(), getMeasuredHeight(),
- mFullscreenParams.mCurrentDrawnCornerRadius);
+ mFullscreenParams.getCurrentDrawnCornerRadius());
canvas.restore();
}
@@ -364,7 +380,8 @@
public void drawOnCanvas(Canvas canvas, float x, float y, float width, float height,
float cornerRadius) {
- if (mTask != null && getTaskView().isRunningTask() && !getTaskView().showScreenshot()) {
+ if (mTask != null && getTaskView().isRunningTask()
+ && !getTaskView().getShouldShowScreenshot()) {
canvas.drawRoundRect(x, y, width, height, cornerRadius, cornerRadius, mClearPaint);
canvas.drawRoundRect(x, y, width, height, cornerRadius, cornerRadius,
mDimmingPaintAfterClearing);
@@ -502,13 +519,13 @@
}
private boolean isThumbnailAspectRatioDifferentFromThumbnailData() {
- if (mThumbnailData == null || mThumbnailData.thumbnail == null) {
+ if (mThumbnailData == null || mThumbnailData.getThumbnail() == null) {
return false;
}
float thumbnailViewAspect = getWidth() / (float) getHeight();
- float thumbnailDataAspect =
- mThumbnailData.thumbnail.getWidth() / (float) mThumbnailData.thumbnail.getHeight();
+ float thumbnailDataAspect = mThumbnailData.getThumbnail().getWidth()
+ / (float) mThumbnailData.getThumbnail().getHeight();
return isRelativePercentDifferenceGreaterThan(thumbnailViewAspect,
thumbnailDataAspect, MAX_PCT_BEFORE_ASPECT_RATIOS_CONSIDERED_DIFFERENT);
@@ -559,10 +576,9 @@
DeviceProfile dp = mContainer.getDeviceProfile();
mPreviewPositionHelper.setOrientationChanged(false);
if (mBitmapShader != null && mThumbnailData != null) {
- mPreviewRect.set(0, 0, mThumbnailData.thumbnail.getWidth(),
- mThumbnailData.thumbnail.getHeight());
- int currentRotation = getTaskView().getRecentsView().getPagedViewOrientedState()
- .getRecentsActivityRotation();
+ mPreviewRect.set(0, 0, mThumbnailData.getThumbnail().getWidth(),
+ mThumbnailData.getThumbnail().getHeight());
+ int currentRotation = getTaskView().getOrientedState().getRecentsActivityRotation();
boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
mPreviewPositionHelper.updateThumbnailMatrix(mPreviewRect, mThumbnailData,
getMeasuredWidth(), getMeasuredHeight(), dp.isTablet, currentRotation, isRtl);
@@ -594,7 +610,7 @@
if (mThumbnailData == null) {
return null;
}
- return mThumbnailData.thumbnail;
+ return mThumbnailData.getThumbnail();
}
/**
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
deleted file mode 100644
index 1187222..0000000
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ /dev/null
@@ -1,2056 +0,0 @@
-/*
- * Copyright (C) 2017 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.quickstep.views;
-
-import static android.view.Display.DEFAULT_DISPLAY;
-import static android.widget.Toast.LENGTH_SHORT;
-
-import static com.android.app.animation.Interpolators.FAST_OUT_SLOW_IN;
-import static com.android.app.animation.Interpolators.LINEAR;
-import static com.android.launcher3.Flags.enableCursorHoverStates;
-import static com.android.launcher3.Flags.enableGridOnlyOverview;
-import static com.android.launcher3.Flags.enableOverviewIconMenu;
-import static com.android.launcher3.Flags.enableRefactorTaskThumbnail;
-import static com.android.launcher3.LauncherState.BACKGROUND_APP;
-import static com.android.launcher3.Utilities.getDescendantCoordRelativeToAncestor;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_ICON_TAP_OR_LONGPRESS;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_LAUNCH_TAP;
-import static com.android.launcher3.model.data.ItemInfoWithIcon.FLAG_NOT_PINNABLE;
-import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
-import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
-import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT;
-import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_UNDEFINED;
-import static com.android.launcher3.util.SplitConfigurationOptions.getLogEventForPosition;
-import static com.android.quickstep.TaskOverlayFactory.getEnabledShortcuts;
-import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.EXPECTING_TASK_APPEARED;
-import static com.android.quickstep.util.BorderAnimator.DEFAULT_BORDER_COLOR;
-
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.AnimatorSet;
-import android.animation.ObjectAnimator;
-import android.annotation.IdRes;
-import android.app.ActivityOptions;
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.TypedArray;
-import android.graphics.Canvas;
-import android.graphics.PointF;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import android.util.AttributeSet;
-import android.util.FloatProperty;
-import android.util.Log;
-import android.view.Display;
-import android.view.MotionEvent;
-import android.view.RemoteAnimationTarget;
-import android.view.TouchDelegate;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewStub;
-import android.view.accessibility.AccessibilityNodeInfo;
-import android.widget.FrameLayout;
-import android.widget.Toast;
-
-import androidx.annotation.IntDef;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-
-import com.android.app.animation.Interpolators;
-import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.Flags;
-import com.android.launcher3.LauncherSettings;
-import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
-import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.model.data.WorkspaceItemInfo;
-import com.android.launcher3.pm.UserCache;
-import com.android.launcher3.popup.SystemShortcut;
-import com.android.launcher3.testing.TestLogging;
-import com.android.launcher3.testing.shared.TestProtocol;
-import com.android.launcher3.util.ActivityOptionsWrapper;
-import com.android.launcher3.util.CancellableTask;
-import com.android.launcher3.util.ComponentKey;
-import com.android.launcher3.util.RunnableList;
-import com.android.launcher3.util.SafeCloseable;
-import com.android.launcher3.util.SplitConfigurationOptions;
-import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
-import com.android.launcher3.util.TraceHelper;
-import com.android.launcher3.util.TransformingTouchDelegate;
-import com.android.launcher3.util.ViewPool.Reusable;
-import com.android.quickstep.RecentsModel;
-import com.android.quickstep.RemoteAnimationTargets;
-import com.android.quickstep.RemoteTargetGluer.RemoteTargetHandle;
-import com.android.quickstep.TaskAnimationManager;
-import com.android.quickstep.TaskIconCache;
-import com.android.quickstep.TaskThumbnailCache;
-import com.android.quickstep.TaskUtils;
-import com.android.quickstep.TaskViewUtils;
-import com.android.quickstep.orientation.RecentsPagedOrientationHandler;
-import com.android.quickstep.task.thumbnail.TaskThumbnail;
-import com.android.quickstep.task.thumbnail.TaskThumbnailView;
-import com.android.quickstep.task.viewmodel.TaskViewData;
-import com.android.quickstep.util.ActiveGestureLog;
-import com.android.quickstep.util.BorderAnimator;
-import com.android.quickstep.util.RecentsOrientedState;
-import com.android.quickstep.util.SplitSelectStateController;
-import com.android.quickstep.util.TaskCornerRadius;
-import com.android.quickstep.util.TaskRemovedDuringLaunchListener;
-import com.android.systemui.shared.recents.model.Task;
-import com.android.systemui.shared.recents.model.ThumbnailData;
-import com.android.systemui.shared.system.ActivityManagerWrapper;
-import com.android.systemui.shared.system.QuickStepContract;
-
-import kotlin.Unit;
-
-import java.lang.annotation.Retention;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Optional;
-import java.util.function.Consumer;
-import java.util.stream.Stream;
-
-
-/**
- * A task in the Recents view.
- */
-public class TaskView extends FrameLayout implements Reusable {
-
- private static final String TAG = "TaskView";
- public static final int FLAG_UPDATE_ICON = 1;
- public static final int FLAG_UPDATE_THUMBNAIL = FLAG_UPDATE_ICON << 1;
- public static final int FLAG_UPDATE_CORNER_RADIUS = FLAG_UPDATE_THUMBNAIL << 1;
-
- public static final int FLAG_UPDATE_ALL = FLAG_UPDATE_ICON | FLAG_UPDATE_THUMBNAIL
- | FLAG_UPDATE_CORNER_RADIUS;
-
- /**
- * Used in conjunction with {@link #onTaskListVisibilityChanged(boolean, int)}, providing more
- * granularity on which components of this task require an update
- */
- @Retention(SOURCE)
- @IntDef({FLAG_UPDATE_ALL, FLAG_UPDATE_ICON, FLAG_UPDATE_THUMBNAIL, FLAG_UPDATE_CORNER_RADIUS})
- public @interface TaskDataChanges {
- }
-
- /**
- * Type of task view
- */
- @Retention(SOURCE)
- @IntDef({Type.SINGLE, Type.GROUPED, Type.DESKTOP})
- public @interface Type {
- int SINGLE = 1;
- int GROUPED = 2;
- int DESKTOP = 3;
- }
-
- /** The maximum amount that a task view can be scrimmed, dimmed or tinted. */
- public static final float MAX_PAGE_SCRIM_ALPHA = 0.4f;
-
- private static final float EDGE_SCALE_DOWN_FACTOR_CAROUSEL = 0.03f;
- private static final float EDGE_SCALE_DOWN_FACTOR_GRID = 0.00f;
-
- public static final long SCALE_ICON_DURATION = 120;
- private static final long DIM_ANIM_DURATION = 700;
-
- /**
- * This technically can be a vanilla {@link TouchDelegate} class, however that class requires
- * setting the touch bounds at construction, so we'd repeatedly be created many instances
- * unnecessarily as scrolling occurs, whereas {@link TransformingTouchDelegate} allows touch
- * delegated bounds only to be updated.
- */
- private TransformingTouchDelegate mIconTouchDelegate;
-
- private static final List<Rect> SYSTEM_GESTURE_EXCLUSION_RECT =
- Collections.singletonList(new Rect());
-
- public static final FloatProperty<TaskView> FOCUS_TRANSITION =
- new FloatProperty<>("focusTransition") {
- @Override
- public void setValue(TaskView taskView, float v) {
- taskView.setIconsAndBannersTransitionProgress(v, false /* invert */);
- }
-
- @Override
- public Float get(TaskView taskView) {
- return taskView.mFocusTransitionProgress;
- }
- };
-
- private static final FloatProperty<TaskView> SPLIT_SELECT_TRANSLATION_X =
- new FloatProperty<>("splitSelectTranslationX") {
- @Override
- public void setValue(TaskView taskView, float v) {
- taskView.setSplitSelectTranslationX(v);
- }
-
- @Override
- public Float get(TaskView taskView) {
- return taskView.mSplitSelectTranslationX;
- }
- };
-
- private static final FloatProperty<TaskView> SPLIT_SELECT_TRANSLATION_Y =
- new FloatProperty<>("splitSelectTranslationY") {
- @Override
- public void setValue(TaskView taskView, float v) {
- taskView.setSplitSelectTranslationY(v);
- }
-
- @Override
- public Float get(TaskView taskView) {
- return taskView.mSplitSelectTranslationY;
- }
- };
-
- private static final FloatProperty<TaskView> DISMISS_TRANSLATION_X =
- new FloatProperty<>("dismissTranslationX") {
- @Override
- public void setValue(TaskView taskView, float v) {
- taskView.setDismissTranslationX(v);
- }
-
- @Override
- public Float get(TaskView taskView) {
- return taskView.mDismissTranslationX;
- }
- };
-
- private static final FloatProperty<TaskView> DISMISS_TRANSLATION_Y =
- new FloatProperty<>("dismissTranslationY") {
- @Override
- public void setValue(TaskView taskView, float v) {
- taskView.setDismissTranslationY(v);
- }
-
- @Override
- public Float get(TaskView taskView) {
- return taskView.mDismissTranslationY;
- }
- };
-
- private static final FloatProperty<TaskView> TASK_OFFSET_TRANSLATION_X =
- new FloatProperty<>("taskOffsetTranslationX") {
- @Override
- public void setValue(TaskView taskView, float v) {
- taskView.setTaskOffsetTranslationX(v);
- }
-
- @Override
- public Float get(TaskView taskView) {
- return taskView.mTaskOffsetTranslationX;
- }
- };
-
- private static final FloatProperty<TaskView> TASK_OFFSET_TRANSLATION_Y =
- new FloatProperty<>("taskOffsetTranslationY") {
- @Override
- public void setValue(TaskView taskView, float v) {
- taskView.setTaskOffsetTranslationY(v);
- }
-
- @Override
- public Float get(TaskView taskView) {
- return taskView.mTaskOffsetTranslationY;
- }
- };
-
- private static final FloatProperty<TaskView> TASK_RESISTANCE_TRANSLATION_X =
- new FloatProperty<>("taskResistanceTranslationX") {
- @Override
- public void setValue(TaskView taskView, float v) {
- taskView.setTaskResistanceTranslationX(v);
- }
-
- @Override
- public Float get(TaskView taskView) {
- return taskView.mTaskResistanceTranslationX;
- }
- };
-
- private static final FloatProperty<TaskView> TASK_RESISTANCE_TRANSLATION_Y =
- new FloatProperty<>("taskResistanceTranslationY") {
- @Override
- public void setValue(TaskView taskView, float v) {
- taskView.setTaskResistanceTranslationY(v);
- }
-
- @Override
- public Float get(TaskView taskView) {
- return taskView.mTaskResistanceTranslationY;
- }
- };
-
- public static final FloatProperty<TaskView> GRID_END_TRANSLATION_X =
- new FloatProperty<>("gridEndTranslationX") {
- @Override
- public void setValue(TaskView taskView, float v) {
- taskView.setGridEndTranslationX(v);
- }
-
- @Override
- public Float get(TaskView taskView) {
- return taskView.mGridEndTranslationX;
- }
- };
-
- public static final FloatProperty<TaskView> SNAPSHOT_SCALE =
- new FloatProperty<>("snapshotScale") {
- @Override
- public void setValue(TaskView taskView, float v) {
- taskView.setSnapshotScale(v);
- }
-
- @Override
- public Float get(TaskView taskView) {
- return taskView.mTaskThumbnailViewDeprecated.getScaleX();
- }
- };
-
- public TaskViewData mTaskViewData = new TaskViewData();
- protected TaskThumbnailViewDeprecated mTaskThumbnailViewDeprecated;
- protected TaskThumbnailView mTaskThumbnailView;
- protected TaskViewIcon mIconView;
- protected final DigitalWellBeingToast mDigitalWellBeingToast;
- protected float mFullscreenProgress;
- private float mGridProgress;
- protected float mTaskThumbnailSplashAlpha;
- private float mNonGridScale = 1;
- private float mDismissScale = 1;
- protected final FullscreenDrawParams mCurrentFullscreenParams;
- protected final RecentsViewContainer mContainer;
-
- // Various causes of changing primary translation, which we aggregate to setTranslationX/Y().
- private float mDismissTranslationX;
- private float mDismissTranslationY;
- private float mTaskOffsetTranslationX;
- private float mTaskOffsetTranslationY;
- private float mTaskResistanceTranslationX;
- private float mTaskResistanceTranslationY;
- // The following translation variables should only be used in the same orientation as Launcher.
- private float mBoxTranslationY;
- // The following grid translations scales with mGridProgress.
- private float mGridTranslationX;
- private float mGridTranslationY;
- // The following grid translation is used to animate closing the gap between grid and clear all.
- private float mGridEndTranslationX;
- // Applied as a complement to gridTranslation, for adjusting the carousel overview and quick
- // switch.
- private float mNonGridTranslationX;
- private float mNonGridPivotTranslationX;
- // Used when in SplitScreenSelectState
- private float mSplitSelectTranslationY;
- private float mSplitSelectTranslationX;
-
- @Nullable
- private ObjectAnimator mIconAndDimAnimator;
- private float mIconScaleAnimStartProgress = 0;
- private float mFocusTransitionProgress = 1;
- private float mModalness = 0;
- private float mStableAlpha = 1;
-
- private int mTaskViewId = -1;
- protected List<TaskContainer> mTaskContainers = Collections.emptyList();
-
- private boolean mShowScreenshot;
- private boolean mBorderEnabled;
-
- // The current background requests to load the task thumbnail and icon
- @Nullable
- private CancellableTask mThumbnailLoadRequest;
- @Nullable
- private CancellableTask mIconLoadRequest;
-
- private boolean mEndQuickswitchCuj;
-
- private final float[] mIconCenterCoords = new float[2];
-
- protected final PointF mLastTouchDownPosition = new PointF();
-
- private boolean mIsClickableAsLiveTile = true;
-
- @Nullable
- private final BorderAnimator mFocusBorderAnimator;
-
- @Nullable
- private final BorderAnimator mHoverBorderAnimator;
-
- public TaskView(Context context) {
- this(context, null);
- }
-
- public TaskView(Context context, @Nullable AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public TaskView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
- this(context, attrs, defStyleAttr, 0);
- }
-
- public TaskView(Context context, @Nullable AttributeSet attrs, int defStyleAttr,
- int defStyleRes) {
- this(context, attrs, defStyleAttr, defStyleRes, null, null);
- }
-
- @VisibleForTesting
- public TaskView(Context context, @Nullable AttributeSet attrs, int defStyleAttr,
- int defStyleRes, BorderAnimator focusBorderAnimator,
- BorderAnimator hoverBorderAnimator) {
- super(context, attrs, defStyleAttr, defStyleRes);
- mContainer = RecentsViewContainer.containerFromContext(context);
- setOnClickListener(this::onClick);
-
- mCurrentFullscreenParams = new FullscreenDrawParams(context);
- mDigitalWellBeingToast = new DigitalWellBeingToast(mContainer, this);
-
- boolean keyboardFocusHighlightEnabled = FeatureFlags.ENABLE_KEYBOARD_QUICK_SWITCH.get()
- || Flags.enableFocusOutline();
- boolean cursorHoverStatesEnabled = enableCursorHoverStates();
-
- setWillNotDraw(!keyboardFocusHighlightEnabled && !cursorHoverStatesEnabled);
-
- TypedArray styledAttrs = context.obtainStyledAttributes(
- attrs, R.styleable.TaskView, defStyleAttr, defStyleRes);
-
- if (focusBorderAnimator != null) {
- mFocusBorderAnimator = focusBorderAnimator;
- } else {
- mFocusBorderAnimator = keyboardFocusHighlightEnabled
- ? BorderAnimator.createSimpleBorderAnimator(
- /* borderRadiusPx= */ (int) mCurrentFullscreenParams.mCornerRadius,
- /* borderWidthPx= */ context.getResources().getDimensionPixelSize(
- R.dimen.keyboard_quick_switch_border_width),
- /* boundsBuilder= */ this::getThumbnailBounds,
- /* targetView= */ this,
- /* borderColor= */ styledAttrs.getColor(
- R.styleable.TaskView_focusBorderColor, DEFAULT_BORDER_COLOR))
- : null;
- }
-
- if (hoverBorderAnimator != null) {
- mHoverBorderAnimator = hoverBorderAnimator;
- } else {
- mHoverBorderAnimator = cursorHoverStatesEnabled
- ? BorderAnimator.createSimpleBorderAnimator(
- /* borderRadiusPx= */ (int) mCurrentFullscreenParams.mCornerRadius,
- /* borderWidthPx= */ context.getResources().getDimensionPixelSize(
- R.dimen.task_hover_border_width),
- /* boundsBuilder= */ this::getThumbnailBounds,
- /* targetView= */ this,
- /* borderColor= */ styledAttrs.getColor(
- R.styleable.TaskView_hoverBorderColor, DEFAULT_BORDER_COLOR))
- : null;
- }
- styledAttrs.recycle();
- }
-
- /** Returns the thumbnail's bounds relative to this view. */
- public Unit getThumbnailBounds(@NonNull Rect bounds) {
- return getThumbnailBounds(bounds, false);
- }
-
- /** Returns the thumbnail's bounds, optionally relative to the screen. */
- public Unit getThumbnailBounds(@NonNull Rect bounds, boolean relativeToDragLayer) {
- View snapshotView = getSnapshotView();
-
- if (relativeToDragLayer) {
- mContainer.getDragLayer().getDescendantRectRelativeToSelf(snapshotView, bounds);
- } else {
- bounds.set(snapshotView.getLeft() + Math.round(snapshotView.getTranslationX()),
- snapshotView.getTop() + Math.round(snapshotView.getTranslationY()),
- snapshotView.getRight() + Math.round(snapshotView.getTranslationX()),
- snapshotView.getBottom() + Math.round(snapshotView.getTranslationY()));
- }
- return Unit.INSTANCE;
- }
-
- public void setTaskViewId(int id) {
- this.mTaskViewId = id;
- }
-
- public int getTaskViewId() {
- return mTaskViewId;
- }
-
- /**
- * Updates [TaskThumbnailView] to reflect the latest [Task] state (i.e., task isRunning).
- */
- public void notifyIsRunningTaskUpdated() {
- // TODO(b/335649589): TaskView's VM will already have access to TaskThumbnailView's VM
- // so there will be no need to access TaskThumbnailView's VM through the TaskThumbnailView
- if (!mTaskContainers.isEmpty()) {
- bindTaskThumbnailView();
- }
- }
-
- /**
- * Builds proto for logging.
- *
- * @deprecated Use {@link #getItemInfo(Task)} instead.
- */
- @Deprecated
- public WorkspaceItemInfo getItemInfo() {
- return getItemInfo(getFirstTask());
- }
-
- /**
- * Builds proto for logging
- */
- @VisibleForTesting
- public WorkspaceItemInfo getItemInfo(@Nullable Task task) {
- WorkspaceItemInfo stubInfo = new WorkspaceItemInfo();
- stubInfo.itemType = LauncherSettings.Favorites.ITEM_TYPE_TASK;
- stubInfo.container = LauncherSettings.Favorites.CONTAINER_TASKSWITCHER;
- if (task == null) {
- return stubInfo;
- }
-
- ComponentKey componentKey = TaskUtils.getLaunchComponentKeyForTask(task.key);
- stubInfo.user = componentKey.user;
- stubInfo.intent = new Intent().setComponent(componentKey.componentName);
- stubInfo.title = task.title;
- if (getRecentsView() != null) {
- stubInfo.screenId = getRecentsView().indexOfChild(this);
- }
- if (Flags.privateSpaceRestrictAccessibilityDrag()) {
- if (UserCache.getInstance(getContext()).getUserInfo(componentKey.user).isPrivate()) {
- stubInfo.runtimeStatusFlags |= FLAG_NOT_PINNABLE;
- }
- }
- return stubInfo;
- }
-
- @Override
- protected void onFinishInflate() {
- super.onFinishInflate();
- mTaskThumbnailViewDeprecated = findViewById(R.id.snapshot);
- if (enableRefactorTaskThumbnail()) {
- mTaskThumbnailView = new TaskThumbnailView(mContext);
- mTaskThumbnailView.setLayoutParams(mTaskThumbnailViewDeprecated.getLayoutParams());
- int indexOfSnapshotView = indexOfChild(mTaskThumbnailViewDeprecated);
- addView(mTaskThumbnailView, indexOfSnapshotView);
- mTaskThumbnailViewDeprecated.setVisibility(View.GONE);
- }
- ViewStub iconViewStub = findViewById(R.id.icon);
- if (enableOverviewIconMenu()) {
- iconViewStub.setLayoutResource(R.layout.icon_app_chip_view);
- } else {
- iconViewStub.setLayoutResource(R.layout.icon_view);
- }
- mIconView = (TaskViewIcon) iconViewStub.inflate();
- mIconTouchDelegate = new TransformingTouchDelegate(mIconView.asView());
- }
-
- @Override
- @VisibleForTesting(otherwise = VisibleForTesting.PROTECTED)
- public void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) {
- super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
- if (mFocusBorderAnimator != null && mBorderEnabled) {
- mFocusBorderAnimator.setBorderVisibility(gainFocus, /* animated= */ true);
- }
- }
-
- @Override
- public boolean onHoverEvent(MotionEvent event) {
- if (mHoverBorderAnimator != null && mBorderEnabled) {
- switch (event.getAction()) {
- case MotionEvent.ACTION_HOVER_ENTER:
- mHoverBorderAnimator.setBorderVisibility(/* visible= */ true, /* animated= */
- true);
- break;
- case MotionEvent.ACTION_HOVER_EXIT:
- mHoverBorderAnimator.setBorderVisibility(/* visible= */ false, /* animated= */
- true);
- break;
- default:
- break;
- }
- }
- return super.onHoverEvent(event);
- }
-
- /**
- * Enable or disable showing border on hover and focus change
- */
- public void setBorderEnabled(boolean enabled) {
- if (mBorderEnabled == enabled) {
- return;
- }
-
- mBorderEnabled = enabled;
- // Set the animation correctly in case it misses the hover/focus event during state
- // transition
- if (mHoverBorderAnimator != null) {
- mHoverBorderAnimator.setBorderVisibility(/* visible= */
- enabled && isHovered(), /* animated= */ true);
- }
-
- if (mFocusBorderAnimator != null) {
- mFocusBorderAnimator.setBorderVisibility(/* visible= */
- enabled && isFocused(), /* animated= */true);
- }
- }
-
- @Override
- public boolean onInterceptHoverEvent(MotionEvent event) {
- if (enableCursorHoverStates()) {
- // avoid triggering hover event on child elements which would cause HOVER_EXIT for this
- // task view
- return true;
- } else {
- return super.onInterceptHoverEvent(event);
- }
- }
-
- @Override
- public void draw(Canvas canvas) {
- // Draw border first so any child views outside of the thumbnail bounds are drawn above it.
- if (mFocusBorderAnimator != null) {
- mFocusBorderAnimator.drawBorder(canvas);
- }
- if (mHoverBorderAnimator != null) {
- mHoverBorderAnimator.drawBorder(canvas);
- }
- super.draw(canvas);
- }
-
- /**
- * Whether the taskview should take the touch event from parent. Events passed to children
- * that might require special handling.
- */
- public boolean offerTouchToChildren(MotionEvent event) {
- if (event.getAction() == MotionEvent.ACTION_DOWN) {
- computeAndSetIconTouchDelegate(mIconView, mIconCenterCoords, mIconTouchDelegate);
- }
- return mIconTouchDelegate != null && mIconTouchDelegate.onTouchEvent(event);
- }
-
- protected void computeAndSetIconTouchDelegate(TaskViewIcon view, float[] tempCenterCoords,
- TransformingTouchDelegate transformingTouchDelegate) {
- if (view == null) {
- return;
- }
- float viewHalfWidth = view.getWidth() / 2f;
- float viewHalfHeight = view.getHeight() / 2f;
- tempCenterCoords[0] = viewHalfWidth;
- tempCenterCoords[1] = viewHalfHeight;
- getDescendantCoordRelativeToAncestor(view.asView(), mContainer.getDragLayer(),
- tempCenterCoords, false);
- transformingTouchDelegate.setBounds(
- (int) (tempCenterCoords[0] - viewHalfWidth),
- (int) (tempCenterCoords[1] - viewHalfHeight),
- (int) (tempCenterCoords[0] + viewHalfWidth),
- (int) (tempCenterCoords[1] + viewHalfHeight));
- }
-
- /**
- * The modalness of this view is how it should be displayed when it is shown on its own in the
- * modal state of overview.
- *
- * @param modalness [0, 1] 0 being in context with other tasks, 1 being shown on its own.
- */
- public void setModalness(float modalness) {
- if (mModalness == modalness) {
- return;
- }
- mModalness = modalness;
- mIconView.setModalAlpha(1 - modalness);
- mDigitalWellBeingToast.updateBannerOffset(modalness);
- }
-
- public DigitalWellBeingToast getDigitalWellBeingToast() {
- return mDigitalWellBeingToast;
- }
-
- /**
- * Updates this task view to the given {@param task}.
- */
- public void bind(Task task, RecentsOrientedState orientedState) {
- cancelPendingLoadTasks();
- mTaskContainers = Collections.singletonList(
- new TaskContainer(task, mTaskThumbnailViewDeprecated, mIconView,
- STAGE_POSITION_UNDEFINED, mDigitalWellBeingToast));
- if (enableRefactorTaskThumbnail()) {
- bindTaskThumbnailView();
- } else {
- mTaskThumbnailViewDeprecated.bind(task);
- }
- setOrientationState(orientedState);
- }
-
- private void bindTaskThumbnailView() {
- // TODO(b/335649589): TaskView's VM will already have access to TaskThumbnailView's VM
- // so there will be no need to access TaskThumbnailView's VM through the TaskThumbnailView
- mTaskThumbnailView.getViewModel().bind(new TaskThumbnail(getFirstTask(), isRunningTask()));
- }
-
- /**
- * Sets up an on-click listener and the visibility for show_windows icon on top of the task.
- */
- public void setUpShowAllInstancesListener() {
- if (mTaskContainers.isEmpty()) {
- return;
- }
- String taskPackageName = mTaskContainers.get(0).getTask().key.getPackageName();
-
- // icon of the top/left task
- View showWindowsView = findViewById(R.id.show_windows);
- updateFilterCallback(showWindowsView, getFilterUpdateCallback(taskPackageName));
- }
-
- /**
- * Returns a callback that updates the state of the filter and the recents overview
- *
- * @param taskPackageName package name of the task to filter by
- */
- @Nullable
- protected View.OnClickListener getFilterUpdateCallback(String taskPackageName) {
- View.OnClickListener cb = (view) -> {
- // update and apply a new filter
- getRecentsView().setAndApplyFilter(taskPackageName);
- };
-
- if (!getRecentsView().getFilterState().shouldShowFilterUI(taskPackageName)) {
- cb = null;
- }
- return cb;
- }
-
- /**
- * Sets the correct visibility and callback on the provided filterView based on whether
- * the callback is null or not
- */
- protected void updateFilterCallback(@NonNull View filterView,
- @Nullable View.OnClickListener callback) {
- // Filtering changes alpha instead of the visibility since visibility
- // can be altered separately through RecentsView#resetFromSplitSelectionState()
- if (callback == null) {
- filterView.setAlpha(0);
- } else {
- filterView.setAlpha(1);
- }
-
- filterView.setOnClickListener(callback);
- }
-
- /**
- * Returns a list of all TaskContainers in the TaskView.
- */
- public List<TaskContainer> getTaskContainers() {
- return mTaskContainers;
- }
-
- /**
- * Returns the first task bound to this TaskView.
- *
- * @deprecated Use {@link #mTaskContainers} instead.
- */
- @Deprecated
- @Nullable
- public Task getFirstTask() {
- return !mTaskContainers.isEmpty() ? mTaskContainers.get(0).getTask() : null;
- }
-
- /**
- * Check if given {@code taskId} is tracked in this view
- */
- public boolean containsTaskId(int taskId) {
- return getTaskContainerById(taskId) != null;
- }
-
- /**
- * Returns a copy of integer array containing taskIds of all tasks in the TaskView.
- */
- public int[] getTaskIds() {
- return mTaskContainers.stream().mapToInt(
- container -> container.getTask().key.id).toArray();
- }
-
- public boolean containsMultipleTasks() {
- return mTaskContainers.size() > 1;
- }
-
- /**
- * Returns the TaskContainer corresponding to a given taskId, or null if the TaskView does
- * not contain a Task with that ID.
- */
- @Nullable
- public TaskContainer getTaskContainerById(int taskId) {
- return mTaskContainers.stream().filter(
- container -> container.getTask().key.id == taskId).findFirst().orElse(null);
- }
-
- /**
- * Returns the first thumbnailView of the TaskView.
- *
- * @deprecated Use {@link #mTaskContainers} instead.
- */
- @Deprecated
- public TaskThumbnailViewDeprecated getFirstThumbnailView() {
- return !mTaskContainers.isEmpty() ? mTaskContainers.get(0).getThumbnailView()
- : mTaskThumbnailViewDeprecated;
- }
-
- void refreshThumbnails(@Nullable HashMap<Integer, ThumbnailData> thumbnailDatas) {
- if (enableRefactorTaskThumbnail()) {
- // TODO(b/334825222) add thumbnail logic
- return;
- }
- if (getFirstTask() != null && thumbnailDatas != null) {
- final ThumbnailData thumbnailData = thumbnailDatas.get(getFirstTask().key.id);
- if (thumbnailData != null) {
- mTaskThumbnailViewDeprecated.setThumbnail(getFirstTask(), thumbnailData);
- return;
- }
- }
-
- mTaskThumbnailViewDeprecated.refresh();
- }
-
- public TaskThumbnailViewDeprecated[] getThumbnailViews() {
- return mTaskContainers.stream().map(
- TaskContainer::getThumbnailView).toArray(
- TaskThumbnailViewDeprecated[]::new);
- }
-
- /**
- * Returns the first iconView of the TaskView.
- *
- * @deprecated Use {@link #mTaskContainers} instead.
- */
- @Deprecated
- @Nullable
- public TaskViewIcon getFirstIconView() {
- return !mTaskContainers.isEmpty() ? mTaskContainers.get(0).getIconView() : null;
- }
-
- @Override
- public boolean dispatchTouchEvent(MotionEvent ev) {
- RecentsView recentsView = getRecentsView();
- if (recentsView == null || getFirstTask() == null) {
- return false;
- }
- SplitSelectStateController splitSelectStateController =
- recentsView.getSplitSelectController();
- // Disable taps for split selection animation unless we have multiple tasks
- boolean disableTapsForSplitSelect =
- splitSelectStateController.isSplitSelectActive()
- && splitSelectStateController.getInitialTaskId() == getFirstTask().key.id
- && !containsMultipleTasks();
- if (disableTapsForSplitSelect) {
- return false;
- }
-
- if (ev.getAction() == MotionEvent.ACTION_DOWN) {
- mLastTouchDownPosition.set(ev.getX(), ev.getY());
- }
- return super.dispatchTouchEvent(ev);
- }
-
- private void onClick(View view) {
- if (getFirstTask() == null) {
- Log.d("b/310064698", "onClick - task is null");
- return;
- }
- if (confirmSecondSplitSelectApp()) {
- Log.d("b/310064698",
- Arrays.toString(getTaskIds()) + " - onClick - split select is active");
- return;
- }
- RunnableList callbackList = launchTasks();
- Log.d("b/310064698",
- Arrays.toString(getTaskIds()) + " - onClick - callbackList: " + callbackList);
- if (callbackList != null) {
- callbackList.add(() -> Log.d("b/310064698",
- Arrays.toString(getTaskIds()) + " - onClick - launchCompleted"));
- }
- mContainer.getStatsLogManager().logger().withItemInfo(getItemInfo())
- .log(LAUNCHER_TASK_LAUNCH_TAP);
- }
-
- /**
- * @return {@code true} if user is already in split select mode and this tap was to choose the
- * second app. {@code false} otherwise
- */
- protected boolean confirmSecondSplitSelectApp() {
- int index = getLastSelectedChildTaskIndex();
- if (index >= mTaskContainers.size()) {
- return false;
- }
- TaskContainer container = mTaskContainers.get(index);
- if (container != null) {
- return getRecentsView().confirmSplitSelect(this, container.getTask(),
- container.getIconView().getDrawable(), container.getThumbnailView(),
- container.getThumbnailView().getThumbnail(), /* intent */ null,
- /* user */ null, container.getItemInfo());
- }
- return false;
- }
-
- /**
- * Returns the task index of the last selected child task (0 or 1).
- * If we contain multiple tasks and this TaskView is used as part of split selection, the
- * selected child task index will be that of the remaining task.
- */
- protected int getLastSelectedChildTaskIndex() {
- return 0;
- }
-
- /**
- * Starts the task associated with this view and animates the startup.
- *
- * @return CompletionStage to indicate the animation completion or null if the launch failed.
- */
- @Nullable
- public RunnableList launchTaskAnimated() {
- if (getFirstTask() != null) {
- TestLogging.recordEvent(
- TestProtocol.SEQUENCE_MAIN, "startActivityFromRecentsAsync", Arrays.toString(
- getTaskIds()));
- ActivityOptionsWrapper opts = mContainer.getActivityLaunchOptions(this, null);
- opts.options.setLaunchDisplayId(
- getDisplay() == null ? DEFAULT_DISPLAY : getDisplay().getDisplayId());
- if (ActivityManagerWrapper.getInstance()
- .startActivityFromRecents(getFirstTask().key, opts.options)) {
- Log.d(TAG, "launchTaskAnimated - startActivityFromRecents: " + Arrays.toString(
- getTaskIds()));
- ActiveGestureLog.INSTANCE.trackEvent(EXPECTING_TASK_APPEARED);
- RecentsView recentsView = getRecentsView();
- if (recentsView.getRunningTaskViewId() != -1) {
- recentsView.onTaskLaunchedInLiveTileMode();
-
- // Return a fresh callback in the live tile case, so that it's not accidentally
- // triggered by QuickstepTransitionManager.AppLaunchAnimationRunner.
- RunnableList callbackList = new RunnableList();
- recentsView.addSideTaskLaunchCallback(callbackList);
- return callbackList;
- }
- if (TaskAnimationManager.ENABLE_SHELL_TRANSITIONS) {
- // If the recents transition is running (ie. in live tile mode), then the start
- // of a new task will merge into the existing transition and it currently will
- // not be run independently, so we need to rely on the onTaskAppeared() call
- // for the new task to trigger the side launch callback to flush this runnable
- // list (which is usually flushed when the app launch animation finishes)
- recentsView.addSideTaskLaunchCallback(opts.onEndCallback);
- }
- return opts.onEndCallback;
- } else {
- notifyTaskLaunchFailed(TAG);
- return null;
- }
- } else {
- Log.d(TAG, "launchTaskAnimated - getTask() is null" + Arrays.toString(getTaskIds()));
- return null;
- }
- }
-
- /**
- * Starts the task associated with this view without any animation
- */
- public void launchTask(@NonNull Consumer<Boolean> callback) {
- launchTask(callback, false /* isQuickswitch */);
- }
-
- /**
- * Starts the task associated with this view without any animation
- */
- public void launchTask(@NonNull Consumer<Boolean> callback, boolean isQuickswitch) {
- if (getFirstTask() != null) {
- TestLogging.recordEvent(
- TestProtocol.SEQUENCE_MAIN, "startActivityFromRecentsAsync", Arrays.toString(
- getTaskIds()));
-
- TaskRemovedDuringLaunchListener failureListener = new TaskRemovedDuringLaunchListener(
- getContext().getApplicationContext());
- if (isQuickswitch) {
- // We only listen for failures to launch in quickswitch because the during this
- // gesture launcher is in the background state, vs other launches which are in
- // the actual overview state
- failureListener.register(mContainer, getFirstTask().key.id, () -> {
- notifyTaskLaunchFailed(TAG);
- RecentsView rv = getRecentsView();
- if (rv != null) {
- // Disable animations for now, as it is an edge case and the app usually
- // covers launcher and also any state transition animation also gets
- // clobbered by QuickstepTransitionManager.createWallpaperOpenAnimations
- // when launcher shows again
- rv.startHome(false /* animated */);
- if (rv.mSizeStrategy.getTaskbarController() != null) {
- // LauncherTaskbarUIController depends on the launcher state when
- // checking whether to handle resume, but that can come in before
- // startHome() changes the state, so force-refresh here to ensure the
- // taskbar is updated
- rv.mSizeStrategy.getTaskbarController().refreshResumedState();
- }
- }
- });
- }
- // Indicate success once the system has indicated that the transition has started
- ActivityOptions opts = ActivityOptions.makeCustomTaskAnimation(getContext(), 0, 0,
- MAIN_EXECUTOR.getHandler(),
- elapsedRealTime -> callback.accept(true),
- elapsedRealTime -> failureListener.onTransitionFinished());
- opts.setLaunchDisplayId(
- getDisplay() == null ? DEFAULT_DISPLAY : getDisplay().getDisplayId());
- if (isQuickswitch) {
- opts.setFreezeRecentTasksReordering();
- }
- // TODO(b/334826842) add splash functionality to new TTV
- if (!enableRefactorTaskThumbnail()) {
- opts.setDisableStartingWindow(mTaskThumbnailViewDeprecated.shouldShowSplashView());
- }
- Task.TaskKey key = getFirstTask().key;
- UI_HELPER_EXECUTOR.execute(() -> {
- if (!ActivityManagerWrapper.getInstance().startActivityFromRecents(key, opts)) {
- // If the call to start activity failed, then post the result immediately,
- // otherwise, wait for the animation start callback from the activity options
- // above
- MAIN_EXECUTOR.post(() -> {
- notifyTaskLaunchFailed(TAG);
- callback.accept(false);
- });
- }
- Log.d(TAG,
- "launchTask - startActivityFromRecents: " + Arrays.toString(getTaskIds()));
- });
- } else {
- callback.accept(false);
- Log.d(TAG, "launchTask - getTask() is null" + Arrays.toString(getTaskIds()));
- }
- }
-
- /**
- * Launch of the current task (both live and inactive tasks) with an animation.
- */
- @Nullable
- public RunnableList launchTasks() {
- RecentsView recentsView = getRecentsView();
- RemoteTargetHandle[] remoteTargetHandles = recentsView.mRemoteTargetHandles;
- if (isRunningTask() && remoteTargetHandles != null) {
- if (!mIsClickableAsLiveTile) {
- Log.e(TAG, "TaskView is not clickable as a live tile; returning to home.");
- return null;
- }
-
- mIsClickableAsLiveTile = false;
- RemoteAnimationTargets targets;
- if (remoteTargetHandles.length == 1) {
- targets = remoteTargetHandles[0].getTransformParams().getTargetSet();
- } else {
- RemoteAnimationTarget[] apps = Arrays.stream(remoteTargetHandles)
- .flatMap(handle -> Stream.of(
- handle.getTransformParams().getTargetSet().apps))
- .toArray(RemoteAnimationTarget[]::new);
- RemoteAnimationTarget[] wallpapers = Arrays.stream(remoteTargetHandles)
- .flatMap(handle -> Stream.of(
- handle.getTransformParams().getTargetSet().wallpapers))
- .toArray(RemoteAnimationTarget[]::new);
- targets = new RemoteAnimationTargets(apps, wallpapers,
- remoteTargetHandles[0].getTransformParams().getTargetSet().nonApps,
- remoteTargetHandles[0].getTransformParams().getTargetSet().targetMode);
- }
- if (targets == null) {
- // If the recents animation is cancelled somehow between the parent if block and
- // here, try to launch the task as a non live tile task.
- RunnableList runnableList = launchTaskAnimated();
- if (runnableList == null) {
- Log.e(TAG, "Recents animation cancelled and cannot launch task as non-live tile"
- + "; returning to home");
- }
- mIsClickableAsLiveTile = true;
- return runnableList;
- }
-
- RunnableList runnableList = new RunnableList();
- AnimatorSet anim = new AnimatorSet();
- TaskViewUtils.composeRecentsLaunchAnimator(
- anim, this, targets.apps,
- targets.wallpapers, targets.nonApps, true /* launcherClosing */,
- recentsView.getStateManager(), recentsView,
- recentsView.getDepthController());
- anim.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animator) {
- if (getFirstTask() != null
- && getFirstTask().key.displayId != getRootViewDisplayId()) {
- launchTaskAnimated();
- }
- mIsClickableAsLiveTile = true;
- runEndCallback();
- }
-
- @Override
- public void onAnimationCancel(Animator animation) {
- runEndCallback();
- }
-
- private void runEndCallback() {
- runnableList.executeAllAndDestroy();
- }
- });
- anim.start();
- Log.d(TAG, "launchTasks - composeRecentsLaunchAnimator: " + Arrays.toString(
- getTaskIds()));
- recentsView.onTaskLaunchedInLiveTileMode();
- return runnableList;
- } else {
- return launchTaskAnimated();
- }
- }
-
- /**
- * See {@link TaskDataChanges}
- *
- * @param visible If this task view will be visible to the user in overview or hidden
- */
- public void onTaskListVisibilityChanged(boolean visible) {
- onTaskListVisibilityChanged(visible, FLAG_UPDATE_ALL);
- }
-
- /**
- * See {@link TaskDataChanges}
- *
- * @param visible If this task view will be visible to the user in overview or hidden
- */
- public void onTaskListVisibilityChanged(boolean visible, @TaskDataChanges int changes) {
- if (getFirstTask() == null) {
- return;
- }
- cancelPendingLoadTasks();
- if (visible) {
- // These calls are no-ops if the data is already loaded, try and load the high
- // resolution thumbnail if the state permits
- RecentsModel model = RecentsModel.INSTANCE.get(getContext());
- TaskThumbnailCache thumbnailCache = model.getThumbnailCache();
- TaskIconCache iconCache = model.getIconCache();
-
- if (needsUpdate(changes, FLAG_UPDATE_THUMBNAIL)) {
- mThumbnailLoadRequest = thumbnailCache.updateThumbnailInBackground(
- getFirstTask(), thumbnail -> {
- if (!enableRefactorTaskThumbnail()) {
- // TODO(b/334825222) add thumbnail state
- mTaskThumbnailViewDeprecated.setThumbnail(getFirstTask(),
- thumbnail);
- }
- });
- }
- if (needsUpdate(changes, FLAG_UPDATE_ICON)) {
- mIconLoadRequest = iconCache.updateIconInBackground(getFirstTask(),
- (task) -> {
- setIcon(mIconView, task.icon);
- if (enableOverviewIconMenu()) {
- setText(mIconView, task.title);
- }
- mDigitalWellBeingToast.initialize(task);
- });
- }
- if (needsUpdate(changes, FLAG_UPDATE_CORNER_RADIUS)) {
- mCurrentFullscreenParams.updateCornerRadius(getContext());
- }
- } else {
- if (needsUpdate(changes, FLAG_UPDATE_THUMBNAIL)) {
- if (!enableRefactorTaskThumbnail()) {
- // TODO(b/334825222) add thumbnail state
- mTaskThumbnailViewDeprecated.setThumbnail(null, null);
- }
- // Reset the task thumbnail reference as well (it will be fetched from the cache or
- // reloaded next time we need it)
- getFirstTask().thumbnail = null;
- }
- if (needsUpdate(changes, FLAG_UPDATE_ICON)) {
- setIcon(mIconView, null);
- if (enableOverviewIconMenu()) {
- setText(mIconView, null);
- }
- }
- }
- }
-
- protected boolean needsUpdate(@TaskDataChanges int dataChange, @TaskDataChanges int flag) {
- return (dataChange & flag) == flag;
- }
-
- protected void cancelPendingLoadTasks() {
- if (mThumbnailLoadRequest != null) {
- mThumbnailLoadRequest.cancel();
- mThumbnailLoadRequest = null;
- }
- if (mIconLoadRequest != null) {
- mIconLoadRequest.cancel();
- mIconLoadRequest = null;
- }
- }
-
- private boolean showTaskMenu(TaskViewIcon iconView) {
- if (!getRecentsView().canLaunchFullscreenTask()) {
- // Don't show menu when selecting second split screen app
- return true;
- }
-
- if (!mContainer.getDeviceProfile().isTablet
- && !getRecentsView().isClearAllHidden()) {
- getRecentsView().snapToPage(getRecentsView().indexOfChild(this));
- return false;
- } else {
- mContainer.getStatsLogManager().logger().withItemInfo(getItemInfo())
- .log(LAUNCHER_TASK_ICON_TAP_OR_LONGPRESS);
- return showTaskMenuWithContainer(iconView);
- }
- }
-
- protected boolean showTaskMenuWithContainer(TaskViewIcon iconView) {
- Optional<TaskContainer> menuContainer = mTaskContainers.stream().filter(
- container -> container.getIconView() == iconView).findAny();
- if (menuContainer.isEmpty()) {
- return false;
- }
- DeviceProfile dp = mContainer.getDeviceProfile();
- if (enableOverviewIconMenu() && iconView instanceof IconAppChipView) {
- ((IconAppChipView) iconView).revealAnim(/* isRevealing= */ true);
- return TaskMenuView.showForTask(menuContainer.get(),
- () -> ((IconAppChipView) iconView).revealAnim(/* isRevealing= */ false));
- } else if (dp.isTablet) {
- int alignedOptionIndex = 0;
- if (getRecentsView().isOnGridBottomRow(menuContainer.get().getTaskView())
- && dp.isLandscape) {
- if (Flags.enableGridOnlyOverview()) {
- // With no focused task, there is less available space below the tasks, so align
- // the arrow to the third option in the menu.
- alignedOptionIndex = 2;
- } else {
- // Bottom row of landscape grid aligns arrow to second option to avoid clipping
- alignedOptionIndex = 1;
- }
- }
- return TaskMenuViewWithArrow.Companion.showForTask(menuContainer.get(),
- alignedOptionIndex);
- } else {
- return TaskMenuView.showForTask(menuContainer.get());
- }
- }
-
- protected void setIcon(TaskViewIcon iconView, @Nullable Drawable icon) {
- if (icon != null) {
- iconView.setDrawable(icon);
- iconView.setOnClickListener(v -> {
- if (confirmSecondSplitSelectApp()) {
- return;
- }
- showTaskMenu(iconView);
- });
- iconView.setOnLongClickListener(v -> {
- requestDisallowInterceptTouchEvent(true);
- return showTaskMenu(iconView);
- });
- } else {
- iconView.setDrawable(null);
- iconView.setOnClickListener(null);
- iconView.setOnLongClickListener(null);
- }
- }
-
- protected void setText(TaskViewIcon iconView, CharSequence text) {
- iconView.setText(text);
- }
-
- public void setOrientationState(RecentsOrientedState orientationState) {
- mIconView.setIconOrientation(orientationState, isGridTask());
- setThumbnailOrientation(orientationState);
- }
-
- protected void setThumbnailOrientation(RecentsOrientedState orientationState) {
- DeviceProfile deviceProfile = mContainer.getDeviceProfile();
- int thumbnailTopMargin = deviceProfile.overviewTaskThumbnailTopMarginPx;
-
- // TODO(b/271468547), we should default to setting trasnlations only on the snapshot instead
- // of a hybrid of both margins and translations
- LayoutParams snapshotParams = (LayoutParams) getSnapshotView().getLayoutParams();
- snapshotParams.topMargin = thumbnailTopMargin;
- getSnapshotView().setLayoutParams(snapshotParams);
-
- // TODO(b/335606129) Investigate the usage of [TaskOverlay] in the new TaskThumbnailView.
- // and if it's still necessary we should support that in the new TTV class.
- if (!enableRefactorTaskThumbnail()) {
- mTaskThumbnailViewDeprecated.getTaskOverlay().updateOrientationState(orientationState);
- }
- mDigitalWellBeingToast.initialize(getFirstTask());
- }
-
- /**
- * Returns whether the task is part of overview grid and not being focused.
- */
- public boolean isGridTask() {
- DeviceProfile deviceProfile = mContainer.getDeviceProfile();
- return deviceProfile.isTablet && !isFocusedTask();
- }
-
- /**
- * Called to animate a smooth transition when going directly from an app into Overview (and
- * vice versa). Icons fade in, and DWB banners slide in with a "shift up" animation.
- */
- protected void setIconsAndBannersTransitionProgress(float progress, boolean invert) {
- if (invert) {
- progress = 1 - progress;
- }
- mFocusTransitionProgress = progress;
- float iconScalePercentage = (float) SCALE_ICON_DURATION / DIM_ANIM_DURATION;
- float lowerClamp = invert ? 1f - iconScalePercentage : 0;
- float upperClamp = invert ? 1 : iconScalePercentage;
- float scale = Interpolators.clampToProgress(FAST_OUT_SLOW_IN, lowerClamp, upperClamp)
- .getInterpolation(progress);
- mIconView.setContentAlpha(scale);
- mDigitalWellBeingToast.updateBannerOffset(1f - scale);
- }
-
- public void setIconScaleAnimStartProgress(float startProgress) {
- mIconScaleAnimStartProgress = startProgress;
- }
-
- public void animateIconScaleAndDimIntoView() {
- if (mIconAndDimAnimator != null) {
- mIconAndDimAnimator.cancel();
- }
- mIconAndDimAnimator = ObjectAnimator.ofFloat(this, FOCUS_TRANSITION, 1);
- mIconAndDimAnimator.setCurrentFraction(mIconScaleAnimStartProgress);
- mIconAndDimAnimator.setDuration(DIM_ANIM_DURATION).setInterpolator(LINEAR);
- mIconAndDimAnimator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- mIconAndDimAnimator = null;
- }
- });
- mIconAndDimAnimator.start();
- }
-
- protected void setIconScaleAndDim(float iconScale) {
- setIconScaleAndDim(iconScale, false);
- }
-
- private void setIconScaleAndDim(float iconScale, boolean invert) {
- if (mIconAndDimAnimator != null) {
- mIconAndDimAnimator.cancel();
- }
- setIconsAndBannersTransitionProgress(iconScale, invert);
- }
-
- protected void resetPersistentViewTransforms() {
- mNonGridTranslationX = mGridTranslationX =
- mGridTranslationY = mBoxTranslationY = mNonGridPivotTranslationX = 0f;
- resetViewTransforms();
- }
-
- protected void resetViewTransforms() {
- // fullscreenTranslation and accumulatedTranslation should not be reset, as
- // resetViewTransforms is called during Quickswitch scrolling.
- mDismissTranslationX = mTaskOffsetTranslationX =
- mTaskResistanceTranslationX = mSplitSelectTranslationX = mGridEndTranslationX = 0f;
- mDismissTranslationY = mTaskOffsetTranslationY = mTaskResistanceTranslationY = 0f;
- if (getRecentsView() == null || !getRecentsView().isSplitSelectionActive()) {
- mSplitSelectTranslationY = 0f;
- }
-
- setSnapshotScale(1f);
- applyTranslationX();
- applyTranslationY();
- setTranslationZ(0);
- setAlpha(mStableAlpha);
- setIconScaleAndDim(1);
- setColorTint(0, 0);
- if (!enableRefactorTaskThumbnail()) {
- // TODO(b/335399428) add split select functionality to new TTV
- mTaskThumbnailViewDeprecated.resetViewTransforms();
- }
- }
-
- public void setStableAlpha(float parentAlpha) {
- mStableAlpha = parentAlpha;
- setAlpha(mStableAlpha);
- }
-
- @Override
- public void onRecycle() {
- resetPersistentViewTransforms();
- // Clear any references to the thumbnail (it will be re-read either from the cache or the
- // system on next bind)
- // TODO(b/334825222): Implement thumbnail/snapshot for the new [TaskThumbnailView].
- if (enableRefactorTaskThumbnail()) {
- notifyIsRunningTaskUpdated();
- } else {
- mTaskThumbnailViewDeprecated.setThumbnail(getFirstTask(), null);
- }
- setOverlayEnabled(false);
- onTaskListVisibilityChanged(false);
- mBorderEnabled = false;
- }
-
- public float getTaskCornerRadius() {
- return mCurrentFullscreenParams.mCornerRadius;
- }
-
- @Override
- protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
- super.onLayout(changed, left, top, right, bottom);
- DeviceProfile deviceProfile = mContainer.getDeviceProfile();
- int thumbnailTopMargin = deviceProfile.overviewTaskThumbnailTopMarginPx;
- if (deviceProfile.isTablet) {
- setPivotX(getLayoutDirection() == LAYOUT_DIRECTION_RTL ? 0 : right - left);
- setPivotY(thumbnailTopMargin);
- } else {
- setPivotX((right - left) * 0.5f);
- setPivotY(thumbnailTopMargin + (getHeight() - thumbnailTopMargin) * 0.5f);
- }
- SYSTEM_GESTURE_EXCLUSION_RECT.get(0).set(0, 0, getWidth(), getHeight());
- setSystemGestureExclusionRects(SYSTEM_GESTURE_EXCLUSION_RECT);
- }
-
- /**
- * How much to scale down pages near the edge of the screen.
- */
- public static float getEdgeScaleDownFactor(DeviceProfile deviceProfile) {
- return deviceProfile.isTablet ? EDGE_SCALE_DOWN_FACTOR_GRID
- : EDGE_SCALE_DOWN_FACTOR_CAROUSEL;
- }
-
- private void setNonGridScale(float nonGridScale) {
- mNonGridScale = nonGridScale;
- applyScale();
- }
-
- public float getNonGridScale() {
- return mNonGridScale;
- }
-
- private void setSnapshotScale(float dismissScale) {
- mDismissScale = dismissScale;
- applyScale();
- }
-
- /**
- * Moves TaskView between carousel and 2 row grid.
- *
- * @param gridProgress 0 = carousel; 1 = 2 row grid.
- */
- public void setGridProgress(float gridProgress) {
- mGridProgress = gridProgress;
- applyTranslationX();
- applyTranslationY();
- applyScale();
- }
-
- private void applyScale() {
- float scale = 1;
- scale *= getPersistentScale();
- scale *= mDismissScale;
- setScaleX(scale);
- setScaleY(scale);
- if (enableRefactorTaskThumbnail()) {
- mTaskViewData.getScale().setValue(scale);
- }
- updateSnapshotRadius();
- }
-
- /**
- * Returns multiplication of scale that is persistent (e.g. fullscreen and grid), and does not
- * change according to a temporary state.
- */
- public float getPersistentScale() {
- float scale = 1;
- scale *= Utilities.mapRange(mGridProgress, mNonGridScale, 1f);
- return scale;
- }
-
- /**
- * Updates alpha of task thumbnail splash on swipe up/down.
- */
- public void setTaskThumbnailSplashAlpha(float taskThumbnailSplashAlpha) {
- mTaskThumbnailSplashAlpha = taskThumbnailSplashAlpha;
- applyThumbnailSplashAlpha();
- }
-
- protected void applyThumbnailSplashAlpha() {
- if (!enableRefactorTaskThumbnail()) {
- // TODO(b/334826842) add splash functionality to new TTV
- mTaskThumbnailViewDeprecated.setSplashAlpha(mTaskThumbnailSplashAlpha);
- }
- }
-
- protected void refreshTaskThumbnailSplash() {
- if (!enableRefactorTaskThumbnail()) {
- // TODO(b/334826842) add splash functionality to new TTV
- mTaskThumbnailViewDeprecated.refreshSplashView();
- }
- }
-
- private void setSplitSelectTranslationX(float x) {
- mSplitSelectTranslationX = x;
- applyTranslationX();
- }
-
- private void setSplitSelectTranslationY(float y) {
- mSplitSelectTranslationY = y;
- applyTranslationY();
- }
-
- private void setDismissTranslationX(float x) {
- mDismissTranslationX = x;
- applyTranslationX();
- }
-
- private void setDismissTranslationY(float y) {
- mDismissTranslationY = y;
- applyTranslationY();
- }
-
- private void setTaskOffsetTranslationX(float x) {
- mTaskOffsetTranslationX = x;
- applyTranslationX();
- }
-
- private void setTaskOffsetTranslationY(float y) {
- mTaskOffsetTranslationY = y;
- applyTranslationY();
- }
-
- private void setTaskResistanceTranslationX(float x) {
- mTaskResistanceTranslationX = x;
- applyTranslationX();
- }
-
- private void setTaskResistanceTranslationY(float y) {
- mTaskResistanceTranslationY = y;
- applyTranslationY();
- }
-
- public float getNonGridTranslationX() {
- return mNonGridTranslationX;
- }
-
- /**
- * Updates X coordinate of non-grid translation.
- */
- public void setNonGridTranslationX(float nonGridTranslationX) {
- mNonGridTranslationX = nonGridTranslationX;
- applyTranslationX();
- }
-
- public void setGridTranslationX(float gridTranslationX) {
- mGridTranslationX = gridTranslationX;
- applyTranslationX();
- }
-
- public float getGridTranslationX() {
- return mGridTranslationX;
- }
-
- public void setGridTranslationY(float gridTranslationY) {
- mGridTranslationY = gridTranslationY;
- applyTranslationY();
- }
-
- public float getGridTranslationY() {
- return mGridTranslationY;
- }
-
- private void setGridEndTranslationX(float gridEndTranslationX) {
- mGridEndTranslationX = gridEndTranslationX;
- applyTranslationX();
- }
-
- /**
- * Set translation X for non-grid pivot
- */
- public void setNonGridPivotTranslationX(float nonGridPivotTranslationX) {
- mNonGridPivotTranslationX = nonGridPivotTranslationX;
- applyTranslationX();
- }
-
- public float getScrollAdjustment(boolean gridEnabled) {
- float scrollAdjustment = 0;
- if (gridEnabled) {
- scrollAdjustment += mGridTranslationX;
- } else {
- scrollAdjustment += getNonGridTranslationX();
- }
- return scrollAdjustment;
- }
-
- public float getOffsetAdjustment(boolean gridEnabled) {
- return getScrollAdjustment(gridEnabled);
- }
-
- public float getSizeAdjustment(boolean fullscreenEnabled) {
- float sizeAdjustment = 1;
- if (fullscreenEnabled) {
- sizeAdjustment *= mNonGridScale;
- }
- return sizeAdjustment;
- }
-
- private void setBoxTranslationY(float boxTranslationY) {
- mBoxTranslationY = boxTranslationY;
- applyTranslationY();
- }
-
- private void applyTranslationX() {
- setTranslationX(mDismissTranslationX + mTaskOffsetTranslationX + mTaskResistanceTranslationX
- + mSplitSelectTranslationX + mGridEndTranslationX + getPersistentTranslationX());
- }
-
- private void applyTranslationY() {
- setTranslationY(mDismissTranslationY + mTaskOffsetTranslationY + mTaskResistanceTranslationY
- + mSplitSelectTranslationY + getPersistentTranslationY());
- }
-
- /**
- * Returns addition of translationX that is persistent (e.g. fullscreen and grid), and does not
- * change according to a temporary state (e.g. task offset).
- */
- public float getPersistentTranslationX() {
- return getNonGridTrans(mNonGridTranslationX) + getGridTrans(mGridTranslationX)
- + getNonGridTrans(mNonGridPivotTranslationX);
- }
-
- /**
- * Returns addition of translationY that is persistent (e.g. fullscreen and grid), and does not
- * change according to a temporary state (e.g. task offset).
- */
- public float getPersistentTranslationY() {
- return mBoxTranslationY + getGridTrans(mGridTranslationY);
- }
-
- public FloatProperty<TaskView> getPrimarySplitTranslationProperty() {
- return getPagedOrientationHandler().getPrimaryValue(
- SPLIT_SELECT_TRANSLATION_X, SPLIT_SELECT_TRANSLATION_Y);
- }
-
- public FloatProperty<TaskView> getSecondarySplitTranslationProperty() {
- return getPagedOrientationHandler().getSecondaryValue(
- SPLIT_SELECT_TRANSLATION_X, SPLIT_SELECT_TRANSLATION_Y);
- }
-
- public FloatProperty<TaskView> getPrimaryDismissTranslationProperty() {
- return getPagedOrientationHandler().getPrimaryValue(
- DISMISS_TRANSLATION_X, DISMISS_TRANSLATION_Y);
- }
-
- public FloatProperty<TaskView> getSecondaryDismissTranslationProperty() {
- return getPagedOrientationHandler().getSecondaryValue(
- DISMISS_TRANSLATION_X, DISMISS_TRANSLATION_Y);
- }
-
- public FloatProperty<TaskView> getPrimaryTaskOffsetTranslationProperty() {
- return getPagedOrientationHandler().getPrimaryValue(
- TASK_OFFSET_TRANSLATION_X, TASK_OFFSET_TRANSLATION_Y);
- }
-
- public FloatProperty<TaskView> getSecondaryTaskOffsetTranslationProperty() {
- return getPagedOrientationHandler().getSecondaryValue(
- TASK_OFFSET_TRANSLATION_X, TASK_OFFSET_TRANSLATION_Y);
- }
-
- public FloatProperty<TaskView> getTaskResistanceTranslationProperty() {
- return getPagedOrientationHandler().getSecondaryValue(
- TASK_RESISTANCE_TRANSLATION_X, TASK_RESISTANCE_TRANSLATION_Y);
- }
-
- @Override
- public boolean hasOverlappingRendering() {
- // TODO: Clip-out the icon region from the thumbnail, since they are overlapping.
- return false;
- }
-
- public boolean isEndQuickswitchCuj() {
- return mEndQuickswitchCuj;
- }
-
- public void setEndQuickswitchCuj(boolean endQuickswitchCuj) {
- mEndQuickswitchCuj = endQuickswitchCuj;
- }
-
- @Override
- public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
- super.onInitializeAccessibilityNodeInfo(info);
-
- info.addAction(
- new AccessibilityNodeInfo.AccessibilityAction(R.string.accessibility_close,
- getContext().getText(R.string.accessibility_close)));
-
- final Context context = getContext();
- for (TaskContainer taskContainer : mTaskContainers) {
- for (SystemShortcut s : TraceHelper.allowIpcs(
- "TV.a11yInfo", () -> getEnabledShortcuts(this, taskContainer))) {
- info.addAction(s.createAccessibilityAction(context));
- }
- }
-
- if (mDigitalWellBeingToast.hasLimit()) {
- info.addAction(
- new AccessibilityNodeInfo.AccessibilityAction(
- R.string.accessibility_app_usage_settings,
- getContext().getText(R.string.accessibility_app_usage_settings)));
- }
-
- final RecentsView recentsView = getRecentsView();
- final AccessibilityNodeInfo.CollectionItemInfo itemInfo =
- AccessibilityNodeInfo.CollectionItemInfo.obtain(
- 0, 1, recentsView.getTaskViewCount() - recentsView.indexOfChild(this) - 1,
- 1, false);
- info.setCollectionItemInfo(itemInfo);
- }
-
- @Override
- public boolean performAccessibilityAction(int action, Bundle arguments) {
- if (action == R.string.accessibility_close) {
- getRecentsView().dismissTask(this, true /*animateTaskView*/,
- true /*removeTask*/);
- return true;
- }
-
- if (action == R.string.accessibility_app_usage_settings) {
- mDigitalWellBeingToast.openAppUsageSettings(this);
- return true;
- }
-
- for (TaskContainer taskContainer : mTaskContainers) {
- for (SystemShortcut s : getEnabledShortcuts(this,
- taskContainer)) {
- if (s.hasHandlerForAction(action)) {
- s.onClick(this);
- return true;
- }
- }
- }
-
- return super.performAccessibilityAction(action, arguments);
- }
-
- @Nullable
- public RecentsView<?, ?> getRecentsView() {
- return (RecentsView<?, ?>) getParent();
- }
-
- RecentsPagedOrientationHandler getPagedOrientationHandler() {
- return getRecentsView().mOrientationState.getOrientationHandler();
- }
-
- private void notifyTaskLaunchFailed(String tag) {
- String msg = "Failed to launch task";
- if (getFirstTask() != null) {
- msg += " (task=" + getFirstTask().key.baseIntent + " userId="
- + getFirstTask().key.userId + ")";
- }
- Log.w(tag, msg);
- Toast.makeText(getContext(), R.string.activity_not_available, LENGTH_SHORT).show();
- }
-
- /**
- * Hides the icon and shows insets when this TaskView is about to be shown fullscreen.
- *
- * @param progress: 0 = show icon and no insets; 1 = don't show icon and show full insets.
- */
- public void setFullscreenProgress(float progress) {
- progress = Utilities.boundToRange(progress, 0, 1);
- mFullscreenProgress = progress;
- mIconView.setVisibility(progress < 1 ? VISIBLE : INVISIBLE);
- mTaskThumbnailViewDeprecated.getTaskOverlay().setFullscreenProgress(progress);
-
- RecentsView recentsView = mContainer.getOverviewPanel();
- // Animate icons and DWB banners in/out, except in QuickSwitch state, when tiles are
- // oversized and banner would look disproportionately large.
- if (recentsView.getStateManager().getState() != BACKGROUND_APP) {
- setIconsAndBannersTransitionProgress(progress, true);
- }
-
- updateSnapshotRadius();
- }
-
- protected void updateSnapshotRadius() {
- updateCurrentFullscreenParams();
- mTaskThumbnailViewDeprecated.setFullscreenParams(mCurrentFullscreenParams);
- }
-
- void updateCurrentFullscreenParams() {
- updateFullscreenParams(mCurrentFullscreenParams);
- }
-
- protected void updateFullscreenParams(TaskView.FullscreenDrawParams fullscreenParams) {
- if (getRecentsView() == null) {
- return;
- }
- fullscreenParams.setProgress(
- mFullscreenProgress, getRecentsView().getScaleX(), getScaleX());
- }
-
- /**
- * Updates TaskView scaling and translation required to support variable width if enabled, while
- * ensuring TaskView fits into screen in fullscreen.
- */
- void updateTaskSize() {
- ViewGroup.LayoutParams params = getLayoutParams();
- float nonGridScale;
- float boxTranslationY;
- int expectedWidth;
- int expectedHeight;
- DeviceProfile deviceProfile = mContainer.getDeviceProfile();
- final int thumbnailPadding = deviceProfile.overviewTaskThumbnailTopMarginPx;
- final Rect lastComputedTaskSize = getRecentsView().getLastComputedTaskSize();
- final int taskWidth = lastComputedTaskSize.width();
- final int taskHeight = lastComputedTaskSize.height();
- if (deviceProfile.isTablet) {
- int boxWidth;
- int boxHeight;
- boolean isFocusedTask = isFocusedTask();
- if (isFocusedTask) {
- // Task will be focused and should use focused task size. Use focusTaskRatio
- // that is associated with the original orientation of the focused task.
- boxWidth = taskWidth;
- boxHeight = taskHeight;
- } else {
- // Otherwise task is in grid, and should use lastComputedGridTaskSize.
- Rect lastComputedGridTaskSize = getRecentsView().getLastComputedGridTaskSize();
- boxWidth = lastComputedGridTaskSize.width();
- boxHeight = lastComputedGridTaskSize.height();
- }
-
- // Bound width/height to the box size.
- expectedWidth = boxWidth;
- expectedHeight = boxHeight + thumbnailPadding;
-
- // Scale to to fit task Rect.
- if (enableGridOnlyOverview()) {
- final Rect lastComputedCarouselTaskSize =
- getRecentsView().getLastComputedCarouselTaskSize();
- nonGridScale = lastComputedCarouselTaskSize.width() / (float) taskWidth;
- } else {
- nonGridScale = taskWidth / (float) boxWidth;
- }
-
- // Align to top of task Rect.
- boxTranslationY = (expectedHeight - thumbnailPadding - taskHeight) / 2.0f;
- } else {
- nonGridScale = 1f;
- boxTranslationY = 0f;
- expectedWidth = enableOverviewIconMenu() ? taskWidth : LayoutParams.MATCH_PARENT;
- expectedHeight = enableOverviewIconMenu()
- ? taskHeight + thumbnailPadding
- : LayoutParams.MATCH_PARENT;
- }
-
- setNonGridScale(nonGridScale);
- setBoxTranslationY(boxTranslationY);
- if (params.width != expectedWidth || params.height != expectedHeight) {
- params.width = expectedWidth;
- params.height = expectedHeight;
- setLayoutParams(params);
- }
- }
-
- private float getGridTrans(float endTranslation) {
- return Utilities.mapRange(mGridProgress, 0, endTranslation);
- }
-
- private float getNonGridTrans(float endTranslation) {
- return endTranslation - getGridTrans(endTranslation);
- }
-
- public boolean isRunningTask() {
- if (getRecentsView() == null) {
- return false;
- }
- return this == getRecentsView().getRunningTaskView();
- }
-
- public boolean isFocusedTask() {
- if (getRecentsView() == null) {
- return false;
- }
- return this == getRecentsView().getFocusedTaskView();
- }
-
- public void setShowScreenshot(boolean showScreenshot) {
- mShowScreenshot = showScreenshot;
- }
-
- public boolean showScreenshot() {
- if (!isRunningTask()) {
- return true;
- }
- return mShowScreenshot;
- }
-
- public void setOverlayEnabled(boolean overlayEnabled) {
- // TODO(b/335606129) Investigate the usage of [TaskOverlay] in the new TaskThumbnailView.
- // and if it's still necessary we should support that in the new TTV class.
- if (!enableRefactorTaskThumbnail()) {
- mTaskThumbnailViewDeprecated.setOverlayEnabled(overlayEnabled);
- }
- }
-
- public void initiateSplitSelect(SplitPositionOption splitPositionOption) {
- getRecentsView().initiateSplitSelect(this, splitPositionOption.stagePosition,
- getLogEventForPosition(splitPositionOption.stagePosition));
- }
-
- /**
- * Set a color tint on the snapshot and supporting views.
- */
- public void setColorTint(float amount, int tintColor) {
- if (!enableRefactorTaskThumbnail()) {
- // TODO(b/334832108) Add scrim to new TTV
- mTaskThumbnailViewDeprecated.setDimAlpha(amount);
- }
- mIconView.setIconColorTint(tintColor, amount);
- mDigitalWellBeingToast.setBannerColorTint(tintColor, amount);
- }
-
-
- private int getRootViewDisplayId() {
- Display display = getRootView().getDisplay();
- return display != null ? display.getDisplayId() : DEFAULT_DISPLAY;
- }
-
- /**
- * Sets visibility for the thumbnail and associated elements (DWB banners and action chips).
- * IconView is unaffected.
- *
- * @param taskId is only used when setting visibility to a non-{@link View#VISIBLE} value
- */
- void setThumbnailVisibility(int visibility, int taskId) {
- for (int i = 0; i < getChildCount(); i++) {
- View child = getChildAt(i);
- if (child != mIconView) {
- child.setVisibility(visibility);
- }
- }
- }
-
- private View getSnapshotView() {
- return enableRefactorTaskThumbnail() ? mTaskThumbnailView : mTaskThumbnailViewDeprecated;
- }
-
- /**
- * We update and subsequently draw these in {@link #setFullscreenProgress(float)}.
- */
- public static class FullscreenDrawParams implements SafeCloseable {
-
- private float mCornerRadius;
- private float mWindowCornerRadius;
-
- public float mCurrentDrawnCornerRadius;
-
- public FullscreenDrawParams(Context context) {
- updateCornerRadius(context);
- }
-
- /** Recomputes the start and end corner radius for the given Context. */
- public void updateCornerRadius(Context context) {
- mCornerRadius = computeTaskCornerRadius(context);
- mWindowCornerRadius = computeWindowCornerRadius(context);
- }
-
- @VisibleForTesting
- public float computeTaskCornerRadius(Context context) {
- return TaskCornerRadius.get(context);
- }
-
- @VisibleForTesting
- public float computeWindowCornerRadius(Context context) {
- return QuickStepContract.getWindowCornerRadius(context);
- }
-
- /**
- * Sets the progress in range [0, 1]
- */
- public void setProgress(float fullscreenProgress, float parentScale, float taskViewScale) {
- mCurrentDrawnCornerRadius =
- Utilities.mapRange(fullscreenProgress, mCornerRadius, mWindowCornerRadius)
- / parentScale / taskViewScale;
- }
-
- @Override
- public void close() {
- }
- }
-
- /**
- * Holder for all Task dependent information.
- */
- public class TaskContainer {
- private final TaskThumbnailViewDeprecated mThumbnailView;
- private final Task mTask;
- private final TaskViewIcon mIconView;
- /** Defaults to STAGE_POSITION_UNDEFINED if in not a split screen task view */
- private @SplitConfigurationOptions.StagePosition int mStagePosition;
- @IdRes
- private final int mA11yNodeId;
- private final DigitalWellBeingToast mDigitalWellBeingToast;
-
- public TaskContainer(Task task, TaskThumbnailViewDeprecated thumbnailView,
- TaskViewIcon iconView, int stagePosition,
- DigitalWellBeingToast digitalWellBeingToast) {
- this.mTask = task;
- this.mThumbnailView = thumbnailView;
- this.mIconView = iconView;
- this.mStagePosition = stagePosition;
- this.mA11yNodeId = (stagePosition == STAGE_POSITION_BOTTOM_OR_RIGHT) ?
- R.id.split_bottomRight_appInfo : R.id.split_topLeft_appInfo;
- this.mDigitalWellBeingToast = digitalWellBeingToast;
- }
-
- public TaskThumbnailViewDeprecated getThumbnailView() {
- return mThumbnailView;
- }
-
- public Task getTask() {
- return mTask;
- }
-
- public WorkspaceItemInfo getItemInfo() {
- return TaskView.this.getItemInfo(mTask);
- }
-
- public TaskView getTaskView() {
- return TaskView.this;
- }
-
- public TaskViewIcon getIconView() {
- return mIconView;
- }
-
- public int getStagePosition() {
- return mStagePosition;
- }
-
- void setStagePosition(@SplitConfigurationOptions.StagePosition int stagePosition) {
- this.mStagePosition = stagePosition;
- }
-
- public int getA11yNodeId() {
- return mA11yNodeId;
- }
-
- public DigitalWellBeingToast getDigitalWellBeingToast() {
- return mDigitalWellBeingToast;
- }
- }
-}
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.kt b/quickstep/src/com/android/quickstep/views/TaskView.kt
new file mode 100644
index 0000000..baeaa87
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/views/TaskView.kt
@@ -0,0 +1,1634 @@
+/*
+ * Copyright (C) 2017 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.quickstep.views
+
+import android.animation.Animator
+import android.animation.AnimatorListenerAdapter
+import android.animation.AnimatorSet
+import android.animation.ObjectAnimator
+import android.annotation.IdRes
+import android.app.ActivityOptions
+import android.content.Context
+import android.content.Intent
+import android.graphics.Canvas
+import android.graphics.PointF
+import android.graphics.Rect
+import android.graphics.drawable.Drawable
+import android.os.Bundle
+import android.util.AttributeSet
+import android.util.FloatProperty
+import android.util.Log
+import android.view.Display
+import android.view.MotionEvent
+import android.view.View
+import android.view.View.OnClickListener
+import android.view.ViewGroup
+import android.view.ViewStub
+import android.view.accessibility.AccessibilityNodeInfo
+import android.widget.FrameLayout
+import android.widget.Toast
+import androidx.annotation.IntDef
+import androidx.annotation.VisibleForTesting
+import androidx.core.view.children
+import androidx.core.view.updateLayoutParams
+import com.android.app.animation.Interpolators
+import com.android.launcher3.Flags.enableCursorHoverStates
+import com.android.launcher3.Flags.enableFocusOutline
+import com.android.launcher3.Flags.enableGridOnlyOverview
+import com.android.launcher3.Flags.enableOverviewIconMenu
+import com.android.launcher3.Flags.enableRefactorTaskThumbnail
+import com.android.launcher3.Flags.privateSpaceRestrictAccessibilityDrag
+import com.android.launcher3.LauncherSettings
+import com.android.launcher3.LauncherState
+import com.android.launcher3.R
+import com.android.launcher3.Utilities
+import com.android.launcher3.config.FeatureFlags.ENABLE_KEYBOARD_QUICK_SWITCH
+import com.android.launcher3.logging.StatsLogManager.LauncherEvent
+import com.android.launcher3.model.data.ItemInfoWithIcon
+import com.android.launcher3.model.data.WorkspaceItemInfo
+import com.android.launcher3.pm.UserCache
+import com.android.launcher3.testing.TestLogging
+import com.android.launcher3.testing.shared.TestProtocol
+import com.android.launcher3.util.CancellableTask
+import com.android.launcher3.util.Executors
+import com.android.launcher3.util.RunnableList
+import com.android.launcher3.util.SafeCloseable
+import com.android.launcher3.util.SplitConfigurationOptions
+import com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT
+import com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_UNDEFINED
+import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption
+import com.android.launcher3.util.SplitConfigurationOptions.StagePosition
+import com.android.launcher3.util.TraceHelper
+import com.android.launcher3.util.TransformingTouchDelegate
+import com.android.launcher3.util.ViewPool
+import com.android.launcher3.util.rects.set
+import com.android.quickstep.RecentsModel
+import com.android.quickstep.RemoteAnimationTargets
+import com.android.quickstep.TaskAnimationManager
+import com.android.quickstep.TaskOverlayFactory
+import com.android.quickstep.TaskUtils
+import com.android.quickstep.TaskViewUtils
+import com.android.quickstep.orientation.RecentsPagedOrientationHandler
+import com.android.quickstep.task.thumbnail.TaskThumbnail
+import com.android.quickstep.task.thumbnail.TaskThumbnailView
+import com.android.quickstep.task.viewmodel.TaskViewData
+import com.android.quickstep.util.ActiveGestureErrorDetector
+import com.android.quickstep.util.ActiveGestureLog
+import com.android.quickstep.util.BorderAnimator
+import com.android.quickstep.util.BorderAnimator.Companion.createSimpleBorderAnimator
+import com.android.quickstep.util.RecentsOrientedState
+import com.android.quickstep.util.TaskCornerRadius
+import com.android.quickstep.util.TaskRemovedDuringLaunchListener
+import com.android.systemui.shared.recents.model.Task
+import com.android.systemui.shared.recents.model.ThumbnailData
+import com.android.systemui.shared.system.ActivityManagerWrapper
+import com.android.systemui.shared.system.QuickStepContract
+
+/** A task in the Recents view. */
+open class TaskView
+@JvmOverloads
+constructor(
+ context: Context,
+ attrs: AttributeSet? = null,
+ defStyleAttr: Int = 0,
+ defStyleRes: Int = 0,
+ focusBorderAnimator: BorderAnimator? = null,
+ hoverBorderAnimator: BorderAnimator? = null
+) : FrameLayout(context, attrs), ViewPool.Reusable {
+ /**
+ * Used in conjunction with [onTaskListVisibilityChanged], providing more granularity on which
+ * components of this task require an update
+ */
+ @Retention(AnnotationRetention.SOURCE)
+ @IntDef(FLAG_UPDATE_ALL, FLAG_UPDATE_ICON, FLAG_UPDATE_THUMBNAIL, FLAG_UPDATE_CORNER_RADIUS)
+ annotation class TaskDataChanges
+
+ /** Type of task view */
+ @Retention(AnnotationRetention.SOURCE)
+ @IntDef(Type.SINGLE, Type.GROUPED, Type.DESKTOP)
+ annotation class Type {
+ companion object {
+ const val SINGLE = 1
+ const val GROUPED = 2
+ const val DESKTOP = 3
+ }
+ }
+
+ val taskViewData = TaskViewData()
+ val taskIds: IntArray
+ /** 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.thumbnailView }.toTypedArray()
+ val isGridTask: Boolean
+ /** Returns whether the task is part of overview grid and not being focused. */
+ get() = container.deviceProfile.isTablet && !isFocusedTask
+ val isRunningTask: Boolean
+ get() = this === recentsView?.runningTaskView
+ val isFocusedTask: Boolean
+ get() = this === recentsView?.focusedTaskView
+ val taskCornerRadius: Float
+ get() = currentFullscreenParams.cornerRadius
+ val recentsView: RecentsView<*, *>?
+ get() = parent as? RecentsView<*, *>
+ val pagedOrientationHandler: RecentsPagedOrientationHandler
+ get() = orientedState.orientationHandler
+
+ @get:Deprecated("Use {@link #mTaskContainers} instead.")
+ val firstTask: Task
+ /** Returns the first task bound to this TaskView. */
+ get() = taskContainers[0].task
+ @get:Deprecated("Use {@link #mTaskContainers} instead.")
+ val firstThumbnailView: TaskThumbnailViewDeprecated
+ /** Returns the first thumbnailView of the TaskView. */
+ get() = taskContainers[0].thumbnailView
+ @get:Deprecated("Use {@link #mTaskContainers} instead.")
+ val firstIconView: TaskViewIcon
+ /** Returns the first iconView of the TaskView. */
+ get() = taskContainers[0].iconView
+ protected val currentFullscreenParams = FullscreenDrawParams(context)
+ protected val container: RecentsViewContainer =
+ RecentsViewContainer.containerFromContext(context)
+ @VisibleForTesting(otherwise = VisibleForTesting.PROTECTED)
+ val digitalWellBeingToast = DigitalWellBeingToast(container, this)
+ protected val mLastTouchDownPosition = PointF()
+ protected val snapshotView: View
+ get() =
+ if (enableRefactorTaskThumbnail()) taskThumbnailView!! else taskThumbnailViewDeprecated
+
+ // Derived view properties
+ protected val persistentScale: Float
+ /**
+ * Returns multiplication of scale that is persistent (e.g. fullscreen and grid), and does
+ * not change according to a temporary state.
+ */
+ get() = Utilities.mapRange(gridProgress, nonGridScale, 1f)
+ protected val persistentTranslationX: Float
+ /**
+ * Returns addition of translationX that is persistent (e.g. fullscreen and grid), and does
+ * not change according to a temporary state (e.g. task offset).
+ */
+ get() =
+ (getNonGridTrans(nonGridTranslationX) +
+ getGridTrans(this.gridTranslationX) +
+ getNonGridTrans(nonGridPivotTranslationX))
+ protected val persistentTranslationY: Float
+ /**
+ * Returns addition of translationY that is persistent (e.g. fullscreen and grid), and does
+ * not change according to a temporary state (e.g. task offset).
+ */
+ get() = boxTranslationY + getGridTrans(gridTranslationY)
+ protected val primarySplitTranslationProperty: FloatProperty<TaskView>
+ get() =
+ pagedOrientationHandler.getPrimaryValue(
+ SPLIT_SELECT_TRANSLATION_X,
+ SPLIT_SELECT_TRANSLATION_Y
+ )
+ protected val secondarySplitTranslationProperty: FloatProperty<TaskView>
+ get() =
+ pagedOrientationHandler.getSecondaryValue(
+ SPLIT_SELECT_TRANSLATION_X,
+ SPLIT_SELECT_TRANSLATION_Y
+ )
+ protected val primaryDismissTranslationProperty: FloatProperty<TaskView>
+ get() =
+ pagedOrientationHandler.getPrimaryValue(DISMISS_TRANSLATION_X, DISMISS_TRANSLATION_Y)
+ protected val secondaryDismissTranslationProperty: FloatProperty<TaskView>
+ get() =
+ pagedOrientationHandler.getSecondaryValue(DISMISS_TRANSLATION_X, DISMISS_TRANSLATION_Y)
+ protected val primaryTaskOffsetTranslationProperty: FloatProperty<TaskView>
+ get() =
+ pagedOrientationHandler.getPrimaryValue(
+ TASK_OFFSET_TRANSLATION_X,
+ TASK_OFFSET_TRANSLATION_Y
+ )
+ protected val secondaryTaskOffsetTranslationProperty: FloatProperty<TaskView>
+ get() =
+ pagedOrientationHandler.getSecondaryValue(
+ TASK_OFFSET_TRANSLATION_X,
+ TASK_OFFSET_TRANSLATION_Y
+ )
+ protected val taskResistanceTranslationProperty: FloatProperty<TaskView>
+ get() =
+ pagedOrientationHandler.getSecondaryValue(
+ TASK_RESISTANCE_TRANSLATION_X,
+ TASK_RESISTANCE_TRANSLATION_Y
+ )
+
+ private val mIconCenterCoordinates = FloatArray(2)
+ private val mFocusBorderAnimator: BorderAnimator?
+ private val mHoverBorderAnimator: BorderAnimator?
+ private val rootViewDisplayId: Int
+ get() = rootView.display?.displayId ?: Display.DEFAULT_DISPLAY
+
+ /** Returns a list of all TaskContainers in the TaskView. */
+ lateinit var taskContainers: List<TaskContainer>
+ protected set
+ lateinit var orientedState: RecentsOrientedState
+ protected lateinit var taskThumbnailViewDeprecated: TaskThumbnailViewDeprecated
+ protected lateinit var iconView: TaskViewIcon
+ /**
+ * This technically can be a vanilla [android.view.TouchDelegate] class, however that class
+ * requires setting the touch bounds at construction, so we'd repeatedly be created many
+ * instances unnecessarily as scrolling occurs, whereas [TransformingTouchDelegate] allows touch
+ * delegated bounds only to be updated.
+ */
+ private lateinit var iconTouchDelegate: TransformingTouchDelegate
+ private var taskThumbnailView: TaskThumbnailView? = null
+
+ var taskViewId = -1
+ var isEndQuickSwitchCuj = false
+
+ // Various animation progress variables.
+ // progress: 0 = show icon and no insets; 1 = don't show icon and show full insets.
+ protected var fullscreenProgress = 0f
+ set(value) {
+ field = Utilities.boundToRange(value, 0f, 1f)
+ onFullscreenProgressChanged(field)
+ }
+ // gridProgress 0 = carousel; 1 = 2 row grid.
+ protected var gridProgress = 0f
+ set(value) {
+ field = value
+ onGridProgressChanged()
+ }
+ /**
+ * The modalness of this view is how it should be displayed when it is shown on its own in the
+ * modal state of overview. 0 being in context with other tasks, 1 being shown on its own.
+ */
+ protected var modalness = 0f
+ set(value) {
+ field = value
+ onModalnessUpdated(field)
+ }
+ protected var taskThumbnailSplashAlpha = 0f
+ set(value) {
+ field = value
+ applyThumbnailSplashAlpha()
+ }
+ protected var nonGridScale = 1f
+ set(value) {
+ field = value
+ applyScale()
+ }
+ private var dismissScale = 1f
+ set(value) {
+ field = value
+ applyScale()
+ }
+ private var dismissTranslationX = 0f
+ set(value) {
+ field = value
+ applyTranslationX()
+ }
+ private var dismissTranslationY = 0f
+ set(value) {
+ field = value
+ applyTranslationY()
+ }
+ private var taskOffsetTranslationX = 0f
+ set(value) {
+ field = value
+ applyTranslationX()
+ }
+ private var taskOffsetTranslationY = 0f
+ set(value) {
+ field = value
+ applyTranslationY()
+ }
+ private var taskResistanceTranslationX = 0f
+ set(value) {
+ field = value
+ applyTranslationX()
+ }
+ private var taskResistanceTranslationY = 0f
+ set(value) {
+ field = value
+ applyTranslationY()
+ }
+ // The following translation variables should only be used in the same orientation as Launcher.
+ private var boxTranslationY = 0f
+ set(value) {
+ field = value
+ applyTranslationY()
+ }
+ // The following grid translations scales with mGridProgress.
+ protected var gridTranslationX = 0f
+ set(value) {
+ field = value
+ applyTranslationX()
+ }
+ var gridTranslationY = 0f
+ protected set(value) {
+ field = value
+ applyTranslationY()
+ }
+ // The following grid translation is used to animate closing the gap between grid and clear all.
+ private var gridEndTranslationX = 0f
+ set(value) {
+ field = value
+ applyTranslationX()
+ }
+ // Applied as a complement to gridTranslation, for adjusting the carousel overview and quick
+ // switch.
+ protected var nonGridTranslationX = 0f
+ set(value) {
+ field = value
+ applyTranslationX()
+ }
+ protected var nonGridPivotTranslationX = 0f
+ set(value) {
+ field = value
+ applyTranslationX()
+ }
+ // Used when in SplitScreenSelectState
+ private var splitSelectTranslationY = 0f
+ set(value) {
+ field = value
+ applyTranslationY()
+ }
+ private var splitSelectTranslationX = 0f
+ set(value) {
+ field = value
+ applyTranslationX()
+ }
+ protected var stableAlpha = 1f
+ set(value) {
+ field = value
+ alpha = stableAlpha
+ }
+ protected var shouldShowScreenshot = false
+ get() = !isRunningTask || field
+ /** Enable or disable showing border on hover and focus change */
+ @VisibleForTesting(otherwise = VisibleForTesting.PROTECTED)
+ var borderEnabled = false
+ set(value) {
+ if (field == value) {
+ return
+ }
+ field = value
+ // Set the animation correctly in case it misses the hover/focus event during state
+ // transition
+ mHoverBorderAnimator?.setBorderVisibility(visible = field && isHovered, animated = true)
+ mFocusBorderAnimator?.setBorderVisibility(visible = field && isFocused, animated = true)
+ }
+ protected var iconScaleAnimStartProgress = 0f
+ private var focusTransitionProgress = 1f
+
+ private var iconAndDimAnimator: ObjectAnimator? = null
+ // The current background requests to load the task thumbnail and icon
+ private var thumbnailLoadRequest: CancellableTask<*>? = null
+ private var iconLoadRequest: CancellableTask<*>? = null
+ private var isClickableAsLiveTile = true
+
+ init {
+ setOnClickListener { view: View -> onClick(view) }
+ val keyboardFocusHighlightEnabled =
+ (ENABLE_KEYBOARD_QUICK_SWITCH.get() || enableFocusOutline())
+ val cursorHoverStatesEnabled = enableCursorHoverStates()
+ setWillNotDraw(!keyboardFocusHighlightEnabled && !cursorHoverStatesEnabled)
+ context.obtainStyledAttributes(attrs, R.styleable.TaskView, defStyleAttr, defStyleRes).use {
+ mFocusBorderAnimator =
+ focusBorderAnimator
+ ?: if (keyboardFocusHighlightEnabled)
+ createSimpleBorderAnimator(
+ currentFullscreenParams.cornerRadius.toInt(),
+ context.resources.getDimensionPixelSize(
+ R.dimen.keyboard_quick_switch_border_width
+ ),
+ { bounds: Rect -> getThumbnailBounds(bounds) },
+ this,
+ it.getColor(
+ R.styleable.TaskView_focusBorderColor,
+ BorderAnimator.DEFAULT_BORDER_COLOR
+ )
+ )
+ else null
+ mHoverBorderAnimator =
+ hoverBorderAnimator
+ ?: if (cursorHoverStatesEnabled)
+ createSimpleBorderAnimator(
+ currentFullscreenParams.cornerRadius.toInt(),
+ context.resources.getDimensionPixelSize(
+ R.dimen.task_hover_border_width
+ ),
+ { bounds: Rect -> getThumbnailBounds(bounds) },
+ this,
+ it.getColor(
+ R.styleable.TaskView_hoverBorderColor,
+ BorderAnimator.DEFAULT_BORDER_COLOR
+ )
+ )
+ else null
+ }
+ }
+
+ override fun onFinishInflate() {
+ super.onFinishInflate()
+ taskThumbnailViewDeprecated = findViewById(R.id.snapshot)!!
+ if (enableRefactorTaskThumbnail()) {
+ val indexOfSnapshotView = indexOfChild(taskThumbnailViewDeprecated)
+ taskThumbnailView =
+ TaskThumbnailView(mContext).apply {
+ layoutParams = taskThumbnailViewDeprecated.layoutParams
+ addView(this, indexOfSnapshotView)
+ }
+ taskThumbnailViewDeprecated.visibility = GONE
+ }
+ val iconViewStub =
+ findViewById<ViewStub>(R.id.icon)!!.apply {
+ layoutResource =
+ if (enableOverviewIconMenu()) R.layout.icon_app_chip_view
+ else R.layout.icon_view
+ }
+ iconView = iconViewStub.inflate() as TaskViewIcon
+ iconTouchDelegate = TransformingTouchDelegate(iconView.asView())
+ }
+
+ @VisibleForTesting(otherwise = VisibleForTesting.PROTECTED)
+ public override fun onFocusChanged(
+ gainFocus: Boolean,
+ direction: Int,
+ previouslyFocusedRect: Rect?
+ ) {
+ super.onFocusChanged(gainFocus, direction, previouslyFocusedRect)
+ if (borderEnabled) {
+ mFocusBorderAnimator?.setBorderVisibility(gainFocus, /* animated= */ true)
+ }
+ }
+
+ override fun onHoverEvent(event: MotionEvent): Boolean {
+ if (borderEnabled) {
+ when (event.action) {
+ MotionEvent.ACTION_HOVER_ENTER ->
+ mHoverBorderAnimator?.setBorderVisibility(visible = true, animated = true)
+ MotionEvent.ACTION_HOVER_EXIT ->
+ mHoverBorderAnimator?.setBorderVisibility(visible = false, animated = true)
+ else -> {}
+ }
+ }
+ return super.onHoverEvent(event)
+ }
+
+ // avoid triggering hover event on child elements which would cause HOVER_EXIT for this
+ // task view
+ override fun onInterceptHoverEvent(event: MotionEvent) =
+ if (enableCursorHoverStates()) true else super.onInterceptHoverEvent(event)
+
+ override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
+ val recentsView = recentsView ?: return false
+ val splitSelectStateController = recentsView.splitSelectController
+ // Disable taps for split selection animation unless we have multiple tasks
+ if (
+ splitSelectStateController.isSplitSelectActive &&
+ splitSelectStateController.initialTaskId == firstTask.key.id &&
+ !containsMultipleTasks()
+ ) {
+ return false
+ }
+ if (ev.action == MotionEvent.ACTION_DOWN) {
+ mLastTouchDownPosition.apply {
+ x = ev.x
+ y = ev.y
+ }
+ }
+ return super.dispatchTouchEvent(ev)
+ }
+
+ override fun draw(canvas: Canvas) {
+ // Draw border first so any child views outside of the thumbnail bounds are drawn above it.
+ mFocusBorderAnimator?.drawBorder(canvas)
+ mHoverBorderAnimator?.drawBorder(canvas)
+ super.draw(canvas)
+ }
+
+ override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
+ super.onLayout(changed, left, top, right, bottom)
+ val thumbnailTopMargin = container.deviceProfile.overviewTaskThumbnailTopMarginPx
+ if (container.deviceProfile.isTablet) {
+ pivotX = (if (layoutDirection == LAYOUT_DIRECTION_RTL) 0 else right - left).toFloat()
+ pivotY = thumbnailTopMargin.toFloat()
+ } else {
+ pivotX = (right - left) * 0.5f
+ pivotY = thumbnailTopMargin + (height - thumbnailTopMargin) * 0.5f
+ }
+ systemGestureExclusionRects =
+ SYSTEM_GESTURE_EXCLUSION_RECT.onEach {
+ it.right = width
+ it.bottom = height
+ }
+ }
+
+ override fun onRecycle() {
+ resetPersistentViewTransforms()
+ // Clear any references to the thumbnail (it will be re-read either from the cache or the
+ // system on next bind)
+ // TODO(b/334825222): Implement thumbnail/snapshot for the new [TaskThumbnailView].
+ if (enableRefactorTaskThumbnail()) {
+ notifyIsRunningTaskUpdated()
+ } else {
+ taskThumbnailViewDeprecated.setThumbnail(firstTask, null)
+ }
+ setOverlayEnabled(false)
+ onTaskListVisibilityChanged(false)
+ borderEnabled = false
+ }
+
+ // TODO: Clip-out the icon region from the thumbnail, since they are overlapping.
+ override fun hasOverlappingRendering() = false
+
+ override fun onInitializeAccessibilityNodeInfo(info: AccessibilityNodeInfo) {
+ super.onInitializeAccessibilityNodeInfo(info)
+ with(info) {
+ addAction(
+ AccessibilityNodeInfo.AccessibilityAction(
+ R.string.accessibility_close,
+ context.getText(R.string.accessibility_close)
+ )
+ )
+ taskContainers.forEach {
+ TraceHelper.allowIpcs("TV.a11yInfo") {
+ TaskOverlayFactory.getEnabledShortcuts(this@TaskView, it).forEach { shortcut ->
+ addAction(shortcut.createAccessibilityAction(context))
+ }
+ }
+ }
+ if (digitalWellBeingToast.hasLimit()) {
+ addAction(
+ AccessibilityNodeInfo.AccessibilityAction(
+ R.string.accessibility_app_usage_settings,
+ context.getText(R.string.accessibility_app_usage_settings)
+ )
+ )
+ }
+ recentsView?.let {
+ collectionItemInfo =
+ AccessibilityNodeInfo.CollectionItemInfo.obtain(
+ 0,
+ 1,
+ it.taskViewCount - it.indexOfChild(this@TaskView) - 1,
+ 1,
+ false
+ )
+ }
+ }
+ }
+
+ override fun performAccessibilityAction(action: Int, arguments: Bundle?): Boolean {
+ if (action == R.string.accessibility_close) {
+ recentsView?.dismissTask(this, true /*animateTaskView*/, true /*removeTask*/)
+ return true
+ }
+ if (action == R.string.accessibility_app_usage_settings) {
+ digitalWellBeingToast.openAppUsageSettings(this)
+ return true
+ }
+ taskContainers.forEach {
+ TaskOverlayFactory.getEnabledShortcuts(this, it).forEach { shortcut ->
+ if (shortcut.hasHandlerForAction(action)) {
+ shortcut.onClick(this)
+ return true
+ }
+ }
+ }
+ return super.performAccessibilityAction(action, arguments)
+ }
+
+ /** Updates this task view to the given {@param task}. */
+ open fun bind(
+ task: Task,
+ orientedState: RecentsOrientedState,
+ taskOverlayFactory: TaskOverlayFactory
+ ) {
+ cancelPendingLoadTasks()
+ setupTaskContainers(task, taskOverlayFactory)
+ setOrientationState(orientedState)
+ }
+
+ protected fun setupTaskContainers(task: Task, taskOverlayFactory: TaskOverlayFactory) {
+ taskContainers =
+ listOf(
+ TaskContainer(
+ task,
+ taskThumbnailViewDeprecated,
+ iconView,
+ STAGE_POSITION_UNDEFINED,
+ digitalWellBeingToast
+ )
+ )
+ if (enableRefactorTaskThumbnail()) {
+ taskThumbnailViewDeprecated.setTaskOverlayFactory(taskOverlayFactory)
+ bindTaskThumbnailView()
+ } else {
+ taskThumbnailViewDeprecated.bind(task, taskOverlayFactory)
+ }
+ }
+
+ protected fun isTaskContainersInitialized() = this::taskContainers.isInitialized
+
+ fun containsMultipleTasks() = taskContainers.size > 1
+
+ /**
+ * Returns the TaskContainer corresponding to a given taskId, or null if the TaskView does not
+ * contain a Task with that ID.
+ */
+ fun getTaskContainerById(taskId: Int) = taskContainers.firstOrNull { it.task.key.id == taskId }
+
+ /** Check if given `taskId` is tracked in this view */
+ fun containsTaskId(taskId: Int) = getTaskContainerById(taskId) != null
+
+ // TODO(b/335649589): TaskView's VM will already have access to TaskThumbnailView's VM
+ // so there will be no need to access TaskThumbnailView's VM through the TaskThumbnailView
+ private fun bindTaskThumbnailView() {
+ taskThumbnailView!!.viewModel.bind(TaskThumbnail(firstTask, isRunningTask))
+ }
+
+ open fun setOrientationState(orientationState: RecentsOrientedState) {
+ this.orientedState = orientationState
+ iconView.setIconOrientation(orientationState, isGridTask)
+ setThumbnailOrientation(orientationState)
+ }
+
+ protected open fun setThumbnailOrientation(orientationState: RecentsOrientedState) {
+ val thumbnailTopMargin = container.deviceProfile.overviewTaskThumbnailTopMarginPx
+
+ // TODO(b/271468547), we should default to setting translations only on the snapshot instead
+ // of a hybrid of both margins and translations
+ snapshotView.updateLayoutParams<LayoutParams> { topMargin = thumbnailTopMargin }
+
+ // TODO(b/335606129) Investigate the usage of [TaskOverlay] in the new TaskThumbnailView.
+ // and if it's still necessary we should support that in the new TTV class.
+ if (!enableRefactorTaskThumbnail()) {
+ taskThumbnailViewDeprecated.taskOverlay.updateOrientationState(orientationState)
+ }
+ digitalWellBeingToast.initialize(firstTask)
+ }
+
+ /**
+ * Updates TaskView scaling and translation required to support variable width if enabled, while
+ * ensuring TaskView fits into screen in fullscreen.
+ */
+ fun updateTaskSize(
+ lastComputedTaskSize: Rect,
+ lastComputedGridTaskSize: Rect,
+ lastComputedCarouselTaskSize: Rect
+ ) {
+ val thumbnailPadding = container.deviceProfile.overviewTaskThumbnailTopMarginPx
+ val taskWidth = lastComputedTaskSize.width()
+ val taskHeight = lastComputedTaskSize.height()
+ val nonGridScale: Float
+ val boxTranslationY: Float
+ val expectedWidth: Int
+ val expectedHeight: Int
+ if (container.deviceProfile.isTablet) {
+ val boxWidth: Int
+ val boxHeight: Int
+ val isFocusedTask = isFocusedTask
+ if (isFocusedTask) {
+ // Task will be focused and should use focused task size. Use focusTaskRatio
+ // that is associated with the original orientation of the focused task.
+ boxWidth = taskWidth
+ boxHeight = taskHeight
+ } else {
+ // Otherwise task is in grid, and should use lastComputedGridTaskSize.
+ boxWidth = lastComputedGridTaskSize.width()
+ boxHeight = lastComputedGridTaskSize.height()
+ }
+
+ // Bound width/height to the box size.
+ expectedWidth = boxWidth
+ expectedHeight = boxHeight + thumbnailPadding
+
+ // Scale to to fit task Rect.
+ nonGridScale =
+ if (enableGridOnlyOverview()) {
+ lastComputedCarouselTaskSize.width() / taskWidth.toFloat()
+ } else {
+ taskWidth / boxWidth.toFloat()
+ }
+
+ // Align to top of task Rect.
+ boxTranslationY = (expectedHeight - thumbnailPadding - taskHeight) / 2.0f
+ } else {
+ nonGridScale = 1f
+ boxTranslationY = 0f
+ expectedWidth = if (enableOverviewIconMenu()) taskWidth else LayoutParams.MATCH_PARENT
+ expectedHeight =
+ if (enableOverviewIconMenu()) taskHeight + thumbnailPadding
+ else LayoutParams.MATCH_PARENT
+ }
+ this.nonGridScale = nonGridScale
+ this.boxTranslationY = boxTranslationY
+ updateLayoutParams<ViewGroup.LayoutParams> {
+ width = expectedWidth
+ height = expectedHeight
+ }
+ }
+
+ /** Returns the thumbnail's bounds, optionally relative to the screen. */
+ @JvmOverloads
+ open fun getThumbnailBounds(bounds: Rect, relativeToDragLayer: Boolean = false) {
+ val snapshotView = snapshotView
+ if (relativeToDragLayer) {
+ container.dragLayer.getDescendantRectRelativeToSelf(snapshotView, bounds)
+ } else {
+ bounds.apply {
+ set(snapshotView)
+ offset(Math.round(snapshotView.translationX), Math.round(snapshotView.translationY))
+ }
+ }
+ }
+
+ /**
+ * See [TaskDataChanges]
+ *
+ * @param visible If this task view will be visible to the user in overview or hidden
+ */
+ fun onTaskListVisibilityChanged(visible: Boolean) {
+ onTaskListVisibilityChanged(visible, FLAG_UPDATE_ALL)
+ }
+
+ /**
+ * See [TaskDataChanges]
+ *
+ * @param visible If this task view will be visible to the user in overview or hidden
+ */
+ open fun onTaskListVisibilityChanged(visible: Boolean, @TaskDataChanges changes: Int) {
+ cancelPendingLoadTasks()
+ val model = RecentsModel.INSTANCE.get(context)
+ // These calls are no-ops if the data is already loaded, try and load the high
+ // resolution thumbnail if the state permits
+ if (needsUpdate(changes, FLAG_UPDATE_THUMBNAIL)) {
+ if (visible) {
+ thumbnailLoadRequest =
+ model.thumbnailCache.updateThumbnailInBackground(firstTask) {
+ if (!enableRefactorTaskThumbnail()) {
+ // TODO(b/334825222) add thumbnail state
+ taskThumbnailViewDeprecated.setThumbnail(firstTask, it)
+ }
+ }
+ } else {
+ if (!enableRefactorTaskThumbnail()) {
+ // TODO(b/334825222) add thumbnail state
+ taskThumbnailViewDeprecated.setThumbnail(null, null)
+ }
+ // Reset the task thumbnail reference as well (it will be fetched from the cache or
+ // reloaded next time we need it)
+ firstTask.thumbnail = null
+ }
+ }
+ if (needsUpdate(changes, FLAG_UPDATE_ICON)) {
+ if (visible) {
+ iconLoadRequest =
+ model.iconCache.updateIconInBackground(firstTask) {
+ setIcon(iconView, it.icon)
+ if (enableOverviewIconMenu()) {
+ setText(iconView, it.title)
+ }
+ digitalWellBeingToast.initialize(it)
+ }
+ } else {
+ setIcon(iconView, null)
+ if (enableOverviewIconMenu()) {
+ setText(iconView, null)
+ }
+ }
+ }
+ if (needsUpdate(changes, FLAG_UPDATE_CORNER_RADIUS)) {
+ currentFullscreenParams.updateCornerRadius(context)
+ }
+ }
+
+ protected fun needsUpdate(@TaskDataChanges dataChange: Int, @TaskDataChanges flag: Int) =
+ (dataChange and flag) == flag
+
+ protected open fun cancelPendingLoadTasks() {
+ thumbnailLoadRequest?.cancel()
+ thumbnailLoadRequest = null
+ iconLoadRequest?.cancel()
+ iconLoadRequest = null
+ }
+
+ protected fun setIcon(iconView: TaskViewIcon, icon: Drawable?) {
+ with(iconView) {
+ if (icon != null) {
+ setDrawable(icon)
+ setOnClickListener {
+ if (!confirmSecondSplitSelectApp()) {
+ showTaskMenu(this)
+ }
+ }
+ setOnLongClickListener {
+ requestDisallowInterceptTouchEvent(true)
+ showTaskMenu(this)
+ }
+ } else {
+ setDrawable(null)
+ setOnClickListener(null)
+ setOnLongClickListener(null)
+ }
+ }
+ }
+
+ protected fun setText(iconView: TaskViewIcon, text: CharSequence?) {
+ iconView.setText(text)
+ }
+
+ open fun refreshThumbnails(thumbnailDatas: HashMap<Int, ThumbnailData?>?) {
+ if (enableRefactorTaskThumbnail()) {
+ // TODO(b/334825222) add thumbnail logic
+ return
+ }
+ thumbnailDatas?.get(firstTask.key.id)?.let {
+ taskThumbnailViewDeprecated.setThumbnail(firstTask, it)
+ }
+ ?: { taskThumbnailViewDeprecated.refresh() }
+ }
+
+ private fun onClick(view: View) {
+ if (confirmSecondSplitSelectApp()) {
+ Log.d("b/310064698", "${taskIds.contentToString()} - onClick - split select is active")
+ return
+ }
+ val callbackList =
+ launchTasks()?.apply {
+ add {
+ Log.d("b/310064698", "${taskIds.contentToString()} - onClick - launchCompleted")
+ }
+ }
+ Log.d("b/310064698", "${taskIds.contentToString()} - onClick - callbackList: $callbackList")
+ container.statsLogManager
+ .logger()
+ .withItemInfo(getItemInfo())
+ .log(LauncherEvent.LAUNCHER_TASK_LAUNCH_TAP)
+ }
+
+ /**
+ * Starts the task associated with this view and animates the startup.
+ *
+ * @return CompletionStage to indicate the animation completion or null if the launch failed.
+ */
+ open fun launchTaskAnimated(): RunnableList? {
+ TestLogging.recordEvent(
+ TestProtocol.SEQUENCE_MAIN,
+ "startActivityFromRecentsAsync",
+ taskIds.contentToString()
+ )
+ val opts =
+ container.getActivityLaunchOptions(this, null).apply {
+ options.launchDisplayId = display?.displayId ?: Display.DEFAULT_DISPLAY
+ }
+ if (
+ ActivityManagerWrapper.getInstance()
+ .startActivityFromRecents(firstTask.key, opts.options)
+ ) {
+ Log.d(
+ TAG,
+ "launchTaskAnimated - startActivityFromRecents: ${taskIds.contentToString()}"
+ )
+ ActiveGestureLog.INSTANCE.trackEvent(
+ ActiveGestureErrorDetector.GestureEvent.EXPECTING_TASK_APPEARED
+ )
+ val recentsView = recentsView ?: return null
+ if (recentsView.runningTaskViewId != -1) {
+ recentsView.onTaskLaunchedInLiveTileMode()
+
+ // Return a fresh callback in the live tile case, so that it's not accidentally
+ // triggered by QuickstepTransitionManager.AppLaunchAnimationRunner.
+ return RunnableList().also { recentsView.addSideTaskLaunchCallback(it) }
+ }
+ if (TaskAnimationManager.ENABLE_SHELL_TRANSITIONS) {
+ // If the recents transition is running (ie. in live tile mode), then the start
+ // of a new task will merge into the existing transition and it currently will
+ // not be run independently, so we need to rely on the onTaskAppeared() call
+ // for the new task to trigger the side launch callback to flush this runnable
+ // list (which is usually flushed when the app launch animation finishes)
+ recentsView.addSideTaskLaunchCallback(opts.onEndCallback)
+ }
+ return opts.onEndCallback
+ } else {
+ notifyTaskLaunchFailed()
+ return null
+ }
+ }
+
+ /** Starts the task associated with this view without any animation */
+ fun launchTask(callback: (launched: Boolean) -> Unit) {
+ launchTask(callback, isQuickSwitch = false)
+ }
+
+ /** Starts the task associated with this view without any animation */
+ open fun launchTask(callback: (launched: Boolean) -> Unit, isQuickSwitch: Boolean) {
+ TestLogging.recordEvent(
+ TestProtocol.SEQUENCE_MAIN,
+ "startActivityFromRecentsAsync",
+ taskIds.contentToString()
+ )
+ val failureListener = TaskRemovedDuringLaunchListener(context.applicationContext)
+ if (isQuickSwitch) {
+ // We only listen for failures to launch in quickswitch because the during this
+ // gesture launcher is in the background state, vs other launches which are in
+ // the actual overview state
+ failureListener.register(container, firstTask.key.id) {
+ notifyTaskLaunchFailed()
+ recentsView?.let {
+ // Disable animations for now, as it is an edge case and the app usually
+ // covers launcher and also any state transition animation also gets
+ // clobbered by QuickstepTransitionManager.createWallpaperOpenAnimations
+ // when launcher shows again
+ it.startHome(false /* animated */)
+ // LauncherTaskbarUIController depends on the launcher state when
+ // checking whether to handle resume, but that can come in before
+ // startHome() changes the state, so force-refresh here to ensure the
+ // taskbar is updated
+ it.mSizeStrategy.taskbarController?.refreshResumedState()
+ }
+ }
+ }
+ // Indicate success once the system has indicated that the transition has started
+ val opts =
+ ActivityOptions.makeCustomTaskAnimation(
+ context,
+ 0,
+ 0,
+ Executors.MAIN_EXECUTOR.handler,
+ { callback(true) }
+ ) {
+ failureListener.onTransitionFinished()
+ }
+ .apply {
+ launchDisplayId = display?.displayId ?: Display.DEFAULT_DISPLAY
+ if (isQuickSwitch) {
+ setFreezeRecentTasksReordering()
+ }
+ // TODO(b/334826842) add splash functionality to new TTV
+ if (!enableRefactorTaskThumbnail()) {
+ disableStartingWindow = taskThumbnailViewDeprecated.shouldShowSplashView()
+ }
+ }
+ Executors.UI_HELPER_EXECUTOR.execute {
+ if (
+ !ActivityManagerWrapper.getInstance().startActivityFromRecents(firstTask.key, opts)
+ ) {
+ // If the call to start activity failed, then post the result immediately,
+ // otherwise, wait for the animation start callback from the activity options
+ // above
+ Executors.MAIN_EXECUTOR.post {
+ notifyTaskLaunchFailed()
+ callback(false)
+ }
+ }
+ Log.d(TAG, "launchTask - startActivityFromRecents: ${taskIds.contentToString()}")
+ }
+ }
+
+ /** Launch of the current task (both live and inactive tasks) with an animation. */
+ fun launchTasks(): RunnableList? {
+ val recentsView = recentsView ?: return null
+ val remoteTargetHandles = recentsView.mRemoteTargetHandles
+ if (!isRunningTask || remoteTargetHandles == null) {
+ return launchTaskAnimated()
+ }
+ if (!isClickableAsLiveTile) {
+ Log.e(TAG, "TaskView is not clickable as a live tile; returning to home.")
+ return null
+ }
+ isClickableAsLiveTile = false
+ val targets =
+ if (remoteTargetHandles.size == 1) {
+ remoteTargetHandles[0].transformParams.targetSet
+ } else {
+ val apps =
+ remoteTargetHandles.flatMap { it.transformParams.targetSet.apps.asIterable() }
+ val wallpapers =
+ remoteTargetHandles.flatMap {
+ it.transformParams.targetSet.wallpapers.asIterable()
+ }
+ RemoteAnimationTargets(
+ apps.toTypedArray(),
+ wallpapers.toTypedArray(),
+ remoteTargetHandles[0].transformParams.targetSet.nonApps,
+ remoteTargetHandles[0].transformParams.targetSet.targetMode
+ )
+ }
+ if (targets == null) {
+ // If the recents animation is cancelled somehow between the parent if block and
+ // here, try to launch the task as a non live tile task.
+ val runnableList = launchTaskAnimated()
+ if (runnableList == null) {
+ Log.e(
+ TAG,
+ "Recents animation cancelled and cannot launch task as non-live tile" +
+ "; returning to home"
+ )
+ }
+ isClickableAsLiveTile = true
+ return runnableList
+ }
+ val runnableList = RunnableList()
+ AnimatorSet().apply {
+ TaskViewUtils.composeRecentsLaunchAnimator(
+ this,
+ this@TaskView,
+ targets.apps,
+ targets.wallpapers,
+ targets.nonApps,
+ true /* launcherClosing */,
+ recentsView.stateManager,
+ recentsView,
+ recentsView.depthController
+ )
+ addListener(
+ object : AnimatorListenerAdapter() {
+ override fun onAnimationEnd(animator: Animator) {
+ if (firstTask.key.displayId != rootViewDisplayId) {
+ launchTaskAnimated()
+ }
+ isClickableAsLiveTile = true
+ runEndCallback()
+ }
+
+ override fun onAnimationCancel(animation: Animator) {
+ runEndCallback()
+ }
+
+ private fun runEndCallback() {
+ runnableList.executeAllAndDestroy()
+ }
+ }
+ )
+ start()
+ }
+ Log.d(TAG, "launchTasks - composeRecentsLaunchAnimator: ${taskIds.contentToString()}")
+ recentsView.onTaskLaunchedInLiveTileMode()
+ return runnableList
+ }
+
+ private fun notifyTaskLaunchFailed() {
+ Log.w(
+ TAG,
+ "Failed to launch task (task=${firstTask.key.baseIntent} userId=${firstTask.key.userId})"
+ )
+ Toast.makeText(context, R.string.activity_not_available, Toast.LENGTH_SHORT).show()
+ }
+
+ fun initiateSplitSelect(splitPositionOption: SplitPositionOption) {
+ recentsView?.initiateSplitSelect(
+ this,
+ splitPositionOption.stagePosition,
+ SplitConfigurationOptions.getLogEventForPosition(splitPositionOption.stagePosition)
+ )
+ }
+
+ /**
+ * Returns `true` if user is already in split select mode and this tap was to choose the second
+ * app. `false` otherwise
+ */
+ protected open fun confirmSecondSplitSelectApp(): Boolean {
+ val index = getLastSelectedChildTaskIndex()
+ if (index >= taskContainers.size) {
+ return false
+ }
+ val container = taskContainers[index]
+ val recentsView = recentsView ?: return false
+ return recentsView.confirmSplitSelect(
+ this,
+ container.task,
+ container.iconView.drawable,
+ container.thumbnailView,
+ container.thumbnailView.thumbnail, /* intent */
+ null, /* user */
+ null,
+ container.itemInfo
+ )
+ }
+
+ /**
+ * Returns the task index of the last selected child task (0 or 1). If we contain multiple tasks
+ * and this TaskView is used as part of split selection, the selected child task index will be
+ * that of the remaining task.
+ */
+ protected open fun getLastSelectedChildTaskIndex() = 0
+
+ private fun showTaskMenu(iconView: TaskViewIcon): Boolean {
+ val recentsView = recentsView ?: return false
+ if (!recentsView.canLaunchFullscreenTask()) {
+ // Don't show menu when selecting second split screen app
+ return true
+ }
+ if (!container.deviceProfile.isTablet && !recentsView.isClearAllHidden) {
+ recentsView.snapToPage(recentsView.indexOfChild(this))
+ return false
+ }
+ val menuContainer = taskContainers.firstOrNull { it.iconView === iconView } ?: return false
+ container.statsLogManager
+ .logger()
+ .withItemInfo(menuContainer.itemInfo)
+ .log(LauncherEvent.LAUNCHER_TASK_ICON_TAP_OR_LONGPRESS)
+ return showTaskMenuWithContainer(menuContainer)
+ }
+
+ private fun showTaskMenuWithContainer(menuContainer: TaskContainer): Boolean {
+ val recentsView = recentsView ?: return false
+ return if (enableOverviewIconMenu() && menuContainer.iconView is IconAppChipView) {
+ menuContainer.iconView.revealAnim(/* isRevealing= */ true)
+ TaskMenuView.showForTask(menuContainer) {
+ menuContainer.iconView.revealAnim(/* isRevealing= */ false)
+ }
+ } else if (container.deviceProfile.isTablet) {
+ val alignedOptionIndex =
+ if (
+ recentsView.isOnGridBottomRow(menuContainer.taskView) &&
+ container.deviceProfile.isLandscape
+ ) {
+ if (enableGridOnlyOverview()) {
+ // With no focused task, there is less available space below the tasks, so
+ // align the arrow to the third option in the menu.
+ 2
+ } else {
+ // Bottom row of landscape grid aligns arrow to second option to avoid
+ // clipping
+ 1
+ }
+ } else {
+ 0
+ }
+ TaskMenuViewWithArrow.showForTask(menuContainer, alignedOptionIndex)
+ } else {
+ TaskMenuView.showForTask(menuContainer)
+ }
+ }
+
+ @Deprecated("Use {@link #getItemInfo(Task)} instead.")
+ /** Builds proto for logging. */
+ fun getItemInfo() = getItemInfo(firstTask)
+
+ /** Builds proto for logging */
+ @VisibleForTesting
+ fun getItemInfo(task: Task): WorkspaceItemInfo {
+ return WorkspaceItemInfo().apply {
+ itemType = LauncherSettings.Favorites.ITEM_TYPE_TASK
+ container = LauncherSettings.Favorites.CONTAINER_TASKSWITCHER
+ val componentKey = TaskUtils.getLaunchComponentKeyForTask(task.key)
+ user = componentKey.user
+ intent = Intent().setComponent(componentKey.componentName)
+ title = task.title
+ recentsView?.let { screenId = it.indexOfChild(this@TaskView) }
+ if (privateSpaceRestrictAccessibilityDrag()) {
+ if (UserCache.getInstance(context).getUserInfo(componentKey.user).isPrivate) {
+ runtimeStatusFlags = runtimeStatusFlags or ItemInfoWithIcon.FLAG_NOT_PINNABLE
+ }
+ }
+ }
+ }
+
+ /**
+ * Whether the taskview should take the touch event from parent. Events passed to children that
+ * might require special handling.
+ */
+ open fun offerTouchToChildren(event: MotionEvent): Boolean {
+ if (event.action == MotionEvent.ACTION_DOWN) {
+ computeAndSetIconTouchDelegate(iconView, mIconCenterCoordinates, iconTouchDelegate)
+ }
+ return iconTouchDelegate.onTouchEvent(event)
+ }
+
+ protected fun computeAndSetIconTouchDelegate(
+ view: TaskViewIcon,
+ tempCenterCoordinates: FloatArray,
+ transformingTouchDelegate: TransformingTouchDelegate
+ ) {
+ val viewHalfWidth = view.width / 2f
+ val viewHalfHeight = view.height / 2f
+ Utilities.getDescendantCoordRelativeToAncestor(
+ view.asView(),
+ container.dragLayer,
+ tempCenterCoordinates.apply {
+ this[0] = viewHalfWidth
+ this[1] = viewHalfHeight
+ },
+ false
+ )
+ transformingTouchDelegate.setBounds(
+ (tempCenterCoordinates[0] - viewHalfWidth).toInt(),
+ (tempCenterCoordinates[1] - viewHalfHeight).toInt(),
+ (tempCenterCoordinates[0] + viewHalfWidth).toInt(),
+ (tempCenterCoordinates[1] + viewHalfHeight).toInt()
+ )
+ }
+
+ /** Sets up an on-click listener and the visibility for show_windows icon on top of the task. */
+ open fun setUpShowAllInstancesListener() {
+ val taskPackageName = taskContainers[0].task.key.packageName
+ // icon of the top/left task
+ val showWindowsView = findViewById<View>(R.id.show_windows)!!
+ updateFilterCallback(showWindowsView, getFilterUpdateCallback(taskPackageName))
+ }
+
+ /**
+ * Returns a callback that updates the state of the filter and the recents overview
+ *
+ * @param taskPackageName package name of the task to filter by
+ */
+ protected fun getFilterUpdateCallback(taskPackageName: String?) =
+ if (recentsView?.filterState?.shouldShowFilterUI(taskPackageName) == true)
+ OnClickListener { recentsView?.setAndApplyFilter(taskPackageName) }
+ else null
+
+ /**
+ * Sets the correct visibility and callback on the provided filterView based on whether the
+ * callback is null or not
+ */
+ protected fun updateFilterCallback(filterView: View, callback: OnClickListener?) {
+ // Filtering changes alpha instead of the visibility since visibility
+ // can be altered separately through RecentsView#resetFromSplitSelectionState()
+ filterView.alpha = if (callback == null) 0f else 1f
+ filterView.setOnClickListener(callback)
+ }
+
+ protected open fun setIconsAndBannersFullscreenProgress(progress: Float) {
+ // Animate icons and DWB banners in/out, except in QuickSwitch state, when tiles are
+ // oversized and banner would look disproportionately large.
+ if (recentsView?.stateManager?.state == LauncherState.BACKGROUND_APP) {
+ return
+ }
+ setIconsAndBannersTransitionProgress(progress, invert = true)
+ }
+
+ /**
+ * Called to animate a smooth transition when going directly from an app into Overview (and vice
+ * versa). Icons fade in, and DWB banners slide in with a "shift up" animation.
+ */
+ protected open fun setIconsAndBannersTransitionProgress(progress: Float, invert: Boolean) {
+ focusTransitionProgress = if (invert) 1 - progress else progress
+ getIconContentScale(invert).let { iconContentScale ->
+ iconView.setContentAlpha(iconContentScale)
+ digitalWellBeingToast.updateBannerOffset(1f - iconContentScale)
+ }
+ }
+
+ protected fun getIconContentScale(invert: Boolean): Float {
+ val iconScalePercentage = SCALE_ICON_DURATION.toFloat() / DIM_ANIM_DURATION
+ val lowerClamp = if (invert) 1f - iconScalePercentage else 0f
+ val upperClamp = if (invert) 1f else iconScalePercentage
+ return Interpolators.clampToProgress(Interpolators.FAST_OUT_SLOW_IN, lowerClamp, upperClamp)
+ .getInterpolation(focusTransitionProgress)
+ }
+
+ fun animateIconScaleAndDimIntoView() {
+ iconAndDimAnimator?.cancel()
+ iconAndDimAnimator =
+ ObjectAnimator.ofFloat(this, FOCUS_TRANSITION, 1f).apply {
+ setCurrentFraction(iconScaleAnimStartProgress)
+ setDuration(DIM_ANIM_DURATION).interpolator = Interpolators.LINEAR
+ addListener(
+ object : AnimatorListenerAdapter() {
+ override fun onAnimationEnd(animation: Animator) {
+ iconAndDimAnimator = null
+ }
+ }
+ )
+ start()
+ }
+ }
+
+ fun setIconScaleAndDim(iconScale: Float) {
+ iconAndDimAnimator?.cancel()
+ setIconsAndBannersTransitionProgress(iconScale, invert = false)
+ }
+
+ /** Set a color tint on the snapshot and supporting views. */
+ open fun setColorTint(amount: Float, tintColor: Int) {
+ if (!enableRefactorTaskThumbnail()) {
+ // TODO(b/334832108) Add scrim to new TTV
+ taskThumbnailViewDeprecated.setDimAlpha(amount)
+ }
+ iconView.setIconColorTint(tintColor, amount)
+ digitalWellBeingToast.setBannerColorTint(tintColor, amount)
+ }
+
+ /**
+ * Sets visibility for the thumbnail and associated elements (DWB banners and action chips).
+ * IconView is unaffected.
+ *
+ * @param taskId is only used when setting visibility to a non-[View.VISIBLE] value
+ */
+ open fun setThumbnailVisibility(visibility: Int, taskId: Int) {
+ children.filterNot { it === iconView }.forEach { it.visibility = visibility }
+ }
+
+ open fun setOverlayEnabled(overlayEnabled: Boolean) {
+ // TODO(b/335606129) Investigate the usage of [TaskOverlay] in the new TaskThumbnailView.
+ // and if it's still necessary we should support that in the new TTV class.
+ if (!enableRefactorTaskThumbnail()) {
+ taskThumbnailViewDeprecated.setOverlayEnabled(overlayEnabled)
+ }
+ }
+
+ protected open fun refreshTaskThumbnailSplash() {
+ if (!enableRefactorTaskThumbnail()) {
+ // TODO(b/334826842) add splash functionality to new TTV
+ taskThumbnailViewDeprecated.refreshSplashView()
+ }
+ }
+
+ protected fun getScrollAdjustment(gridEnabled: Boolean) =
+ if (gridEnabled) gridTranslationX else nonGridTranslationX
+
+ protected fun getOffsetAdjustment(gridEnabled: Boolean) = getScrollAdjustment(gridEnabled)
+
+ fun getSizeAdjustment(fullscreenEnabled: Boolean) = if (fullscreenEnabled) nonGridScale else 1f
+
+ private fun applyScale() {
+ val scale = persistentScale * dismissScale
+ scaleX = scale
+ scaleY = scale
+ if (enableRefactorTaskThumbnail()) {
+ taskViewData.scale.value = scale
+ }
+ updateSnapshotRadius()
+ }
+
+ protected open fun applyThumbnailSplashAlpha() {
+ if (!enableRefactorTaskThumbnail()) {
+ // TODO(b/334826842) add splash functionality to new TTV
+ taskThumbnailViewDeprecated.setSplashAlpha(taskThumbnailSplashAlpha)
+ }
+ }
+
+ private fun applyTranslationX() {
+ translationX =
+ dismissTranslationX +
+ taskOffsetTranslationX +
+ taskResistanceTranslationX +
+ splitSelectTranslationX +
+ gridEndTranslationX +
+ persistentTranslationX
+ }
+
+ private fun applyTranslationY() {
+ translationY =
+ dismissTranslationY +
+ taskOffsetTranslationY +
+ taskResistanceTranslationY +
+ splitSelectTranslationY +
+ persistentTranslationY
+ }
+
+ private fun onGridProgressChanged() {
+ applyTranslationX()
+ applyTranslationY()
+ applyScale()
+ }
+
+ protected open fun onFullscreenProgressChanged(fullscreenProgress: Float) {
+ iconView.setVisibility(if (fullscreenProgress < 1) VISIBLE else INVISIBLE)
+ taskThumbnailViewDeprecated.taskOverlay.setFullscreenProgress(fullscreenProgress)
+ setIconsAndBannersFullscreenProgress(fullscreenProgress)
+ updateSnapshotRadius()
+ }
+
+ protected open fun updateSnapshotRadius() {
+ updateCurrentFullscreenParams()
+ taskThumbnailViewDeprecated.setFullscreenParams(currentFullscreenParams)
+ }
+
+ protected fun updateCurrentFullscreenParams() {
+ updateFullscreenParams(currentFullscreenParams)
+ }
+
+ protected fun updateFullscreenParams(fullscreenParams: FullscreenDrawParams) {
+ recentsView?.let { fullscreenParams.setProgress(fullscreenProgress, it.scaleX, scaleX) }
+ }
+
+ private fun onModalnessUpdated(modalness: Float) {
+ iconView.setModalAlpha(1 - modalness)
+ digitalWellBeingToast.updateBannerOffset(modalness)
+ }
+
+ /** Updates [TaskThumbnailView] to reflect the latest [Task] state (i.e., task isRunning). */
+ fun notifyIsRunningTaskUpdated() {
+ // TODO(b/335649589): TaskView's VM will already have access to TaskThumbnailView's VM
+ // so there will be no need to access TaskThumbnailView's VM through the TaskThumbnailView
+ if (taskContainers.isNotEmpty()) {
+ bindTaskThumbnailView()
+ }
+ }
+
+ fun resetPersistentViewTransforms() {
+ nonGridTranslationX = 0f
+ gridTranslationX = 0f
+ gridTranslationY = 0f
+ boxTranslationY = 0f
+ nonGridPivotTranslationX = 0f
+ resetViewTransforms()
+ }
+
+ open fun resetViewTransforms() {
+ // fullscreenTranslation and accumulatedTranslation should not be reset, as
+ // resetViewTransforms is called during QuickSwitch scrolling.
+ dismissTranslationX = 0f
+ taskOffsetTranslationX = 0f
+ taskResistanceTranslationX = 0f
+ splitSelectTranslationX = 0f
+ gridEndTranslationX = 0f
+ dismissTranslationY = 0f
+ taskOffsetTranslationY = 0f
+ taskResistanceTranslationY = 0f
+ if (recentsView?.isSplitSelectionActive != true) {
+ splitSelectTranslationY = 0f
+ }
+ dismissScale = 1f
+ translationZ = 0f
+ alpha = stableAlpha
+ setIconScaleAndDim(1f)
+ setColorTint(0f, 0)
+ if (!enableRefactorTaskThumbnail()) {
+ // TODO(b/335399428) add split select functionality to new TTV
+ taskThumbnailViewDeprecated.resetViewTransforms()
+ }
+ }
+
+ private fun getGridTrans(endTranslation: Float) =
+ Utilities.mapRange(gridProgress, 0f, endTranslation)
+
+ private fun getNonGridTrans(endTranslation: Float) =
+ endTranslation - getGridTrans(endTranslation)
+
+ /** We update and subsequently draw these in [fullscreenProgress]. */
+ open class FullscreenDrawParams(context: Context) : SafeCloseable {
+ var cornerRadius = 0f
+ private var windowCornerRadius = 0f
+ var currentDrawnCornerRadius = 0f
+
+ init {
+ updateCornerRadius(context)
+ }
+
+ /** Recomputes the start and end corner radius for the given Context. */
+ fun updateCornerRadius(context: Context) {
+ cornerRadius = computeTaskCornerRadius(context)
+ windowCornerRadius = computeWindowCornerRadius(context)
+ }
+
+ @VisibleForTesting(otherwise = VisibleForTesting.PROTECTED)
+ open fun computeTaskCornerRadius(context: Context): Float {
+ return TaskCornerRadius.get(context)
+ }
+
+ @VisibleForTesting(otherwise = VisibleForTesting.PROTECTED)
+ open fun computeWindowCornerRadius(context: Context): Float {
+ return QuickStepContract.getWindowCornerRadius(context)
+ }
+
+ /** Sets the progress in range [0, 1] */
+ fun setProgress(fullscreenProgress: Float, parentScale: Float, taskViewScale: Float) {
+ currentDrawnCornerRadius =
+ Utilities.mapRange(fullscreenProgress, cornerRadius, windowCornerRadius) /
+ parentScale /
+ taskViewScale
+ }
+
+ override fun close() {}
+ }
+
+ /** Holder for all Task dependent information. */
+ inner class TaskContainer(
+ val task: Task,
+ val thumbnailView: TaskThumbnailViewDeprecated,
+ val iconView: TaskViewIcon,
+ /** Defaults to STAGE_POSITION_UNDEFINED if in not a split screen task view */
+ @field:StagePosition var stagePosition: Int,
+ val digitalWellBeingToast: DigitalWellBeingToast?
+ ) {
+ @IdRes
+ val a11yNodeId: Int =
+ if (stagePosition == STAGE_POSITION_BOTTOM_OR_RIGHT) R.id.split_bottomRight_appInfo
+ else R.id.split_topLeft_appInfo
+
+ val itemInfo: WorkspaceItemInfo
+ get() = getItemInfo(task)
+ val taskView: TaskView
+ get() = this@TaskView
+ }
+
+ companion object {
+ private const val TAG = "TaskView"
+ const val FLAG_UPDATE_ICON = 1
+ const val FLAG_UPDATE_THUMBNAIL = FLAG_UPDATE_ICON shl 1
+ const val FLAG_UPDATE_CORNER_RADIUS = FLAG_UPDATE_THUMBNAIL shl 1
+ const val FLAG_UPDATE_ALL =
+ (FLAG_UPDATE_ICON or FLAG_UPDATE_THUMBNAIL or FLAG_UPDATE_CORNER_RADIUS)
+
+ /** The maximum amount that a task view can be scrimmed, dimmed or tinted. */
+ const val MAX_PAGE_SCRIM_ALPHA = 0.4f
+ const val SCALE_ICON_DURATION: Long = 120
+ private const val DIM_ANIM_DURATION: Long = 700
+ private val SYSTEM_GESTURE_EXCLUSION_RECT = listOf(Rect())
+
+ @JvmField
+ val FOCUS_TRANSITION: FloatProperty<TaskView> =
+ object : FloatProperty<TaskView>("focusTransition") {
+ override fun setValue(taskView: TaskView, v: Float) {
+ taskView.setIconsAndBannersTransitionProgress(v, false /* invert */)
+ }
+
+ override fun get(taskView: TaskView) = taskView.focusTransitionProgress
+ }
+ private val SPLIT_SELECT_TRANSLATION_X: FloatProperty<TaskView> =
+ object : FloatProperty<TaskView>("splitSelectTranslationX") {
+ override fun setValue(taskView: TaskView, v: Float) {
+ taskView.splitSelectTranslationX = v
+ }
+
+ override fun get(taskView: TaskView) = taskView.splitSelectTranslationX
+ }
+ private val SPLIT_SELECT_TRANSLATION_Y: FloatProperty<TaskView> =
+ object : FloatProperty<TaskView>("splitSelectTranslationY") {
+ override fun setValue(taskView: TaskView, v: Float) {
+ taskView.splitSelectTranslationY = v
+ }
+
+ override fun get(taskView: TaskView) = taskView.splitSelectTranslationY
+ }
+ private val DISMISS_TRANSLATION_X: FloatProperty<TaskView> =
+ object : FloatProperty<TaskView>("dismissTranslationX") {
+ override fun setValue(taskView: TaskView, v: Float) {
+ taskView.dismissTranslationX = v
+ }
+
+ override fun get(taskView: TaskView) = taskView.dismissTranslationX
+ }
+ private val DISMISS_TRANSLATION_Y: FloatProperty<TaskView> =
+ object : FloatProperty<TaskView>("dismissTranslationY") {
+ override fun setValue(taskView: TaskView, v: Float) {
+ taskView.dismissTranslationY = v
+ }
+
+ override fun get(taskView: TaskView) = taskView.dismissTranslationY
+ }
+ private val TASK_OFFSET_TRANSLATION_X: FloatProperty<TaskView> =
+ object : FloatProperty<TaskView>("taskOffsetTranslationX") {
+ override fun setValue(taskView: TaskView, v: Float) {
+ taskView.taskOffsetTranslationX = v
+ }
+
+ override fun get(taskView: TaskView) = taskView.taskOffsetTranslationX
+ }
+ private val TASK_OFFSET_TRANSLATION_Y: FloatProperty<TaskView> =
+ object : FloatProperty<TaskView>("taskOffsetTranslationY") {
+ override fun setValue(taskView: TaskView, v: Float) {
+ taskView.taskOffsetTranslationY = v
+ }
+
+ override fun get(taskView: TaskView) = taskView.taskOffsetTranslationY
+ }
+ private val TASK_RESISTANCE_TRANSLATION_X: FloatProperty<TaskView> =
+ object : FloatProperty<TaskView>("taskResistanceTranslationX") {
+ override fun setValue(taskView: TaskView, v: Float) {
+ taskView.taskResistanceTranslationX = v
+ }
+
+ override fun get(taskView: TaskView) = taskView.taskResistanceTranslationX
+ }
+ private val TASK_RESISTANCE_TRANSLATION_Y: FloatProperty<TaskView> =
+ object : FloatProperty<TaskView>("taskResistanceTranslationY") {
+ override fun setValue(taskView: TaskView, v: Float) {
+ taskView.taskResistanceTranslationY = v
+ }
+
+ override fun get(taskView: TaskView) = taskView.taskResistanceTranslationY
+ }
+ @JvmField
+ val GRID_END_TRANSLATION_X: FloatProperty<TaskView> =
+ object : FloatProperty<TaskView>("gridEndTranslationX") {
+ override fun setValue(taskView: TaskView, v: Float) {
+ taskView.gridEndTranslationX = v
+ }
+
+ override fun get(taskView: TaskView) = taskView.gridEndTranslationX
+ }
+ @JvmField
+ val DISMISS_SCALE: FloatProperty<TaskView> =
+ object : FloatProperty<TaskView>("dismissScale") {
+ override fun setValue(taskView: TaskView, v: Float) {
+ taskView.dismissScale = v
+ }
+
+ override fun get(taskView: TaskView) = taskView.dismissScale
+ }
+ }
+}
diff --git a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimatorTest.kt b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimatorTest.kt
index 7ad432b..c54755b 100644
--- a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimatorTest.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimatorTest.kt
@@ -174,7 +174,7 @@
InstrumentationRegistry.getInstrumentation().runOnMainSync {}
PhysicsAnimatorTestUtils.blockUntilFirstAnimationFrameWhereTrue(handleAnimator) { true }
- assertThat(handleAnimator.isRunning()).isTrue()
+ handleAnimator.assertIsRunning()
assertThat(bubbleBarView.isAnimatingNewBubble).isTrue()
// verify the hide bubble animation is pending
assertThat(animatorScheduler.delayedBlock).isNotNull()
@@ -191,7 +191,7 @@
// PhysicsAnimatorTestUtils posts the cancellation to the main thread so we need to wait
// again
InstrumentationRegistry.getInstrumentation().waitForIdleSync()
- assertThat(handleAnimator.isRunning()).isFalse()
+ handleAnimator.assertIsNotRunning()
}
@Test
@@ -220,7 +220,7 @@
// wait for the hide animation to start
InstrumentationRegistry.getInstrumentation().runOnMainSync {}
- assertThat(handleAnimator.isRunning()).isTrue()
+ handleAnimator.assertIsRunning()
InstrumentationRegistry.getInstrumentation().runOnMainSync {
animator.onStashStateChangingWhileAnimating()
@@ -232,7 +232,7 @@
// PhysicsAnimatorTestUtils posts the cancellation to the main thread so we need to wait
// again
InstrumentationRegistry.getInstrumentation().waitForIdleSync()
- assertThat(handleAnimator.isRunning()).isFalse()
+ handleAnimator.assertIsNotRunning()
}
@Test
@@ -255,12 +255,12 @@
InstrumentationRegistry.getInstrumentation().runOnMainSync {}
PhysicsAnimatorTestUtils.blockUntilFirstAnimationFrameWhereTrue(handleAnimator) { true }
- assertThat(handleAnimator.isRunning()).isTrue()
+ handleAnimator.assertIsRunning()
assertThat(bubbleBarView.isAnimatingNewBubble).isTrue()
assertThat(animatorScheduler.delayedBlock).isNotNull()
handleAnimator.cancel()
- assertThat(handleAnimator.isRunning()).isFalse()
+ handleAnimator.assertIsNotRunning()
assertThat(bubbleBarView.isAnimatingNewBubble).isFalse()
assertThat(animatorScheduler.delayedBlock).isNull()
}
@@ -288,7 +288,7 @@
InstrumentationRegistry.getInstrumentation().runOnMainSync {}
PhysicsAnimatorTestUtils.blockUntilAnimationsEnd(DynamicAnimation.TRANSLATION_Y)
- assertThat(barAnimator.isRunning()).isFalse()
+ barAnimator.assertIsNotRunning()
assertThat(bubbleBarView.isAnimatingNewBubble).isTrue()
assertThat(bubbleBarView.alpha).isEqualTo(1)
assertThat(bubbleBarView.translationY).isEqualTo(BAR_TRANSLATION_Y_FOR_TASKBAR)
@@ -330,7 +330,7 @@
InstrumentationRegistry.getInstrumentation().runOnMainSync {}
PhysicsAnimatorTestUtils.blockUntilAnimationsEnd(DynamicAnimation.TRANSLATION_Y)
- assertThat(barAnimator.isRunning()).isFalse()
+ barAnimator.assertIsNotRunning()
assertThat(bubbleBarView.isAnimatingNewBubble).isTrue()
assertThat(bubbleBarView.alpha).isEqualTo(1)
assertThat(bubbleBarView.translationY).isEqualTo(BAR_TRANSLATION_Y_FOR_TASKBAR)
@@ -364,7 +364,7 @@
InstrumentationRegistry.getInstrumentation().runOnMainSync {}
PhysicsAnimatorTestUtils.blockUntilAnimationsEnd(DynamicAnimation.TRANSLATION_Y)
- assertThat(barAnimator.isRunning()).isFalse()
+ barAnimator.assertIsNotRunning()
assertThat(bubbleBarView.isAnimatingNewBubble).isTrue()
assertThat(bubbleBarView.alpha).isEqualTo(1)
assertThat(bubbleBarView.translationY).isEqualTo(BAR_TRANSLATION_Y_FOR_HOTSEAT)
@@ -413,6 +413,18 @@
.thenReturn(BAR_TRANSLATION_Y_FOR_TASKBAR)
}
+ private fun <T> PhysicsAnimator<T>.assertIsRunning() {
+ InstrumentationRegistry.getInstrumentation().runOnMainSync {
+ assertThat(isRunning()).isTrue()
+ }
+ }
+
+ private fun <T> PhysicsAnimator<T>.assertIsNotRunning() {
+ InstrumentationRegistry.getInstrumentation().runOnMainSync {
+ assertThat(isRunning()).isFalse()
+ }
+ }
+
private class TestBubbleBarViewAnimatorScheduler : BubbleBarViewAnimator.Scheduler {
var delayedBlock: Runnable? = null
diff --git a/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarKeyguardControllerTest.kt b/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarKeyguardControllerTest.kt
index ed88c29..e619e7c 100644
--- a/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarKeyguardControllerTest.kt
+++ b/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarKeyguardControllerTest.kt
@@ -105,7 +105,7 @@
verify(navbarButtonsViewController, times(1)).setBackForBouncer(false)
}
- private fun setFlags(flags: Int) {
+ private fun setFlags(flags: Long) {
taskbarKeyguardController.updateStateForSysuiFlags(flags)
}
}
diff --git a/quickstep/tests/src/com/android/quickstep/DesktopSystemShortcutTest.kt b/quickstep/tests/src/com/android/quickstep/DesktopSystemShortcutTest.kt
index d59aafb..33a8e79 100644
--- a/quickstep/tests/src/com/android/quickstep/DesktopSystemShortcutTest.kt
+++ b/quickstep/tests/src/com/android/quickstep/DesktopSystemShortcutTest.kt
@@ -30,10 +30,13 @@
import com.android.launcher3.uioverrides.QuickstepLauncher
import com.android.launcher3.util.SplitConfigurationOptions
import com.android.quickstep.views.LauncherRecentsView
+import com.android.quickstep.views.TaskThumbnailViewDeprecated
import com.android.quickstep.views.TaskView
+import com.android.quickstep.views.TaskViewIcon
import com.android.systemui.shared.recents.model.Task
import com.android.systemui.shared.recents.model.Task.TaskKey
import com.android.window.flags.Flags
+import com.android.wm.shell.shared.DesktopModeStatus
import com.google.common.truth.Truth.assertThat
import org.junit.After
import org.junit.Before
@@ -58,6 +61,8 @@
private val taskView: TaskView = mock()
private val workspaceItemInfo: WorkspaceItemInfo = mock()
private val abstractFloatingViewHelper: AbstractFloatingViewHelper = mock()
+ private val thumbnailView: TaskThumbnailViewDeprecated = mock()
+ private val iconView: TaskViewIcon = mock()
private val factory: TaskShortcutFactory =
DesktopSystemShortcut.createFactory(abstractFloatingViewHelper)
@@ -90,8 +95,8 @@
val taskContainer =
taskView.TaskContainer(
task,
- null,
- null,
+ thumbnailView,
+ iconView,
SplitConfigurationOptions.STAGE_POSITION_UNDEFINED,
null
)
@@ -112,8 +117,8 @@
val taskContainer =
taskView.TaskContainer(
task,
- null,
- null,
+ thumbnailView,
+ iconView,
SplitConfigurationOptions.STAGE_POSITION_UNDEFINED,
null
)
@@ -135,8 +140,8 @@
val taskContainer =
taskView.TaskContainer(
task,
- null,
- null,
+ thumbnailView,
+ iconView,
SplitConfigurationOptions.STAGE_POSITION_UNDEFINED,
null
)
@@ -156,8 +161,8 @@
val taskContainer =
taskView.TaskContainer(
task,
- null,
- null,
+ thumbnailView,
+ iconView,
SplitConfigurationOptions.STAGE_POSITION_UNDEFINED,
null
)
@@ -177,8 +182,8 @@
val taskContainer =
taskView.TaskContainer(
task,
- null,
- null,
+ thumbnailView,
+ iconView,
SplitConfigurationOptions.STAGE_POSITION_UNDEFINED,
null
)
diff --git a/quickstep/tests/src/com/android/quickstep/FullscreenDrawParamsTest.kt b/quickstep/tests/src/com/android/quickstep/FullscreenDrawParamsTest.kt
index db06b6b..5d62a4c 100644
--- a/quickstep/tests/src/com/android/quickstep/FullscreenDrawParamsTest.kt
+++ b/quickstep/tests/src/com/android/quickstep/FullscreenDrawParamsTest.kt
@@ -53,7 +53,7 @@
)
val expectedRadius = TaskCornerRadius.get(context)
- assertThat(params.mCurrentDrawnCornerRadius).isEqualTo(expectedRadius)
+ assertThat(params.currentDrawnCornerRadius).isEqualTo(expectedRadius)
}
@Test
@@ -67,7 +67,7 @@
)
val expectedRadius = QuickStepContract.getWindowCornerRadius(context)
- assertThat(params.mCurrentDrawnCornerRadius).isEqualTo(expectedRadius)
+ assertThat(params.currentDrawnCornerRadius).isEqualTo(expectedRadius)
}
@Test
@@ -81,7 +81,7 @@
)
val expectedRadius = TaskCornerRadius.get(context)
- assertThat(params.mCurrentDrawnCornerRadius).isEqualTo(expectedRadius)
+ assertThat(params.currentDrawnCornerRadius).isEqualTo(expectedRadius)
}
@Test
@@ -95,7 +95,7 @@
)
val expectedRadius = QuickStepContract.getWindowCornerRadius(context)
- assertThat(params.mCurrentDrawnCornerRadius).isEqualTo(expectedRadius)
+ assertThat(params.currentDrawnCornerRadius).isEqualTo(expectedRadius)
}
@Test
@@ -117,7 +117,7 @@
/* parentScale= */ 1.0f,
/* taskViewScale= */ 1.0f
)
- assertThat(spyParams.mCurrentDrawnCornerRadius).isEqualTo(display1TaskRadius)
+ assertThat(spyParams.currentDrawnCornerRadius).isEqualTo(display1TaskRadius)
spyParams.updateCornerRadius(display2Context)
spyParams.setProgress(
@@ -125,7 +125,7 @@
/* parentScale= */ 1.0f,
/* taskViewScale= */ 1.0f
)
- assertThat(spyParams.mCurrentDrawnCornerRadius).isEqualTo(display2TaskRadius)
+ assertThat(spyParams.currentDrawnCornerRadius).isEqualTo(display2TaskRadius)
}
@Test
@@ -147,7 +147,7 @@
/* parentScale= */ 1.0f,
/* taskViewScale= */ 1.0f
)
- assertThat(spyParams.mCurrentDrawnCornerRadius).isEqualTo(display1WindowRadius)
+ assertThat(spyParams.currentDrawnCornerRadius).isEqualTo(display1WindowRadius)
spyParams.updateCornerRadius(display2Context)
spyParams.setProgress(
@@ -155,6 +155,6 @@
/* parentScale= */ 1.0f,
/* taskViewScale= */ 1.0f,
)
- assertThat(spyParams.mCurrentDrawnCornerRadius).isEqualTo(display2WindowRadius)
+ assertThat(spyParams.currentDrawnCornerRadius).isEqualTo(display2WindowRadius)
}
}
diff --git a/res/drawable/bg_ps_mask_left_corner.xml b/res/drawable/bg_ps_mask_left_corner.xml
new file mode 100644
index 0000000..43eeedb
--- /dev/null
+++ b/res/drawable/bg_ps_mask_left_corner.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2024 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.
+ -->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+ <item>
+ <vector
+ android:viewportWidth="28"
+ android:viewportHeight="28"
+ android:width="@dimen/ps_floating_mask_corner_radius"
+ android:height="@dimen/ps_floating_mask_corner_radius">
+ <path
+ android:pathData="M0 28H28C24.3228 28 20.6821 27.2759 17.2847 25.8687C13.8877 24.4614 10.8013 22.3989 8.20117 19.7988C5.60107 17.1987 3.53857 14.1123 2.13135 10.7153C0.724121 7.31787 0 3.67725 0 0V28Z"
+ android:fillType="evenOdd"
+ android:fillColor="?attr/allAppsScrimColor" />
+ </vector>
+ </item>
+</layer-list>
\ No newline at end of file
diff --git a/res/drawable/bg_ps_mask_right_corner.xml b/res/drawable/bg_ps_mask_right_corner.xml
new file mode 100644
index 0000000..d63b866
--- /dev/null
+++ b/res/drawable/bg_ps_mask_right_corner.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ Copyright (C) 2024 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.
+ -->
+
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+ <item>
+ <vector
+ android:viewportWidth="28"
+ android:viewportHeight="28"
+ android:width="@dimen/ps_floating_mask_corner_radius"
+ android:height="@dimen/ps_floating_mask_corner_radius">
+ <path
+ android:pathData="M28 28V0C28 3.67725 27.2759 7.31787 25.8687 10.7153C24.4614 14.1123 22.3989 17.1987 19.7988 19.7988C17.1987 22.3989 14.1123 24.4614 10.7153 25.8687C7.31787 27.2759 3.67725 28 0 28H28Z"
+ android:fillType="evenOdd"
+ android:fillColor="?attr/allAppsScrimColor" />
+ </vector>
+ </item>
+</layer-list>
\ No newline at end of file
diff --git a/res/layout/private_space_mask_view.xml b/res/layout/private_space_mask_view.xml
new file mode 100644
index 0000000..44e2797
--- /dev/null
+++ b/res/layout/private_space_mask_view.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ Copyright (C) 2024 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.
+ -->
+
+<com.android.launcher3.allapps.FloatingMaskView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignParentBottom="true"
+ android:layout_marginLeft="@dimen/ps_floating_mask_end_padding"
+ android:layout_marginRight="@dimen/ps_floating_mask_end_padding"
+ android:importantForAccessibility="noHideDescendants"
+ android:orientation="horizontal">
+
+ <ImageView
+ android:id="@+id/left_corner"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ app:layout_constraintStart_toStartOf="parent"
+ android:importantForAccessibility="no"
+ android:background="@drawable/bg_ps_mask_left_corner"/>
+
+ <ImageView
+ android:id="@+id/right_corner"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:scaleType="centerCrop"
+ app:layout_constraintEnd_toEndOf="parent"
+ android:importantForAccessibility="no"
+ android:background="@drawable/bg_ps_mask_right_corner"/>
+
+ <ImageView
+ android:id="@+id/bottom_box"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ app:layout_constraintStart_toStartOf="@id/left_corner"
+ app:layout_constraintEnd_toEndOf="@id/right_corner"
+ app:layout_constraintTop_toBottomOf="@id/left_corner"
+ android:importantForAccessibility="no"
+ android:background="?attr/allAppsScrimColor"/>
+
+</com.android.launcher3.allapps.FloatingMaskView>
\ No newline at end of file
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index c363dc5..51a736c 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Voorstelle"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Noodsaaklikhede"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Nuus en tydskrifte"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Jou ontspansone"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Vermaak"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Sosiaal"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Gesondheid en fiksheid"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"Weer"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Voorgestel vir jou"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"<xliff:g id="SELECTED_HEADER">%1$s</xliff:g>-legstukke aan die regterkant, soektog en opsies aan die linkerkant"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# legstuk}other{# legstukke}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"Privaat, gesluit."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"Sluit"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"Privaat Ruimte-oorgang"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"Installeer apps"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"Installeer apps in privaat ruimte"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Oorvloei"</string>
</resources>
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index bc211ef..1de35f4 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"የአስተያየት ጥቆማዎች"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"ጠቃሚ ነገሮች"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"ዜና እና መጽሔቶች"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"የሚያርፉበት ቦታዎ"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"መዝናኛ"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"ማህበራዊ"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"ጤና እና የአካል ብቃት"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"የአየር ሁኔታ"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"ለእርስዎ የተጠቆሙ"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"<xliff:g id="SELECTED_HEADER">%1$s</xliff:g> ምግብሮች በቀኝ በኩል፣ ፍለጋ እና አማራጮች በግራ በኩል"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# ምግብር}one{# ምግብሮች}other{# ምግብሮች}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"የግል፣ የተቆለፈ።"</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"ቆልፍ"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"የግል ቦታ ሽግግር"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"መተግበሪያዎችን ይጫኑ"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"መተግበሪያዎችን ወደ የግል ቦታ ይጫኑ"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"ትርፍ ፍሰት"</string>
</resources>
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index becfa8d..4d6528a 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"اقتراحات"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"الأساسيات"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"الأخبار والمجلات"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"محتوى ترفيهي مقترَح"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"الترفيه"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"التواصل الاجتماعي"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"الصحة واللياقة البدنية"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"الطقس"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"اقتراحاتنا لك"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"تطبيقات \"<xliff:g id="SELECTED_HEADER">%1$s</xliff:g>\" المصغّرة على اليسار، والبحث والخيارات على اليمين"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{تطبيق مصغّر واحد}zero{# تطبيق مصغّر}two{تطبيقان مصغّران}few{# تطبيقات مصغّرة}many{# تطبيقًا مصغّرًا}other{# تطبيق مصغّر}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"المساحة الخاصة مُقفلة."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"قفل"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"النقل إلى المساحة الخاصة"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"تثبيت التطبيقات"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"تثبيت التطبيقات في المساحة الخاصّة"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"القائمة الكاملة"</string>
</resources>
diff --git a/res/values-as/strings.xml b/res/values-as/strings.xml
index d2487f8..9798dd2 100644
--- a/res/values-as/strings.xml
+++ b/res/values-as/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"পৰামৰ্শ"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"অত্যাৱশ্যকীয়সমূহ"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"বাতৰি আৰু আলোচনী"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"আপোনাৰ পচন্দৰ স্থান"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"মনোৰঞ্জন"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"সামাজিক"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"স্বাস্থ্য আৰু সুস্থতা"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"বতৰ"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"আপোনাৰ বাবে পৰামৰ্শ হিচাপে আগবঢ়োৱা"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"<xliff:g id="SELECTED_HEADER">%1$s</xliff:g> ৱিজেট সোঁফালে, সন্ধান আৰু বিকল্পসমূহ বাওঁফালে"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# টা ৱিজেট}one{# টা ৱিজেট}other{# টা ৱিজেট}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"ব্যক্তিগত, লক কৰা আছে।"</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"লক কৰক"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"ব্যক্তিগত স্পে’চৰ স্থানান্তৰণ"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"এপ্ ইনষ্টল কৰক"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"এপ্সমূহ প্ৰাইভেট স্পেচত ইনষ্টল কৰক"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"অ’ভাৰফ্ল’"</string>
</resources>
diff --git a/res/values-az/strings.xml b/res/values-az/strings.xml
index 145ec69..a8f0a3f 100644
--- a/res/values-az/strings.xml
+++ b/res/values-az/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Təkliflər"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Əsaslar"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Xəbər və jurnallar"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"İstirahət zonası"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Əyləncə"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Sosial"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Sağlamlıq və fitnes"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"Hava"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Təklif edirik"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"<xliff:g id="SELECTED_HEADER">%1$s</xliff:g> vidcetləri sağda, axtarış və seçimlər solda"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# vidcet}other{# vidcet}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"Şəxsi, kilidli."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"Kilidləyin"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"Şəxsi məkana keçid"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"Tətbiqlər quraşdırın"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"Tətbiqləri şəxsi sahədə quraşdırın"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Kənara çıxma"</string>
</resources>
diff --git a/res/values-b+sr+Latn/strings.xml b/res/values-b+sr+Latn/strings.xml
index 8b69318..371d388 100644
--- a/res/values-b+sr+Latn/strings.xml
+++ b/res/values-b+sr+Latn/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Predlozi"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Osnovno"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Novosti i časopisi"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Zona za opuštanje"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Zabava"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Društvene mreže"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Zdravlje i fitnes"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"Vreme"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Predloženo za vas"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"Vidžeti <xliff:g id="SELECTED_HEADER">%1$s</xliff:g> sa desne strane, pretraga i opcije sa leve strane"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# vidžet}one{# vidžet}few{# vidžeta}other{# vidžeta}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"Privatno, zaključano."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"Zaključavanje"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"Prenos privatnog prostora"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"Instalirajte aplikacije"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"Instaliraj aplikacije u privatan prostor"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Preklopno"</string>
</resources>
diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml
index c3b384c..7614fd8 100644
--- a/res/values-be/strings.xml
+++ b/res/values-be/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Прапановы"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Асноўнае"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Навіны і часопісы"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Зона адпачынку"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Забавы"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Сацыяльныя сеткі"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Здароўе і фітнес"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"Надвор\'е"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Рэкамендавана для вас"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"Віджэты праграмы \"<xliff:g id="SELECTED_HEADER">%1$s</xliff:g>\" справа, пошук і параметры злева"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# віджэт}one{# віджэт}few{# віджэты}many{# віджэтаў}other{# віджэта}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"Прыватная прастора, заблакіравана."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"Заблакіраваць"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"Пераход у прыватную вобласць"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"Усталяваць праграмы"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"Усталяваць праграмы ў прыватнай прасторы"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Дадатковае меню"</string>
</resources>
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index 7915de9..d1edca8 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Предложения"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Приспособления, които трябва да изпробвате"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Новини и списания"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Зоната ви за разпускане"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Развлечения"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Социални мрежи"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Здраве и фитнес"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"Времето"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Предложено за вас"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"Приспособленията за <xliff:g id="SELECTED_HEADER">%1$s</xliff:g> са отдясно, търсенето и опциите – отляво"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# приспособление}other{# приспособления}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"Частно, заключено."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"Заключване"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"Преминаване към личното пространство"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"Инсталиране на приложения"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"Инсталиране на приложения в частно пространство"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Препълване"</string>
</resources>
diff --git a/res/values-bn/strings.xml b/res/values-bn/strings.xml
index a19fbfc..0a791e2 100644
--- a/res/values-bn/strings.xml
+++ b/res/values-bn/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"সাজেশন"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"প্রয়োজনীয় জিনিস"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"খবর ও ম্যাগাজিন"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"আপনার চিল জোন"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"বিনোদন"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"সোশ্যাল"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"স্বাস্থ্য ও ফিটনেস"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"আবহাওয়া"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"আপনার জন্য সাজেস্ট করা হয়েছে"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"<xliff:g id="SELECTED_HEADER">%1$s</xliff:g> উইজেট ডানদিকে, সার্চ ও বিকল্প বাঁদিকে রয়েছে"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{#টি উইজেট}one{#টি উইজেট}other{#টি উইজেট}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"ব্যক্তিগত, লক করা আছে।"</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"লক"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"ব্যক্তিগত স্পেস ট্রানজিট করা"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"অ্যাপ ইনস্টল করুন"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"প্রাইভেট স্পেসে অ্যাপ ইনস্টল করুন"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"ওভারফ্লো"</string>
</resources>
diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml
index 74fe854..7cb54d0 100644
--- a/res/values-bs/strings.xml
+++ b/res/values-bs/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Prijedlozi"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Osnovne aplikacije"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Vijesti i časopisi"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Vaša zona opuštanja"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Zabava"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Društvene mreže"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Zdravlje i fitnes"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"Vrijeme"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Predloženo za vas"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"Vidžeti aplikacije <xliff:g id="SELECTED_HEADER">%1$s</xliff:g> su na desnoj, a pretraživanje i opcije na lijevoj strani"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# vidžet}one{# vidžet}few{# vidžeta}other{# vidžeta}}"</string>
@@ -65,7 +62,7 @@
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Posao"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Razgovori"</string>
<string name="widget_category_note_taking" msgid="3469689394504266039">"Pisanje bilješki"</string>
- <string name="widget_add_button_label" msgid="2761267068711937179">"Dodaj"</string>
+ <string name="widget_add_button_label" msgid="2761267068711937179">"Dodajte"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"Dodavanje vidžeta <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Dodirnite da promijenite postavke vidžeta"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Promjena postavki vidžeta"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"Privatno, zaključano."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"Zaključaj"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"Prelazak u privatan prostor"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"Instaliranje aplikacija"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"Instaliranje aplikacija u privatni prostor"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Preklopni meni"</string>
</resources>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index 50bb41f..fc57a88 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Suggeriments"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Essencials"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Notícies i revistes"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"La teva zona de relax"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Entreteniment"</string>
- <string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Social"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Salut i fitnes"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"Temps"</string>
+ <string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Xarxes socials"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Suggeriments per a tu"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"Widgets de <xliff:g id="SELECTED_HEADER">%1$s</xliff:g> a la dreta, cerca i opcions a l\'esquerra"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}other{# widgets}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"Privat, bloquejat."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"Bloqueja"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"Canvia a Espai privat"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"Instal·la apps"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"Instal·la les aplicacions a Espai privat"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Menú addicional"</string>
</resources>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index 736eaab..28fd138 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Návrhy"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Nejdůležitější aplikace"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Zprávy a časopisy"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Vaše klidová zóna"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Zábava"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Sociální sítě"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Zdraví a fitness"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"Počasí"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Návrhy pro vás"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"Widgety <xliff:g id="SELECTED_HEADER">%1$s</xliff:g> vpravo, vyhledávání a možnosti vlevo"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{ # widget}few{# widgety}many{# widgetu}other{# widgetů}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"Soukromé, uzamčeno."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"Zamknout"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"Převádění soukromého prostoru"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"Instalovat aplikace"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"Instalovat aplikace do soukromého prostoru"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Rozbalovací nabídka"</string>
</resources>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index 7d4e804..f813ff0 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Forslag"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Vigtige ting"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Aviser og blade"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Dit afslapningshjørne"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Underholdning"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Socialt"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Sundhed og fitness"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"Vejr"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Forslag til dig"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"<xliff:g id="SELECTED_HEADER">%1$s</xliff:g>-widgets til højre, søgning og valgmuligheder til venstre"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}one{# widget}other{# widgets}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"Privat, låst."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"Lås"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"Ændringer af tilstanden for det private område"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"Installer apps"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"Installer apps i privat område"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Overløb"</string>
</resources>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index 230c578..990d533 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Vorschläge"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Must-haves"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Nachrichten und Zeitschriften"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Zum Entspannen"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Unterhaltung"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Soziale Netzwerke"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Gesundheit und Fitness"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"Wetter"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Vorschläge für dich"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"<xliff:g id="SELECTED_HEADER">%1$s</xliff:g>-Widgets rechts, Suche und Optionen links"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# Widget}other{# Widgets}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"Privat, gesperrt."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"Sperren"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"Sperrzustand des privaten Bereichs wird gerade geändert"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"Apps installieren"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"Apps im privaten Bereich installieren"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Weitere Optionen"</string>
</resources>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index 03fce60..59ff1c9 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Προτάσεις"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Απαραίτητα"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Ειδήσεις και περιοδικά"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Ο δικός σας τρόπος χαλάρωσης"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Ψυχαγωγία"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Κοινωνικά δίκτυα"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Υγεία και φυσική κατάσταση"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"Καιρός"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Προτεινόμενα για εσάς"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"Γραφικά στοιχεία <xliff:g id="SELECTED_HEADER">%1$s</xliff:g> στα δεξιά, αναζήτηση και επιλογές στα αριστερά"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# γραφικό στοιχείο}other{# γραφικά στοιχεία}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"Ιδιωτικό, κλειδωμένο."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"Κλείδωμα"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"Μετάβαση στον Ιδιωτικό χώρο"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"Εγκατάσταση εφαρμογών"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"Εγκατάσταση εφαρμογών στον απόρρητο χώρο"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Υπερχείλιση"</string>
</resources>
diff --git a/res/values-en-rAU/strings.xml b/res/values-en-rAU/strings.xml
index 37c74a5..000a021 100644
--- a/res/values-en-rAU/strings.xml
+++ b/res/values-en-rAU/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Suggestions"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Essentials"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"News and magazines"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Your chill zone"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Entertainment"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Social"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Health and fitness"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"Weather"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Suggested for you"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"<xliff:g id="SELECTED_HEADER">%1$s</xliff:g> widgets on right, search and options on left"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}other{# widgets}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"Private, locked."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"Lock"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"Private Space transitioning"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"Install apps"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"Install apps to private space"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Overflow"</string>
</resources>
diff --git a/res/values-en-rCA/strings.xml b/res/values-en-rCA/strings.xml
index a36e96c..b96374d 100644
--- a/res/values-en-rCA/strings.xml
+++ b/res/values-en-rCA/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Suggestions"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Essentials"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"News & magazines"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Your Chill Zone"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Entertainment"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Social"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Health & fitness"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"Weather"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Suggested for you"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"<xliff:g id="SELECTED_HEADER">%1$s</xliff:g> widgets on right, search and options on left"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}other{# widgets}}"</string>
@@ -193,7 +190,7 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"Private, locked."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"Lock"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"Private Space Transitioning"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"Install apps"</string>
+ <string name="ps_add_button_label" msgid="8127988716897128773">"Install"</string>
<string name="ps_add_button_content_description" msgid="3254274107740952556">"Install apps to Private Space"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Overflow"</string>
</resources>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index 37c74a5..000a021 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Suggestions"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Essentials"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"News and magazines"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Your chill zone"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Entertainment"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Social"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Health and fitness"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"Weather"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Suggested for you"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"<xliff:g id="SELECTED_HEADER">%1$s</xliff:g> widgets on right, search and options on left"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}other{# widgets}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"Private, locked."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"Lock"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"Private Space transitioning"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"Install apps"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"Install apps to private space"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Overflow"</string>
</resources>
diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml
index 37c74a5..000a021 100644
--- a/res/values-en-rIN/strings.xml
+++ b/res/values-en-rIN/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Suggestions"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Essentials"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"News and magazines"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Your chill zone"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Entertainment"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Social"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Health and fitness"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"Weather"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Suggested for you"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"<xliff:g id="SELECTED_HEADER">%1$s</xliff:g> widgets on right, search and options on left"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}other{# widgets}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"Private, locked."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"Lock"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"Private Space transitioning"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"Install apps"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"Install apps to private space"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Overflow"</string>
</resources>
diff --git a/res/values-en-rXC/strings.xml b/res/values-en-rXC/strings.xml
index 04c2dcf..f6e3152 100644
--- a/res/values-en-rXC/strings.xml
+++ b/res/values-en-rXC/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Suggestions"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Essentials"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"News & magazines"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Your Chill Zone"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Entertainment"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Social"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Health & fitness"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"Weather"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Suggested for you"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"<xliff:g id="SELECTED_HEADER">%1$s</xliff:g> widgets on right, search and options on left"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}other{# widgets}}"</string>
@@ -193,7 +190,7 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"Private, locked."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"Lock"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"Private Space Transitioning"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"Install apps"</string>
+ <string name="ps_add_button_label" msgid="8127988716897128773">"Install"</string>
<string name="ps_add_button_content_description" msgid="3254274107740952556">"Install apps to Private Space"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Overflow"</string>
</resources>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index 623b183..9b252b47 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Sugerencias"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Imprescindibles"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Noticias y revistas"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Zona de descanso"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Entretenimiento"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Redes sociales"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Salud y bienestar"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"Clima"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Sugerencias para ti"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"Widgets de <xliff:g id="SELECTED_HEADER">%1$s</xliff:g> a la derecha, búsqueda y opciones a la izquierda"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}other{# widgets}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"Privado (bloqueado)"</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"Bloqueo"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"Pasar a Espacio privado"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"Instala apps"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"Instala las apps en el espacio privado"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Ampliada"</string>
</resources>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index 4df953a..cd22d50 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Sugerencias"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Imprescindibles"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Noticias y revistas"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Tu zona de descanso"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Entretenimiento"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Redes sociales"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Salud y actividad física"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"El tiempo"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Sugerencias para ti"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"Widgets de <xliff:g id="SELECTED_HEADER">%1$s</xliff:g> a la derecha, búsqueda y opciones a la izquierda"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}other{# widgets}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"Privado, bloqueado."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"Bloquear"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"Cambiar a espacio privado"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"Descarg. apps"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"Descargar aplicaciones en el espacio privado"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Desplegable"</string>
</resources>
diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml
index 226ccd1..83b5a65 100644
--- a/res/values-et/strings.xml
+++ b/res/values-et/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Soovitused"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Põhiasjad"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Uudised ja ajakirjad"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Teie lõõgastumiskoht"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Meelelahutus"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Suhtlus"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Tervis ja vormisolek"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"Ilm"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Teile soovitatud"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"Teenuse <xliff:g id="SELECTED_HEADER">%1$s</xliff:g> vidinad paremal, otsing ja valikud vasakul"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# vidin}other{# vidinat}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"Privaatne, lukustatud."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"Lukk"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"Privaatse ruumi üleviimine"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"Rakenduste installimine"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"Rakenduste installimine privaatses ruumis"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Ületäide"</string>
</resources>
diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml
index b564f57..c6e6ca7 100644
--- a/res/values-eu/strings.xml
+++ b/res/values-eu/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Iradokizunak"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Oinarrizkoak"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Albisteak eta aldizkariak"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Lasaitzeko gunea"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Aisia"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Sare sozialak"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Osasuna eta ongizatea"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"Eguraldia"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Zuri iradokiak"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"<xliff:g id="SELECTED_HEADER">%1$s</xliff:g> zerbitzuaren widgetak eskuinean, bilaketa eta aukerak ezkerrean"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}other{# widget}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"Pribatua, blokeatuta."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"Blokeatu"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"Eremu pribaturako trantsizioa"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"Instalatu aplikazioak"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"Instalatu aplikazioak eremu pribatuan"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Luzapena"</string>
</resources>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index 2ef33d8..ac3d27b 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"پیشنهادها"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"بایدها"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"اخبار و مجله"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"منطقه آرامش شما"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"سرگرمی"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"اجتماعی"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"سلامتی و تناسب اندام"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"آبوهوا"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"پیشنهاداتی برای شما"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"ابزارکهای <xliff:g id="SELECTED_HEADER">%1$s</xliff:g> در سمت چپ، جستجو و گزینهها در سمت راست"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# ابزارک}one{# ابزارک}other{# ابزارک}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"خصوصی، قفل."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"قفل کردن"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"انتقال «فضای خصوصی»"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"نصب برنامهها"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"نصب برنامهها در «فضای خصوصی»"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"سرریز"</string>
</resources>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index f6d6ab8..9b432de 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Ehdotukset"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Kaikki tarvittava"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Uutiset ja aikakauslehdet"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Ota rennosti"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Viihde"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Sosiaalinen"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Terveys ja kuntoilu"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"Sää"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Sinulle ehdotetut"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"<xliff:g id="SELECTED_HEADER">%1$s</xliff:g> widgetit oikealla, haku ja vaihtoehdot vasemmalla"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}other{# widgetiä}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"Yksityinen, lukittu."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"Lukko"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"Yksityisen tilan siirtäminen"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"Asenna sovelluksia"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"Asenna sovelluksia yksityiseen tilaan"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Ylivuoto"</string>
</resources>
diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml
index c83f57e..e650524 100644
--- a/res/values-fr-rCA/strings.xml
+++ b/res/values-fr-rCA/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Suggestions"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Essentiels"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Actualités et magazines"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Zone de divertissement"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Divertissement"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Médias sociaux"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Santé et mise en forme"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"Météo"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Suggestions personnalisées"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"Widgets <xliff:g id="SELECTED_HEADER">%1$s</xliff:g> à droite, recherche et options à gauche"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}one{# widget}other{# widgets}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"Privé, verrouillé."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"Verrouiller"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"Transition vers l\'Espace privé"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"Installer des applications"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"Installer des applications dans l\'Espace privé"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Menu à développer"</string>
</resources>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index 4c72f00..93d94fb 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Suggestions"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Indispensables"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Actualités et magazines"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Votre espace détente"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Divertissement"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Réseaux sociaux"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Santé et bien-être"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"Météo"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Recommandations"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"Widgets <xliff:g id="SELECTED_HEADER">%1$s</xliff:g> à droite, recherche et options à gauche"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}one{# widget}other{# widgets}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"Privé, verrouillé"</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"Verrouiller"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"Transition vers Espace privé"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"Installer applis"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"Installer des applis dans l\'espace privé"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Dépassement"</string>
</resources>
diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml
index 3137d94..fa01b31 100644
--- a/res/values-gl/strings.xml
+++ b/res/values-gl/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Suxestións"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Esenciais"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Noticias e revistas"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Reláxate"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Entretemento"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Redes sociais"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Saúde e forma física"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"O tempo"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Suxestións personalizadas"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"Widgets de <xliff:g id="SELECTED_HEADER">%1$s</xliff:g> á dereita, busca e opcións á esquerda"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}other{# widgets}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"Privado, bloqueado."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"Bloquear"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"Transición ao espazo privado"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"Instalar apps"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"Instalar as aplicacións no espazo privado"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Menú adicional"</string>
</resources>
diff --git a/res/values-gu/strings.xml b/res/values-gu/strings.xml
index 8ef75fe..794d2fc 100644
--- a/res/values-gu/strings.xml
+++ b/res/values-gu/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"સૂચનો"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"આવશ્યક"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"ન્યૂઝ અને સામાયિકો"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"તમારો આરામદાયક ઝોન"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"મનોરંજન"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"સામાજિક"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"આરોગ્ય અને ફિટનેસ"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"હવામાન"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"તમારા માટે સૂચવેલી સેવાઓ"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"<xliff:g id="SELECTED_HEADER">%1$s</xliff:g>ની વિજેટ જમણે, શોધ અને વિકલ્પો ડાબે"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# વિજેટ}one{# વિજેટ}other{# વિજેટ}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"ખાનગી સ્પેસ, લૉક કરેલી છે."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"લૉક"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"ખાનગી સ્પેસ પર સ્થાનાંતરણ"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"ઍપ ઇન્સ્ટૉલ કરો"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"ખાનગી સ્પેસમાં ઍપ ઇન્સ્ટૉલ કરો"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"ઓવરફ્લો"</string>
</resources>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index 5f489ae..0b505a3 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"सुझाव"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"ज़रूरी ऐप्लिकेशन"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"खबरों और पत्रिकाओं वाले ऐप्लिकेशन"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"आपके मनोरंजन के लिए"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"मनोरंजन से जुड़े ऐप्लिकेशन"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"सोशल मीडिया ऐप्लिकेशन"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"हेल्थ और फ़िटनेस वाले ऐप्लिकेशन"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"मौसम"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"आपके लिए सुझाए गए ऐप्लिकेशन"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"<xliff:g id="SELECTED_HEADER">%1$s</xliff:g> के विजेट दाईं ओर, खोज का विजेट और अन्य विकल्प बाईं ओर"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# विजेट}one{# विजेट}other{# विजेट}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"प्राइवेट स्पेस को लॉक किया गया."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"लॉक"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"प्राइवेट स्पेस की सेटिंग में बदलाव किया जा रहा है"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"ऐप्लिकेशन इंस्टॉल करें"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"प्राइवेट स्पेस में ऐप्लिकेशन इंस्टॉल करें"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"ओवरफ़्लो"</string>
</resources>
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index db947fe..64d5d10 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Prijedlozi"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Osnovno"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Vijesti i časopisi"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Vaša zona za opuštanje"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Zabava"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Društvene mreže"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Zdravlje i fitness"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"Vrijeme"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Prijedlozi za vas"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"<xliff:g id="SELECTED_HEADER">%1$s</xliff:g> –widgeti zdesna, pretraživanje i opcije slijeva"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}one{# widget}few{# widgeta}other{# widgeta}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"Privatno, zaključano."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"Zaključavanje"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"Prelazak na privatni prostor"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"Instalirajte aplikacije"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"Instaliranje aplikacija u privatni prostor"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Dodatni izbornik"</string>
</resources>
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index bdf5aa6..40b1072 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Javaslatok"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Legfontosabbak"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Újságok és magazinok"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Az Ön relaxáló zónája"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Szórakozás"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Közösségi"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Egészség és fitnesz"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"Időjárás"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Neked javasolt"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"A <xliff:g id="SELECTED_HEADER">%1$s</xliff:g>-modulok a jobb, a kereső és a beállítások pedig a bal oldalon találhatók"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# modul}other{# modul}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"Privát, zárolt."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"Zárolás"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"Átállás privát területre…"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"App telepítése"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"Alkalmazások telepítése magánterületre"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Túlcsordulás"</string>
</resources>
diff --git a/res/values-hy/strings.xml b/res/values-hy/strings.xml
index 4a427f4..afd0a99 100644
--- a/res/values-hy/strings.xml
+++ b/res/values-hy/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Առաջարկներ"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Հիմնական"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Նորություններ և ամսագրեր"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Ձեր հանգստի գոտին"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Զվարճանք"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Սոցցանցեր"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Առողջություն և ֆիթնես"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"Եղանակ"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Առաջարկում ենք"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"«<xliff:g id="SELECTED_HEADER">%1$s</xliff:g>» հավելվածի վիջեթներն աջ կողմում են, իսկ որոնման դաշտը և կարգավորումները՝ ձախ կողմում"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# վիջեթ}one{# վիջեթ}other{# վիջեթ}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"Անձնական, կողպված է։"</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"Կողպում"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"Անցում մասնավոր տարածք"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"Հավելվածների տեղադրում"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"Հավելվածների տեղադրում անձնական տարածքում"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Լրացուցիչ ընտրացանկ"</string>
</resources>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index 141a4d2..e9f3f73 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Saran"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Penting"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Berita & majalah"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Zona Nyaman Anda"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Hiburan"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Sosial"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Kesehatan & kebugaran"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"Cuaca"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Disarankan untuk Anda"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"Widget <xliff:g id="SELECTED_HEADER">%1$s</xliff:g> di bagian kanan, penelusuran dan opsi di bagian kiri"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}other{# widget}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"Pribadi, dikunci."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"Kunci"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"Ruang Pribadi Bertransisi"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"Instal aplikasi"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"Instal aplikasi ke Ruang Pribadi"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Menu tambahan"</string>
</resources>
diff --git a/res/values-is/strings.xml b/res/values-is/strings.xml
index 5c4b3e9..93b8fe0 100644
--- a/res/values-is/strings.xml
+++ b/res/values-is/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Tillögur"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Það nauðsynlegasta"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Fréttir og tímarit"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Slakaðu á"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Afþreying"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Samfélag"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Heilsa og líkamsrækt"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"Veður"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Tillögur fyrir þig"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"<xliff:g id="SELECTED_HEADER">%1$s</xliff:g>-græjur til hægri, leit og valkostir til vinstri"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# græja}one{# græja}other{# græjur}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"Lokað, læst."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"Læsa"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"Einkarými að breytast"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"Setja upp forrit"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"Setja upp forrit í leynirými"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Yfirflæði"</string>
</resources>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index bb178f5..4257b5f 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Suggerimenti"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Essenziali"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Notizie e riviste"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Il tuo angolo di tranquillità"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Intrattenimento"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Social"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Salute e fitness"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"Meteo"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Consigliati per te"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"Widget di <xliff:g id="SELECTED_HEADER">%1$s</xliff:g> a destra, ricerca e opzioni a sinistra"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}other{# widget}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"Privato, bloccato."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"Blocca"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"Transizione dello Spazio privato in corso…"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"Installa app"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"Installa le app su spazi privati"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Extra"</string>
</resources>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index 4140088..2ecb026 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -44,13 +44,10 @@
<string name="add_to_home_screen" msgid="9168649446635919791">"הוספה למסך הבית"</string>
<string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"הווידג\'ט <xliff:g id="WIDGET_NAME">%1$s</xliff:g> נוסף למסך הבית"</string>
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"הצעות"</string>
- <string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"האפליקציות שחייבים להכיר"</string>
+ <string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"הכי חשוב"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"חדשות וכתבי עת"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"המקום שלך לרגיעה"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"בידור"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"רשתות חברתיות"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"בריאות וכושר"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"מזג אוויר"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"הצעות בשבילך"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"<xliff:g id="SELECTED_HEADER">%1$s</xliff:g> ווידג\'טים מימין, חיפוש ואפשרויות משמאל"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{ווידג\'ט אחד}one{# ווידג\'טים}two{# ווידג\'טים}other{# ווידג\'טים}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"פרטי, נעול."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"נעילה"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"מעבר למרחב הפרטי"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"התקנת אפליקציות"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"התקנת אפליקציות במרחב הפרטי"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"אפשרויות נוספות"</string>
</resources>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index 6276a20..f4f3852 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"候補"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"基本"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"ニュース&雑誌"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"休憩エリア"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"エンタメ"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"ソーシャル"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"健康&フィットネス"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"天気"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"おすすめ"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"<xliff:g id="SELECTED_HEADER">%1$s</xliff:g> のウィジェットは右側に、検索とオプションは左側にあります"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# 件のウィジェット}other{# 件のウィジェット}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"非公開で、ロックされています。"</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"ロック"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"プライベート スペース移行中"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"アプリをインストールする"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"プライベート スペースにアプリをインストールします"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"オーバーフロー"</string>
</resources>
diff --git a/res/values-ka/strings.xml b/res/values-ka/strings.xml
index d6c44ea..cd5598b 100644
--- a/res/values-ka/strings.xml
+++ b/res/values-ka/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"შეთავაზებები"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"უმნიშვნელოვანესები"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"ახალი ამბები და ჟურნალები"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"განტვირთვის ადგილი"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"გართობა"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"სოციალური"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"ჯანმრთელობა და ფიტნესი"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"ამინდი"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"თქვენთვის შემოთავაზებული"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"<xliff:g id="SELECTED_HEADER">%1$s</xliff:g> ვიჯეტები მდებარეობს მარჯვნივ, ძებნა და პარამეტრები — მარცხნივ"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# ვიჯეტი}other{# ვიჯეტი}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"პირადი (ჩაკეტილი)."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"ჩაკეტვა"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"პირად სივრცეზე გადასვლა"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"აპების ინსტალაცია"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"კერძო სივრცეში აპების ინსტალაცია"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"გადავსება"</string>
</resources>
diff --git a/res/values-kk/strings.xml b/res/values-kk/strings.xml
index 6fd40e5..f364ed5 100644
--- a/res/values-kk/strings.xml
+++ b/res/values-kk/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Ұсыныстар"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Ең қажетті"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Жаңалықтар мен журналдар"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Жанға жайлы жер"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Ойын-сауық"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Қоғам"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Денсаулық және фитнес"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"Ауа райы"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Сізге ұсынылғандар"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"<xliff:g id="SELECTED_HEADER">%1$s</xliff:g> виджеттері оң жақта, іздеу мен опциялар сол жақта"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# виджет}other{# виджет}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"Құпия (құлыптаулы)."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"Құлыптау"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"Жеке бөлмеге өту"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"Қолданбалар орнату"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"Қолданбаларды \"Құпия кеңістікке\" орнатыңыз."</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Қосымша мәзір"</string>
</resources>
diff --git a/res/values-km/strings.xml b/res/values-km/strings.xml
index 7abe7fd..8f24162 100644
--- a/res/values-km/strings.xml
+++ b/res/values-km/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"ការណែនាំ"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"សំខាន់"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"ព័ត៌មាន និងទស្សនាវដ្ដី"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"តំបន់បន្ធូរអារម្មណ៍របស់អ្នក"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"កម្សាន្ត"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"សង្គម"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"សុខភាព និងសម្បទា"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"អាកាសធាតុ"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"ណែនាំជូនអ្នក"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"ធាតុក្រាហ្វិក <xliff:g id="SELECTED_HEADER">%1$s</xliff:g> នៅខាងស្ដាំ ការស្វែងរក និងជម្រើសនៅខាងឆ្វេង"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{ធាតុក្រាហ្វិក #}other{ធាតុក្រាហ្វិក #}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"ឯកជន ជាប់សោ។"</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"ចាក់សោ"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"ការផ្លាស់ប្ដូរ Private Space"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"ដំឡើងកម្មវិធី"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"ដំឡើងកម្មវិធីទៅលំហឯកជន"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"ម៉ឺនុយបន្ថែម"</string>
</resources>
diff --git a/res/values-kn/strings.xml b/res/values-kn/strings.xml
index 01800a8..aa50b3b 100644
--- a/res/values-kn/strings.xml
+++ b/res/values-kn/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"ಸಲಹೆಗಳು"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"ಅಗತ್ಯತೆಗಳು"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"ಸುದ್ದಿ ಮತ್ತು ನಿಯತಕಾಲಿಕೆಗಳು"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"ನೀವು ವಿಶ್ರಾಂತಿ ಪಡೆಯುವ ಸ್ಥಳ"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"ಮನರಂಜನೆ"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"ಸಾಮಾಜಿಕ"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"ಆರೋಗ್ಯ ಮತ್ತು ಫಿಟ್ನೆಸ್"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"ಹವಾಮಾನ"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"ನಿಮಗಾಗಿ ಸೂಚಿಸಲಾಗಿರುವುದು"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"ಬಲಭಾಗದಲ್ಲಿ <xliff:g id="SELECTED_HEADER">%1$s</xliff:g> ವಿಜೆಟ್ಗಳು, ಎಡಭಾಗದಲ್ಲಿ ಹುಡುಕಾಟ ಮತ್ತು ಆಯ್ಕೆಗಳು"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# ವಿಜೆಟ್}one{# ವಿಜೆಟ್ಗಳು}other{# ವಿಜೆಟ್ಗಳು}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"ಖಾಸಗಿ, ಲಾಕ್ ಮಾಡಲಾಗಿದೆ."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"ಲಾಕ್ ಮಾಡಿ"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"ಖಾಸಗಿ ಸ್ಪೇಸ್ ಪರಿವರ್ತನೆಯಾಗುತ್ತಿದೆ"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"ಆ್ಯಪ್ಗಳನ್ನು ಇನ್ಸ್ಟಾಲ್ ಮಾಡಿ"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"ಆ್ಯಪ್ಗಳನ್ನು ಪ್ರೈವೇಟ್ ಸ್ಪೇಸ್ನಲ್ಲಿ ಇನ್ಸ್ಟಾಲ್ ಮಾಡಿ"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"ಓವರ್ಫ್ಲೋ"</string>
</resources>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index 0b11f1a..5514416 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"추천"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"필수"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"뉴스 및 잡지"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"휴식 공간"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"엔터테인먼트"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"소셜"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"건강 및 피트니스"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"날씨"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"추천"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"오른쪽에 <xliff:g id="SELECTED_HEADER">%1$s</xliff:g> 위젯, 왼쪽에 검색 및 옵션"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{위젯 #개}other{위젯 #개}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"비공개, 잠김."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"잠금"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"비공개 스페이스 전환"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"앱 설치"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"비공개 스페이스에 앱 설치"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"오버플로"</string>
</resources>
diff --git a/res/values-ky/strings.xml b/res/values-ky/strings.xml
index 6561559..cd73445 100644
--- a/res/values-ky/strings.xml
+++ b/res/values-ky/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Сунуштар"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Эң зарыл параметрлер"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Жаңылыктар жана журналдар"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Чер жазуу"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Көңүл ачуу"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Коомдук тармактар"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Ден соолук жана дене-бойду чыңдоо"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"Аба ырайы"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Сизге сунушталат"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"<xliff:g id="SELECTED_HEADER">%1$s</xliff:g> виджеттери оң, ал эми издөө жана параметрлер сол жакта"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# виджет}other{# виджет}}"</string>
@@ -186,14 +183,15 @@
<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>
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"Купуя, кулпуланган."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"Кулпулоо"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"Жеке чөйрөгө өтүү"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"Колдонмолорду орнотуу"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"Колдонмолорду Жеке мейкиндикке орнотуe"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Кошумча меню"</string>
</resources>
diff --git a/res/values-lo/strings.xml b/res/values-lo/strings.xml
index 89be107..7f5cd65 100644
--- a/res/values-lo/strings.xml
+++ b/res/values-lo/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"ການແນະນຳ"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"ສິ່ງຈຳເປັນ"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"ຂ່າວ ແລະ ວາລະສານ"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"ພື້ນທີ່ພັກຜ່ອນຂອງທ່ານ"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"ຄວາມບັນເທີງ"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"ສັງຄົມ"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"ສຸຂະພາບ ແລະ ການອອກກຳລັງກາຍ"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"ສະພາບອາກາດ"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"ແນະນຳສຳລັບທ່ານ"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"ວິດເຈັດ <xliff:g id="SELECTED_HEADER">%1$s</xliff:g> ຢູ່ທາງຂວາ, ການຊອກຫາ ແລະ ຕົວເລືອກຢູ່ທາງຊ້າຍ"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# ວິດເຈັດ}other{# ວິດເຈັດ}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"ສ່ວນຕົວ, ລັອກແລ້ວ."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"ລັອກ"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"ການປ່ຽນແປງພື້ນທີ່ສ່ວນຕົວ"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"ຕິດຕັ້ງແອັບ"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"ຕິດຕັ້ງແອັບໄປໃສ່ພື້ນທີ່ສ່ວນບຸກຄົນ"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"ການດຳເນີນການເພີ່ມເຕີມ"</string>
</resources>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index 9a19094..38d4597 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Pasiūlymai"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Būtiniausi"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Naujienos ir žurnalai"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Jūsų atsipalaidavimo zona"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Pramogos"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Socialiniai tinklai"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Sveikata ir kūno rengyba"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"Orai"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Siūloma jums"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"<xliff:g id="SELECTED_HEADER">%1$s</xliff:g> valdikliai dešinėje, paieška ir parinktys kairėje"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# valdiklis}one{# valdiklis}few{# valdikliai}many{# valdiklio}other{# valdiklių}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"Privatus, užrakintas."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"Užrakinti"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"Privačios erdvės perkėlimas"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"Programų diegimas"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"Įdiegti programas privačioje erdvėje"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Perpildymas"</string>
</resources>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index 2c77a54..417464c 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Ieteikumi"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Produktivitātei"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Ziņas un žurnāli"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Jūsu atpūtas stūrītis"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Izklaide"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Sociālie tīkli"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Veselība un fitness"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"Laikapstākļi"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Ieteikumi jums"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"Pa labi logrīki <xliff:g id="SELECTED_HEADER">%1$s</xliff:g>, pa kreisi meklēšana un iespējas"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# logrīks}zero{# logrīku}one{# logrīks}other{# logrīki}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"Privāta un bloķēta."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"Bloķēšana"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"Pāriet uz privāto mapi"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"Lietotņu instalēšana"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"Instalējiet lietotnes privātajā telpā."</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Pārpilde"</string>
</resources>
diff --git a/res/values-mk/strings.xml b/res/values-mk/strings.xml
index 3618e22..828a65e 100644
--- a/res/values-mk/strings.xml
+++ b/res/values-mk/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Предлози"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Неопходни"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Вести и списанија"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Вашата зона за релаксација"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Забава"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Друштвени"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Здравје и фитнес"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"Време"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Препорачано за вас"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"<xliff:g id="SELECTED_HEADER">%1$s</xliff:g> виџети оддесно, „Пребарување“ и „Опции“ одлево"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# виџет}one{# виџет}other{# виџети}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"Приватно, заклучено."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"Заклучи"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"Префрлање на „Приватен простор“"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"Инсталирајте апликации"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"Инсталирање апликации во „Приватен простор“"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Проширено балонче"</string>
</resources>
diff --git a/res/values-ml/strings.xml b/res/values-ml/strings.xml
index dde91aa..290c7fe 100644
--- a/res/values-ml/strings.xml
+++ b/res/values-ml/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"നിർദ്ദേശങ്ങൾ"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"ആവശ്യമായവ"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"വാർത്തകളും മാസികകളും"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"നിങ്ങൾക്ക് സുഖപ്രദമായ സ്ഥലം"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"വിനോദം"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"സാമൂഹികം"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"ആരോഗ്യവും ശാരീരികക്ഷമതയും"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"കാലാവസ്ഥ"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"നിങ്ങൾക്കായി നിർദ്ദേശിച്ചവ"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"വലതുവശത്ത് <xliff:g id="SELECTED_HEADER">%1$s</xliff:g> വിജറ്റുകളും ഇടതുവശത്ത് തിരയൽ, ഓപ്ഷനുകൾ എന്നിവയും"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# വിജറ്റ്}other{# വിജറ്റുകൾ}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"സ്വകാര്യം, ലോക്ക് ചെയ്തു."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"ലോക്ക് ചെയ്യുക"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"പ്രൈവറ്റ് സ്പേസ് ട്രാൻസിഷനിംഗ്"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"ആപ്പുകൾ ഇൻസ്റ്റാൾ ചെയ്യുക"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"സ്വകാര്യ സ്പേസിലേക്ക് ആപ്പുകൾ ഇൻസ്റ്റാൾ ചെയ്യുക"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"ഓവർഫ്ലോ"</string>
</resources>
diff --git a/res/values-mn/strings.xml b/res/values-mn/strings.xml
index ed17387..71f5b77 100644
--- a/res/values-mn/strings.xml
+++ b/res/values-mn/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Зөвлөмжүүд"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Зайлшгүй хэрэгтэй"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Мэдээ, сэтгүүлүүд"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Таны амралтын бүс"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Энтертэйнмент"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Сошиал"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Эрүүл мэнд, фитнес"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"Цаг агаар"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Танд санал болгосон"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"Баруун талд <xliff:g id="SELECTED_HEADER">%1$s</xliff:g>-н виджет, зүүн талд хайлт болон сонгуултууд байна"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# виджет}other{# виджет}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"Хувийн, түгжээтэй."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"Түгжээ"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"Private Space-н шилжилт"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"Аппуудыг суулгах"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"Хувийн орон зайд аппууд суулгана уу"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Урт цэс"</string>
</resources>
diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml
index e7287d8..a95eb6c 100644
--- a/res/values-mr/strings.xml
+++ b/res/values-mr/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"सूचना"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"आवश्यक गोष्टी"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"बातम्या आणि मासिके"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"तुमचा आरामदायक झोन"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"मनोरंजन"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"सोशल"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"आरोग्य आणि फिटनेस"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"हवामान"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"तुमच्यासाठी सुचवलेले"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"उजवीकडे <xliff:g id="SELECTED_HEADER">%1$s</xliff:g> विजेट, डावीकडे शोध आणि पर्याय"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# विजेट}other{# विजेट}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"खाजगी, लॉक केलेली."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"लॉक"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"खाजगी स्पेस वर स्विच करणे"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"अॅप्स इंस्टॉल करा"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"अॅप्स खाजगी स्पेस मध्ये इंस्टॉल करा"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"ओव्हरफ्लो"</string>
</resources>
diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml
index 099400f..3704ec9 100644
--- a/res/values-ms/strings.xml
+++ b/res/values-ms/strings.xml
@@ -44,13 +44,10 @@
<string name="add_to_home_screen" msgid="9168649446635919791">"Tambahkan pada skrin utama"</string>
<string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"Widget <xliff:g id="WIDGET_NAME">%1$s</xliff:g> ditambahkan pada skrin utama"</string>
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Cadangan"</string>
- <string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Apl Asas"</string>
+ <string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Penting"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Berita & majalah"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Zon Santai Anda"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Hiburan"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Sosial"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Kesihatan & kecergasan"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"Cuaca"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Dicadangkan untuk anda"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"Widget <xliff:g id="SELECTED_HEADER">%1$s</xliff:g> pada sebelah kanan, carian dan pilihan pada sebelah kiri"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}other{# widget}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"Peribadi, dikunci."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"Kunci"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"Peralihan Ruang Peribadi"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"Pasang apl"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"Pasang apl pada Ruang Peribadi"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Limpahan"</string>
</resources>
diff --git a/res/values-my/strings.xml b/res/values-my/strings.xml
index 01d1a8f..a4ec89a 100644
--- a/res/values-my/strings.xml
+++ b/res/values-my/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"အကြံပြုချက်"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"မရှိမဖြစ်များ"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"သတင်းနှင့် မဂ္ဂဇင်း"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"သင်အနားယူသောနေရာ"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"ဖျော်ဖြေရေး"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"လူမှုရေး"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"ကျန်းမာကြံ့ခိုင်ရေး"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"မိုးလေဝသ"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"သင့်အတွက် အကြံပြုထားသည်များ"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"<xliff:g id="SELECTED_HEADER">%1$s</xliff:g> ဝိဂျက်များသည် ညာဘက်တွင်ရှိပြီး ရှာဖွေမှုနှင့် ရွေးစရာများသည် ဘယ်ဘက်တွင်ရှိသည်"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{ဝိဂျက် # ခု}other{ဝိဂျက် # ခု}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"သီးသန့် လော့ခ်ချထားသည်။"</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"လော့ခ်ချခြင်း"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"သီးသန့်ချတ်ခန်း အပြောင်းအလဲ"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"အက်ပ်ထည့်ခြင်း"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"‘သီးသန့်နေရာ’ တွင် အက်ပ်များ ထည့်သွင်းနိုင်သည်"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"မီနူးအပို"</string>
</resources>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index 56ef9e7..c2fdeaa 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Forslag"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Anbefalt"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Nyheter og tidsskrifter"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Avslappingssonen din"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Underholdning"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Sosialt"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Kropp og helse"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"Været"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Foreslått for deg"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"<xliff:g id="SELECTED_HEADER">%1$s</xliff:g> moduler til høyre, søk og alternativer til venstre"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# modul}other{# moduler}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"Privat (låst)."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"Lås"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"Private Space-overgang"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"Installer apper"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"Installer apper i privat område"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Overflyt"</string>
</resources>
diff --git a/res/values-ne/strings.xml b/res/values-ne/strings.xml
index 4686ba0..2d407b2 100644
--- a/res/values-ne/strings.xml
+++ b/res/values-ne/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"सुझावहरू"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"अत्यावश्यक कुराहरू"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"समाचार तथा पत्रपत्रिकाहरू"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"तपाईंको Chill Zone"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"मनोरञ्जन"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"सोसल मिडिया"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"स्वास्थ्य तथा तन्दुरुस्ती"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"मौसम"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"तपाईंका लागि सिफारिस गरिएका"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"दायाँ भागमा <xliff:g id="SELECTED_HEADER">%1$s</xliff:g> विजेटहरू, बायाँ भागमा खोज र विकल्पहरू"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# विजेट}other{# वटा विजेट}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"निजी, लक गरिएको।"</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"लक गर्नुहोस्"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"निजी स्पेस ट्रान्जिसन गरिँदै छ"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"एपहरू इन्स्टल गर्नुहोस्"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"निजी स्पेसमा एपहरू इन्स्टल गर्नुहोस्"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"ओभरफ्लो"</string>
</resources>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index a61416e..a9e5359 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Suggesties"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Essentials"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Nieuws en tijdschriften"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Je chillzone"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Entertainment"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Sociaal"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Gezondheid en fitness"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"Weer"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Voorgesteld voor jou"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"<xliff:g id="SELECTED_HEADER">%1$s</xliff:g>-widgets aan de rechterkant, zoeken en opties aan de linkerkant"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}other{# widgets}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"Privé, vergrendeld."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"Vergrendelen"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"Overschakelen naar privéruimte"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"Apps installeren"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"Apps installeren in privégedeelte"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Overloop"</string>
</resources>
diff --git a/res/values-or/strings.xml b/res/values-or/strings.xml
index da70678..291fd9b 100644
--- a/res/values-or/strings.xml
+++ b/res/values-or/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"ପରାମର୍ଶଗୁଡ଼ିକ"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"ଅତ୍ୟାବଶ୍ୟକୀୟ"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"ନ୍ୟୁଜ ଓ ମାଗାଜିନ"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"ଆପଣଙ୍କ ଚିଲ ଜୋନ"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"ମନୋରଞ୍ଜନ"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"ସୋସିଆଲ"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"ସ୍ୱାସ୍ଥ୍ୟ ଓ ଫିଟନେସ"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"ପାଣିପାଗ"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"ଆପଣଙ୍କ ପାଇଁ ପ୍ରସ୍ତାବିତ"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"ଡାହାଣରେ <xliff:g id="SELECTED_HEADER">%1$s</xliff:g> ୱିଜେଟଗୁଡ଼ିକ ଅଛି, ବାମରେ ସର୍ଚ୍ଚ ଓ ବିକଳ୍ପଗୁଡ଼ିକ ଅଛି"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# ୱିଜେଟ}other{# ୱିଜେଟ}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"ପ୍ରାଇଭେଟ, ଲକ କରାଯାଇଛି।"</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"ଲକ କରନ୍ତୁ"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"ପ୍ରାଇଭେଟ ସ୍ପେସ ଟ୍ରାଞ୍ଜିସନିଂ"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"ଆପ୍ ଇନଷ୍ଟଲ୍ କରନ୍ତୁ"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"ଆପ୍ସକୁ ପ୍ରାଇଭେଟ ସ୍ପେସରେ ଇନଷ୍ଟଲ କରନ୍ତୁ"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"ଓଭରଫ୍ଲୋ"</string>
</resources>
diff --git a/res/values-pa/strings.xml b/res/values-pa/strings.xml
index 3c1a37e..097d466 100644
--- a/res/values-pa/strings.xml
+++ b/res/values-pa/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"ਸੁਝਾਅ"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"ਲੋੜੀਂਦੀਆਂ"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"ਖਬਰਾਂ ਅਤੇ ਰਸਾਲੇ"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"ਤੁਹਾਡੇ ਲਈ ਸਕੂਨਮਈ ਖੇਤਰ"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"ਮਨੋਰੰਜਨ"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"ਸੋਸ਼ਲ"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"ਸਿਹਤ ਅਤੇ ਫਿੱਟਨੈੱਸ"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"ਮੌਸਮ"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"ਤੁਹਾਡੇ ਲਈ ਸੁਝਾਅ"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"<xliff:g id="SELECTED_HEADER">%1$s</xliff:g> ਵਿਜੇਟ ਸੱਜੇ ਪਾਸੇ ਹਨ, ਖੋਜ ਵਿਜੇਟ ਅਤੇ ਹੋਰ ਵਿਕਲਪ ਖੱਬੇ ਪਾਸੇ ਹਨ"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# ਵਿਜੇਟ}one{# ਵਿਜੇਟ}other{# ਵਿਜੇਟ}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"ਨਿੱਜੀ, ਲਾਕ ਕੀਤਾ ਗਿਆ।"</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"ਲਾਕ ਕਰੋ"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"ਨਿੱਜੀ ਸਪੇਸ ਨੂੰ ਤਬਦੀਲ ਕਰਨਾ"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"ਐਪਾਂ ਸਥਾਪਤ ਕਰੋ"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"ਪ੍ਰਾਈਵੇਟ ਸਪੇਸ ਵਿੱਚ ਐਪਾਂ ਸਥਾਪਤ ਕਰੋ"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"ਓਵਰਫ਼ਲੋ"</string>
</resources>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index da6a711..1d51c8e 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Sugestie"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Najbardziej przydatne"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Wiadomości i czasopisma"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Strefa relaksu"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Rozrywka"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Społecznościowe"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Zdrowie i fitness"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"Pogoda"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Proponowane dla Ciebie"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"Widżety (<xliff:g id="SELECTED_HEADER">%1$s</xliff:g>) po prawej, wyszukiwanie i opcje po lewej"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widżet}few{# widżety}many{# widżetów}other{# widżetu}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"Prywatna, zablokowana."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"Zablokuj"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"Przenoszenie obszaru prywatnego"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"Instaluj aplikacje"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"Zainstaluj aplikacje w przestrzeni prywatnej"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Rozwiń menu"</string>
</resources>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index e07d8cc..4ec41d9 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Sugestões"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Essenciais"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Notícias e revistas"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"A sua zona de relaxamento"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Entretenimento"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Redes sociais"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Saúde e fitness"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"Meteorologia"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Sugestões para si"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"Widgets de <xliff:g id="SELECTED_HEADER">%1$s</xliff:g> à direita, pesquisa e opções à esquerda"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}other{# widgets}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"Privado, bloqueado."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"Bloquear"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"Transição do espaço privado"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"Instalar apps"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"Instale apps no espaço privado"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Menu adicional"</string>
</resources>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index 3b2aeec..386bcd0 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Sugestões"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Essenciais"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Notícias e revistas"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Sua zona de relaxamento"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Entretenimento"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Social"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Saúde e bem-estar"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"Clima"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Sugestões para você"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"Widgets da <xliff:g id="SELECTED_HEADER">%1$s</xliff:g> à direita, pesquisa e opções à esquerda"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}one{# widget}other{# widgets}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"Privada, bloqueado."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"Bloquear"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"Espaço particular em transição"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"Instalar apps"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"Instalar apps no espaço privado"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Balão flutuante"</string>
</resources>
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index d4c303e..86497ed 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Sugestii"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Esențiale"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Știri și reviste"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Zona de relaxare"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Divertisment"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Rețele sociale"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Sănătate și fitness"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"Meteo"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Sugerate pentru tine"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"Widgeturi pentru <xliff:g id="SELECTED_HEADER">%1$s</xliff:g> în dreapta, căutare și opțiuni în stânga"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}few{# widgeturi}other{# de widgeturi}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"Privat, blocat."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"Blochează"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"Tranziție pentru spațiul privat"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"Instalează aplicații"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"Instalează aplicații în Spațiul privat"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Suplimentar"</string>
</resources>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index a7e2666..48bdf7b 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Подсказки"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Основное"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Новости и журналы"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Развлечение и общение"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Развлечения"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Общение"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Здоровье и спорт"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"Погода"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Рекомендации"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"Виджеты приложения \"<xliff:g id="SELECTED_HEADER">%1$s</xliff:g>\" находятся справа, а панель поиска и настройки – слева"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# виджет}one{# виджет}few{# виджета}many{# виджетов}other{# виджета}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"Личное, заблокировано."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"Блокировка"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"Переход к личному пространству"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"Установить приложения"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"Установить приложения в личном пространстве"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Дополнительное меню"</string>
</resources>
diff --git a/res/values-si/strings.xml b/res/values-si/strings.xml
index fce3499..6ae5a84 100644
--- a/res/values-si/strings.xml
+++ b/res/values-si/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"යෝජනා"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"අත්යවශ්යාංග"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"පුවත් සහ සඟරා"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"ඔබේ නිවුණු කලාපය"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"විනෝදාස්වාදය"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"සමාජයීය"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"සෞඛ්යය සහ යෝග්යතාව"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"කාලගුණ"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"ඔබ සඳහා යෝජිත"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"දකුණේ <xliff:g id="SELECTED_HEADER">%1$s</xliff:g> විජට්, වමේ සෙවීම සහ විකල්ප"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{විජට් #}one{විජට් #}other{විජට් #}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"පුද්ගලික, අගුලු දමන ලදි."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"අගුළු දමන්න"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"පෞද්ගලික අවකාශ සංක්රමණය"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"යෙදුම් ස්ථාපනය කරන්න"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"පෞද්ගලික අවකාශයට යෙදුම් ස්ථාපනය කරන්න"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"පිටාර යාම"</string>
</resources>
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index a93c332..604b6a5 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Návrhy"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Všetko dôležité"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Noviny a časopisy"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Vaša komfortná zóna"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Zábava"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Sociálne siete"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Zdravie a kondícia"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"Počasie"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Navrhnuté pre vás"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"Miniaplikácie <xliff:g id="SELECTED_HEADER">%1$s</xliff:g> vpravo, vyhľadávanie a možnosti vľavo"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# miniaplikácia}few{# miniaplikácie}many{# widgets}other{# miniaplikácií}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"Súkromné, uzamknuté."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"Uzamknúť"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"Prechod súkromného priestoru"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"Inštalovať aplikácie"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"Inštalácia aplikácií v súkromnom priestore"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Rozšírená ponuka"</string>
</resources>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index 26fed22..1f5a83f 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Predlogi"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Osnove"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Novice in revije"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Vaš kotiček za sprostitev"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Razvedrilo"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Družbeno"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Zdravje in fitnes"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"Vreme"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Predlagano za vas"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"Pripomočki <xliff:g id="SELECTED_HEADER">%1$s</xliff:g> na desni, iskanje in možnosti na levi"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# pripomoček}one{# pripomoček}two{# pripomočka}few{# pripomočki}other{# pripomočkov}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"Zasebno, zaklenjeno."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"Zaklepanje"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"Preklapljanje zasebnega prostora"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"Nameščanje aplikacij"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"Nameščanje aplikacij v zasebni prostor"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Oblaček z dodatnimi elementi"</string>
</resources>
diff --git a/res/values-sq/strings.xml b/res/values-sq/strings.xml
index 95c0782..57c4b69 100644
--- a/res/values-sq/strings.xml
+++ b/res/values-sq/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Sugjerime"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Thelbësoret"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Lajme dhe revista"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Zona jote e qetësisë"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Argëtim"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Rrjetet sociale"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Shëndet dhe fitnes"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"Moti"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Sugjeruar për ty"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"Miniaplikacionet e <xliff:g id="SELECTED_HEADER">%1$s</xliff:g> në të djathtë, kërkimi dhe opsionet në të majtë"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# miniaplikacion}other{# miniaplikacione}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"Private, e kyçur."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"Kyç"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"Kalimi te \"Hapësira private\""</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"Instalo aplikacionet"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"Instalo aplikacionet në hapësirën private"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Tejkalimi"</string>
</resources>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index 9eaae37..10ea212 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Предлози"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Основно"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Новости и часописи"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Зона за опуштање"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Забава"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Друштвене мреже"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Здравље и фитнес"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"Време"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Предложено за вас"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"Виџети <xliff:g id="SELECTED_HEADER">%1$s</xliff:g> са десне стране, претрага и опције са леве стране"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# виџет}one{# виџет}few{# виџета}other{# виџета}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"Приватно, закључано."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"Закључавање"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"Пренос приватног простора"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"Инсталирајте апликације"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"Инсталирај апликације у приватан простор"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Преклопно"</string>
</resources>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index 5d13f13..555600d 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Förslag"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Viktigt"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Nyheter och tidskrifter"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Koppla av"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Underhållning"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Socialt"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Hälsa och träning"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"Väder"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Våra förslag"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"Widgetar för <xliff:g id="SELECTED_HEADER">%1$s</xliff:g> till höger, sökning och alternativ till vänster"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}other{# widgetar}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"Privat, låst."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"Lås"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"Överföring av privat rum"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"Installera appar"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"Installera appar i privat rum"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Fler alternativ"</string>
</resources>
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index 830b56d..1f9690b 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -44,13 +44,10 @@
<string name="add_to_home_screen" msgid="9168649446635919791">"Weka kwenye skrini ya kwanza"</string>
<string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"Umeongeza wijeti ya <xliff:g id="WIDGET_NAME">%1$s</xliff:g> kwenye skrini ya kwanza"</string>
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Mapendekezo"</string>
- <string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Essentials"</string>
+ <string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Vya msingi"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Habari na magazeti"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Mahali Pako pa Kupumzika"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Burudani"</string>
- <string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Mitandao jamii"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Afya na siha"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"Hali ya Hewa"</string>
+ <string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Mitandao ya kijamii"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Unayopendekezewa"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"Wijeti za <xliff:g id="SELECTED_HEADER">%1$s</xliff:g> ziko upande wa kulia, utafutaji na chaguo ziko upande wa kushoto"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{Wijeti #}other{Wijeti #}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"Ya faragha, imefungwa."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"Funga"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"Mabadiliko ya Nafasi ya Faragha"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"Sakinisha programu"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"Sakinisha programu kwenye Sehemu ya Faragha"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Menyu ya vipengee vya ziada"</string>
</resources>
diff --git a/res/values-ta/strings.xml b/res/values-ta/strings.xml
index 061cfb3..88aab6e 100644
--- a/res/values-ta/strings.xml
+++ b/res/values-ta/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"பரிந்துரைகள்"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"அத்தியாவசியமானவை"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"செய்திகள் & பத்திரிக்கைகள்"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"உங்கள் மனதுக்கு இதமானவை"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"பொழுதுபோக்கு"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"சமூகம்"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"ஆரோக்கியம் & உடற்பயிற்சி"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"வானிலை"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"உங்களுக்கான பரிந்துரைகள்"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"<xliff:g id="SELECTED_HEADER">%1$s</xliff:g> விட்ஜெட்கள் வலதுபுறத்தில் உள்ளன, தேடல் மற்றும் விருப்பங்கள் இடதுபுறத்தில் உள்ளன"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# விட்ஜெட்}other{# விட்ஜெட்டுகள்}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"தனிப்பட்டது, லாக் செய்யப்பட்டுள்ளது."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"பூட்டு"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"தனிப்பட்ட சேமிப்பிடத்திற்கு மாற்றுகிறது"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"ஆப்ஸை நிறுவுதல்"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"தனிப்பட்ட சேமிப்பிடத்தில் ஆப்ஸை நிறுவும்"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"கூடுதல் விருப்பங்களைக் காட்டும்"</string>
</resources>
diff --git a/res/values-te/strings.xml b/res/values-te/strings.xml
index d3aea7b..29916c9 100644
--- a/res/values-te/strings.xml
+++ b/res/values-te/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"సూచనలు"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"నిత్యావసరాలు"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"వార్తలు & మ్యాగజైన్లు"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"మీరు ప్రశాంతంగా ఉండే ప్రదేశం"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"వినోదం"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"సామాజికం"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"ఆరోగ్యం & ఫిట్నెస్"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"వాతావరణం"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"మీ కోసం సూచించినవి"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"కుడి వైపున <xliff:g id="SELECTED_HEADER">%1$s</xliff:g> విడ్జెట్లు, ఎడమ వైపున సెర్చ్, ఇతర ఆప్షన్లు"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# విడ్జెట్}other{# విడ్జెట్లు}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"ప్రైవేట్, లాక్ చేయబడింది."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"లాక్ చేయండి"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"ప్రైవేట్ స్పేస్ కేటాయించడం జరుగుతుంది"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"యాప్లను ఇన్స్టాల్ చేయండి"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"ప్రైవేట్ స్పేస్కు యాప్లను ఇన్స్టాల్ చేయండి"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"ఓవర్ఫ్లో"</string>
</resources>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index 1a7c6d1..0ae1abe 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"คำแนะนำ"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"รายการที่ห้ามพลาด"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"ข่าวสารและนิตยสาร"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"พื้นที่สบายๆ ของคุณ"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"ความบันเทิง"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"โซเชียล"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"สุขภาพและการออกกำลังกาย"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"สภาพอากาศ"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"แนะนำให้คุณ"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"วิดเจ็ต<xliff:g id="SELECTED_HEADER">%1$s</xliff:g>ทางด้านขวา การค้นหาและตัวเลือกทางด้านซ้าย"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{วิดเจ็ต # รายการ}other{วิดเจ็ต # รายการ}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"ส่วนตัว ล็อกอยู่"</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"ล็อก"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"การเปลี่ยนไปใช้พื้นที่ส่วนตัว"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"ติดตั้งแอป"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"ติดตั้งแอปไปยังพื้นที่ส่วนตัว"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"การดำเนินการเพิ่มเติม"</string>
</resources>
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index 87b89e3..b94f0c1 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Mga Suhestyon"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Mga essential"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Balita at mga magazine"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Ang Iyong Chill Zone"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Entertainment"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Social"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Kalusugan at fitness"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"Lagay ng panahon"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Iminumungkahi para sa iyo"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"Mga widget ng <xliff:g id="SELECTED_HEADER">%1$s</xliff:g> sa kanan, paghahanap at mga opsyon sa kaliwa"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}one{# widget}other{# na widget}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"Pribado, naka-lock."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"I-lock"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"Pag-transition ng Pribadong Space"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"Mag-install ng mga app"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"Mag-install ng mga app sa Pribadong Space"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Overflow"</string>
</resources>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index 5440378..df4afbd 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Öneriler"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Önemliler"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Haberler ve dergiler"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Huzur alanınız"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Eğlence"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Sosyal"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Sağlık ve fitness"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"Hava durumu"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Sizin için önerilenler"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"<xliff:g id="SELECTED_HEADER">%1$s</xliff:g> widget\'ları sağda, arama ve seçenekler solda"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}other{# widget}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"Gizli, kilitli."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"Kilit"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"Gizli Alana Geçiş"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"Uygulamaları yükleme"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"Uygulamaları özel alana yükleyin"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Taşma"</string>
</resources>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index 50c8f01..692e73e 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Пропозиції"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Основне"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Новини й журнали"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Ваша зона розваг"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Розваги"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Соціальні мережі"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Здоров’я і фітнес"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"Погода"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Пропозиції для вас"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"<xliff:g id="SELECTED_HEADER">%1$s</xliff:g>: віджети праворуч, пошук і опції ліворуч"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# віджет}one{# віджет}few{# віджети}many{# віджетів}other{# віджета}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"Приватний простір, заблоковано."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"Заблокувати"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"Перехід у приватний простір"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"Установити додатки"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"Установити додатки в особистому просторі"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Додаткове меню"</string>
</resources>
diff --git a/res/values-ur/strings.xml b/res/values-ur/strings.xml
index 9cd3e07..7be222e 100644
--- a/res/values-ur/strings.xml
+++ b/res/values-ur/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"تجاویز"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"لوازمات"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"خبریں اور میگزینز"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"آپ کا آرام دہ زون"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"تفریح"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"سماجی"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"صحت اور تندرستی"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"موسم"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"آپ کے لیے تجویز کردہ"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"<xliff:g id="SELECTED_HEADER">%1$s</xliff:g> دائیں طرف وجیٹس، بائیں طرف تلاش اور اختیارات"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# ویجیٹ}other{# ویجیٹس}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"نجی اسپیس مقفل ہے۔"</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"مقفل کریں"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"نجی اسپیس کی منتقلی"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"ایپس انسٹال کریں"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"پرائیویٹ اسپیس میں ایپس انسٹال کریں"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"اوورفلو"</string>
</resources>
diff --git a/res/values-uz/strings.xml b/res/values-uz/strings.xml
index 36df592..ae9d0f9 100644
--- a/res/values-uz/strings.xml
+++ b/res/values-uz/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Takliflar"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Asosiy ilovalar"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Yangiliklar va jurnallar"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Sokin hududingiz"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Hordiq"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Ijtimoiy"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Salomatlik va sport"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"Ob-havo"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Sizga tavsiya etiladi"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"<xliff:g id="SELECTED_HEADER">%1$s</xliff:g> vidjetlari oʻngda, qidiruv va sozlamalar chapda"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# ta vidjet}other{# ta vidjet}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"Shaxsiy, qulflandi."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"Qulflash"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"Maxfiy joyga almashtirish"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"Ilovalar oʻrnatish"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"Ilovalarni Maxfiy makonga oʻrnatish"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Kengaytirish"</string>
</resources>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index 01c7736..24d9c8e 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Nội dung đề xuất"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Các tiện ích thiết yếu"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Tin tức và tạp chí"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Giai điệu thư giãn của bạn"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Giải trí"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Mạng xã hội"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Sức khoẻ và thể chất"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"Thời tiết"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Đề xuất cho bạn"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"Tiện ích <xliff:g id="SELECTED_HEADER">%1$s</xliff:g> ở bên phải, công cụ tìm kiếm và tuỳ chọn ở bên trái"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# tiện ích}other{# tiện ích}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"Riêng tư, đã khoá."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"Khoá"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"Chuyển đổi sang không gian riêng tư"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"Cài đặt ứng dụng"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"Cài đặt ứng dụng vào Không gian riêng tư"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Bong bóng bổ sung"</string>
</resources>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index a18aab6..bf6252a 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"建议"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"必备之选"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"新闻与杂志"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"您的休闲区"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"娱乐"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"社交"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"健康与健身"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"天气"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"为您推荐"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"右边是<xliff:g id="SELECTED_HEADER">%1$s</xliff:g>微件,左边是搜索功能和选项"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# 个微件}other{# 个微件}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"私密,已锁定。"</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"锁定"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"私密空间转换"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"安装应用"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"将应用安装到私密空间"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"菜单"</string>
</resources>
diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml
index e2adcc9..70e27c6 100644
--- a/res/values-zh-rHK/strings.xml
+++ b/res/values-zh-rHK/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"建議"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"必備之選"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"新聞和雜誌"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"放鬆專區"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"娛樂"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"社交"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"健康和健身"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"天氣"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"為你推薦"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"右邊係「<xliff:g id="SELECTED_HEADER">%1$s</xliff:g>」小工具,左邊係搜尋功能同選項"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# 個小工具}other{# 個小工具}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"私人,已鎖定。"</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"上鎖"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"轉為「私人空間」"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"安裝應用程式"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"將應用程式安裝在「私人空間」中"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"顯示更多"</string>
</resources>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index f5eafe4..c14636a 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"建議"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"常用項目"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"新聞與雜誌"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"放鬆專區"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"娛樂"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"社群"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"健康與塑身"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"天氣"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"個人化建議"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"右邊是「<xliff:g id="SELECTED_HEADER">%1$s</xliff:g>」小工具,左邊是搜尋功能和選項"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# 項小工具}other{# 項小工具}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"私人,已鎖定。"</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"鎖定"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"轉換私人空間狀態"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"安裝應用程式"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"將應用程式安裝在私人空間中"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"溢位"</string>
</resources>
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
index 6de2436..449d2a2 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -46,11 +46,8 @@
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Iziphakamiso"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Okusemqoka"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Izindaba nomagazini"</string>
- <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Indawo Ozipholela Kuyo"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Okokozijabulisa"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Okomphakathi"</string>
- <string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Ezempilo nokufaneleka"</string>
- <string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"Isimo sezulu"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Okuphakanyiselwe wena"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"Amawijethi okuthi <xliff:g id="SELECTED_HEADER">%1$s</xliff:g> kwesokudla, ukusesha nokukhethwayo kwesobunxele"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{iwijethi #}one{amawijethi #}other{amawijethi #}}"</string>
@@ -193,7 +190,8 @@
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"Iyimfihlo, ikhiyiwe."</string>
<string name="ps_container_lock_title" msgid="2640257399982364682">"Khiya"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"Ukuguqulwa Kwendawo Yangasese"</string>
- <string name="ps_add_button_label" msgid="8611055839242385935">"Faka ama-app"</string>
+ <!-- no translation found for ps_add_button_label (8127988716897128773) -->
+ <skip />
<string name="ps_add_button_content_description" msgid="3254274107740952556">"Faka ama-app Endaweni Engasese"</string>
<string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Ukugcwala kakhulu"</string>
</resources>
diff --git a/res/values/config.xml b/res/values/config.xml
index a808a3f..2a3b588 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -103,8 +103,8 @@
<item name="swipe_up_rect_scale_stiffness" type="dimen" format="float">200</item>
<item name="swipe_up_rect_scale_higher_stiffness" type="dimen" format="float">400</item>
<!-- Flag: enableScalingRevealHomeAnimation() -->
- <item name="swipe_up_rect_scale_damping_ratio_v2" type="dimen" format="float">0.8</item>
- <item name="swipe_up_rect_scale_stiffness_v2" type="dimen" format="float">650</item>
+ <item name="swipe_up_rect_scale_damping_ratio_v2" type="dimen" format="float">0.99</item>
+ <item name="swipe_up_rect_scale_stiffness_v2" type="dimen" format="float">500</item>
<item name="swipe_up_rect_xy_fling_friction" type="dimen" format="float">1.5</item>
@@ -114,9 +114,9 @@
<item name="swipe_up_rect_xy_stiffness" type="dimen" format="float">200</item>
<!-- Flag: enableScalingRevealHomeAnimation() -->
<item name="swipe_up_rect_x_damping_ratio" type="dimen" format="float">0.965</item>
- <item name="swipe_up_rect_x_stiffness" type="dimen" format="float">300</item>
+ <item name="swipe_up_rect_x_stiffness" type="dimen" format="float">450</item>
<item name="swipe_up_rect_y_damping_ratio" type="dimen" format="float">0.95</item>
- <item name="swipe_up_rect_y_stiffness" type="dimen" format="float">190</item>
+ <item name="swipe_up_rect_y_stiffness" type="dimen" format="float">400</item>
<!-- Taskbar -->
<!-- This is a float because it is converted to dp later in DeviceProfile -->
@@ -155,11 +155,6 @@
<string-array name="filtered_components" ></string-array>
- <!-- Widget component names to be included in weather category of widget suggestions. -->
- <string-array name="weather_recommendations"></string-array>
- <!-- Widget component names to be included in fitness category of widget suggestions. -->
- <string-array name="fitness_recommendations"></string-array>
-
<!-- Swipe back to home related -->
<dimen name="swipe_back_window_scale_x_margin">10dp</dimen>
<dimen name="swipe_back_window_corner_radius">40dp</dimen>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 54edab4..74fadda 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -536,6 +536,8 @@
<dimen name="ps_lock_icon_text_margin_start_expanded">8dp</dimen>
<dimen name="ps_lock_icon_text_margin_end_expanded">6dp</dimen>
<dimen name="ps_lock_button_background_padding">10dp</dimen>
+ <dimen name="ps_floating_mask_corner_radius">28dp</dimen>
+ <dimen name="ps_floating_mask_end_padding">16dp</dimen>
<!-- WindowManagerProxy -->
<dimen name="max_width_and_height_of_small_display_cutout">136px</dimen>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index c3d4273..02e84e0 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -83,13 +83,20 @@
<!-- Widget suggestions header title in the full widgets picker for large screen devices
in landscape mode. [CHAR_LIMIT=50] -->
<string name="suggested_widgets_header_title">Suggestions</string>
+ <!-- Title for the widget suggestions category that displays widgets provided by
+ productivity apps for daily use [CHAR_LIMIT=50] -->
<string name="productivity_widget_recommendation_category_label">Essentials</string>
+ <!-- Title for the widget suggestions category that displays widgets provided by
+ news and magazines related apps [CHAR_LIMIT=50] -->
<string name="news_widget_recommendation_category_label">News & magazines</string>
- <string name="social_and_entertainment_widget_recommendation_category_label">Your Chill Zone</string>
+ <!-- Title for the widget suggestions category that displays widgets provided by
+ entertainment apps [CHAR_LIMIT=50] -->
<string name="entertainment_widget_recommendation_category_label">Entertainment</string>
+ <!-- Title for the widget suggestions category that displays widgets provided by
+ social apps [CHAR_LIMIT=50] -->
<string name="social_widget_recommendation_category_label">Social</string>
- <string name="fitness_widget_recommendation_category_label">Health & fitness</string>
- <string name="weather_widget_recommendation_category_label">Weather</string>
+ <!-- Title for the widget suggestions category that displays general widget suggestions
+ [CHAR_LIMIT=50] -->
<string name="others_widget_recommendation_category_label">Suggested for you</string>
<!-- accessibilityPaneTitle for the right pane when showing suggested widgets. -->
<string name="widget_picker_right_pane_accessibility_title"><xliff:g id="selected_header" example="Calendar">%1$s</xliff:g> widgets on right, search and options on left</string>
@@ -333,7 +340,7 @@
<!-- Title for an app whose download has been started. -->
<string name="app_waiting_download_title"><xliff:g id="name" example="Messenger">%1$s</xliff:g> waiting to install</string>
<!-- Title for an app which is archived. -->
- <string name="app_archived_title"><xliff:g id="name" example="Messenger">%1$s</xliff:g> is archived. Tap to download.</string>
+ <string name="app_archived_title"><xliff:g id="name" example="Messenger">%1$s</xliff:g> is archived. Tap to download and restore.</string>
<!-- Title shown on the alert dialog prompting the user to update the application in market
diff --git a/src/com/android/launcher3/AutoInstallsLayout.java b/src/com/android/launcher3/AutoInstallsLayout.java
index cf86528..175d6ec 100644
--- a/src/com/android/launcher3/AutoInstallsLayout.java
+++ b/src/com/android/launcher3/AutoInstallsLayout.java
@@ -19,6 +19,8 @@
import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
import static com.android.launcher3.LauncherSettings.Favorites.TABLE_NAME;
import static com.android.launcher3.provider.LauncherDbUtils.itemIdMatch;
+import static com.android.launcher3.util.UserIconInfo.TYPE_CLONED;
+import static com.android.launcher3.util.UserIconInfo.TYPE_WORK;
import android.content.ComponentName;
import android.content.ContentValues;
@@ -34,6 +36,7 @@
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.os.Process;
+import android.os.UserHandle;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.AttributeSet;
@@ -56,6 +59,7 @@
import com.android.launcher3.util.IntArray;
import com.android.launcher3.util.Partner;
import com.android.launcher3.util.Thunk;
+import com.android.launcher3.util.UserIconInfo;
import com.android.launcher3.widget.LauncherWidgetHolder;
import org.xmlpull.v1.XmlPullParser;
@@ -63,6 +67,7 @@
import java.io.IOException;
import java.util.Collections;
+import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.function.Supplier;
@@ -125,34 +130,38 @@
private static final String TAG_INCLUDE = "include";
public static final String TAG_WORKSPACE = "workspace";
private static final String TAG_APP_ICON = "appicon";
- private static final String TAG_AUTO_INSTALL = "autoinstall";
- private static final String TAG_FOLDER = "folder";
- private static final String TAG_APPWIDGET = "appwidget";
+ public static final String TAG_AUTO_INSTALL = "autoinstall";
+ public static final String TAG_FOLDER = "folder";
+ public static final String TAG_APPWIDGET = "appwidget";
protected static final String TAG_SEARCH_WIDGET = "searchwidget";
- private static final String TAG_SHORTCUT = "shortcut";
+ public static final String TAG_SHORTCUT = "shortcut";
private static final String TAG_EXTRA = "extra";
- private static final String ATTR_CONTAINER = "container";
- private static final String ATTR_RANK = "rank";
+ public static final String ATTR_CONTAINER = "container";
+ public static final String ATTR_RANK = "rank";
- private static final String ATTR_PACKAGE_NAME = "packageName";
- private static final String ATTR_CLASS_NAME = "className";
- private static final String ATTR_TITLE = "title";
- private static final String ATTR_TITLE_TEXT = "titleText";
- private static final String ATTR_SCREEN = "screen";
- private static final String ATTR_SHORTCUT_ID = "shortcutId";
+ public static final String ATTR_PACKAGE_NAME = "packageName";
+ public static final String ATTR_CLASS_NAME = "className";
+ public static final String ATTR_TITLE = "title";
+ public static final String ATTR_TITLE_TEXT = "titleText";
+ public static final String ATTR_SCREEN = "screen";
+ public static final String ATTR_SHORTCUT_ID = "shortcutId";
// x and y can be specified as negative integers, in which case -1 represents the
// last row / column, -2 represents the second last, and so on.
- private static final String ATTR_X = "x";
- private static final String ATTR_Y = "y";
+ public static final String ATTR_X = "x";
+ public static final String ATTR_Y = "y";
- private static final String ATTR_SPAN_X = "spanX";
- private static final String ATTR_SPAN_Y = "spanY";
+ public static final String ATTR_SPAN_X = "spanX";
+ public static final String ATTR_SPAN_Y = "spanY";
// Attrs for "Include"
private static final String ATTR_WORKSPACE = "workspace";
+ public static final String ATTR_USER_TYPE = "userType";
+ public static final String USER_TYPE_WORK = "work";
+ public static final String USER_TYPE_CLONED = "cloned";
+
// Style attrs -- "Extra"
private static final String ATTR_KEY = "key";
private static final String ATTR_VALUE = "value";
@@ -168,6 +177,8 @@
protected final SourceResources mSourceRes;
protected final Supplier<XmlPullParser> mInitialLayoutSupplier;
+ private final Map<String, Long> mUserTypeToSerial;
+
private final InvariantDeviceProfile mIdp;
private final int mRowCount;
private final int mColumnCount;
@@ -204,15 +215,25 @@
mRowCount = mIdp.numRows;
mColumnCount = mIdp.numColumns;
mActivityOverride = ApiWrapper.INSTANCE.get(context).getActivityOverrides();
+
+ mUserTypeToSerial = new HashMap<>();
+ UserCache cache = UserCache.getInstance(context);
+ for (UserHandle user : cache.getUserProfiles()) {
+ UserIconInfo uii = cache.getUserInfo(user);
+ switch (uii.type) {
+ case TYPE_WORK -> mUserTypeToSerial.put(USER_TYPE_WORK, uii.userSerial);
+ case TYPE_CLONED -> mUserTypeToSerial.put(USER_TYPE_CLONED, uii.userSerial);
+ }
+ }
}
/**
* Loads the layout in the db and returns the number of entries added on the desktop.
*/
- public int loadLayout(SQLiteDatabase db, IntArray screenIds) {
+ public int loadLayout(SQLiteDatabase db) {
mDb = db;
try {
- return parseLayout(mInitialLayoutSupplier.get(), screenIds);
+ return parseLayout(mInitialLayoutSupplier.get());
} catch (Exception e) {
Log.e(TAG, "Error parsing layout: ", e);
return -1;
@@ -222,7 +243,7 @@
/**
* Parses the layout and returns the number of elements added on the homescreen.
*/
- protected int parseLayout(XmlPullParser parser, IntArray screenIds)
+ protected int parseLayout(XmlPullParser parser)
throws XmlPullParserException, IOException {
beginDocument(parser, mRootTag);
final int depth = parser.getDepth();
@@ -235,7 +256,7 @@
if (type != XmlPullParser.START_TAG) {
continue;
}
- count += parseAndAddNode(parser, tagParserMap, screenIds);
+ count += parseAndAddNode(parser, tagParserMap);
}
return count;
}
@@ -259,14 +280,14 @@
* Parses the current node and returns the number of elements added.
*/
protected int parseAndAddNode(
- XmlPullParser parser, ArrayMap<String, TagParser> tagParserMap, IntArray screenIds)
+ XmlPullParser parser, ArrayMap<String, TagParser> tagParserMap)
throws XmlPullParserException, IOException {
if (TAG_INCLUDE.equals(parser.getName())) {
final int resId = getAttributeResourceValue(parser, ATTR_WORKSPACE, 0);
if (resId != 0) {
// recursively load some more favorites, why not?
- return parseLayout(mSourceRes.getXml(resId), screenIds);
+ return parseLayout(mSourceRes.getXml(resId));
} else {
return 0;
}
@@ -284,22 +305,17 @@
convertToDistanceFromEnd(getAttributeValue(parser, ATTR_X), mColumnCount));
mValues.put(Favorites.CELLY,
convertToDistanceFromEnd(getAttributeValue(parser, ATTR_Y), mRowCount));
+ Long profileId = mUserTypeToSerial.get(getAttributeValue(parser, ATTR_USER_TYPE));
+ if (profileId != null) {
+ mValues.put(Favorites.PROFILE_ID, profileId);
+ }
TagParser tagParser = tagParserMap.get(parser.getName());
if (tagParser == null) {
if (LOGD) Log.d(TAG, "Ignoring unknown element tag: " + parser.getName());
return 0;
}
- int newElementId = tagParser.parseAndAdd(parser);
- if (newElementId >= 0) {
- // Keep track of the set of screens which need to be added to the db.
- if (!screenIds.contains(screenId) &&
- container == Favorites.CONTAINER_DESKTOP) {
- screenIds.add(screenId);
- }
- return 1;
- }
- return 0;
+ return tagParser.parseAndAdd(parser) >= 0 ? 1 : 0;
}
protected int addShortcut(String title, Intent intent, int type) {
@@ -311,10 +327,11 @@
mValues.put(Favorites.SPANY, 1);
mValues.put(Favorites._ID, id);
- if (type == ITEM_TYPE_APPLICATION) {
- ComponentName cn = intent.getComponent();
- if (cn != null && mActivityOverride.containsKey(cn.getPackageName())) {
- LauncherActivityInfo replacementInfo = mActivityOverride.get(cn.getPackageName());
+ ComponentName cn = intent.getComponent();
+ if (cn != null && type == ITEM_TYPE_APPLICATION
+ && !mValues.containsKey(Favorites.PROFILE_ID)) {
+ LauncherActivityInfo replacementInfo = mActivityOverride.get(cn.getPackageName());
+ if (replacementInfo != null) {
mValues.put(Favorites.PROFILE_ID, UserCache.INSTANCE.get(mContext)
.getSerialNumberForUser(replacementInfo.getUser()));
mValues.put(Favorites.INTENT, AppInfo.makeLaunchIntent(replacementInfo).toUri(0));
@@ -420,11 +437,7 @@
}
mValues.put(Favorites.RESTORED, WorkspaceItemInfo.FLAG_AUTOINSTALL_ICON);
- final Intent intent = new Intent(Intent.ACTION_MAIN, null)
- .addCategory(Intent.CATEGORY_LAUNCHER)
- .setComponent(new ComponentName(packageName, className))
- .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
- | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
+ Intent intent = AppInfo.makeLaunchIntent(new ComponentName(packageName, className));
return addShortcut(mContext.getString(R.string.package_state_unknown), intent,
ITEM_TYPE_APPLICATION);
}
diff --git a/src/com/android/launcher3/LauncherState.java b/src/com/android/launcher3/LauncherState.java
index 3bdd863..72a3c53 100644
--- a/src/com/android/launcher3/LauncherState.java
+++ b/src/com/android/launcher3/LauncherState.java
@@ -83,7 +83,7 @@
public static final int FLAG_HAS_SYS_UI_SCRIM = BaseState.getFlag(4);
// Flag to inticate that all popups should be closed when this state is enabled.
public static final int FLAG_CLOSE_POPUPS = BaseState.getFlag(5);
- public static final int FLAG_OVERVIEW_UI = BaseState.getFlag(6);
+ public static final int FLAG_RECENTS_VIEW_VISIBLE = BaseState.getFlag(6);
// Flag indicating that hotseat and its contents are not accessible.
public static final int FLAG_HOTSEAT_INACCESSIBLE = BaseState.getFlag(7);
@@ -158,14 +158,14 @@
/**
* True if the state has overview panel visible.
*/
- public final boolean overviewUi;
+ public final boolean isRecentsViewVisible;
private final int mFlags;
public LauncherState(int id, int statsLogOrdinal, int flags) {
this.statsLogOrdinal = statsLogOrdinal;
this.mFlags = flags;
- this.overviewUi = (flags & FLAG_OVERVIEW_UI) != 0;
+ this.isRecentsViewVisible = (flags & FLAG_RECENTS_VIEW_VISIBLE) != 0;
this.ordinal = id;
sAllStates[id] = this;
}
diff --git a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
index 0792641..56a7fef 100644
--- a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
@@ -18,7 +18,6 @@
import static com.android.launcher3.Flags.enableExpandingPauseWorkButton;
import static com.android.launcher3.allapps.ActivityAllAppsContainerView.AdapterHolder.MAIN;
import static com.android.launcher3.allapps.ActivityAllAppsContainerView.AdapterHolder.SEARCH;
-import static com.android.launcher3.allapps.ActivityAllAppsContainerView.AdapterHolder.WORK;
import static com.android.launcher3.allapps.BaseAllAppsAdapter.VIEW_TYPE_PRIVATE_SPACE_HEADER;
import static com.android.launcher3.allapps.BaseAllAppsAdapter.VIEW_TYPE_WORK_DISABLED_CARD;
import static com.android.launcher3.allapps.BaseAllAppsAdapter.VIEW_TYPE_WORK_EDU_CARD;
@@ -587,12 +586,6 @@
return;
}
- if (!FeatureFlags.ENABLE_SEARCH_RESULT_BACKGROUND_DRAWABLES.get()) {
- RecyclerView.ItemDecoration decoration = getMainAdapterProvider().getDecorator();
- getSearchRecyclerView().removeItemDecoration(decoration);
- getSearchRecyclerView().addItemDecoration(decoration);
- }
-
// replaceAppsRVcontainer() needs to use both mUsingTabs value to remove the old view AND
// showTabs value to create new view. Hence the mUsingTabs new value assignment MUST happen
// after this call.
diff --git a/src/com/android/launcher3/allapps/FloatingMaskView.java b/src/com/android/launcher3/allapps/FloatingMaskView.java
new file mode 100644
index 0000000..606eb03
--- /dev/null
+++ b/src/com/android/launcher3/allapps/FloatingMaskView.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2024 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.allapps;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+
+import androidx.constraintlayout.widget.ConstraintLayout;
+
+import com.android.launcher3.R;
+import com.android.launcher3.views.ActivityContext;
+
+public class FloatingMaskView extends ConstraintLayout {
+
+ private final ActivityContext mActivityContext;
+ private ImageView mBottomBox;
+
+ public FloatingMaskView(Context context) {
+ this(context, null, 0);
+ }
+
+ public FloatingMaskView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public FloatingMaskView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ mActivityContext = ActivityContext.lookupContext(context);
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ mBottomBox = findViewById(R.id.bottom_box);
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ super.onLayout(changed, left, top, right, bottom);
+ ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) getLayoutParams();
+ AllAppsRecyclerView allAppsContainerView =
+ mActivityContext.getAppsView().getActiveRecyclerView();
+ if (lp != null) {
+ lp.rightMargin = allAppsContainerView.getPaddingRight();
+ lp.leftMargin = allAppsContainerView.getPaddingLeft();
+ mBottomBox.setMinimumHeight(allAppsContainerView.getPaddingBottom());
+ }
+ }
+}
diff --git a/src/com/android/launcher3/allapps/PrivateProfileManager.java b/src/com/android/launcher3/allapps/PrivateProfileManager.java
index 53f9cfc..27340a3 100644
--- a/src/com/android/launcher3/allapps/PrivateProfileManager.java
+++ b/src/com/android/launcher3/allapps/PrivateProfileManager.java
@@ -60,6 +60,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
+import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.recyclerview.widget.LinearSmoothScroller;
import androidx.recyclerview.widget.RecyclerView;
@@ -96,14 +97,17 @@
private static final int TEXT_UNLOCK_OPACITY_DURATION = 300;
private static final int TEXT_LOCK_OPACITY_DURATION = 50;
private static final int APP_OPACITY_DURATION = 400;
+ private static final int MASK_VIEW_DURATION = 200;
private static final int APP_OPACITY_DELAY = 400;
private static final int SETTINGS_AND_LOCK_GROUP_TRANSITION_DELAY = 400;
private static final int SETTINGS_OPACITY_DELAY = 400;
private static final int LOCK_TEXT_OPACITY_DELAY = 500;
+ private static final int MASK_VIEW_DELAY = 400;
private static final int NO_DELAY = 0;
private final ActivityAllAppsContainerView<?> mAllApps;
private final Predicate<UserHandle> mPrivateProfileMatcher;
private final int mPsHeaderHeight;
+ private final int mFloatingMaskViewCornerRadius;
private final RecyclerView.OnScrollListener mOnIdleScrollListener =
new RecyclerView.OnScrollListener() {
@Override
@@ -123,6 +127,7 @@
private Runnable mOnPSHeaderAdded;
@Nullable
private RelativeLayout mPSHeader;
+ private ConstraintLayout mFloatingMaskView;
private final String mLockedStateContentDesc;
private final String mUnLockedStateContentDesc;
@@ -142,6 +147,8 @@
.getString(R.string.ps_container_lock_button_content_description);
mUnLockedStateContentDesc = mAllApps.getContext()
.getString(R.string.ps_container_unlock_button_content_description);
+ mFloatingMaskViewCornerRadius = mAllApps.getContext().getResources().getDimensionPixelSize(
+ R.dimen.ps_floating_mask_corner_radius);
}
/** Adds Private Space Header to the layout. */
@@ -219,6 +226,7 @@
.hasModelFlag(FLAG_PRIVATE_PROFILE_QUIET_MODE_ENABLED);
int updatedState = isEnabled ? STATE_ENABLED : STATE_DISABLED;
setCurrentState(updatedState);
+ mFloatingMaskView = null;
if (mPSHeader != null) {
mPSHeader.setAlpha(1);
}
@@ -494,12 +502,15 @@
RecyclerView.LayoutManager layoutManager = allAppsRecyclerView.getLayoutManager();
if (layoutManager != null) {
startAnimationScroll(allAppsRecyclerView, layoutManager, smoothScroller);
- currentItem.decorationInfo = null;
+ // Preserve decorator if floating mask view exists.
+ if (mFloatingMaskView == null) {
+ currentItem.decorationInfo = null;
+ }
}
break;
}
// Make the private space apps gone to "collapse".
- if (isPrivateSpaceItem(currentItem)) {
+ if (mFloatingMaskView == null && isPrivateSpaceItem(currentItem)) {
RecyclerView.ViewHolder viewHolder =
allAppsRecyclerView.findViewHolderForAdapterPosition(i);
if (viewHolder != null) {
@@ -637,6 +648,7 @@
setAnimationRunning(false);
return;
}
+ attachFloatingMaskView(expand);
ViewGroup settingsAndLockGroup = mPSHeader.findViewById(R.id.settingsAndLockGroup);
if (settingsAndLockGroup.getLayoutTransition() == null) {
// Set a new transition if the current ViewGroup does not already contain one as each
@@ -662,6 +674,11 @@
mPSHeader.findViewById(R.id.lock_text).setVisibility(expand ? VISIBLE : GONE);
setAnimationRunning(true);
}
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ detachFloatingMaskView();
+ }
});
animatorSet.addListener(forEndCallback(() -> {
setAnimationRunning(false);
@@ -681,13 +698,17 @@
}
}));
if (expand) {
- animatorSet.playTogether(animateAlphaOfIcons(true));
+ animatorSet.playTogether(animateAlphaOfIcons(true),
+ translateFloatingMaskView(false));
} else {
if (isPrivateSpaceHidden()) {
- animatorSet.playSequentially(animateAlphaOfIcons(false),
- animateCollapseAnimation(), fadeOutHeaderAlpha());
+ animatorSet.playSequentially(translateFloatingMaskView(false),
+ animateAlphaOfIcons(false),
+ animateCollapseAnimation(),
+ fadeOutHeaderAlpha());
} else {
- animatorSet.playSequentially(animateAlphaOfIcons(false),
+ animatorSet.playSequentially(translateFloatingMaskView(true),
+ animateAlphaOfIcons(false),
animateCollapseAnimation());
}
}
@@ -715,6 +736,27 @@
return alphaAnim;
}
+ /** Fades out the private space container. */
+ private ValueAnimator translateFloatingMaskView(boolean animateIn) {
+ if (!Flags.privateSpaceFloatingMaskView() || mFloatingMaskView == null) {
+ return new ValueAnimator();
+ }
+ // Translate base on the height amount. Translates out on expand and in on collapse.
+ float floatingMaskViewHeight = getFloatingMaskViewHeight();
+ float from = animateIn ? floatingMaskViewHeight : 0;
+ float to = animateIn ? 0 : floatingMaskViewHeight;
+ ValueAnimator alphaAnim = ObjectAnimator.ofFloat(from, to);
+ alphaAnim.setDuration(MASK_VIEW_DURATION);
+ alphaAnim.setStartDelay(MASK_VIEW_DELAY);
+ alphaAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator valueAnimator) {
+ mFloatingMaskView.setTranslationY((float) valueAnimator.getAnimatedValue());
+ }
+ });
+ return alphaAnim;
+ }
+
/** Animates the layout changes when the text of the button becomes visible/gone. */
private void enableLayoutTransition(ViewGroup settingsAndLockGroup) {
LayoutTransition settingsAndLockTransition = new LayoutTransition();
@@ -806,6 +848,28 @@
});
}
+ private void attachFloatingMaskView(boolean expand) {
+ if (!Flags.privateSpaceFloatingMaskView()) {
+ return;
+ }
+ mFloatingMaskView = (FloatingMaskView) mAllApps.getLayoutInflater().inflate(
+ R.layout.private_space_mask_view, mAllApps, false);
+ mAllApps.addView(mFloatingMaskView);
+ // Translate off the screen first if its collapsing so this header view isn't visible to
+ // user when animation starts.
+ if (!expand) {
+ mFloatingMaskView.setTranslationY(getFloatingMaskViewHeight());
+ }
+ mFloatingMaskView.setVisibility(VISIBLE);
+ }
+
+ private void detachFloatingMaskView() {
+ if (mFloatingMaskView != null) {
+ mAllApps.removeView(mFloatingMaskView);
+ }
+ mFloatingMaskView = null;
+ }
+
/** Starts the smooth scroll with the provided smoothScroller and add idle listener. */
private void startAnimationScroll(AllAppsRecyclerView allAppsRecyclerView,
RecyclerView.LayoutManager layoutManager, RecyclerView.SmoothScroller smoothScroller) {
@@ -815,6 +879,10 @@
allAppsRecyclerView.addOnScrollListener(mOnIdleScrollListener);
}
+ private float getFloatingMaskViewHeight() {
+ return mFloatingMaskViewCornerRadius + getMainRecyclerView().getPaddingBottom();
+ }
+
AllAppsRecyclerView getMainRecyclerView() {
return mAllApps.mAH.get(ActivityAllAppsContainerView.AdapterHolder.MAIN).mRecyclerView;
}
diff --git a/src/com/android/launcher3/allapps/search/DefaultSearchAdapterProvider.java b/src/com/android/launcher3/allapps/search/DefaultSearchAdapterProvider.java
index 64fd237..4a8c96b 100644
--- a/src/com/android/launcher3/allapps/search/DefaultSearchAdapterProvider.java
+++ b/src/com/android/launcher3/allapps/search/DefaultSearchAdapterProvider.java
@@ -19,8 +19,6 @@
import android.view.View;
import android.view.ViewGroup;
-import androidx.recyclerview.widget.RecyclerView;
-
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.allapps.AllAppsGridAdapter;
import com.android.launcher3.model.data.ItemInfo;
@@ -30,13 +28,10 @@
* Provides views for local search results.
*/
public class DefaultSearchAdapterProvider extends SearchAdapterProvider<ActivityContext> {
-
- private final RecyclerView.ItemDecoration mDecoration;
private View mHighlightedView;
public DefaultSearchAdapterProvider(ActivityContext launcher) {
super(launcher);
- mDecoration = new RecyclerView.ItemDecoration() { };
}
@Override
@@ -74,11 +69,6 @@
}
@Override
- public RecyclerView.ItemDecoration getDecorator() {
- return mDecoration;
- }
-
- @Override
public void clearHighlightedItem() {
mHighlightedView = null;
}
diff --git a/src/com/android/launcher3/allapps/search/SearchAdapterProvider.java b/src/com/android/launcher3/allapps/search/SearchAdapterProvider.java
index 15756f5..82c9c90 100644
--- a/src/com/android/launcher3/allapps/search/SearchAdapterProvider.java
+++ b/src/com/android/launcher3/allapps/search/SearchAdapterProvider.java
@@ -20,8 +20,6 @@
import android.view.View;
import android.view.ViewGroup;
-import androidx.recyclerview.widget.RecyclerView;
-
import com.android.launcher3.allapps.AllAppsGridAdapter;
import com.android.launcher3.views.ActivityContext;
@@ -50,11 +48,6 @@
public abstract View getHighlightedItem();
/**
- * Returns the item decorator.
- */
- public abstract RecyclerView.ItemDecoration getDecorator();
-
- /**
* Clear the highlighted view.
*/
public abstract void clearHighlightedItem();
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index e1a7d66..4b908bf 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -61,15 +61,6 @@
* and set a default value for the flag. This will be the default value on Debug builds.
* <p>
*/
- // TODO(Block 1): Clean up flags
- public static final BooleanFlag ENABLE_SEARCH_RESULT_BACKGROUND_DRAWABLES = getReleaseFlag(
- 270394041, "ENABLE_SEARCH_RESULT_BACKGROUND_DRAWABLES", ENABLED,
- "Enable option to replace decorator-based search result backgrounds with drawables");
-
- public static final BooleanFlag ENABLE_SEARCH_RESULT_LAUNCH_TRANSITION = getReleaseFlag(
- 270394392, "ENABLE_SEARCH_RESULT_LAUNCH_TRANSITION", ENABLED,
- "Enable option to launch search results using the new view container transitions");
-
// TODO(Block 2): Clean up flags
public static final BooleanFlag ENABLE_MULTI_DISPLAY_PARTIAL_DEPTH = getDebugFlag(270395073,
"ENABLE_MULTI_DISPLAY_PARTIAL_DEPTH", DISABLED,
diff --git a/src/com/android/launcher3/icons/IconCache.java b/src/com/android/launcher3/icons/IconCache.java
index 329f717..04d8ac0 100644
--- a/src/com/android/launcher3/icons/IconCache.java
+++ b/src/com/android/launcher3/icons/IconCache.java
@@ -373,8 +373,13 @@
infoInOut.user, activityInfoProvider, mLauncherActivityInfoCachingLogic,
usePkgIcon, useLowResIcon);
applyPackageEntry(packageEntry, infoInOut, entry);
- } else {
+ } else if (useLowResIcon || !entry.bitmap.isNullOrLowRes()
+ || infoInOut.bitmap.isNullOrLowRes()) {
+ // Only use cache entry if it will not downgrade the current bitmap in infoInOut
applyCacheEntry(entry, infoInOut);
+ } else {
+ Log.d(TAG, "getTitleAndIcon: Cache entry bitmap was a downgrade of existing bitmap"
+ + " in ItemInfo. Skipping.");
}
}
diff --git a/src/com/android/launcher3/logging/StatsLogManager.java b/src/com/android/launcher3/logging/StatsLogManager.java
index 25eeacb..861631d 100644
--- a/src/com/android/launcher3/logging/StatsLogManager.java
+++ b/src/com/android/launcher3/logging/StatsLogManager.java
@@ -781,7 +781,19 @@
LAUNCHER_PRIVATE_SPACE_UNLOCK_ANIMATION_BEGIN(1727),
@UiEvent(doc = "Private space unlock animation finished")
- LAUNCHER_PRIVATE_SPACE_UNLOCK_ANIMATION_END(1728)
+ LAUNCHER_PRIVATE_SPACE_UNLOCK_ANIMATION_END(1728),
+
+ @UiEvent(doc = "User rotates whilst in Overview / RecentsView")
+ LAUNCHER_OVERVIEW_ORIENTATION_CHANGED(1762),
+
+ @UiEvent(doc = "User launches Overview from 3 button navigation")
+ LAUNCHER_OVERVIEW_SHOW_OVERVIEW_FROM_3_BUTTON(1763),
+
+ @UiEvent(doc = "User launches Overview from alt+tab keyboard quick switch")
+ LAUNCHER_OVERVIEW_SHOW_OVERVIEW_FROM_KEYBOARD_QUICK_SWITCH(1764),
+
+ @UiEvent(doc = "User launches Overview from meta+tab keyboard shortcut")
+ LAUNCHER_OVERVIEW_SHOW_OVERVIEW_FROM_KEYBOARD_SHORTCUT(1765),
// ADD MORE
;
diff --git a/src/com/android/launcher3/model/DatabaseHelper.java b/src/com/android/launcher3/model/DatabaseHelper.java
index 132b606..8368256 100644
--- a/src/com/android/launcher3/model/DatabaseHelper.java
+++ b/src/com/android/launcher3/model/DatabaseHelper.java
@@ -505,7 +505,7 @@
public int loadFavorites(SQLiteDatabase db, AutoInstallsLayout loader) {
// TODO: Use multiple loaders with fall-back and transaction.
- int count = loader.loadLayout(db, new IntArray());
+ int count = loader.loadLayout(db);
// Ensure that the max ids are initialized
mMaxItemId = initializeMaxItemId(db);
diff --git a/src/com/android/launcher3/model/PackageUpdatedTask.java b/src/com/android/launcher3/model/PackageUpdatedTask.java
index 29d2269..079987b 100644
--- a/src/com/android/launcher3/model/PackageUpdatedTask.java
+++ b/src/com/android/launcher3/model/PackageUpdatedTask.java
@@ -244,7 +244,16 @@
.query(ShortcutRequest.PINNED);
if (shortcut.isEmpty()) {
isTargetValid = false;
+ if (DEBUG) {
+ Log.d(TAG, "Pinned Shortcut not found for updated"
+ + " package=" + si.getTargetPackage());
+ }
} else {
+ if (DEBUG) {
+ Log.d(TAG, "Found pinned shortcut for updated"
+ + " package=" + si.getTargetPackage()
+ + ", isTargetValid=" + isTargetValid);
+ }
si.updateFromDeepShortcutInfo(shortcut.get(0), context);
infoUpdated = true;
}
@@ -252,6 +261,7 @@
isTargetValid = context.getSystemService(LauncherApps.class)
.isActivityEnabled(cn, mUser);
}
+
if (!isTargetValid && (si.hasStatusFlag(
FLAG_RESTORED_ICON | FLAG_AUTOINSTALL_ICON)
|| si.isArchived())) {
@@ -260,20 +270,24 @@
} else if (si.hasPromiseIconUi()) {
removedShortcuts.add(si.id);
if (DEBUG) {
- Log.d(TAG, "Removing restored shortcut promise icon"
+ FileLog.w(TAG, "Removing restored shortcut promise icon"
+ " that no longer points to valid component."
+ " id=" + si.id
- + ", package=" + si.getTargetPackage());
+ + ", package=" + si.getTargetPackage()
+ + ", status=" + si.status
+ + ", isArchived=" + si.isArchived());
}
return;
}
} else if (!isTargetValid) {
removedShortcuts.add(si.id);
- FileLog.e(TAG, "Removing shortcut that no longer points to"
- + " valid component."
- + " id=" + si.id
- + " package=" + si.getTargetPackage()
- + " status=" + si.status);
+ if (DEBUG) {
+ FileLog.w(TAG, "Removing shortcut that no longer points to"
+ + " valid component."
+ + " id=" + si.id
+ + " package=" + si.getTargetPackage()
+ + " status=" + si.status);
+ }
return;
} else {
si.status = WorkspaceItemInfo.DEFAULT;
diff --git a/src/com/android/launcher3/model/UserManagerState.java b/src/com/android/launcher3/model/UserManagerState.java
index 720f08e..ed32430 100644
--- a/src/com/android/launcher3/model/UserManagerState.java
+++ b/src/com/android/launcher3/model/UserManagerState.java
@@ -17,6 +17,7 @@
import android.os.UserHandle;
import android.os.UserManager;
+import android.util.Log;
import android.util.LongSparseArray;
import android.util.SparseBooleanArray;
@@ -27,6 +28,8 @@
*/
public class UserManagerState {
+ private static final String TAG = "UserManagerState";
+
public final LongSparseArray<UserHandle> allUsers = new LongSparseArray<>();
private final LongSparseArray<Boolean> mQuietUsersSerialNoMap = new LongSparseArray<>();
@@ -39,6 +42,13 @@
for (UserHandle user : userManager.getUserProfiles()) {
long serialNo = userCache.getSerialNumberForUser(user);
boolean isUserQuiet = userManager.isQuietModeEnabled(user);
+ // Mapping different UserHandles to the same serialNo in allUsers could lead to losing
+ // UserHandle and cause a series of problems, such as incorrectly marking app as
+ // disabled and deleting app icons from workspace.
+ if (allUsers.get(serialNo) != null) {
+ Log.w(TAG, String.format("Override allUsers[%d]=%s with %s",
+ serialNo, allUsers.get(serialNo), user));
+ }
allUsers.put(serialNo, user);
mQuietUsersHashCodeMap.put(user.hashCode(), isUserQuiet);
mQuietUsersSerialNoMap.put(serialNo, isUserQuiet);
diff --git a/src/com/android/launcher3/model/data/WorkspaceItemInfo.java b/src/com/android/launcher3/model/data/WorkspaceItemInfo.java
index 2c533ac..40e3813 100644
--- a/src/com/android/launcher3/model/data/WorkspaceItemInfo.java
+++ b/src/com/android/launcher3/model/data/WorkspaceItemInfo.java
@@ -22,6 +22,7 @@
import android.content.Intent;
import android.content.pm.ShortcutInfo;
import android.text.TextUtils;
+import android.util.Log;
import androidx.annotation.NonNull;
@@ -186,9 +187,12 @@
if (shortcutInfo.isEnabled()) {
runtimeStatusFlags &= ~FLAG_DISABLED_BY_PUBLISHER;
} else {
+ Log.w(TAG, "updateFromDeepShortcutInfo: Updated shortcut has been disabled. "
+ + " package=" + shortcutInfo.getPackage()
+ + " disabledReason=" + shortcutInfo.getDisabledReason());
runtimeStatusFlags |= FLAG_DISABLED_BY_PUBLISHER;
}
- disabledMessage = shortcutInfo.getDisabledMessage();
+
if (shortcutInfo.getDisabledReason() == ShortcutInfo.DISABLED_REASON_VERSION_LOWER) {
runtimeStatusFlags |= FLAG_DISABLED_VERSION_LOWER;
} else {
diff --git a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
index 50f98f2..3817563 100644
--- a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
+++ b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
@@ -411,17 +411,29 @@
mLauncher.getStatsLogManager().logger()
.withSrcState(mStartState.statsLogOrdinal)
.withDstState(targetState.statsLogOrdinal)
- .withContainerInfo(LauncherAtom.ContainerInfo.newBuilder()
- .setWorkspace(
- LauncherAtom.WorkspaceContainer.newBuilder()
- .setPageIndex(mLauncher.getWorkspace().getCurrentPage()))
- .build())
+ .withContainerInfo(getContainerInfo(targetState))
.log(StatsLogManager.getLauncherAtomEvent(mStartState.statsLogOrdinal,
targetState.statsLogOrdinal, mToState.ordinal > mFromState.ordinal
? LAUNCHER_UNKNOWN_SWIPEUP
: LAUNCHER_UNKNOWN_SWIPEDOWN));
}
+ private LauncherAtom.ContainerInfo getContainerInfo(LauncherState targetState) {
+ if (targetState.isRecentsViewVisible) {
+ return LauncherAtom.ContainerInfo.newBuilder()
+ .setTaskSwitcherContainer(
+ LauncherAtom.TaskSwitcherContainer.getDefaultInstance()
+ )
+ .build();
+ }
+
+ return LauncherAtom.ContainerInfo.newBuilder()
+ .setWorkspace(
+ LauncherAtom.WorkspaceContainer.newBuilder()
+ .setPageIndex(mLauncher.getWorkspace().getCurrentPage()))
+ .build();
+ }
+
protected void clearState() {
cancelAnimationControllers();
mGoingBetweenStates = true;
diff --git a/src/com/android/launcher3/util/FlagDebugUtils.kt b/src/com/android/launcher3/util/FlagDebugUtils.kt
index f281943..33b8330 100644
--- a/src/com/android/launcher3/util/FlagDebugUtils.kt
+++ b/src/com/android/launcher3/util/FlagDebugUtils.kt
@@ -2,6 +2,7 @@
import java.util.StringJoiner
import java.util.function.IntFunction
+import java.util.function.LongFunction
object FlagDebugUtils {
@@ -12,6 +13,13 @@
str.add(flagName)
}
}
+ /** Appends the [flagName] to [str] when the [flag] is set in [flags]. */
+ @JvmStatic
+ fun appendFlag(str: StringJoiner, flags: Long, flag: Long, flagName: String) {
+ if (flags and flag != 0L) {
+ str.add(flagName)
+ }
+ }
/**
* Produces a human-readable representation of the [current] flags, followed by a diff from from
@@ -34,4 +42,30 @@
}
return result.toString()
}
+
+ /**
+ * Produces a human-readable representation of the [current] flags, followed by a diff from from
+ * [previous].
+ *
+ * The resulting string is intented for logging and debugging.
+ */
+ @JvmStatic
+ fun formatFlagChange(
+ current: Long,
+ previous: Long,
+ flagSerializer: LongFunction<String>
+ ): String {
+ val result = StringJoiner(" ")
+ result.add("[" + flagSerializer.apply(current) + "]")
+ val changed = current xor previous
+ val added = current and changed
+ if (added != 0L) {
+ result.add("+[" + flagSerializer.apply(added) + "]")
+ }
+ val removed = previous and changed
+ if (removed != 0L) {
+ result.add("-[" + flagSerializer.apply(removed) + "]")
+ }
+ return result.toString()
+ }
}
diff --git a/src/com/android/launcher3/util/LauncherLayoutBuilder.kt b/src/com/android/launcher3/util/LauncherLayoutBuilder.kt
new file mode 100644
index 0000000..ecc9953
--- /dev/null
+++ b/src/com/android/launcher3/util/LauncherLayoutBuilder.kt
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2019 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.util
+
+import android.util.Xml
+import com.android.launcher3.AutoInstallsLayout.ATTR_CLASS_NAME
+import com.android.launcher3.AutoInstallsLayout.ATTR_CONTAINER
+import com.android.launcher3.AutoInstallsLayout.ATTR_PACKAGE_NAME
+import com.android.launcher3.AutoInstallsLayout.ATTR_RANK
+import com.android.launcher3.AutoInstallsLayout.ATTR_SCREEN
+import com.android.launcher3.AutoInstallsLayout.ATTR_SHORTCUT_ID
+import com.android.launcher3.AutoInstallsLayout.ATTR_SPAN_X
+import com.android.launcher3.AutoInstallsLayout.ATTR_SPAN_Y
+import com.android.launcher3.AutoInstallsLayout.ATTR_TITLE
+import com.android.launcher3.AutoInstallsLayout.ATTR_TITLE_TEXT
+import com.android.launcher3.AutoInstallsLayout.ATTR_USER_TYPE
+import com.android.launcher3.AutoInstallsLayout.ATTR_X
+import com.android.launcher3.AutoInstallsLayout.ATTR_Y
+import com.android.launcher3.AutoInstallsLayout.TAG_APPWIDGET
+import com.android.launcher3.AutoInstallsLayout.TAG_AUTO_INSTALL
+import com.android.launcher3.AutoInstallsLayout.TAG_FOLDER
+import com.android.launcher3.AutoInstallsLayout.TAG_SHORTCUT
+import com.android.launcher3.AutoInstallsLayout.TAG_WORKSPACE
+import com.android.launcher3.LauncherSettings.Favorites.CONTAINER_DESKTOP
+import com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT
+import com.android.launcher3.LauncherSettings.Favorites.containerToString
+import java.io.IOException
+import java.io.StringWriter
+import java.io.Writer
+import org.xmlpull.v1.XmlSerializer
+
+/** Helper class to build xml for Launcher Layout */
+class LauncherLayoutBuilder {
+ private val nodes = ArrayList<Node>()
+
+ fun atHotseat(rank: Int) =
+ ItemTarget(
+ mapOf(
+ ATTR_CONTAINER to containerToString(CONTAINER_HOTSEAT),
+ ATTR_RANK to rank.toString()
+ )
+ )
+
+ fun atWorkspace(x: Int, y: Int, screen: Int) =
+ ItemTarget(
+ mapOf(
+ ATTR_CONTAINER to containerToString(CONTAINER_DESKTOP),
+ ATTR_X to x.toString(),
+ ATTR_Y to y.toString(),
+ ATTR_SCREEN to screen.toString()
+ )
+ )
+
+ @Throws(IOException::class) fun build() = StringWriter().apply { build(this) }.toString()
+
+ @Throws(IOException::class)
+ fun build(writer: Writer) {
+ Xml.newSerializer().apply {
+ setOutput(writer)
+ setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true)
+ startDocument("UTF-8", true)
+ startTag(null, TAG_WORKSPACE)
+ writeNodes(nodes)
+ endTag(null, TAG_WORKSPACE)
+ endDocument()
+ flush()
+ }
+ }
+
+ open inner class ItemTarget(private val baseValues: Map<String, String>) {
+ @JvmOverloads
+ fun putApp(packageName: String, className: String?, userType: String? = null) =
+ addItem(
+ TAG_AUTO_INSTALL,
+ userType,
+ mapOf(
+ ATTR_PACKAGE_NAME to packageName,
+ ATTR_CLASS_NAME to (className ?: packageName)
+ )
+ )
+
+ @JvmOverloads
+ fun putShortcut(packageName: String, shortcutId: String, userType: String? = null) =
+ addItem(
+ TAG_SHORTCUT,
+ userType,
+ mapOf(ATTR_PACKAGE_NAME to packageName, ATTR_SHORTCUT_ID to shortcutId)
+ )
+
+ @JvmOverloads
+ fun putWidget(
+ packageName: String,
+ className: String,
+ spanX: Int,
+ spanY: Int,
+ userType: String? = null
+ ) =
+ addItem(
+ TAG_APPWIDGET,
+ userType,
+ mapOf(
+ ATTR_PACKAGE_NAME to packageName,
+ ATTR_CLASS_NAME to className,
+ ATTR_SPAN_X to spanX.toString(),
+ ATTR_SPAN_Y to spanY.toString()
+ )
+ )
+
+ fun putFolder(titleResId: Int) = putFolder(ATTR_TITLE, titleResId.toString())
+
+ fun putFolder(title: String?) = putFolder(ATTR_TITLE_TEXT, title)
+
+ protected open fun addItem(
+ tag: String,
+ userType: String?,
+ props: Map<String, String>,
+ children: List<Node>? = null
+ ): LauncherLayoutBuilder {
+ nodes.add(
+ Node(
+ tag,
+ HashMap(baseValues).apply {
+ putAll(props)
+ userType?.let { put(ATTR_USER_TYPE, it) }
+ },
+ children
+ )
+ )
+ return this@LauncherLayoutBuilder
+ }
+
+ protected open fun putFolder(titleKey: String, titleValue: String?): FolderBuilder {
+ val folderBuilder = FolderBuilder()
+ addItem(TAG_FOLDER, null, mapOf(titleKey to (titleValue ?: "")), folderBuilder.children)
+ return folderBuilder
+ }
+ }
+
+ inner class FolderBuilder : ItemTarget(mapOf()) {
+
+ val children = ArrayList<Node>()
+
+ fun addApp(packageName: String, className: String?): FolderBuilder {
+ putApp(packageName, className)
+ return this
+ }
+
+ fun addShortcut(packageName: String, shortcutId: String): FolderBuilder {
+ putShortcut(packageName, shortcutId)
+ return this
+ }
+
+ override fun addItem(
+ tag: String,
+ userType: String?,
+ props: Map<String, String>,
+ childrenIgnored: List<Node>?
+ ): LauncherLayoutBuilder {
+ children.add(
+ Node(tag, HashMap(props).apply { userType?.let { put(ATTR_USER_TYPE, it) } })
+ )
+ return this@LauncherLayoutBuilder
+ }
+
+ override fun putFolder(titleKey: String, titleValue: String?): FolderBuilder {
+ throw IllegalArgumentException("Can't have folder inside a folder")
+ }
+
+ fun build() = this@LauncherLayoutBuilder
+ }
+
+ @Throws(IOException::class)
+ private fun XmlSerializer.writeNodes(nodes: List<Node>) {
+ nodes.forEach { node ->
+ startTag(null, node.name)
+ node.attrs.forEach { (key, value) -> attribute(null, key, value) }
+ node.children?.let { writeNodes(it) }
+ endTag(null, node.name)
+ }
+ }
+
+ data class Node(
+ val name: String,
+ val attrs: Map<String, String>,
+ val children: List<Node>? = null
+ )
+}
diff --git a/src/com/android/launcher3/util/LogConfig.java b/src/com/android/launcher3/util/LogConfig.java
index d59c339..3d4b409 100644
--- a/src/com/android/launcher3/util/LogConfig.java
+++ b/src/com/android/launcher3/util/LogConfig.java
@@ -70,4 +70,10 @@
* When turned on, we enable long press nav handle related logging.
*/
public static final String NAV_HANDLE_LONG_PRESS = "NavHandleLongPress";
+
+
+ /**
+ * When turned on, we enable zero state web data loader related logging.
+ */
+ public static final String ZERO_WEB_DATA_LOADER = "ZeroStateWebDataLoaderLog";
}
diff --git a/src/com/android/launcher3/util/rects/Rects.kt b/src/com/android/launcher3/util/rects/Rects.kt
new file mode 100644
index 0000000..ac1f3f8
--- /dev/null
+++ b/src/com/android/launcher3/util/rects/Rects.kt
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2024 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.util.rects
+
+import android.graphics.Rect
+import android.view.View
+
+/** Copy the coordinates of the [view] relative to its parent into this rectangle. */
+fun Rect.set(view: View) {
+ set(view.left, view.top, view.right, view.bottom)
+}
diff --git a/src/com/android/launcher3/widget/picker/WidgetRecommendationCategoryProvider.java b/src/com/android/launcher3/widget/picker/WidgetRecommendationCategoryProvider.java
index 80bda22..9253b37 100644
--- a/src/com/android/launcher3/widget/picker/WidgetRecommendationCategoryProvider.java
+++ b/src/com/android/launcher3/widget/picker/WidgetRecommendationCategoryProvider.java
@@ -64,14 +64,11 @@
Preconditions.assertWorkerThread();
try (PackageManagerHelper pmHelper = new PackageManagerHelper(context)) {
if (item.widgetInfo != null && item.widgetInfo.getComponent() != null) {
- String widgetComponentName = item.widgetInfo.getComponent().getClassName();
ApplicationInfo applicationInfo = pmHelper.getApplicationInfo(
item.widgetInfo.getComponent().getPackageName(), item.widgetInfo.getUser(),
0 /* flags */);
if (applicationInfo != null) {
- int predictionCategory = applicationInfo.category;
- return getCategoryFromApplicationCategory(context, predictionCategory,
- widgetComponentName);
+ return getCategoryFromApplicationCategory(applicationInfo.category);
}
}
}
@@ -80,29 +77,7 @@
/** Maps application category to an appropriate displayable category. */
private static WidgetRecommendationCategory getCategoryFromApplicationCategory(
- Context context, int applicationCategory, String componentName) {
- // Weather categories don't map to a specific application category, so, we maintain an
- // allowlist.
- String[] weatherRecommendationAllowlist =
- context.getResources().getStringArray(R.array.weather_recommendations);
- for (String allowedWeatherComponentName : weatherRecommendationAllowlist) {
- if (componentName.equalsIgnoreCase(allowedWeatherComponentName)) {
- return new WidgetRecommendationCategory(
- R.string.weather_widget_recommendation_category_label, /*order=*/3);
- }
- }
-
- // Fitness categories don't map to a specific application category, so, we maintain an
- // allowlist.
- String[] fitnessRecommendationAllowlist =
- context.getResources().getStringArray(R.array.fitness_recommendations);
- for (String allowedFitnessComponentName : fitnessRecommendationAllowlist) {
- if (componentName.equalsIgnoreCase(allowedFitnessComponentName)) {
- return new WidgetRecommendationCategory(
- R.string.fitness_widget_recommendation_category_label, /*order=*/2);
- }
- }
-
+ int applicationCategory) {
if (applicationCategory == ApplicationInfo.CATEGORY_PRODUCTIVITY) {
return new WidgetRecommendationCategory(
R.string.productivity_widget_recommendation_category_label, /*order=*/0);
@@ -116,7 +91,7 @@
if (applicationCategory == ApplicationInfo.CATEGORY_SOCIAL) {
return new WidgetRecommendationCategory(
R.string.social_widget_recommendation_category_label,
- /*order=*/5);
+ /*order=*/3);
}
if (applicationCategory == ApplicationInfo.CATEGORY_AUDIO
@@ -124,11 +99,10 @@
|| applicationCategory == ApplicationInfo.CATEGORY_IMAGE) {
return new WidgetRecommendationCategory(
R.string.entertainment_widget_recommendation_category_label,
- /*order=*/6);
+ /*order=*/4);
}
return new WidgetRecommendationCategory(
- R.string.others_widget_recommendation_category_label, /*order=*/4);
+ R.string.others_widget_recommendation_category_label, /*order=*/2);
}
-
}
diff --git a/tests/AndroidManifest-common.xml b/tests/AndroidManifest-common.xml
index 8c5195e..4b926a8 100644
--- a/tests/AndroidManifest-common.xml
+++ b/tests/AndroidManifest-common.xml
@@ -407,7 +407,7 @@
</intent-filter>
</activity>
- <!-- [b/197780098] Disable eager initialization of Jetpack libraries. -->
+ <!-- Disable eager initialization of Jetpack libraries. See bug 197780098. -->
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
diff --git a/tests/multivalentTests/src/com/android/launcher3/AutoInstallsLayoutTest.kt b/tests/multivalentTests/src/com/android/launcher3/AutoInstallsLayoutTest.kt
new file mode 100644
index 0000000..b04bcca
--- /dev/null
+++ b/tests/multivalentTests/src/com/android/launcher3/AutoInstallsLayoutTest.kt
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) 2024 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
+
+import android.content.ComponentName
+import android.content.ContentValues
+import android.database.sqlite.SQLiteDatabase
+import android.os.Process.myUserHandle
+import android.os.UserHandle
+import android.util.Xml
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.launcher3.AutoInstallsLayout.LayoutParserCallback
+import com.android.launcher3.AutoInstallsLayout.SourceResources
+import com.android.launcher3.AutoInstallsLayout.TAG_WORKSPACE
+import com.android.launcher3.AutoInstallsLayout.USER_TYPE_WORK
+import com.android.launcher3.LauncherSettings.Favorites.APPWIDGET_PROVIDER
+import com.android.launcher3.LauncherSettings.Favorites.CONTAINER
+import com.android.launcher3.LauncherSettings.Favorites.CONTAINER_DESKTOP
+import com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT
+import com.android.launcher3.LauncherSettings.Favorites.INTENT
+import com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE
+import com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPLICATION
+import com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET
+import com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_FOLDER
+import com.android.launcher3.LauncherSettings.Favorites.PROFILE_ID
+import com.android.launcher3.LauncherSettings.Favorites.SPANX
+import com.android.launcher3.LauncherSettings.Favorites.SPANY
+import com.android.launcher3.LauncherSettings.Favorites._ID
+import com.android.launcher3.model.data.AppInfo
+import com.android.launcher3.pm.UserCache
+import com.android.launcher3.util.ApiWrapper
+import com.android.launcher3.util.Executors
+import com.android.launcher3.util.LauncherLayoutBuilder
+import com.android.launcher3.util.LauncherModelHelper
+import com.android.launcher3.util.LauncherModelHelper.SandboxModelContext
+import com.android.launcher3.util.TestUtil
+import com.android.launcher3.util.UserIconInfo
+import com.android.launcher3.util.UserIconInfo.TYPE_MAIN
+import com.android.launcher3.util.UserIconInfo.TYPE_WORK
+import com.android.launcher3.widget.LauncherWidgetHolder
+import com.google.common.truth.Truth.assertThat
+import java.io.StringReader
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.spy
+import org.mockito.kotlin.whenever
+
+/** Tests for [AutoInstallsLayout] */
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class AutoInstallsLayoutTest {
+
+ lateinit var modelHelper: LauncherModelHelper
+ lateinit var targetContext: SandboxModelContext
+
+ lateinit var callback: MyCallback
+
+ @Mock lateinit var widgetHolder: LauncherWidgetHolder
+ @Mock lateinit var db: SQLiteDatabase
+
+ @Before
+ fun setup() {
+ MockitoAnnotations.initMocks(this)
+ modelHelper = LauncherModelHelper()
+ targetContext = modelHelper.sandboxContext
+ callback = MyCallback()
+ }
+
+ @After
+ fun tearDown() {
+ modelHelper.destroy()
+ }
+
+ @Test
+ fun pending_icon_added_on_home() {
+ LauncherLayoutBuilder()
+ .atWorkspace(1, 1, 0)
+ .putApp("p1", "c1")
+ .toAutoInstallsLayout()
+ .loadLayout(db)
+
+ assertThat(callback.items.size).isEqualTo(1)
+ assertThat(callback.items[0][ITEM_TYPE]).isEqualTo(ITEM_TYPE_APPLICATION)
+ assertThat(callback.items[0][INTENT])
+ .isEqualTo(AppInfo.makeLaunchIntent(ComponentName("p1", "c1")).toUri(0))
+ assertThat(callback.items[0][CONTAINER]).isEqualTo(CONTAINER_DESKTOP)
+ assertThat(callback.items[0].containsKey(PROFILE_ID)).isFalse()
+ }
+
+ @Test
+ fun pending_icon_added_on_hotseat() {
+ LauncherLayoutBuilder()
+ .atHotseat(1)
+ .putApp("p1", "c1")
+ .toAutoInstallsLayout()
+ .loadLayout(db)
+
+ assertThat(callback.items.size).isEqualTo(1)
+ assertThat(callback.items[0][ITEM_TYPE]).isEqualTo(ITEM_TYPE_APPLICATION)
+ assertThat(callback.items[0][CONTAINER]).isEqualTo(CONTAINER_HOTSEAT)
+ }
+
+ @Test
+ fun widget_added_to_home() {
+ LauncherLayoutBuilder()
+ .atWorkspace(1, 1, 0)
+ .putWidget("p1", "c1", 2, 3)
+ .toAutoInstallsLayout()
+ .loadLayout(db)
+
+ assertThat(callback.items.size).isEqualTo(1)
+ assertThat(callback.items[0][ITEM_TYPE]).isEqualTo(ITEM_TYPE_APPWIDGET)
+ assertThat(callback.items[0][CONTAINER]).isEqualTo(CONTAINER_DESKTOP)
+ assertThat(callback.items[0][APPWIDGET_PROVIDER])
+ .isEqualTo(ComponentName("p1", "c1").flattenToString())
+ assertThat(callback.items[0][SPANX]).isEqualTo(2.toString())
+ assertThat(callback.items[0][SPANY]).isEqualTo(3.toString())
+ }
+
+ @Test
+ fun items_added_to_folder() {
+ LauncherLayoutBuilder()
+ .atHotseat(1)
+ .putFolder("Test")
+ .addApp("p1", "c")
+ .addApp("p2", "c")
+ .addApp("p3", "c")
+ .build()
+ .toAutoInstallsLayout()
+ .loadLayout(db)
+
+ assertThat(callback.items.size).isEqualTo(4)
+ assertThat(callback.items[0][ITEM_TYPE]).isEqualTo(ITEM_TYPE_FOLDER)
+ assertThat(callback.items[0][CONTAINER]).isEqualTo(CONTAINER_HOTSEAT)
+
+ val folderId = callback.items[0][_ID]
+ assertThat(callback.items[1][CONTAINER]).isEqualTo(folderId)
+ assertThat(callback.items[2][CONTAINER]).isEqualTo(folderId)
+ assertThat(callback.items[3][CONTAINER]).isEqualTo(folderId)
+ }
+
+ @Test
+ fun work_item_added_to_home() {
+ val apiWrapperMock = spy(ApiWrapper.INSTANCE[targetContext])
+ targetContext.putObject(ApiWrapper.INSTANCE, apiWrapperMock)
+ doReturn(
+ mapOf(
+ myUserHandle() to UserIconInfo(myUserHandle(), TYPE_MAIN, 0),
+ UserHandle.of(20) to UserIconInfo(UserHandle.of(20), TYPE_WORK, 20),
+ )
+ )
+ .whenever(apiWrapperMock)
+ .queryAllUsers()
+
+ val cache = UserCache.getInstance(targetContext)
+ TestUtil.runOnExecutorSync(Executors.MODEL_EXECUTOR) {
+ assertThat(cache.userProfiles.size).isEqualTo(2)
+ }
+
+ LauncherLayoutBuilder()
+ .atWorkspace(1, 1, 0)
+ .putApp("p1", "c1", USER_TYPE_WORK)
+ .toAutoInstallsLayout()
+ .loadLayout(db)
+
+ assertThat(callback.items.size).isEqualTo(1)
+ assertThat(callback.items[0][ITEM_TYPE]).isEqualTo(ITEM_TYPE_APPLICATION)
+ assertThat(callback.items[0][INTENT])
+ .isEqualTo(AppInfo.makeLaunchIntent(ComponentName("p1", "c1")).toUri(0))
+ assertThat(callback.items[0][CONTAINER]).isEqualTo(CONTAINER_DESKTOP)
+ assertThat(callback.items[0][PROFILE_ID]).isEqualTo(20)
+ }
+
+ private fun LauncherLayoutBuilder.toAutoInstallsLayout() =
+ AutoInstallsLayout(
+ targetContext,
+ widgetHolder,
+ callback,
+ SourceResources.wrap(targetContext.resources),
+ { Xml.newPullParser().also { it.setInput(StringReader(build())) } },
+ TAG_WORKSPACE
+ )
+
+ class MyCallback : LayoutParserCallback {
+
+ val items = ArrayList<ContentValues>()
+
+ override fun generateNewItemId() = items.size
+
+ override fun insertAndCheck(db: SQLiteDatabase?, values: ContentValues): Int {
+ val id = values[_ID]
+ items.add(ContentValues(values))
+ return if (id is Int) id else 0
+ }
+ }
+}
diff --git a/tests/multivalentTests/src/com/android/launcher3/util/LauncherLayoutBuilder.java b/tests/multivalentTests/src/com/android/launcher3/util/LauncherLayoutBuilder.java
deleted file mode 100644
index ba01b04..0000000
--- a/tests/multivalentTests/src/com/android/launcher3/util/LauncherLayoutBuilder.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/**
- * Copyright (C) 2019 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.util;
-
-
-import android.text.TextUtils;
-import android.util.Pair;
-import android.util.Xml;
-
-import org.xmlpull.v1.XmlSerializer;
-
-import java.io.IOException;
-import java.io.StringWriter;
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Helper class to build xml for Launcher Layout
- */
-public class LauncherLayoutBuilder {
-
- // Object Tags
- private static final String TAG_WORKSPACE = "workspace";
- private static final String TAG_AUTO_INSTALL = "autoinstall";
- private static final String TAG_FOLDER = "folder";
- private static final String TAG_APPWIDGET = "appwidget";
- private static final String TAG_SHORTCUT = "shortcut";
- private static final String TAG_EXTRA = "extra";
-
- private static final String ATTR_CONTAINER = "container";
- private static final String ATTR_RANK = "rank";
-
- private static final String ATTR_PACKAGE_NAME = "packageName";
- private static final String ATTR_CLASS_NAME = "className";
- private static final String ATTR_TITLE = "title";
- private static final String ATTR_TITLE_TEXT = "titleText";
- private static final String ATTR_SCREEN = "screen";
- private static final String ATTR_SHORTCUT_ID = "shortcutId";
-
- // x and y can be specified as negative integers, in which case -1 represents the
- // last row / column, -2 represents the second last, and so on.
- private static final String ATTR_X = "x";
- private static final String ATTR_Y = "y";
- private static final String ATTR_SPAN_X = "spanX";
- private static final String ATTR_SPAN_Y = "spanY";
-
- private static final String ATTR_CHILDREN = "children";
-
-
- // Style attrs -- "Extra"
- private static final String ATTR_KEY = "key";
- private static final String ATTR_VALUE = "value";
-
- private static final String CONTAINER_DESKTOP = "desktop";
- private static final String CONTAINER_HOTSEAT = "hotseat";
-
- private final ArrayList<Pair<String, HashMap<String, Object>>> mNodes = new ArrayList<>();
-
- public Location atHotseat(int rank) {
- Location l = new Location();
- l.items.put(ATTR_CONTAINER, CONTAINER_HOTSEAT);
- l.items.put(ATTR_RANK, Integer.toString(rank));
- return l;
- }
-
- public Location atWorkspace(int x, int y, int screen) {
- Location l = new Location();
- l.items.put(ATTR_CONTAINER, CONTAINER_DESKTOP);
- l.items.put(ATTR_X, Integer.toString(x));
- l.items.put(ATTR_Y, Integer.toString(y));
- l.items.put(ATTR_SCREEN, Integer.toString(screen));
- return l;
- }
-
- public String build() throws IOException {
- StringWriter writer = new StringWriter();
- build(writer);
- return writer.toString();
- }
-
- public void build(Writer writer) throws IOException {
- XmlSerializer serializer = Xml.newSerializer();
- serializer.setOutput(writer);
-
- serializer.startDocument("UTF-8", true);
- serializer.startTag(null, TAG_WORKSPACE);
- writeNodes(serializer, mNodes);
- serializer.endTag(null, TAG_WORKSPACE);
- serializer.endDocument();
- serializer.flush();
- }
-
- private static void writeNodes(XmlSerializer serializer,
- ArrayList<Pair<String, HashMap<String, Object>>> nodes) throws IOException {
- for (Pair<String, HashMap<String, Object>> node : nodes) {
- ArrayList<Pair<String, HashMap<String, Object>>> children = null;
-
- serializer.startTag(null, node.first);
- for (Map.Entry<String, Object> attr : node.second.entrySet()) {
- if (ATTR_CHILDREN.equals(attr.getKey())) {
- children = (ArrayList<Pair<String, HashMap<String, Object>>>) attr.getValue();
- } else {
- serializer.attribute(null, attr.getKey(), (String) attr.getValue());
- }
- }
-
- if (children != null) {
- writeNodes(serializer, children);
- }
- serializer.endTag(null, node.first);
- }
- }
-
- public class Location {
-
- final HashMap<String, Object> items = new HashMap<>();
-
- public LauncherLayoutBuilder putApp(String packageName, String className) {
- items.put(ATTR_PACKAGE_NAME, packageName);
- items.put(ATTR_CLASS_NAME, TextUtils.isEmpty(className) ? packageName : className);
- mNodes.add(Pair.create(TAG_AUTO_INSTALL, items));
- return LauncherLayoutBuilder.this;
- }
-
- public LauncherLayoutBuilder putShortcut(String packageName, String shortcutId) {
- items.put(ATTR_PACKAGE_NAME, packageName);
- items.put(ATTR_SHORTCUT_ID, shortcutId);
- mNodes.add(Pair.create(TAG_SHORTCUT, items));
- return LauncherLayoutBuilder.this;
- }
-
- public LauncherLayoutBuilder putWidget(String packageName, String className,
- int spanX, int spanY) {
- items.put(ATTR_PACKAGE_NAME, packageName);
- items.put(ATTR_CLASS_NAME, className);
- items.put(ATTR_SPAN_X, Integer.toString(spanX));
- items.put(ATTR_SPAN_Y, Integer.toString(spanY));
- mNodes.add(Pair.create(TAG_APPWIDGET, items));
- return LauncherLayoutBuilder.this;
- }
-
- public FolderBuilder putFolder(int titleResId) {
- items.put(ATTR_TITLE, Integer.toString(titleResId));
- return putFolder();
- }
-
- public FolderBuilder putFolder(String title) {
- items.put(ATTR_TITLE_TEXT, title);
- return putFolder();
- }
-
- private FolderBuilder putFolder() {
- FolderBuilder folderBuilder = new FolderBuilder();
- items.put(ATTR_CHILDREN, folderBuilder.mChildren);
- mNodes.add(Pair.create(TAG_FOLDER, items));
- return folderBuilder;
- }
- }
-
- public class FolderBuilder {
-
- final ArrayList<Pair<String, HashMap<String, Object>>> mChildren = new ArrayList<>();
-
- public FolderBuilder addApp(String packageName, String className) {
- HashMap<String, Object> items = new HashMap<>();
- items.put(ATTR_PACKAGE_NAME, packageName);
- items.put(ATTR_CLASS_NAME, TextUtils.isEmpty(className) ? packageName : className);
- mChildren.add(Pair.create(TAG_AUTO_INSTALL, items));
- return this;
- }
-
- public FolderBuilder addShortcut(String packageName, String shortcutId) {
- HashMap<String, Object> items = new HashMap<>();
- items.put(ATTR_PACKAGE_NAME, packageName);
- items.put(ATTR_SHORTCUT_ID, shortcutId);
- mChildren.add(Pair.create(TAG_SHORTCUT, items));
- return this;
- }
-
- public LauncherLayoutBuilder build() {
- return LauncherLayoutBuilder.this;
- }
- }
-}
diff --git a/tests/src/com/android/launcher3/FakeInvariantDeviceProfileTest.kt b/tests/src/com/android/launcher3/FakeInvariantDeviceProfileTest.kt
index 13d7499..0538870 100644
--- a/tests/src/com/android/launcher3/FakeInvariantDeviceProfileTest.kt
+++ b/tests/src/com/android/launcher3/FakeInvariantDeviceProfileTest.kt
@@ -46,7 +46,7 @@
@IgnoreLimit(ignoreLimit = BuildConfig.IS_STUDIO_BUILD)
abstract class FakeInvariantDeviceProfileTest {
- protected var context: Context? = null
+ protected lateinit var context: Context
protected var inv: InvariantDeviceProfile? = null
protected val info: Info = mock()
protected var windowBounds: WindowBounds? = null
@@ -257,10 +257,10 @@
}
protected fun initializeVarsForTwoPanel(
- isLandscape: Boolean = false,
- isGestureMode: Boolean = true,
- rows: Int = 4,
- cols: Int = 4,
+ isLandscape: Boolean = false,
+ isGestureMode: Boolean = true,
+ rows: Int = 4,
+ cols: Int = 4,
) {
val (x, y) = if (isLandscape) Pair(2208, 1840) else Pair(1840, 2208)
diff --git a/tests/src/com/android/launcher3/allapps/TaplKeyboardFocusTest.java b/tests/src/com/android/launcher3/allapps/TaplKeyboardFocusTest.java
index 20684eb..4e627a9 100644
--- a/tests/src/com/android/launcher3/allapps/TaplKeyboardFocusTest.java
+++ b/tests/src/com/android/launcher3/allapps/TaplKeyboardFocusTest.java
@@ -75,7 +75,6 @@
}
@Test
- @TestStabilityRule.Stability(flavors = LOCAL | PLATFORM_POSTSUBMIT) // b/311410127
public void testAllAppsExitSearchAndFocusSearchResults() {
final HomeAllApps allApps = mLauncher.goHome().switchToAllApps();
assertTrue("Launcher internal state is not All Apps",
diff --git a/tests/src/com/android/launcher3/ui/widget/TaplAddWidgetTest.java b/tests/src/com/android/launcher3/ui/widget/TaplAddWidgetTest.java
index 9dbd866..9b184ae 100644
--- a/tests/src/com/android/launcher3/ui/widget/TaplAddWidgetTest.java
+++ b/tests/src/com/android/launcher3/ui/widget/TaplAddWidgetTest.java
@@ -32,7 +32,6 @@
import com.android.launcher3.ui.AbstractLauncherUiTest;
import com.android.launcher3.ui.PortraitLandscapeRunner.PortraitLandscape;
import com.android.launcher3.ui.TestViewHelpers;
-import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord;
import com.android.launcher3.util.rule.ShellCommandRule;
import com.android.launcher3.util.rule.TestStabilityRule.Stability;
import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
@@ -54,7 +53,6 @@
@Test
@PortraitLandscape
- @ScreenRecord // b/316910614
public void testDragIcon() throws Throwable {
mLauncher.enableDebugTracing(); // b/289161193
commitTransactionAndLoadHome(new FavoriteItemsTransaction(mTargetContext));
@@ -107,7 +105,6 @@
@Stability(flavors = LOCAL | PLATFORM_POSTSUBMIT) // b/316910614
@PlatinumTest(focusArea = "launcher")
@Test
- @ScreenRecord // b/316910614
public void testResizeWidget() throws Throwable {
commitTransactionAndLoadHome(new FavoriteItemsTransaction(mTargetContext));
diff --git a/tests/src/com/android/launcher3/widget/picker/WidgetRecommendationCategoryProviderTest.java b/tests/src/com/android/launcher3/widget/picker/WidgetRecommendationCategoryProviderTest.java
index 60a4cd3..7476454 100644
--- a/tests/src/com/android/launcher3/widget/picker/WidgetRecommendationCategoryProviderTest.java
+++ b/tests/src/com/android/launcher3/widget/picker/WidgetRecommendationCategoryProviderTest.java
@@ -79,15 +79,15 @@
R.string.news_widget_recommendation_category_label, /*order=*/1);
private static final WidgetRecommendationCategory SUGGESTED_FOR_YOU =
new WidgetRecommendationCategory(
- R.string.others_widget_recommendation_category_label, /*order=*/4);
+ R.string.others_widget_recommendation_category_label, /*order=*/2);
private static final WidgetRecommendationCategory SOCIAL =
new WidgetRecommendationCategory(
R.string.social_widget_recommendation_category_label,
- /*order=*/5);
+ /*order=*/3);
private static final WidgetRecommendationCategory ENTERTAINMENT =
new WidgetRecommendationCategory(
R.string.entertainment_widget_recommendation_category_label,
- /*order=*/6);
+ /*order=*/4);
private final ApplicationInfo mTestAppInfo = ApplicationInfoBuilder.newBuilder().setPackageName(
TEST_PACKAGE).setName(TEST_APP_NAME).build();