summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
Diffstat (limited to 'libs')
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java168
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java17
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java16
-rw-r--r--libs/WindowManager/Shell/res/color/tv_pip_menu_close_icon.xml19
-rw-r--r--libs/WindowManager/Shell/res/color/tv_pip_menu_close_icon_bg.xml21
-rw-r--r--libs/WindowManager/Shell/res/values-af/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-am/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-ar/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-as/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-az/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-b+sr+Latn/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-be/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-bg/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-bn/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-bs/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-ca/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-ca/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-cs/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-da/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-de/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-el/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-en-rAU/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-en-rCA/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-en-rGB/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-en-rIN/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-en-rXC/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-es-rUS/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-es/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-et/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-eu/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-fa/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-fi/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-fr-rCA/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-fr/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-gl/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-gu/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-hi/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-hr/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-hu/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-hy/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-in/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-is/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-it/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-iw/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-ja/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-ka/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-kk/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-km/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-kn/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-ko/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-ky/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-lo/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-lt/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-lv/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-mk/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-ml/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-mn/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-mr/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-ms/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-my/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-nb/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-ne/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-nl/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-or/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-pa/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-pl/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-pt-rBR/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-pt-rPT/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-pt/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-ro/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-ru/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-si/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-sk/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-sl/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-sq/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-sr/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-sv/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-sw/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-ta/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-te/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-television/config.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-th/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-tl/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-tr/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-uk/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-ur/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-uz/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-vi/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-zh-rCN/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-zh-rHK/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-zh-rTW/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-zu/strings_tv.xml1
-rw-r--r--libs/WindowManager/Shell/res/values/colors_tv.xml4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java8
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java9
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduWindowManager.java14
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java6
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizer.java8
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PinnedStackListenerForwarder.java13
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipMenuController.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java24
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java11
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java3
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java8
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java59
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuActionButton.java11
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuController.java128
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuView.java103
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipNotificationController.java12
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java20
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenIconDrawableFactory.java23
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java6
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java29
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduWindowManagerTest.java103
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizerTest.java8
117 files changed, 683 insertions, 265 deletions
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
index 2aa695346c89..418ff0e7263a 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
@@ -37,6 +37,7 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
+import android.util.SparseArray;
import android.window.TaskFragmentInfo;
import android.window.WindowContainerTransaction;
@@ -58,14 +59,20 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
// Currently applied split configuration.
private final List<EmbeddingRule> mSplitRules = new ArrayList<>();
- private final List<TaskFragmentContainer> mContainers = new ArrayList<>();
- private final List<SplitContainer> mSplitContainers = new ArrayList<>();
+ /**
+ * Map from Task id to {@link TaskContainer} which contains all TaskFragment and split pair info
+ * below it.
+ * When the app is host of multiple Tasks, there can be multiple splits controlled by the same
+ * organizer.
+ */
+ private final SparseArray<TaskContainer> mTaskContainers = new SparseArray<>();
// Callback to Jetpack to notify about changes to split states.
private @NonNull Consumer<List<SplitInfo>> mEmbeddingCallback;
private final List<SplitInfo> mLastReportedSplitStates = new ArrayList<>();
// We currently only support split activity embedding within the one root Task.
+ // TODO(b/207720388): move to TaskContainer
private final Rect mParentBounds = new Rect();
public SplitController() {
@@ -244,7 +251,8 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
mPresenter.expandTaskFragment(currentContainer.getTaskFragmentToken());
} else {
// Put activity into a new expanded container
- final TaskFragmentContainer newContainer = newContainer(launchedActivity);
+ final TaskFragmentContainer newContainer = newContainer(launchedActivity,
+ launchedActivity.getTaskId());
mPresenter.expandActivity(newContainer.getTaskFragmentToken(),
launchedActivity);
}
@@ -327,12 +335,14 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
*/
@Nullable
TaskFragmentContainer getContainerWithActivity(@NonNull IBinder activityToken) {
- for (TaskFragmentContainer container : mContainers) {
- if (container.hasActivity(activityToken)) {
- return container;
+ for (int i = mTaskContainers.size() - 1; i >= 0; i--) {
+ final List<TaskFragmentContainer> containers = mTaskContainers.valueAt(i).mContainers;
+ for (TaskFragmentContainer container : containers) {
+ if (container.hasActivity(activityToken)) {
+ return container;
+ }
}
}
-
return null;
}
@@ -340,9 +350,12 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
* Creates and registers a new organized container with an optional activity that will be
* re-parented to it in a WCT.
*/
- TaskFragmentContainer newContainer(@Nullable Activity activity) {
- TaskFragmentContainer container = new TaskFragmentContainer(activity);
- mContainers.add(container);
+ TaskFragmentContainer newContainer(@Nullable Activity activity, int taskId) {
+ final TaskFragmentContainer container = new TaskFragmentContainer(activity, taskId);
+ if (!mTaskContainers.contains(taskId)) {
+ mTaskContainers.put(taskId, new TaskContainer());
+ }
+ mTaskContainers.get(taskId).mContainers.add(container);
return container;
}
@@ -354,13 +367,13 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
@NonNull TaskFragmentContainer primaryContainer, @NonNull Activity primaryActivity,
@NonNull TaskFragmentContainer secondaryContainer,
@NonNull SplitRule splitRule) {
- SplitContainer splitContainer = new SplitContainer(primaryContainer, primaryActivity,
+ final SplitContainer splitContainer = new SplitContainer(primaryContainer, primaryActivity,
secondaryContainer, splitRule);
// Remove container later to prevent pinning escaping toast showing in lock task mode.
if (splitRule instanceof SplitPairRule && ((SplitPairRule) splitRule).shouldClearTop()) {
removeExistingSecondaryContainers(wct, primaryContainer);
}
- mSplitContainers.add(splitContainer);
+ mTaskContainers.get(primaryContainer.getTaskId()).mSplitContainers.add(splitContainer);
}
/**
@@ -368,15 +381,26 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
*/
void removeContainer(@NonNull TaskFragmentContainer container) {
// Remove all split containers that included this one
- mContainers.remove(container);
- List<SplitContainer> containersToRemove = new ArrayList<>();
- for (SplitContainer splitContainer : mSplitContainers) {
+ final int taskId = container.getTaskId();
+ final TaskContainer taskContainer = mTaskContainers.get(taskId);
+ if (taskContainer == null) {
+ return;
+ }
+ taskContainer.mContainers.remove(container);
+ if (taskContainer.mContainers.isEmpty()) {
+ mTaskContainers.remove(taskId);
+ // No more TaskFragment in this Task, so no need to check split container.
+ return;
+ }
+
+ final List<SplitContainer> containersToRemove = new ArrayList<>();
+ for (SplitContainer splitContainer : taskContainer.mSplitContainers) {
if (container.equals(splitContainer.getSecondaryContainer())
|| container.equals(splitContainer.getPrimaryContainer())) {
containersToRemove.add(splitContainer);
}
}
- mSplitContainers.removeAll(containersToRemove);
+ taskContainer.mSplitContainers.removeAll(containersToRemove);
}
/**
@@ -399,12 +423,16 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
}
/**
- * Returns the topmost not finished container.
+ * Returns the topmost not finished container in Task of given task id.
*/
@Nullable
- TaskFragmentContainer getTopActiveContainer() {
- for (int i = mContainers.size() - 1; i >= 0; i--) {
- TaskFragmentContainer container = mContainers.get(i);
+ TaskFragmentContainer getTopActiveContainer(int taskId) {
+ final TaskContainer taskContainer = mTaskContainers.get(taskId);
+ if (taskContainer == null) {
+ return null;
+ }
+ for (int i = taskContainer.mContainers.size() - 1; i >= 0; i--) {
+ final TaskFragmentContainer container = taskContainer.mContainers.get(i);
if (!container.isFinished() && container.getRunningActivityCount() > 0) {
return container;
}
@@ -434,7 +462,10 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
if (splitContainer == null) {
return;
}
- if (splitContainer != mSplitContainers.get(mSplitContainers.size() - 1)) {
+ final List<SplitContainer> splitContainers = mTaskContainers.get(container.getTaskId())
+ .mSplitContainers;
+ if (splitContainers == null
+ || splitContainer != splitContainers.get(splitContainers.size() - 1)) {
// Skip position update - it isn't the topmost split.
return;
}
@@ -455,8 +486,13 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
*/
@Nullable
private SplitContainer getActiveSplitForContainer(@NonNull TaskFragmentContainer container) {
- for (int i = mSplitContainers.size() - 1; i >= 0; i--) {
- SplitContainer splitContainer = mSplitContainers.get(i);
+ final List<SplitContainer> splitContainers = mTaskContainers.get(container.getTaskId())
+ .mSplitContainers;
+ if (splitContainers == null) {
+ return null;
+ }
+ for (int i = splitContainers.size() - 1; i >= 0; i--) {
+ final SplitContainer splitContainer = splitContainers.get(i);
if (container.equals(splitContainer.getSecondaryContainer())
|| container.equals(splitContainer.getPrimaryContainer())) {
return splitContainer;
@@ -473,8 +509,13 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
private SplitContainer getActiveSplitForContainers(
@NonNull TaskFragmentContainer firstContainer,
@NonNull TaskFragmentContainer secondContainer) {
- for (int i = mSplitContainers.size() - 1; i >= 0; i--) {
- SplitContainer splitContainer = mSplitContainers.get(i);
+ final List<SplitContainer> splitContainers = mTaskContainers.get(firstContainer.getTaskId())
+ .mSplitContainers;
+ if (splitContainers == null) {
+ return null;
+ }
+ for (int i = splitContainers.size() - 1; i >= 0; i--) {
+ final SplitContainer splitContainer = splitContainers.get(i);
final TaskFragmentContainer primary = splitContainer.getPrimaryContainer();
final TaskFragmentContainer secondary = splitContainer.getSecondaryContainer();
if ((firstContainer == secondary && secondContainer == primary)
@@ -501,7 +542,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
final TaskFragmentContainer container = getContainerWithActivity(
activity.getActivityToken());
// Don't launch placeholder if the container is occluded.
- if (container != null && container != getTopActiveContainer()) {
+ if (container != null && container != getTopActiveContainer(container.getTaskId())) {
return false;
}
@@ -588,24 +629,30 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
@Nullable
private List<SplitInfo> getActiveSplitStates() {
List<SplitInfo> splitStates = new ArrayList<>();
- for (SplitContainer container : mSplitContainers) {
- if (container.getPrimaryContainer().isEmpty()
- || container.getSecondaryContainer().isEmpty()) {
- // We are in an intermediate state because either the split container is about to be
- // removed or the primary or secondary container are about to receive an activity.
- return null;
+ for (int i = mTaskContainers.size() - 1; i >= 0; i--) {
+ final List<SplitContainer> splitContainers = mTaskContainers.valueAt(i)
+ .mSplitContainers;
+ for (SplitContainer container : splitContainers) {
+ if (container.getPrimaryContainer().isEmpty()
+ || container.getSecondaryContainer().isEmpty()) {
+ // We are in an intermediate state because either the split container is about
+ // to be removed or the primary or secondary container are about to receive an
+ // activity.
+ return null;
+ }
+ final ActivityStack primaryContainer = container.getPrimaryContainer()
+ .toActivityStack();
+ final ActivityStack secondaryContainer = container.getSecondaryContainer()
+ .toActivityStack();
+ final SplitInfo splitState = new SplitInfo(primaryContainer, secondaryContainer,
+ // Splits that are not showing side-by-side are reported as having 0 split
+ // ratio, since by definition in the API the primary container occupies no
+ // width of the split when covered by the secondary.
+ mPresenter.shouldShowSideBySide(container)
+ ? container.getSplitRule().getSplitRatio()
+ : 0.0f);
+ splitStates.add(splitState);
}
- ActivityStack primaryContainer = container.getPrimaryContainer().toActivityStack();
- ActivityStack secondaryContainer = container.getSecondaryContainer().toActivityStack();
- SplitInfo splitState = new SplitInfo(primaryContainer,
- secondaryContainer,
- // Splits that are not showing side-by-side are reported as having 0 split
- // ratio, since by definition in the API the primary container occupies no
- // width of the split when covered by the secondary.
- mPresenter.shouldShowSideBySide(container)
- ? container.getSplitRule().getSplitRatio()
- : 0.0f);
- splitStates.add(splitState);
}
return splitStates;
}
@@ -615,11 +662,14 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
* the client.
*/
private boolean allActivitiesCreated() {
- for (TaskFragmentContainer container : mContainers) {
- if (container.getInfo() == null
- || container.getInfo().getActivities().size()
- != container.collectActivities().size()) {
- return false;
+ for (int i = mTaskContainers.size() - 1; i >= 0; i--) {
+ final List<TaskFragmentContainer> containers = mTaskContainers.valueAt(i).mContainers;
+ for (TaskFragmentContainer container : containers) {
+ if (container.getInfo() == null
+ || container.getInfo().getActivities().size()
+ != container.collectActivities().size()) {
+ return false;
+ }
}
}
return true;
@@ -633,7 +683,12 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
if (container == null) {
return false;
}
- for (SplitContainer splitContainer : mSplitContainers) {
+ final List<SplitContainer> splitContainers = mTaskContainers.get(container.getTaskId())
+ .mSplitContainers;
+ if (splitContainers == null) {
+ return true;
+ }
+ for (SplitContainer splitContainer : splitContainers) {
if (container.equals(splitContainer.getPrimaryContainer())
|| container.equals(splitContainer.getSecondaryContainer())) {
return false;
@@ -684,9 +739,12 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
@Nullable
TaskFragmentContainer getContainer(@NonNull IBinder fragmentToken) {
- for (TaskFragmentContainer container : mContainers) {
- if (container.getTaskFragmentToken().equals(fragmentToken)) {
- return container;
+ for (int i = mTaskContainers.size() - 1; i >= 0; i--) {
+ final List<TaskFragmentContainer> containers = mTaskContainers.valueAt(i).mContainers;
+ for (TaskFragmentContainer container : containers) {
+ if (container.getTaskFragmentToken().equals(fragmentToken)) {
+ return container;
+ }
}
}
return null;
@@ -969,4 +1027,10 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
// Not reuse if it needs to destroy the existing.
return !pairRule.shouldClearTop();
}
+
+ /** Represents TaskFragments and split pairs below a Task. */
+ private static class TaskContainer {
+ final List<TaskFragmentContainer> mContainers = new ArrayList<>();
+ final List<SplitContainer> mSplitContainers = new ArrayList<>();
+ }
}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
index ade573132eef..e7552ff48d52 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
@@ -80,7 +80,8 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
container.finish(shouldFinishDependent, this, wct, mController);
- final TaskFragmentContainer newTopContainer = mController.getTopActiveContainer();
+ final TaskFragmentContainer newTopContainer = mController.getTopActiveContainer(
+ container.getTaskId());
if (newTopContainer != null) {
mController.updateContainer(wct, newTopContainer);
}
@@ -103,7 +104,8 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
primaryActivity, primaryRectBounds, null);
// Create new empty task fragment
- final TaskFragmentContainer secondaryContainer = mController.newContainer(null);
+ final TaskFragmentContainer secondaryContainer = mController.newContainer(null,
+ primaryContainer.getTaskId());
final Rect secondaryRectBounds = getBoundsForPosition(POSITION_END, parentBounds,
rule, isLtr(primaryActivity, rule));
createTaskFragment(wct, secondaryContainer.getTaskFragmentToken(),
@@ -159,7 +161,8 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
* Creates a new expanded container.
*/
TaskFragmentContainer createNewExpandedContainer(@NonNull Activity launchingActivity) {
- final TaskFragmentContainer newContainer = mController.newContainer(null);
+ final TaskFragmentContainer newContainer = mController.newContainer(null,
+ launchingActivity.getTaskId());
final WindowContainerTransaction wct = new WindowContainerTransaction();
createTaskFragment(wct, newContainer.getTaskFragmentToken(),
@@ -180,7 +183,7 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
TaskFragmentContainer container = mController.getContainerWithActivity(
activity.getActivityToken());
if (container == null || container == containerToAvoid) {
- container = mController.newContainer(activity);
+ container = mController.newContainer(activity, activity.getTaskId());
final TaskFragmentCreationParams fragmentOptions =
createFragmentOptions(
@@ -222,10 +225,12 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
TaskFragmentContainer primaryContainer = mController.getContainerWithActivity(
launchingActivity.getActivityToken());
if (primaryContainer == null) {
- primaryContainer = mController.newContainer(launchingActivity);
+ primaryContainer = mController.newContainer(launchingActivity,
+ launchingActivity.getTaskId());
}
- TaskFragmentContainer secondaryContainer = mController.newContainer(null);
+ TaskFragmentContainer secondaryContainer = mController.newContainer(null,
+ primaryContainer.getTaskId());
final WindowContainerTransaction wct = new WindowContainerTransaction();
mController.registerSplit(wct, primaryContainer, launchingActivity, secondaryContainer,
rule);
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
index 4d2d0551d828..e49af41d4eac 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
@@ -16,6 +16,8 @@
package androidx.window.extensions.embedding;
+import static android.app.ActivityTaskManager.INVALID_TASK_ID;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.Activity;
@@ -41,6 +43,9 @@ class TaskFragmentContainer {
@NonNull
private final IBinder mToken;
+ /** Parent leaf Task id. */
+ private final int mTaskId;
+
/**
* Server-provided task fragment information.
*/
@@ -71,8 +76,12 @@ class TaskFragmentContainer {
* Creates a container with an existing activity that will be re-parented to it in a window
* container transaction.
*/
- TaskFragmentContainer(@Nullable Activity activity) {
+ TaskFragmentContainer(@Nullable Activity activity, int taskId) {
mToken = new Binder("TaskFragmentContainer");
+ if (taskId == INVALID_TASK_ID) {
+ throw new IllegalArgumentException("Invalid Task id");
+ }
+ mTaskId = taskId;
if (activity != null) {
addPendingAppearedActivity(activity);
}
@@ -275,6 +284,11 @@ class TaskFragmentContainer {
}
}
+ /** Gets the parent leaf Task id. */
+ int getTaskId() {
+ return mTaskId;
+ }
+
@Override
public String toString() {
return toString(true /* includeContainersToFinishOnExit */);
diff --git a/libs/WindowManager/Shell/res/color/tv_pip_menu_close_icon.xml b/libs/WindowManager/Shell/res/color/tv_pip_menu_close_icon.xml
new file mode 100644
index 000000000000..ce8640df0093
--- /dev/null
+++ b/libs/WindowManager/Shell/res/color/tv_pip_menu_close_icon.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2022 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:color="@color/tv_pip_menu_icon_unfocused" />
+</selector> \ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/color/tv_pip_menu_close_icon_bg.xml b/libs/WindowManager/Shell/res/color/tv_pip_menu_close_icon_bg.xml
new file mode 100644
index 000000000000..6cbf66f00df7
--- /dev/null
+++ b/libs/WindowManager/Shell/res/color/tv_pip_menu_close_icon_bg.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2022 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_focused="true"
+ android:color="@color/tv_pip_menu_close_icon_bg_focused" />
+ <item android:color="@color/tv_pip_menu_close_icon_bg_unfocused" />
+</selector> \ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/values-af/strings_tv.xml b/libs/WindowManager/Shell/res/values-af/strings_tv.xml
index f552b81d9b77..c87bec093cca 100644
--- a/libs/WindowManager/Shell/res/values-af/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-af/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"Skuif PIP"</string>
<string name="pip_expand" msgid="7605396312689038178">"Vou PIP uit"</string>
<string name="pip_collapse" msgid="5732233773786896094">"Vou PIP in"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" Dubbeldruk "<annotation icon="home_icon">" TUIS "</annotation>" vir kontroles"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-am/strings_tv.xml b/libs/WindowManager/Shell/res/values-am/strings_tv.xml
index 6b6fe9fb8045..d23353858de6 100644
--- a/libs/WindowManager/Shell/res/values-am/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-am/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"ፒአይፒ ውሰድ"</string>
<string name="pip_expand" msgid="7605396312689038178">"ፒአይፒን ዘርጋ"</string>
<string name="pip_collapse" msgid="5732233773786896094">"ፒአይፒን ሰብስብ"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" ለመቆጣጠሪያዎች "<annotation icon="home_icon">"መነሻ"</annotation>"ን ሁለቴ ይጫኑ"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-ar/strings_tv.xml b/libs/WindowManager/Shell/res/values-ar/strings_tv.xml
index a85d7b1c8da5..a1ceda5fc987 100644
--- a/libs/WindowManager/Shell/res/values-ar/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-ar/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"‏نقل نافذة داخل النافذة (PIP)"</string>
<string name="pip_expand" msgid="7605396312689038178">"‏توسيع نافذة داخل النافذة (PIP)"</string>
<string name="pip_collapse" msgid="5732233773786896094">"‏تصغير نافذة داخل النافذة (PIP)"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" انقر مرتين على "<annotation icon="home_icon">" الصفحة الرئيسية "</annotation>" للوصول لعناصر التحكم."</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-as/strings_tv.xml b/libs/WindowManager/Shell/res/values-as/strings_tv.xml
index 9e2f5502bbfe..8d7bd9f6a27e 100644
--- a/libs/WindowManager/Shell/res/values-as/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-as/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"পিপ স্থানান্তৰ কৰক"</string>
<string name="pip_expand" msgid="7605396312689038178">"পিপ বিস্তাৰ কৰক"</string>
<string name="pip_collapse" msgid="5732233773786896094">"পিপ সংকোচন কৰক"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" নিয়ন্ত্ৰণৰ বাবে "<annotation icon="home_icon">" গৃহপৃষ্ঠা "</annotation>" বুটামত দুবাৰ হেঁচক"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-az/strings_tv.xml b/libs/WindowManager/Shell/res/values-az/strings_tv.xml
index 670b02fa52c8..87c46fa41a01 100644
--- a/libs/WindowManager/Shell/res/values-az/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-az/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"PIP tətbiq edin"</string>
<string name="pip_expand" msgid="7605396312689038178">"PIP-ni genişləndirin"</string>
<string name="pip_collapse" msgid="5732233773786896094">"PIP-ni yığcamlaşdırın"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" Nizamlayıcılar üçün "<annotation icon="home_icon">" ƏSAS SƏHİFƏ "</annotation>" süçimini iki dəfə basın"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings_tv.xml b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings_tv.xml
index de23d71f1a28..c87f30611a07 100644
--- a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"Premesti sliku u slici"</string>
<string name="pip_expand" msgid="7605396312689038178">"Proširi sliku u slici"</string>
<string name="pip_collapse" msgid="5732233773786896094">"Skupi sliku u slici"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" Dvaput pritisnite "<annotation icon="home_icon">" HOME "</annotation>" za kontrole"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-be/strings_tv.xml b/libs/WindowManager/Shell/res/values-be/strings_tv.xml
index 03de88c8b975..3566bc372820 100644
--- a/libs/WindowManager/Shell/res/values-be/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-be/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"Перамясціць PIP"</string>
<string name="pip_expand" msgid="7605396312689038178">"Разгарнуць відарыс у відарысе"</string>
<string name="pip_collapse" msgid="5732233773786896094">"Згарнуць відарыс у відарысе"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" Двойчы націсніце "<annotation icon="home_icon">" ГАЛОЎНЫ ЭКРАН "</annotation>" для пераходу ў налады"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-bg/strings_tv.xml b/libs/WindowManager/Shell/res/values-bg/strings_tv.xml
index 38e1ef861be9..91049fd2cf02 100644
--- a/libs/WindowManager/Shell/res/values-bg/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-bg/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"„Картина в картина“: Преместв."</string>
<string name="pip_expand" msgid="7605396312689038178">"Разгъване на прозореца за PIP"</string>
<string name="pip_collapse" msgid="5732233773786896094">"Свиване на прозореца за PIP"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" За достъп до контролите натиснете 2 пъти "<annotation icon="home_icon">"НАЧАЛО"</annotation></string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-bn/strings_tv.xml b/libs/WindowManager/Shell/res/values-bn/strings_tv.xml
index 0b24328d8c7c..792708d128a5 100644
--- a/libs/WindowManager/Shell/res/values-bn/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-bn/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"PIP সরান"</string>
<string name="pip_expand" msgid="7605396312689038178">"PIP বড় করুন"</string>
<string name="pip_collapse" msgid="5732233773786896094">"PIP আড়াল করুন"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" কন্ট্রোলের জন্য "<annotation icon="home_icon">" হোম "</annotation>" বোতামে ডবল প্রেস করুন"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-bs/strings_tv.xml b/libs/WindowManager/Shell/res/values-bs/strings_tv.xml
index 63e23c2edace..b7f0dca1b5a5 100644
--- a/libs/WindowManager/Shell/res/values-bs/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-bs/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"Pokreni sliku u slici"</string>
<string name="pip_expand" msgid="7605396312689038178">"Proširi sliku u slici"</string>
<string name="pip_collapse" msgid="5732233773786896094">"Suzi sliku u slici"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" Dvaput pritisnite "<annotation icon="home_icon">" POČETNI EKRAN "</annotation>" za kontrole"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-ca/strings.xml b/libs/WindowManager/Shell/res/values-ca/strings.xml
index 2ec1db4e990b..8a522b3e6397 100644
--- a/libs/WindowManager/Shell/res/values-ca/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ca/strings.xml
@@ -27,7 +27,7 @@
<string name="pip_play" msgid="3496151081459417097">"Reprodueix"</string>
<string name="pip_pause" msgid="690688849510295232">"Posa en pausa"</string>
<string name="pip_skip_to_next" msgid="8403429188794867653">"Ves al següent"</string>
- <string name="pip_skip_to_prev" msgid="7172158111196394092">"Torna a l\'anterior"</string>
+ <string name="pip_skip_to_prev" msgid="7172158111196394092">"Ves a l\'anterior"</string>
<string name="accessibility_action_pip_resize" msgid="4623966104749543182">"Canvia la mida"</string>
<string name="accessibility_action_pip_stash" msgid="4060775037619702641">"Amaga"</string>
<string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Deixa d\'amagar"</string>
diff --git a/libs/WindowManager/Shell/res/values-ca/strings_tv.xml b/libs/WindowManager/Shell/res/values-ca/strings_tv.xml
index e35390ad2abb..1c560c7afa06 100644
--- a/libs/WindowManager/Shell/res/values-ca/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-ca/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"Mou pantalla en pantalla"</string>
<string name="pip_expand" msgid="7605396312689038178">"Desplega pantalla en pantalla"</string>
<string name="pip_collapse" msgid="5732233773786896094">"Replega pantalla en pantalla"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" Prem dos cops "<annotation icon="home_icon">" INICI "</annotation>" per accedir als controls"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-cs/strings_tv.xml b/libs/WindowManager/Shell/res/values-cs/strings_tv.xml
index 9b38537eaa36..9a8cc2b4d70e 100644
--- a/libs/WindowManager/Shell/res/values-cs/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-cs/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"Přesunout PIP"</string>
<string name="pip_expand" msgid="7605396312689038178">"Rozbalit PIP"</string>
<string name="pip_collapse" msgid="5732233773786896094">"Sbalit PIP"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" Ovládací prvky zobrazíte dvojitým stisknutím "<annotation icon="home_icon">"tlačítka plochy"</annotation></string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-da/strings_tv.xml b/libs/WindowManager/Shell/res/values-da/strings_tv.xml
index 2f3b359f40e5..cba660ac723c 100644
--- a/libs/WindowManager/Shell/res/values-da/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-da/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"Flyt PIP"</string>
<string name="pip_expand" msgid="7605396312689038178">"Udvid PIP"</string>
<string name="pip_collapse" msgid="5732233773786896094">"Skjul PIP"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" Tryk to gange på "<annotation icon="home_icon">" HJEM "</annotation>" for at se indstillinger"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-de/strings_tv.xml b/libs/WindowManager/Shell/res/values-de/strings_tv.xml
index 07fc28dc0583..02a1b66eb63f 100644
--- a/libs/WindowManager/Shell/res/values-de/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-de/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"BiB verschieben"</string>
<string name="pip_expand" msgid="7605396312689038178">"BiB maximieren"</string>
<string name="pip_collapse" msgid="5732233773786896094">"BiB minimieren"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" Für Steuerelemente zweimal "<annotation icon="home_icon">"STARTBILDSCHIRMTASTE"</annotation>" drücken"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-el/strings_tv.xml b/libs/WindowManager/Shell/res/values-el/strings_tv.xml
index 1eba0b7caa0c..24cd030cd754 100644
--- a/libs/WindowManager/Shell/res/values-el/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-el/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"Μετακίνηση PIP"</string>
<string name="pip_expand" msgid="7605396312689038178">"Ανάπτυξη PIP"</string>
<string name="pip_collapse" msgid="5732233773786896094">"Σύμπτυξη PIP"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" Πατήστε δύο φορές "<annotation icon="home_icon">" ΑΡΧΙΚΗ ΟΘΟΝΗ "</annotation>" για στοιχεία ελέγχου"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-en-rAU/strings_tv.xml b/libs/WindowManager/Shell/res/values-en-rAU/strings_tv.xml
index 79a8b95263f2..82257b42814d 100644
--- a/libs/WindowManager/Shell/res/values-en-rAU/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-en-rAU/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"Move PIP"</string>
<string name="pip_expand" msgid="7605396312689038178">"Expand PIP"</string>
<string name="pip_collapse" msgid="5732233773786896094">"Collapse PIP"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" Double-press "<annotation icon="home_icon">" HOME "</annotation>" for controls"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-en-rCA/strings_tv.xml b/libs/WindowManager/Shell/res/values-en-rCA/strings_tv.xml
index 79a8b95263f2..82257b42814d 100644
--- a/libs/WindowManager/Shell/res/values-en-rCA/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-en-rCA/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"Move PIP"</string>
<string name="pip_expand" msgid="7605396312689038178">"Expand PIP"</string>
<string name="pip_collapse" msgid="5732233773786896094">"Collapse PIP"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" Double-press "<annotation icon="home_icon">" HOME "</annotation>" for controls"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-en-rGB/strings_tv.xml b/libs/WindowManager/Shell/res/values-en-rGB/strings_tv.xml
index 79a8b95263f2..82257b42814d 100644
--- a/libs/WindowManager/Shell/res/values-en-rGB/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-en-rGB/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"Move PIP"</string>
<string name="pip_expand" msgid="7605396312689038178">"Expand PIP"</string>
<string name="pip_collapse" msgid="5732233773786896094">"Collapse PIP"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" Double-press "<annotation icon="home_icon">" HOME "</annotation>" for controls"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-en-rIN/strings_tv.xml b/libs/WindowManager/Shell/res/values-en-rIN/strings_tv.xml
index 79a8b95263f2..82257b42814d 100644
--- a/libs/WindowManager/Shell/res/values-en-rIN/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-en-rIN/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"Move PIP"</string>
<string name="pip_expand" msgid="7605396312689038178">"Expand PIP"</string>
<string name="pip_collapse" msgid="5732233773786896094">"Collapse PIP"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" Double-press "<annotation icon="home_icon">" HOME "</annotation>" for controls"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-en-rXC/strings_tv.xml b/libs/WindowManager/Shell/res/values-en-rXC/strings_tv.xml
index 8925f183188c..a6e494cfed3c 100644
--- a/libs/WindowManager/Shell/res/values-en-rXC/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-en-rXC/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‏‎‏‏‎‏‏‏‎‎‎‏‏‎‎‏‏‎‎‎‎‏‎‎‏‎‏‏‏‎‏‏‎‎‎‏‎‎‏‏‎‏‏‎‎‏‏‎‏‎‎‏‎‏‏‏‏‎Move PIP‎‏‎‎‏‎"</string>
<string name="pip_expand" msgid="7605396312689038178">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‎‎‏‎‏‏‏‏‎‎‏‎‏‏‏‎‏‎‎‏‏‎‏‎‏‏‏‎‎‏‏‏‏‎‎‏‎‏‎‏‎‏‎‎‏‏‎‏‏‎‎‎‏‎‎Expand PIP‎‏‎‎‏‎"</string>
<string name="pip_collapse" msgid="5732233773786896094">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‏‎‎‎‏‏‎‎‏‏‏‏‏‏‎‎‎‎‏‏‏‏‏‏‎‎‏‎‎‎‎‎‎‎‎‏‎‎‎‎‏‎‎‏‎‏‏‎‏‏‎‏‏‏‏‎‎Collapse PIP‎‏‎‎‏‎"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" ‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‎‏‏‏‏‏‎‎‏‎‎‎‏‏‏‎‏‏‎‎‏‎‏‎‎‏‏‏‏‎‎‎‏‏‏‎‏‏‏‎‏‎‎‎‎‎‎‏‎‏‏‎‏‏‏‎‏‎ Double press ‎‏‎‎‏‏‎"<annotation icon="home_icon">"‎‏‎‎‏‏‏‎ HOME ‎‏‎‎‏‏‎"</annotation>"‎‏‎‎‏‏‏‎ for controls‎‏‎‎‏‎"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-es-rUS/strings_tv.xml b/libs/WindowManager/Shell/res/values-es-rUS/strings_tv.xml
index 1b1a41910242..458f6b15b857 100644
--- a/libs/WindowManager/Shell/res/values-es-rUS/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-es-rUS/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"Mover PIP"</string>
<string name="pip_expand" msgid="7605396312689038178">"Maximizar PIP"</string>
<string name="pip_collapse" msgid="5732233773786896094">"Minimizar PIP"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" Presiona dos veces "<annotation icon="home_icon">"INICIO"</annotation>" para ver los controles"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-es/strings_tv.xml b/libs/WindowManager/Shell/res/values-es/strings_tv.xml
index 29ff1c6105bb..0a690984dac5 100644
--- a/libs/WindowManager/Shell/res/values-es/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-es/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"Mover imagen en imagen"</string>
<string name="pip_expand" msgid="7605396312689038178">"Mostrar imagen en imagen"</string>
<string name="pip_collapse" msgid="5732233773786896094">"Ocultar imagen en imagen"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" Pulsa dos veces "<annotation icon="home_icon">"INICIO"</annotation>" para ver los controles"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-et/strings_tv.xml b/libs/WindowManager/Shell/res/values-et/strings_tv.xml
index f528bb2065b9..dc0232303a70 100644
--- a/libs/WindowManager/Shell/res/values-et/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-et/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"Teisalda PIP-režiimi"</string>
<string name="pip_expand" msgid="7605396312689038178">"Laienda PIP-akent"</string>
<string name="pip_collapse" msgid="5732233773786896094">"Ahenda PIP-aken"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" Nuppude nägemiseks vajutage 2 korda nuppu "<annotation icon="home_icon">"AVAKUVA"</annotation></string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-eu/strings_tv.xml b/libs/WindowManager/Shell/res/values-eu/strings_tv.xml
index 72f9980a97c3..bce06da2c66f 100644
--- a/libs/WindowManager/Shell/res/values-eu/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-eu/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"Mugitu pantaila txiki gainjarria"</string>
<string name="pip_expand" msgid="7605396312689038178">"Zabaldu pantaila txiki gainjarria"</string>
<string name="pip_collapse" msgid="5732233773786896094">"Tolestu pantaila txiki gainjarria"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" Kontrolatzeko aukerak atzitzeko, sakatu birritan "<annotation icon="home_icon">" HASIERA "</annotation></string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-fa/strings_tv.xml b/libs/WindowManager/Shell/res/values-fa/strings_tv.xml
index 5fa59beae1a5..ff9a03c6cefb 100644
--- a/libs/WindowManager/Shell/res/values-fa/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-fa/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"‏انتقال PIP (تصویر در تصویر)"</string>
<string name="pip_expand" msgid="7605396312689038178">"گسترده کردن «تصویر در تصویر»"</string>
<string name="pip_collapse" msgid="5732233773786896094">"جمع کردن «تصویر در تصویر»"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" برای کنترل‌ها، دکمه "<annotation icon="home_icon">"صفحه اصلی"</annotation>" را دوبار فشار دهید"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-fi/strings_tv.xml b/libs/WindowManager/Shell/res/values-fi/strings_tv.xml
index 217a85ceb791..3e8bf9032780 100644
--- a/libs/WindowManager/Shell/res/values-fi/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-fi/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"Siirrä PIP"</string>
<string name="pip_expand" msgid="7605396312689038178">"Laajenna PIP"</string>
<string name="pip_collapse" msgid="5732233773786896094">"Tiivistä PIP"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" Asetukset: paina "<annotation icon="home_icon">"ALOITUSNÄYTTÖPAINIKETTA"</annotation>" kahdesti"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-fr-rCA/strings_tv.xml b/libs/WindowManager/Shell/res/values-fr-rCA/strings_tv.xml
index b6f401fae144..66e13b89c64b 100644
--- a/libs/WindowManager/Shell/res/values-fr-rCA/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-fr-rCA/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"Déplacer l\'image incrustée"</string>
<string name="pip_expand" msgid="7605396312689038178">"Développer l\'image incrustée"</string>
<string name="pip_collapse" msgid="5732233773786896094">"Réduire l\'image incrustée"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" Appuyez deux fois sur "<annotation icon="home_icon">" ACCUEIL "</annotation>" pour les commandes"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-fr/strings_tv.xml b/libs/WindowManager/Shell/res/values-fr/strings_tv.xml
index ffa4a229b9f2..ed9baf5b6215 100644
--- a/libs/WindowManager/Shell/res/values-fr/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-fr/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"Déplacer le PIP"</string>
<string name="pip_expand" msgid="7605396312689038178">"Développer la fenêtre PIP"</string>
<string name="pip_collapse" msgid="5732233773786896094">"Réduire la fenêtre PIP"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" Menu de commandes : appuyez deux fois sur "<annotation icon="home_icon">"ACCUEIL"</annotation></string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-gl/strings_tv.xml b/libs/WindowManager/Shell/res/values-gl/strings_tv.xml
index 3a7ed890961c..a057434d7853 100644
--- a/libs/WindowManager/Shell/res/values-gl/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-gl/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"Mover pantalla superposta"</string>
<string name="pip_expand" msgid="7605396312689038178">"Despregar pantalla superposta"</string>
<string name="pip_collapse" msgid="5732233773786896094">"Contraer pantalla superposta"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" Preme "<annotation icon="home_icon">"INICIO"</annotation>" dúas veces para acceder aos controis"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-gu/strings_tv.xml b/libs/WindowManager/Shell/res/values-gu/strings_tv.xml
index 7a9bb25d63c2..d9525910e4c6 100644
--- a/libs/WindowManager/Shell/res/values-gu/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-gu/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"PIP ખસેડો"</string>
<string name="pip_expand" msgid="7605396312689038178">"PIP મોટી કરો"</string>
<string name="pip_collapse" msgid="5732233773786896094">"PIP નાની કરો"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" નિયંત્રણો માટે "<annotation icon="home_icon">" હોમ "</annotation>" બટન પર બે વાર દબાવો"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-hi/strings_tv.xml b/libs/WindowManager/Shell/res/values-hi/strings_tv.xml
index 5776f8190868..d897ac73f80d 100644
--- a/libs/WindowManager/Shell/res/values-hi/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-hi/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"पीआईपी को दूसरी जगह लेकर जाएं"</string>
<string name="pip_expand" msgid="7605396312689038178">"पीआईपी विंडो को बड़ा करें"</string>
<string name="pip_collapse" msgid="5732233773786896094">"पीआईपी विंडो को छोटा करें"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" कंट्रोल मेन्यू पर जाने के लिए, "<annotation icon="home_icon">" होम बटन"</annotation>" दो बार दबाएं"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-hr/strings_tv.xml b/libs/WindowManager/Shell/res/values-hr/strings_tv.xml
index e4d69442c5c0..8f5f3164c4d7 100644
--- a/libs/WindowManager/Shell/res/values-hr/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-hr/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"Premjesti PIP"</string>
<string name="pip_expand" msgid="7605396312689038178">"Proširi PIP"</string>
<string name="pip_collapse" msgid="5732233773786896094">"Sažmi PIP"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" Dvaput pritisnite "<annotation icon="home_icon">"POČETNI ZASLON"</annotation>" za kontrole"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-hu/strings_tv.xml b/libs/WindowManager/Shell/res/values-hu/strings_tv.xml
index 43beeeaa44f5..fc8d79589121 100644
--- a/libs/WindowManager/Shell/res/values-hu/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-hu/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"PIP áthelyezése"</string>
<string name="pip_expand" msgid="7605396312689038178">"Kép a képben kibontása"</string>
<string name="pip_collapse" msgid="5732233773786896094">"Kép a képben összecsukása"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" Vezérlők: "<annotation icon="home_icon">" KEZDŐKÉPERNYŐ "</annotation>" gomb kétszer megnyomva"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-hy/strings_tv.xml b/libs/WindowManager/Shell/res/values-hy/strings_tv.xml
index e439d5c6fbbd..f5665b8dd166 100644
--- a/libs/WindowManager/Shell/res/values-hy/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-hy/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"Տեղափոխել PIP-ը"</string>
<string name="pip_expand" msgid="7605396312689038178">"Ծավալել PIP-ը"</string>
<string name="pip_collapse" msgid="5732233773786896094">"Ծալել PIP-ը"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" Կարգավորումների համար կրկնակի սեղմեք "<annotation icon="home_icon">"ԳԼԽԱՎՈՐ ԷԿՐԱՆ"</annotation></string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-in/strings_tv.xml b/libs/WindowManager/Shell/res/values-in/strings_tv.xml
index 25cb7567e33e..a1535653f679 100644
--- a/libs/WindowManager/Shell/res/values-in/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-in/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"Pindahkan PIP"</string>
<string name="pip_expand" msgid="7605396312689038178">"Luaskan PIP"</string>
<string name="pip_collapse" msgid="5732233773786896094">"Ciutkan PIP"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" Tekan dua kali "<annotation icon="home_icon">" HOME "</annotation>" untuk membuka kontrol"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-is/strings_tv.xml b/libs/WindowManager/Shell/res/values-is/strings_tv.xml
index 56b973996ea9..70ca1afe3aea 100644
--- a/libs/WindowManager/Shell/res/values-is/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-is/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"Færa innfellda mynd"</string>
<string name="pip_expand" msgid="7605396312689038178">"Stækka innfellda mynd"</string>
<string name="pip_collapse" msgid="5732233773786896094">"Minnka innfellda mynd"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" Ýttu tvisvar á "<annotation icon="home_icon">" HEIM "</annotation>" til að opna stillingar"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-it/strings_tv.xml b/libs/WindowManager/Shell/res/values-it/strings_tv.xml
index 735c5cd6c065..cda627517872 100644
--- a/libs/WindowManager/Shell/res/values-it/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-it/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"Sposta PIP"</string>
<string name="pip_expand" msgid="7605396312689038178">"Espandi PIP"</string>
<string name="pip_collapse" msgid="5732233773786896094">"Comprimi PIP"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" Premi due volte "<annotation icon="home_icon">" HOME "</annotation>" per aprire i controlli"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-iw/strings_tv.xml b/libs/WindowManager/Shell/res/values-iw/strings_tv.xml
index e4e0bf6002b0..30ce97b998ca 100644
--- a/libs/WindowManager/Shell/res/values-iw/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-iw/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"‏העברת תמונה בתוך תמונה (PIP)"</string>
<string name="pip_expand" msgid="7605396312689038178">"הרחבת חלון תמונה-בתוך-תמונה"</string>
<string name="pip_collapse" msgid="5732233773786896094">"כיווץ של חלון תמונה-בתוך-תמונה"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" לחיצה כפולה על "<annotation icon="home_icon">" הלחצן הראשי "</annotation>" תציג את אמצעי הבקרה"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-ja/strings_tv.xml b/libs/WindowManager/Shell/res/values-ja/strings_tv.xml
index c8326a6552c4..e58e7bf6fabc 100644
--- a/libs/WindowManager/Shell/res/values-ja/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-ja/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"PIP を移動"</string>
<string name="pip_expand" msgid="7605396312689038178">"PIP を開く"</string>
<string name="pip_collapse" msgid="5732233773786896094">"PIP を閉じる"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" コントロールにアクセス: "<annotation icon="home_icon">" ホーム "</annotation>" を 2 回押します"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-ka/strings_tv.xml b/libs/WindowManager/Shell/res/values-ka/strings_tv.xml
index 025e5a554de1..b09686646c8b 100644
--- a/libs/WindowManager/Shell/res/values-ka/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-ka/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"PIP გადატანა"</string>
<string name="pip_expand" msgid="7605396312689038178">"PIP-ის გაშლა"</string>
<string name="pip_collapse" msgid="5732233773786896094">"PIP-ის ჩაკეცვა"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" მართვის საშუალებებზე წვდომისთვის ორმაგად დააჭირეთ "<annotation icon="home_icon">" მთავარ ღილაკს "</annotation></string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-kk/strings_tv.xml b/libs/WindowManager/Shell/res/values-kk/strings_tv.xml
index 27afe2ec4131..7bade0dff0d9 100644
--- a/libs/WindowManager/Shell/res/values-kk/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-kk/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"PIP клипін жылжыту"</string>
<string name="pip_expand" msgid="7605396312689038178">"PIP терезесін жаю"</string>
<string name="pip_collapse" msgid="5732233773786896094">"PIP терезесін жию"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" Басқару элементтері: "<annotation icon="home_icon">" НЕГІЗГІ ЭКРАН "</annotation>" түймесін екі рет басыңыз."</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-km/strings_tv.xml b/libs/WindowManager/Shell/res/values-km/strings_tv.xml
index 86bad2776c37..721be1fc1650 100644
--- a/libs/WindowManager/Shell/res/values-km/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-km/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"ផ្លាស់ទី PIP"</string>
<string name="pip_expand" msgid="7605396312689038178">"ពង្រីក PIP"</string>
<string name="pip_collapse" msgid="5732233773786896094">"បង្រួម PIP"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" ចុចពីរដងលើ"<annotation icon="home_icon">"ប៊ូតុងដើម"</annotation>" ដើម្បីបើកផ្ទាំងគ្រប់គ្រង"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-kn/strings_tv.xml b/libs/WindowManager/Shell/res/values-kn/strings_tv.xml
index 3fbfdaa85a70..8310c8a1169c 100644
--- a/libs/WindowManager/Shell/res/values-kn/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-kn/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"PIP ಅನ್ನು ಸರಿಸಿ"</string>
<string name="pip_expand" msgid="7605396312689038178">"ಚಿತ್ರದಲ್ಲಿ ಚಿತ್ರವನ್ನು ವಿಸ್ತರಿಸಿ"</string>
<string name="pip_collapse" msgid="5732233773786896094">"ಚಿತ್ರದಲ್ಲಿ ಚಿತ್ರವನ್ನು ಕುಗ್ಗಿಸಿ"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" ಕಂಟ್ರೋಲ್‌ಗಳಿಗಾಗಿ "<annotation icon="home_icon">" ಹೋಮ್ "</annotation>" ಅನ್ನು ಎರಡು ಬಾರಿ ಒತ್ತಿ"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-ko/strings_tv.xml b/libs/WindowManager/Shell/res/values-ko/strings_tv.xml
index fa8c898011fc..a3e055a515a1 100644
--- a/libs/WindowManager/Shell/res/values-ko/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-ko/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"PIP 이동"</string>
<string name="pip_expand" msgid="7605396312689038178">"PIP 펼치기"</string>
<string name="pip_collapse" msgid="5732233773786896094">"PIP 접기"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" 제어 메뉴에 액세스하려면 "<annotation icon="home_icon">" 홈 "</annotation>"을 두 번 누르세요."</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-ky/strings_tv.xml b/libs/WindowManager/Shell/res/values-ky/strings_tv.xml
index 6e2b810e9b8b..887ac52c8e43 100644
--- a/libs/WindowManager/Shell/res/values-ky/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-ky/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"PIP\'ти жылдыруу"</string>
<string name="pip_expand" msgid="7605396312689038178">"PIP\'ти жайып көрсөтүү"</string>
<string name="pip_collapse" msgid="5732233773786896094">"PIP\'ти жыйыштыруу"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" Башкаруу элементтерин ачуу үчүн "<annotation icon="home_icon">" БАШКЫ БЕТ "</annotation>" баскычын эки жолу басыңыз"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-lo/strings_tv.xml b/libs/WindowManager/Shell/res/values-lo/strings_tv.xml
index 3d4505d77d75..91c4a033356d 100644
--- a/libs/WindowManager/Shell/res/values-lo/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-lo/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"ຍ້າຍ PIP"</string>
<string name="pip_expand" msgid="7605396312689038178">"ຂະຫຍາຍ PIP"</string>
<string name="pip_collapse" msgid="5732233773786896094">"ຫຍໍ້ PIP ລົງ"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" ກົດ "<annotation icon="home_icon">" HOME "</annotation>" ສອງເທື່ອສຳລັບການຄວບຄຸມ"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-lt/strings_tv.xml b/libs/WindowManager/Shell/res/values-lt/strings_tv.xml
index f907055872ca..04265ca01b48 100644
--- a/libs/WindowManager/Shell/res/values-lt/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-lt/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"Perkelti PIP"</string>
<string name="pip_expand" msgid="7605396312689038178">"Iškleisti PIP"</string>
<string name="pip_collapse" msgid="5732233773786896094">"Sutraukti PIP"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" Jei reikia valdiklių, dukart paspauskite "<annotation icon="home_icon">"PAGRINDINIS"</annotation></string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-lv/strings_tv.xml b/libs/WindowManager/Shell/res/values-lv/strings_tv.xml
index 04d9409cb3ac..8c6191e00833 100644
--- a/libs/WindowManager/Shell/res/values-lv/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-lv/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"Pārvietot attēlu attēlā"</string>
<string name="pip_expand" msgid="7605396312689038178">"Izvērst “Attēls attēlā” logu"</string>
<string name="pip_collapse" msgid="5732233773786896094">"Sakļaut “Attēls attēlā” logu"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" Atvērt vadīklas: divreiz nospiediet pogu "<annotation icon="home_icon">"SĀKUMS"</annotation></string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-mk/strings_tv.xml b/libs/WindowManager/Shell/res/values-mk/strings_tv.xml
index e9ee13884afc..beef1fef862b 100644
--- a/libs/WindowManager/Shell/res/values-mk/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-mk/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"Премести PIP"</string>
<string name="pip_expand" msgid="7605396312689038178">"Прошири ја сликата во слика"</string>
<string name="pip_collapse" msgid="5732233773786896094">"Собери ја сликата во слика"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" Притиснете двапати на "<annotation icon="home_icon">" HOME "</annotation>" за контроли"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-ml/strings_tv.xml b/libs/WindowManager/Shell/res/values-ml/strings_tv.xml
index 1ed6b6e566de..c2a532d09647 100644
--- a/libs/WindowManager/Shell/res/values-ml/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-ml/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"PIP നീക്കുക"</string>
<string name="pip_expand" msgid="7605396312689038178">"PIP വികസിപ്പിക്കുക"</string>
<string name="pip_collapse" msgid="5732233773786896094">"PIP ചുരുക്കുക"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" നിയന്ത്രണങ്ങൾക്കായി "<annotation icon="home_icon">" ഹോം "</annotation>" രണ്ട് തവണ അമർത്തുക"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-mn/strings_tv.xml b/libs/WindowManager/Shell/res/values-mn/strings_tv.xml
index d4a6942ae9dc..bf8c59b57359 100644
--- a/libs/WindowManager/Shell/res/values-mn/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-mn/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"PIP-г зөөх"</string>
<string name="pip_expand" msgid="7605396312689038178">"PIP-г дэлгэх"</string>
<string name="pip_collapse" msgid="5732233773786896094">"PIP-г хураах"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" Хяналтад хандах бол "<annotation icon="home_icon">" HOME "</annotation>" дээр хоёр дарна уу"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-mr/strings_tv.xml b/libs/WindowManager/Shell/res/values-mr/strings_tv.xml
index 940f9832eb4a..5d519b7afe9a 100644
--- a/libs/WindowManager/Shell/res/values-mr/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-mr/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"PIP हलवा"</string>
<string name="pip_expand" msgid="7605396312689038178">"PIP चा विस्तार करा"</string>
<string name="pip_collapse" msgid="5732233773786896094">"PIP कोलॅप्स करा"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" नियंत्रणांसाठी "<annotation icon="home_icon">" होम "</annotation>" दोनदा दाबा"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-ms/strings_tv.xml b/libs/WindowManager/Shell/res/values-ms/strings_tv.xml
index f4b180c8fe74..08642c47c91a 100644
--- a/libs/WindowManager/Shell/res/values-ms/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-ms/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"Alihkan PIP"</string>
<string name="pip_expand" msgid="7605396312689038178">"Kembangkan PIP"</string>
<string name="pip_collapse" msgid="5732233773786896094">"Kuncupkan PIP"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" Tekan dua kali "<annotation icon="home_icon">" LAMAN UTAMA "</annotation>" untuk mengakses kawalan"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-my/strings_tv.xml b/libs/WindowManager/Shell/res/values-my/strings_tv.xml
index 4b2a5ecbce0c..e01daee115ca 100644
--- a/libs/WindowManager/Shell/res/values-my/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-my/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"PIP ရွှေ့ရန်"</string>
<string name="pip_expand" msgid="7605396312689038178">"PIP ကို ချဲ့ရန်"</string>
<string name="pip_collapse" msgid="5732233773786896094">"PIP ကို လျှော့ပြပါ"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" ထိန်းချုပ်မှုအတွက် "<annotation icon="home_icon">" ပင်မခလုတ် "</annotation>" နှစ်ချက်နှိပ်ပါ"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-nb/strings_tv.xml b/libs/WindowManager/Shell/res/values-nb/strings_tv.xml
index be74eeb78bba..65ed0b7f5bff 100644
--- a/libs/WindowManager/Shell/res/values-nb/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-nb/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"Flytt BIB"</string>
<string name="pip_expand" msgid="7605396312689038178">"Vis BIB"</string>
<string name="pip_collapse" msgid="5732233773786896094">"Skjul BIB"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" Dobbelttrykk på "<annotation icon="home_icon">"HJEM"</annotation>" for å åpne kontroller"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-ne/strings_tv.xml b/libs/WindowManager/Shell/res/values-ne/strings_tv.xml
index a36cad696159..d33fed67efb6 100644
--- a/libs/WindowManager/Shell/res/values-ne/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-ne/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"PIP सार्नुहोस्"</string>
<string name="pip_expand" msgid="7605396312689038178">"PIP विन्डो एक्स्पान्ड गर्नु…"</string>
<string name="pip_collapse" msgid="5732233773786896094">"PIP विन्डो कोल्याप्स गर्नुहोस्"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" कन्ट्रोल मेनु खोल्न "<annotation icon="home_icon">" होम "</annotation>" बटन दुई पटक थिच्नुहोस्"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-nl/strings_tv.xml b/libs/WindowManager/Shell/res/values-nl/strings_tv.xml
index eb7ec606b0fa..9763c5665ab2 100644
--- a/libs/WindowManager/Shell/res/values-nl/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-nl/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"SIS verplaatsen"</string>
<string name="pip_expand" msgid="7605396312689038178">"SIS uitvouwen"</string>
<string name="pip_collapse" msgid="5732233773786896094">"SIS samenvouwen"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" Druk twee keer op "<annotation icon="home_icon">" HOME "</annotation>" voor bedieningselementen"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-or/strings_tv.xml b/libs/WindowManager/Shell/res/values-or/strings_tv.xml
index e48199f9de50..e0344855bd1f 100644
--- a/libs/WindowManager/Shell/res/values-or/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-or/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"PIPକୁ ମୁଭ କରନ୍ତୁ"</string>
<string name="pip_expand" msgid="7605396312689038178">"PIPକୁ ବିସ୍ତାର କରନ୍ତୁ"</string>
<string name="pip_collapse" msgid="5732233773786896094">"PIPକୁ ସଙ୍କୁଚିତ କରନ୍ତୁ"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକ ପାଇଁ "<annotation icon="home_icon">" ହୋମ ବଟନ "</annotation>"କୁ ଦୁଇଥର ଦବାନ୍ତୁ"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-pa/strings_tv.xml b/libs/WindowManager/Shell/res/values-pa/strings_tv.xml
index 891107e765f6..9c01ac3f3cc0 100644
--- a/libs/WindowManager/Shell/res/values-pa/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-pa/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"PIP ਨੂੰ ਲਿਜਾਓ"</string>
<string name="pip_expand" msgid="7605396312689038178">"PIP ਦਾ ਵਿਸਤਾਰ ਕਰੋ"</string>
<string name="pip_collapse" msgid="5732233773786896094">"PIP ਨੂੰ ਸਮੇਟੋ"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" ਕੰਟਰੋਲਾਂ ਲਈ "<annotation icon="home_icon">" ਹੋਮ ਬਟਨ "</annotation>" ਨੂੰ ਦੋ ਵਾਰ ਦਬਾਓ"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-pl/strings_tv.xml b/libs/WindowManager/Shell/res/values-pl/strings_tv.xml
index 7b5d08acd504..b922e2d5a6ba 100644
--- a/libs/WindowManager/Shell/res/values-pl/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-pl/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"Przenieś PIP"</string>
<string name="pip_expand" msgid="7605396312689038178">"Rozwiń PIP"</string>
<string name="pip_collapse" msgid="5732233773786896094">"Zwiń PIP"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" Naciśnij dwukrotnie "<annotation icon="home_icon">"EKRAN GŁÓWNY"</annotation>", aby wyświetlić ustawienia"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-pt-rBR/strings_tv.xml b/libs/WindowManager/Shell/res/values-pt-rBR/strings_tv.xml
index b669f161c625..cc4eb3c32c1f 100644
--- a/libs/WindowManager/Shell/res/values-pt-rBR/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-pt-rBR/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"Mover picture-in-picture"</string>
<string name="pip_expand" msgid="7605396312689038178">"Abrir picture-in-picture"</string>
<string name="pip_collapse" msgid="5732233773786896094">"Fechar picture-in-picture"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" Pressione o botão "<annotation icon="home_icon">"home"</annotation>" duas vezes para acessar os controles"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-pt-rPT/strings_tv.xml b/libs/WindowManager/Shell/res/values-pt-rPT/strings_tv.xml
index 6c1fa5905d1a..c4ae78d89ba8 100644
--- a/libs/WindowManager/Shell/res/values-pt-rPT/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-pt-rPT/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"Mover Ecrã no ecrã"</string>
<string name="pip_expand" msgid="7605396312689038178">"Expandir Ecrã no ecrã"</string>
<string name="pip_collapse" msgid="5732233773786896094">"Reduzir Ecrã no ecrã"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" Prima duas vezes "<annotation icon="home_icon">" PÁGINA INICIAL "</annotation>" para controlos"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-pt/strings_tv.xml b/libs/WindowManager/Shell/res/values-pt/strings_tv.xml
index b669f161c625..cc4eb3c32c1f 100644
--- a/libs/WindowManager/Shell/res/values-pt/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-pt/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"Mover picture-in-picture"</string>
<string name="pip_expand" msgid="7605396312689038178">"Abrir picture-in-picture"</string>
<string name="pip_collapse" msgid="5732233773786896094">"Fechar picture-in-picture"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" Pressione o botão "<annotation icon="home_icon">"home"</annotation>" duas vezes para acessar os controles"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-ro/strings_tv.xml b/libs/WindowManager/Shell/res/values-ro/strings_tv.xml
index 8ecf8c5a1593..86a30f49df15 100644
--- a/libs/WindowManager/Shell/res/values-ro/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-ro/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"Mutați fereastra PIP"</string>
<string name="pip_expand" msgid="7605396312689038178">"Extindeți fereastra PIP"</string>
<string name="pip_collapse" msgid="5732233773786896094">"Restrângeți fereastra PIP"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" Apăsați de două ori "<annotation icon="home_icon">"butonul ecran de pornire"</annotation>" pentru comenzi"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-ru/strings_tv.xml b/libs/WindowManager/Shell/res/values-ru/strings_tv.xml
index 19f7a00c758b..08623e1e69c5 100644
--- a/libs/WindowManager/Shell/res/values-ru/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-ru/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"Переместить PIP"</string>
<string name="pip_expand" msgid="7605396312689038178">"Развернуть PIP"</string>
<string name="pip_collapse" msgid="5732233773786896094">"Свернуть PIP"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" Элементы управления: дважды нажмите "<annotation icon="home_icon">" кнопку главного экрана "</annotation></string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-si/strings_tv.xml b/libs/WindowManager/Shell/res/values-si/strings_tv.xml
index 7444369cbc95..fbb0ebba0623 100644
--- a/libs/WindowManager/Shell/res/values-si/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-si/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"PIP ගෙන යන්න"</string>
<string name="pip_expand" msgid="7605396312689038178">"PIP දිග හරින්න"</string>
<string name="pip_collapse" msgid="5732233773786896094">"PIP හකුළන්න"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" පාලන සඳහා "<annotation icon="home_icon">" මුල් පිටුව "</annotation>" දෙවරක් ඔබන්න"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-sk/strings_tv.xml b/libs/WindowManager/Shell/res/values-sk/strings_tv.xml
index 1a8edf183c75..81cb0eafc759 100644
--- a/libs/WindowManager/Shell/res/values-sk/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-sk/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"Presunúť obraz v obraze"</string>
<string name="pip_expand" msgid="7605396312689038178">"Rozbaliť obraz v obraze"</string>
<string name="pip_collapse" msgid="5732233773786896094">"Zbaliť obraz v obraze"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" Ovládanie zobraz. dvoj. stlač. "<annotation icon="home_icon">" TLAČIDLA PLOCHY "</annotation></string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-sl/strings_tv.xml b/libs/WindowManager/Shell/res/values-sl/strings_tv.xml
index c4c04c24fc49..060aaa0ce647 100644
--- a/libs/WindowManager/Shell/res/values-sl/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-sl/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"Premakni sliko v sliki"</string>
<string name="pip_expand" msgid="7605396312689038178">"Razširi sliko v sliki"</string>
<string name="pip_collapse" msgid="5732233773786896094">"Strni sliko v sliki"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" Za kontrolnike dvakrat pritisnite gumb za "<annotation icon="home_icon">" ZAČETNI ZASLON "</annotation></string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-sq/strings_tv.xml b/libs/WindowManager/Shell/res/values-sq/strings_tv.xml
index 2771b89a63eb..9bfdb6a3edd8 100644
--- a/libs/WindowManager/Shell/res/values-sq/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-sq/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"Zhvendos PIP"</string>
<string name="pip_expand" msgid="7605396312689038178">"Zgjero PIP"</string>
<string name="pip_collapse" msgid="5732233773786896094">"Palos PIP"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" Trokit dy herë "<annotation icon="home_icon">" KREU "</annotation>" për kontrollet"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-sr/strings_tv.xml b/libs/WindowManager/Shell/res/values-sr/strings_tv.xml
index 32440302d6d2..6bc5c87bab48 100644
--- a/libs/WindowManager/Shell/res/values-sr/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-sr/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"Премести слику у слици"</string>
<string name="pip_expand" msgid="7605396312689038178">"Прошири слику у слици"</string>
<string name="pip_collapse" msgid="5732233773786896094">"Скупи слику у слици"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" Двапут притисните "<annotation icon="home_icon">" HOME "</annotation>" за контроле"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-sv/strings_tv.xml b/libs/WindowManager/Shell/res/values-sv/strings_tv.xml
index 842c8053e494..b3465ab1db85 100644
--- a/libs/WindowManager/Shell/res/values-sv/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-sv/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"Flytta BIB"</string>
<string name="pip_expand" msgid="7605396312689038178">"Utöka bild-i-bild"</string>
<string name="pip_collapse" msgid="5732233773786896094">"Komprimera bild-i-bild"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" Tryck snabbt två gånger på "<annotation icon="home_icon">" HEM "</annotation>" för kontroller"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-sw/strings_tv.xml b/libs/WindowManager/Shell/res/values-sw/strings_tv.xml
index 8728fd9360c2..baff49ed821a 100644
--- a/libs/WindowManager/Shell/res/values-sw/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-sw/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"Kuhamisha PIP"</string>
<string name="pip_expand" msgid="7605396312689038178">"Panua PIP"</string>
<string name="pip_collapse" msgid="5732233773786896094">"Kunja PIP"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" Bonyeza mara mbili kitufe cha "<annotation icon="home_icon">" UKURASA WA KWANZA "</annotation>" kupata vidhibiti"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-ta/strings_tv.xml b/libs/WindowManager/Shell/res/values-ta/strings_tv.xml
index e325b1a6c32d..4439e299c919 100644
--- a/libs/WindowManager/Shell/res/values-ta/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-ta/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"PIPபை நகர்த்து"</string>
<string name="pip_expand" msgid="7605396312689038178">"PIPபை விரிவாக்கு"</string>
<string name="pip_collapse" msgid="5732233773786896094">"PIPபைச் சுருக்கு"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" கட்டுப்பாடுகள்: "<annotation icon="home_icon">" முகப்பு "</annotation>" பட்டனை இருமுறை அழுத்துக"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-te/strings_tv.xml b/libs/WindowManager/Shell/res/values-te/strings_tv.xml
index 1381e6771936..35579346615f 100644
--- a/libs/WindowManager/Shell/res/values-te/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-te/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"PIPను తరలించండి"</string>
<string name="pip_expand" msgid="7605396312689038178">"PIPని విస్తరించండి"</string>
<string name="pip_collapse" msgid="5732233773786896094">"PIPని కుదించండి"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" కంట్రోల్స్ కోసం "<annotation icon="home_icon">" HOME "</annotation>" బటన్ రెండుసార్లు నొక్కండి"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-television/config.xml b/libs/WindowManager/Shell/res/values-television/config.xml
index dcb4c1026062..86ca65526336 100644
--- a/libs/WindowManager/Shell/res/values-television/config.xml
+++ b/libs/WindowManager/Shell/res/values-television/config.xml
@@ -39,4 +39,8 @@
<!-- Duration (in milliseconds) the PiP stays stashed before automatically unstashing. -->
<integer name="config_pipStashDuration">5000</integer>
+
+ <!-- Time (duration in milliseconds) that the shell waits for an app to close the PiP by itself
+ if a custom action is present before closing it. -->
+ <integer name="config_pipForceCloseDelay">5000</integer>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-th/strings_tv.xml b/libs/WindowManager/Shell/res/values-th/strings_tv.xml
index 6f0001890961..0a07d157ec6f 100644
--- a/libs/WindowManager/Shell/res/values-th/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-th/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"ย้าย PIP"</string>
<string name="pip_expand" msgid="7605396312689038178">"ขยาย PIP"</string>
<string name="pip_collapse" msgid="5732233773786896094">"ยุบ PIP"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" กดปุ่ม "<annotation icon="home_icon">" หน้าแรก "</annotation>" สองครั้งเพื่อเปิดการควบคุม"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-tl/strings_tv.xml b/libs/WindowManager/Shell/res/values-tl/strings_tv.xml
index 868b27874cc3..9a11a38fa492 100644
--- a/libs/WindowManager/Shell/res/values-tl/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-tl/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"Ilipat ang PIP"</string>
<string name="pip_expand" msgid="7605396312689038178">"I-expand ang PIP"</string>
<string name="pip_collapse" msgid="5732233773786896094">"I-collapse ang PIP"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" I-double press ang "<annotation icon="home_icon">" HOME "</annotation>" para sa mga kontrol"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-tr/strings_tv.xml b/libs/WindowManager/Shell/res/values-tr/strings_tv.xml
index 9ffad78df41d..bf4bc6f1fff7 100644
--- a/libs/WindowManager/Shell/res/values-tr/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-tr/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"PIP\'yi taşı"</string>
<string name="pip_expand" msgid="7605396312689038178">"PIP penceresini genişlet"</string>
<string name="pip_collapse" msgid="5732233773786896094">"PIP penceresini daralt"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" Kontroller için "<annotation icon="home_icon">" ANA SAYFA "</annotation>"\'ya iki kez basın"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-uk/strings_tv.xml b/libs/WindowManager/Shell/res/values-uk/strings_tv.xml
index 24c169807e58..7e9f54e68f54 100644
--- a/libs/WindowManager/Shell/res/values-uk/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-uk/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"Перемістити картинку в картинці"</string>
<string name="pip_expand" msgid="7605396312689038178">"Розгорнути картинку в картинці"</string>
<string name="pip_collapse" msgid="5732233773786896094">"Згорнути картинку в картинці"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" Відкрити елементи керування: двічі натисніть "<annotation icon="home_icon">"HOME"</annotation></string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-ur/strings_tv.xml b/libs/WindowManager/Shell/res/values-ur/strings_tv.xml
index c05729a123ed..c2ef69ff1488 100644
--- a/libs/WindowManager/Shell/res/values-ur/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-ur/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"‏PIP کو منتقل کریں"</string>
<string name="pip_expand" msgid="7605396312689038178">"‏PIP کو پھیلائیں"</string>
<string name="pip_collapse" msgid="5732233773786896094">"‏PIP کو سکیڑیں"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" کنٹرولز کے لیے "<annotation icon="home_icon">"ہوم "</annotation>" بٹن کو دو بار دبائیں"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-uz/strings_tv.xml b/libs/WindowManager/Shell/res/values-uz/strings_tv.xml
index 43ab5ac11a80..9ab95c80aa25 100644
--- a/libs/WindowManager/Shell/res/values-uz/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-uz/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"PIPni siljitish"</string>
<string name="pip_expand" msgid="7605396312689038178">"PIP funksiyasini yoyish"</string>
<string name="pip_collapse" msgid="5732233773786896094">"PIP funksiyasini yopish"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" Boshqaruv uchun "<annotation icon="home_icon">"ASOSIY"</annotation>" tugmani ikki marta bosing"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-vi/strings_tv.xml b/libs/WindowManager/Shell/res/values-vi/strings_tv.xml
index 368280c210bc..146376d3cab6 100644
--- a/libs/WindowManager/Shell/res/values-vi/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-vi/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"Di chuyển PIP (Ảnh trong ảnh)"</string>
<string name="pip_expand" msgid="7605396312689038178">"Mở rộng PIP (Ảnh trong ảnh)"</string>
<string name="pip_collapse" msgid="5732233773786896094">"Thu gọn PIP (Ảnh trong ảnh)"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" Nhấn đúp vào nút "<annotation icon="home_icon">" MÀN HÌNH CHÍNH "</annotation>" để mở trình đơn điều khiển"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-zh-rCN/strings_tv.xml b/libs/WindowManager/Shell/res/values-zh-rCN/strings_tv.xml
index e5d879a24a6f..55407d2c699d 100644
--- a/libs/WindowManager/Shell/res/values-zh-rCN/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rCN/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"移动画中画窗口"</string>
<string name="pip_expand" msgid="7605396312689038178">"展开 PIP"</string>
<string name="pip_collapse" msgid="5732233773786896094">"收起 PIP"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" 按两次"<annotation icon="home_icon">"主屏幕"</annotation>"按钮可查看相关控件"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-zh-rHK/strings_tv.xml b/libs/WindowManager/Shell/res/values-zh-rHK/strings_tv.xml
index 8ee5f11a76d8..15e278d8ecc2 100644
--- a/libs/WindowManager/Shell/res/values-zh-rHK/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rHK/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"移動畫中畫"</string>
<string name="pip_expand" msgid="7605396312689038178">"展開畫中畫"</string>
<string name="pip_collapse" msgid="5732233773786896094">"收合畫中畫"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" 按兩下"<annotation icon="home_icon">" 主畫面按鈕"</annotation>"即可顯示控制項"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-zh-rTW/strings_tv.xml b/libs/WindowManager/Shell/res/values-zh-rTW/strings_tv.xml
index b23ecdee3575..0b17b31d23d0 100644
--- a/libs/WindowManager/Shell/res/values-zh-rTW/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rTW/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"移動子母畫面"</string>
<string name="pip_expand" msgid="7605396312689038178">"展開子母畫面"</string>
<string name="pip_collapse" msgid="5732233773786896094">"收合子母畫面"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" 按兩下"<annotation icon="home_icon">"主畫面按鈕"</annotation>"即可顯示控制選項"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-zu/strings_tv.xml b/libs/WindowManager/Shell/res/values-zu/strings_tv.xml
index b14ee992b2ad..dad8c8128222 100644
--- a/libs/WindowManager/Shell/res/values-zu/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-zu/strings_tv.xml
@@ -24,4 +24,5 @@
<string name="pip_move" msgid="1544227837964635439">"Hambisa i-PIP"</string>
<string name="pip_expand" msgid="7605396312689038178">"Nweba i-PIP"</string>
<string name="pip_collapse" msgid="5732233773786896094">"Goqa i-PIP"</string>
+ <string name="pip_edu_text" msgid="3672999496647508701">" Chofoza kabili "<annotation icon="home_icon">" IKHAYA"</annotation>" mayelana nezilawuli"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values/colors_tv.xml b/libs/WindowManager/Shell/res/values/colors_tv.xml
index 08d3cef10428..64b146ec3a83 100644
--- a/libs/WindowManager/Shell/res/values/colors_tv.xml
+++ b/libs/WindowManager/Shell/res/values/colors_tv.xml
@@ -16,8 +16,10 @@
-->
<resources>
<color name="tv_pip_menu_icon_focused">#0E0E0F</color>
- <color name="tv_pip_menu_icon_unfocused">#E8EAED</color>
+ <color name="tv_pip_menu_icon_unfocused">#F8F9FA</color>
<color name="tv_pip_menu_icon_disabled">#80868B</color>
+ <color name="tv_pip_menu_close_icon_bg_focused">#D93025</color>
+ <color name="tv_pip_menu_close_icon_bg_unfocused">#D69F261F</color>
<color name="tv_pip_menu_icon_bg_focused">#E8EAED</color>
<color name="tv_pip_menu_icon_bg_unfocused">#990E0E0F</color>
<color name="tv_pip_menu_focus_border">#E8EAED</color>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
index 84429948c643..31f0ef0192ae 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
@@ -165,8 +165,12 @@ public class ShellTaskOrganizer extends TaskOrganizer implements
private StartingWindowController mStartingWindow;
/**
- * In charge of showing compat UI. Can be {@code null} if device doesn't support size
- * compat.
+ * In charge of showing compat UI. Can be {@code null} if the device doesn't support size
+ * compat or if this isn't the main {@link ShellTaskOrganizer}.
+ *
+ * <p>NOTE: only the main {@link ShellTaskOrganizer} should have a {@link CompatUIController},
+ * and register itself as a {@link CompatUIController.CompatUICallback}. Subclasses should be
+ * initialized with a {@code null} {@link CompatUIController}.
*/
@Nullable
private final CompatUIController mCompatUI;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
index 13d12b3589c0..677c1c7d7759 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
@@ -2802,7 +2802,14 @@ public class BubbleStackView extends FrameLayout
mExpandedViewContainer.setVisibility(View.INVISIBLE);
mExpandedViewContainer.setAlpha(0f);
mExpandedViewContainer.addView(bev);
- bev.setManageClickListener((view) -> showManageMenu(!mShowingManage));
+
+ postDelayed(() -> {
+ // Set the Manage button click handler from postDelayed. This appears to resolve
+ // a race condition with adding the BubbleExpandedView view to the expanded view
+ // container. Due to the race condition the click handler sometimes is not set up
+ // correctly and is never called.
+ bev.setManageClickListener((view) -> showManageMenu(true /* show */));
+ }, 0);
if (!mIsExpansionAnimating) {
mSurfaceSynchronizer.syncSurfaceAndRun(() -> {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java
index 45833898e7c4..8d1afa4a1304 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java
@@ -344,7 +344,7 @@ public class SystemWindows {
@Override
public void resized(ClientWindowFrames frames, boolean reportDraw,
MergedConfiguration newMergedConfiguration, boolean forceLayout,
- boolean alwaysConsumeSystemBars, int displayId, int syncSeqId) {}
+ boolean alwaysConsumeSystemBars, int displayId, int syncSeqId, int resizeMode) {}
@Override
public void insetsChanged(InsetsState insetsState, boolean willMove, boolean willResize) {}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduWindowManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduWindowManager.java
index cc3a3b2206f3..35f1038a6853 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduWindowManager.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduWindowManager.java
@@ -51,7 +51,7 @@ public class LetterboxEduWindowManager extends CompatUIWindowManagerAbstract {
/**
* The name of the {@link SharedPreferences} that holds which user has seen the Letterbox
- * Education for specific packages and which user has seen the full dialog for any package.
+ * Education dialog.
*/
@VisibleForTesting
static final String HAS_SEEN_LETTERBOX_EDUCATION_PREF_NAME =
@@ -66,6 +66,13 @@ public class LetterboxEduWindowManager extends CompatUIWindowManagerAbstract {
private final Transitions mTransitions;
+ /**
+ * The id of the current user, to associate with a boolean in {@link
+ * #HAS_SEEN_LETTERBOX_EDUCATION_PREF_NAME}, indicating whether that user has already seen the
+ * Letterbox Education dialog.
+ */
+ private final int mUserId;
+
// Remember the last reported state in case visibility changes due to keyguard or IME updates.
private boolean mEligibleForLetterboxEducation;
@@ -98,6 +105,7 @@ public class LetterboxEduWindowManager extends CompatUIWindowManagerAbstract {
mTransitions = transitions;
mOnDismissCallback = onDismissCallback;
mAnimationController = animationController;
+ mUserId = taskInfo.userId;
mEligibleForLetterboxEducation = taskInfo.topActivityEligibleForLetterboxEducation;
mSharedPreferences = mContext.getSharedPreferences(HAS_SEEN_LETTERBOX_EDUCATION_PREF_NAME,
Context.MODE_PRIVATE);
@@ -133,7 +141,6 @@ public class LetterboxEduWindowManager extends CompatUIWindowManagerAbstract {
@Override
protected View createLayout() {
- setSeenLetterboxEducation();
mLayout = inflateLayout();
updateDialogMargins();
@@ -177,6 +184,7 @@ public class LetterboxEduWindowManager extends CompatUIWindowManagerAbstract {
// Dialog has already been released.
return;
}
+ setSeenLetterboxEducation();
mLayout.setDismissOnClickListener(this::onDismiss);
// Focus on the dialog title for accessibility.
mLayout.getDialogTitle().sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
@@ -241,7 +249,7 @@ public class LetterboxEduWindowManager extends CompatUIWindowManagerAbstract {
}
private String getPrefKey() {
- return String.valueOf(mContext.getUserId());
+ return String.valueOf(mUserId);
}
@VisibleForTesting
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
index 1ee9407d385d..026eeb09d741 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
@@ -190,15 +190,13 @@ public abstract class WMShellBaseModule {
@ShellMainThread ShellExecutor mainExecutor,
@ShellMainThread Handler mainHandler,
Context context,
- CompatUIController compatUI,
SyncTransactionQueue syncTransactionQueue,
DisplayController displayController,
DisplayInsetsController displayInsetsController,
Optional<RecentTasksController> recentTasksOptional
) {
- return new KidsModeTaskOrganizer(mainExecutor, mainHandler, context, compatUI,
- syncTransactionQueue, displayController, displayInsetsController,
- recentTasksOptional);
+ return new KidsModeTaskOrganizer(mainExecutor, mainHandler, context, syncTransactionQueue,
+ displayController, displayInsetsController, recentTasksOptional);
}
@WMSingleton
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizer.java
index 429eb9963794..003c55977841 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizer.java
@@ -38,7 +38,6 @@ import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;
import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.policy.ForceShowNavigationBarSettingsObserver;
@@ -48,7 +47,6 @@ import com.android.wm.shell.common.DisplayInsetsController;
import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.SyncTransactionQueue;
-import com.android.wm.shell.compatui.CompatUIController;
import com.android.wm.shell.recents.RecentTasksController;
import com.android.wm.shell.startingsurface.StartingWindowController;
@@ -136,13 +134,12 @@ public class KidsModeTaskOrganizer extends ShellTaskOrganizer {
ShellExecutor mainExecutor,
Handler mainHandler,
Context context,
- @Nullable CompatUIController compatUI,
SyncTransactionQueue syncTransactionQueue,
DisplayController displayController,
DisplayInsetsController displayInsetsController,
Optional<RecentTasksController> recentTasks,
ForceShowNavigationBarSettingsObserver forceShowNavigationBarSettingsObserver) {
- super(taskOrganizerController, mainExecutor, context, compatUI, recentTasks);
+ super(taskOrganizerController, mainExecutor, context, /* compatUI= */ null, recentTasks);
mContext = context;
mMainHandler = mainHandler;
mSyncQueue = syncTransactionQueue;
@@ -155,12 +152,11 @@ public class KidsModeTaskOrganizer extends ShellTaskOrganizer {
ShellExecutor mainExecutor,
Handler mainHandler,
Context context,
- @Nullable CompatUIController compatUI,
SyncTransactionQueue syncTransactionQueue,
DisplayController displayController,
DisplayInsetsController displayInsetsController,
Optional<RecentTasksController> recentTasks) {
- super(mainExecutor, context, compatUI, recentTasks);
+ super(mainExecutor, context, /* compatUI= */ null, recentTasks);
mContext = context;
mMainHandler = mainHandler;
mSyncQueue = syncTransactionQueue;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PinnedStackListenerForwarder.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PinnedStackListenerForwarder.java
index 3fefc4a0e0bf..87eca74acd0b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PinnedStackListenerForwarder.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PinnedStackListenerForwarder.java
@@ -72,9 +72,10 @@ public class PinnedStackListenerForwarder {
}
}
- private void onActionsChanged(ParceledListSlice<RemoteAction> actions) {
+ private void onActionsChanged(ParceledListSlice<RemoteAction> actions,
+ RemoteAction closeAction) {
for (PinnedTaskListener listener : mListeners) {
- listener.onActionsChanged(actions);
+ listener.onActionsChanged(actions, closeAction);
}
}
@@ -113,9 +114,10 @@ public class PinnedStackListenerForwarder {
}
@Override
- public void onActionsChanged(ParceledListSlice<RemoteAction> actions) {
+ public void onActionsChanged(ParceledListSlice<RemoteAction> actions,
+ RemoteAction closeAction) {
mMainExecutor.execute(() -> {
- PinnedStackListenerForwarder.this.onActionsChanged(actions);
+ PinnedStackListenerForwarder.this.onActionsChanged(actions, closeAction);
});
}
@@ -152,7 +154,8 @@ public class PinnedStackListenerForwarder {
public void onImeVisibilityChanged(boolean imeVisible, int imeHeight) {}
- public void onActionsChanged(ParceledListSlice<RemoteAction> actions) {}
+ public void onActionsChanged(ParceledListSlice<RemoteAction> actions,
+ RemoteAction closeAction) {}
public void onActivityHidden(ComponentName componentName) {}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipMenuController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipMenuController.java
index caa1f017082b..f6ff294b4328 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipMenuController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipMenuController.java
@@ -66,7 +66,7 @@ public interface PipMenuController {
/**
* Given a set of actions, update the menu.
*/
- void setAppActions(ParceledListSlice<RemoteAction> appActions);
+ void setAppActions(ParceledListSlice<RemoteAction> appActions, RemoteAction closeAction);
/**
* Resize the PiP menu with the given bounds. The PiP SurfaceControl is given if there is a
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
index e5a755c35add..48df28ee4cde 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
@@ -89,6 +89,8 @@ public class PipTransition extends PipTransitionController {
private final Rect mExitDestinationBounds = new Rect();
@Nullable
private IBinder mExitTransition;
+ private IBinder mRequestedEnterTransition;
+ private WindowContainerToken mRequestedEnterTask;
/** The Task window that is currently in PIP windowing mode. */
@Nullable
private WindowContainerToken mCurrentPipTaskToken;
@@ -201,6 +203,9 @@ public class PipTransition extends PipTransitionController {
}
mCurrentPipTaskToken = null;
return true;
+ } else if (transition == mRequestedEnterTransition) {
+ mRequestedEnterTransition = null;
+ mRequestedEnterTask = null;
}
// The previous PIP Task is no longer in PIP, but this is not an exit transition (This can
@@ -243,6 +248,8 @@ public class PipTransition extends PipTransitionController {
if (request.getType() == TRANSIT_PIP) {
WindowContainerTransaction wct = new WindowContainerTransaction();
if (mOneShotAnimationType == ANIM_TYPE_ALPHA) {
+ mRequestedEnterTransition = transition;
+ mRequestedEnterTask = request.getTriggerTask().token;
wct.setActivityWindowingMode(request.getTriggerTask().token,
WINDOWING_MODE_UNDEFINED);
final Rect destinationBounds = mPipBoundsAlgorithm.getEntryDestinationBounds();
@@ -255,6 +262,23 @@ public class PipTransition extends PipTransitionController {
}
@Override
+ public boolean handleRotateDisplay(int startRotation, int endRotation,
+ WindowContainerTransaction wct) {
+ if (mRequestedEnterTransition != null && mOneShotAnimationType == ANIM_TYPE_ALPHA) {
+ // A fade-in was requested but not-yet started. In this case, just recalculate the
+ // initial state under the new rotation.
+ int rotationDelta = deltaRotation(startRotation, endRotation);
+ if (rotationDelta != Surface.ROTATION_0) {
+ mPipBoundsState.getDisplayLayout().rotateTo(mContext.getResources(), endRotation);
+ final Rect destinationBounds = mPipBoundsAlgorithm.getEntryDestinationBounds();
+ wct.setBounds(mRequestedEnterTask, destinationBounds);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
public void onTransitionMerged(@NonNull IBinder transition) {
if (transition != mExitTransition) {
return;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java
index 02e713d2eaa3..24993c621e3c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java
@@ -196,6 +196,17 @@ public abstract class PipTransitionController implements Transitions.TransitionH
}
/**
+ * Called when the display is going to rotate.
+ *
+ * @return {@code true} if it was handled, otherwise the existing pip logic
+ * will deal with rotation.
+ */
+ public boolean handleRotateDisplay(int startRotation, int endRotation,
+ WindowContainerTransaction wct) {
+ return false;
+ }
+
+ /**
* Callback interface for PiP transitions (both from and to PiP mode)
*/
public interface PipTransitionCallback {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java
index c4dadf1f739a..5e4c12ed37ed 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java
@@ -474,7 +474,8 @@ public class PhonePipMenuController implements PipMenuController {
* Sets the menu actions to the actions provided by the current PiP menu.
*/
@Override
- public void setAppActions(ParceledListSlice<RemoteAction> appActions) {
+ public void setAppActions(ParceledListSlice<RemoteAction> appActions,
+ RemoteAction closeAction) {
mAppActions = appActions;
updateMenuActions();
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
index e7a1c4cca07e..ba522c072f11 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
@@ -143,6 +143,9 @@ public class PipController implements PipTransitionController.PipTransitionCallb
*/
private final DisplayChangeController.OnDisplayChangingListener mRotationController = (
int displayId, int fromRotation, int toRotation, WindowContainerTransaction t) -> {
+ if (mPipTransitionController.handleRotateDisplay(fromRotation, toRotation, t)) {
+ return;
+ }
if (mPipBoundsState.getDisplayLayout().rotation() == toRotation) {
// The same rotation may have been set by auto PiP-able or fixed rotation. So notify
// the change with fromRotation=false to apply the rotated destination bounds from
@@ -246,8 +249,9 @@ public class PipController implements PipTransitionController.PipTransitionCallb
}
@Override
- public void onActionsChanged(ParceledListSlice<RemoteAction> actions) {
- mMenuController.setAppActions(actions);
+ public void onActionsChanged(ParceledListSlice<RemoteAction> actions,
+ RemoteAction closeAction) {
+ mMenuController.setAppActions(actions, closeAction);
}
@Override
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java
index f397ac01e60d..46b8e6098273 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java
@@ -22,6 +22,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import android.annotation.IntDef;
import android.app.ActivityManager;
import android.app.ActivityTaskManager;
+import android.app.PendingIntent;
import android.app.RemoteAction;
import android.app.TaskInfo;
import android.content.ComponentName;
@@ -69,7 +70,7 @@ public class TvPipController implements PipTransitionController.PipTransitionCal
private static final int NONEXISTENT_TASK_ID = -1;
@Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = { "STATE_" }, value = {
+ @IntDef(prefix = {"STATE_"}, value = {
STATE_NO_PIP,
STATE_PIP,
STATE_PIP_MENU,
@@ -109,6 +110,10 @@ public class TvPipController implements PipTransitionController.PipTransitionCal
private int mPinnedTaskId = NONEXISTENT_TASK_ID;
private Runnable mUnstashRunnable;
+ private RemoteAction mCloseAction;
+ // How long the shell will wait for the app to close the PiP if a custom action is set.
+ private int mPipForceCloseDelay;
+
private int mResizeAnimationDuration;
public static Pip create(
@@ -229,11 +234,12 @@ public class TvPipController implements PipTransitionController.PipTransitionCal
}
setState(STATE_PIP_MENU);
+ mTvPipMenuController.showMenu();
updatePinnedStackBounds();
}
@Override
- public void closeMenu() {
+ public void onMenuClosed() {
if (DEBUG) {
ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
"%s: closeMenu(), state before=%s", TAG, stateToName(mState));
@@ -280,6 +286,12 @@ public class TvPipController implements PipTransitionController.PipTransitionCal
}
@Override
+ public void enterPipMovementMenu() {
+ setState(STATE_PIP_MENU);
+ mTvPipMenuController.showMovementMenuOnly();
+ }
+
+ @Override
public void movePip(int keycode) {
if (mTvPipBoundsAlgorithm.updateGravity(keycode)) {
mTvPipMenuController.updateGravity(mTvPipBoundsState.getTvPipGravity());
@@ -369,9 +381,29 @@ public class TvPipController implements PipTransitionController.PipTransitionCal
public void closePip() {
if (DEBUG) {
ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
- "%s: closePip(), state=%s", TAG, stateToName(mState));
+ "%s: closePip(), state=%s, loseAction=%s", TAG, stateToName(mState),
+ mCloseAction);
}
+ if (mCloseAction != null) {
+ try {
+ mCloseAction.getActionIntent().send();
+ } catch (PendingIntent.CanceledException e) {
+ ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: Failed to send close action, %s", TAG, e);
+ }
+ mMainExecutor.executeDelayed(() -> closeCurrentPiP(mPinnedTaskId), mPipForceCloseDelay);
+ } else {
+ closeCurrentPiP(mPinnedTaskId);
+ }
+ }
+
+ private void closeCurrentPiP(int pinnedTaskId) {
+ if (mPinnedTaskId != pinnedTaskId) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: PiP has already been closed by custom close action", TAG);
+ return;
+ }
removeTask(mPinnedTaskId);
onPipDisappeared();
}
@@ -413,7 +445,7 @@ public class TvPipController implements PipTransitionController.PipTransitionCal
}
mPipNotificationController.dismiss();
- mTvPipMenuController.hideMenu();
+ mTvPipMenuController.closeMenu();
mTvPipBoundsState.resetTvPipState();
setState(STATE_NO_PIP);
mPinnedTaskId = NONEXISTENT_TASK_ID;
@@ -453,21 +485,12 @@ public class TvPipController implements PipTransitionController.PipTransitionCal
TAG, stateToName(state), stateToName(mState));
}
mState = state;
-
- if (mState == STATE_PIP_MENU) {
- if (DEBUG) {
- ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
- "%s: > show menu", TAG);
- }
- mTvPipMenuController.showMenu();
- }
-
- updatePinnedStackBounds();
}
private void loadConfigurations() {
final Resources res = mContext.getResources();
mResizeAnimationDuration = res.getInteger(R.integer.config_pipResizeAnimationDuration);
+ mPipForceCloseDelay = res.getInteger(R.integer.config_pipForceCloseDelay);
}
private void registerTaskStackListenerCallback(TaskStackListenerImpl taskStackListener) {
@@ -592,13 +615,15 @@ public class TvPipController implements PipTransitionController.PipTransitionCal
public void onMovementBoundsChanged(boolean fromImeAdjustment) {}
@Override
- public void onActionsChanged(ParceledListSlice<RemoteAction> actions) {
+ public void onActionsChanged(ParceledListSlice<RemoteAction> actions,
+ RemoteAction closeAction) {
if (DEBUG) {
ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
"%s: onActionsChanged()", TAG);
}
- mTvPipMenuController.setAppActions(actions);
+ mTvPipMenuController.setAppActions(actions, closeAction);
+ mCloseAction = closeAction;
}
});
} catch (RemoteException e) {
@@ -617,7 +642,7 @@ public class TvPipController implements PipTransitionController.PipTransitionCal
WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED);
if (DEBUG) {
ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
- "%s: > taskInfo=%s", TAG, taskInfo);
+ "%s: taskInfo=%s", TAG, taskInfo);
}
return taskInfo;
} catch (RemoteException e) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuActionButton.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuActionButton.java
index 4eb46d93c887..abbc614b4b4f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuActionButton.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuActionButton.java
@@ -126,4 +126,15 @@ public class TvPipMenuActionButton extends RelativeLayout implements View.OnClic
public boolean isEnabled() {
return mButtonView.isEnabled();
}
+
+ void setIsCustomCloseAction(boolean isCustomCloseAction) {
+ mIconImageView.setImageTintList(
+ getResources().getColorStateList(
+ isCustomCloseAction ? R.color.tv_pip_menu_close_icon
+ : R.color.tv_pip_menu_icon));
+ mButtonView.setBackgroundTintList(getResources()
+ .getColorStateList(isCustomCloseAction ? R.color.tv_pip_menu_close_icon_bg
+ : R.color.tv_pip_menu_icon_bg));
+ }
+
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuController.java
index 1a035c5a68db..35c34ac8315f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuController.java
@@ -45,6 +45,7 @@ import com.android.wm.shell.protolog.ShellProtoLogGroup;
import java.util.ArrayList;
import java.util.List;
+import java.util.Objects;
/**
* Manages the visibility of the PiP Menu as user interacts with PiP.
@@ -64,9 +65,13 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis
// User can actively move the PiP via the DPAD.
private boolean mInMoveMode;
+ // Used when only showing the move menu since we want to close the menu completely when
+ // exiting the move menu instead of showing the regular button menu.
+ private boolean mCloseAfterExitMoveMenu;
private final List<RemoteAction> mMediaActions = new ArrayList<>();
private final List<RemoteAction> mAppActions = new ArrayList<>();
+ private RemoteAction mCloseAction;
private SyncRtSurfaceTransactionApplier mApplier;
RectF mTmpSourceRectF = new RectF();
@@ -100,7 +105,7 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis
final BroadcastReceiver closeSystemDialogsBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
- hideMenu();
+ closeMenu();
}
};
context.registerReceiverForAllUsers(closeSystemDialogsBroadcastReceiver,
@@ -153,29 +158,49 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis
0, SHELL_ROOT_LAYER_PIP);
}
+ void showMovementMenuOnly() {
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: showMovementMenuOnly()", TAG);
+ }
+ mInMoveMode = true;
+ mCloseAfterExitMoveMenu = true;
+ showMenuInternal();
+ }
+
@Override
public void showMenu() {
if (DEBUG) {
ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
"%s: showMenu()", TAG);
}
+ mInMoveMode = false;
+ mCloseAfterExitMoveMenu = false;
+ showMenuInternal();
+ }
- if (mPipMenuView != null) {
- Rect menuBounds = getMenuBounds(mTvPipBoundsState.getBounds());
- mSystemWindows.updateViewLayout(mPipMenuView, getPipMenuLayoutParams(
- MENU_WINDOW_TITLE, menuBounds.width(), menuBounds.height()));
- maybeUpdateMenuViewActions();
- updateExpansionState();
-
- SurfaceControl menuSurfaceControl = getSurfaceControl();
- if (menuSurfaceControl != null) {
- SurfaceControl.Transaction t = new SurfaceControl.Transaction();
- t.setRelativeLayer(mPipMenuView.getWindowSurfaceControl(), mLeash, 1);
- t.setPosition(menuSurfaceControl, menuBounds.left, menuBounds.top);
- t.apply();
- }
- grantPipMenuFocus(true);
- mPipMenuView.show(mInMoveMode, mDelegate.getPipGravity());
+ private void showMenuInternal() {
+ if (mPipMenuView == null) {
+ return;
+ }
+ Rect menuBounds = getMenuBounds(mTvPipBoundsState.getBounds());
+ mSystemWindows.updateViewLayout(mPipMenuView, getPipMenuLayoutParams(
+ MENU_WINDOW_TITLE, menuBounds.width(), menuBounds.height()));
+ maybeUpdateMenuViewActions();
+ updateExpansionState();
+
+ SurfaceControl menuSurfaceControl = getSurfaceControl();
+ if (menuSurfaceControl != null) {
+ SurfaceControl.Transaction t = new SurfaceControl.Transaction();
+ t.setRelativeLayer(mPipMenuView.getWindowSurfaceControl(), mLeash, 1);
+ t.setPosition(menuSurfaceControl, menuBounds.left, menuBounds.top);
+ t.apply();
+ }
+ grantPipMenuFocus(true);
+ if (mInMoveMode) {
+ mPipMenuView.showMoveMenu(mDelegate.getPipGravity());
+ } else {
+ mPipMenuView.showButtonMenu();
}
}
@@ -197,25 +222,18 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis
return menuBounds;
}
- void hideMenu() {
- if (!isMenuVisible()) {
- if (DEBUG) {
- ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
- "%s: hideMenu() - Menu isn't visible, so don't hide", TAG);
- }
+ void closeMenu() {
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: closeMenu()", TAG);
+ }
+ if (mPipMenuView == null) {
return;
- } else {
- if (DEBUG) {
- ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
- "%s: hideMenu()", TAG);
- }
}
- mPipMenuView.hide();
- if (!mInMoveMode) {
- grantPipMenuFocus(false);
- mDelegate.closeMenu();
- }
+ mPipMenuView.hideAll();
+ grantPipMenuFocus(false);
+ mDelegate.onMenuClosed();
}
boolean isInMoveMode() {
@@ -226,25 +244,29 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis
public void onEnterMoveMode() {
if (DEBUG) {
ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
- "%s: onEnterMoveMode - %b", TAG, mInMoveMode);
+ "%s: onEnterMoveMode - %b, close when exiting move menu: %b", TAG, mInMoveMode,
+ mCloseAfterExitMoveMenu);
}
mInMoveMode = true;
- mPipMenuView.showMenuButtons(false);
- mPipMenuView.showMovementHints(mDelegate.getPipGravity());
- mDelegate.onInMoveModeChanged();
+ mPipMenuView.showMoveMenu(mDelegate.getPipGravity());
}
@Override
public boolean onExitMoveMode() {
if (DEBUG) {
ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
- "%s: onExitMoveMode - %b", TAG, mInMoveMode);
+ "%s: onExitMoveMode - %b, close when exiting move menu: %b", TAG, mInMoveMode,
+ mCloseAfterExitMoveMenu);
+ }
+ if (mCloseAfterExitMoveMenu) {
+ mInMoveMode = false;
+ mCloseAfterExitMoveMenu = false;
+ closeMenu();
+ return true;
}
if (mInMoveMode) {
mInMoveMode = false;
- mPipMenuView.showMenuButtons(true);
- mPipMenuView.hideMovementHints();
- mDelegate.onInMoveModeChanged();
+ mPipMenuView.showButtonMenu();
return true;
}
return false;
@@ -264,18 +286,18 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis
@Override
public void detach() {
- hideMenu();
+ closeMenu();
detachPipMenuView();
mLeash = null;
}
@Override
- public void setAppActions(ParceledListSlice<RemoteAction> actions) {
+ public void setAppActions(ParceledListSlice<RemoteAction> actions, RemoteAction closeAction) {
if (DEBUG) {
ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
"%s: setAppActions()", TAG);
}
- updateAdditionalActionsList(mAppActions, actions.getList());
+ updateAdditionalActionsList(mAppActions, actions.getList(), closeAction);
}
private void onMediaActionsChanged(List<RemoteAction> actions) {
@@ -291,17 +313,19 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis
enabledActions.add(remoteAction);
}
}
- updateAdditionalActionsList(mMediaActions, enabledActions);
+ updateAdditionalActionsList(mMediaActions, enabledActions, mCloseAction);
}
- private void updateAdditionalActionsList(
- List<RemoteAction> destination, @Nullable List<RemoteAction> source) {
+ private void updateAdditionalActionsList(List<RemoteAction> destination,
+ @Nullable List<RemoteAction> source, RemoteAction closeAction) {
final int number = source != null ? source.size() : 0;
- if (number == 0 && destination.isEmpty()) {
+ if (number == 0 && destination.isEmpty() && Objects.equals(closeAction, mCloseAction)) {
// Nothing changed.
return;
}
+ mCloseAction = closeAction;
+
destination.clear();
if (number > 0) {
destination.addAll(source);
@@ -314,9 +338,9 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis
return;
}
if (!mAppActions.isEmpty()) {
- mPipMenuView.setAdditionalActions(mAppActions, mMainHandler);
+ mPipMenuView.setAdditionalActions(mAppActions, mCloseAction, mMainHandler);
} else {
- mPipMenuView.setAdditionalActions(mMediaActions, mMainHandler);
+ mPipMenuView.setAdditionalActions(mMediaActions, mCloseAction, mMainHandler);
}
}
@@ -482,7 +506,7 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis
@Override
public void onBackPress() {
if (!onExitMoveMode()) {
- hideMenu();
+ closeMenu();
}
}
@@ -512,7 +536,7 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis
void togglePipExpansion();
- void closeMenu();
+ void onMenuClosed();
void closePip();
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuView.java
index 984dea2c016e..ccd054aa7680 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuView.java
@@ -50,6 +50,7 @@ import com.android.wm.shell.protolog.ShellProtoLogGroup;
import java.util.ArrayList;
import java.util.List;
+import java.util.Objects;
/**
* A View that represents Pip Menu on TV. It's responsible for displaying 3 ever-present Pip Menu
@@ -78,6 +79,7 @@ public class TvPipMenuView extends FrameLayout implements View.OnClickListener {
private Rect mCurrentBounds;
private final TvPipMenuActionButton mExpandButton;
+ private final TvPipMenuActionButton mCloseButton;
public TvPipMenuView(@NonNull Context context) {
this(context, null);
@@ -100,8 +102,11 @@ public class TvPipMenuView extends FrameLayout implements View.OnClickListener {
mActionButtonsContainer = findViewById(R.id.tv_pip_menu_action_buttons);
mActionButtonsContainer.findViewById(R.id.tv_pip_menu_fullscreen_button)
.setOnClickListener(this);
- mActionButtonsContainer.findViewById(R.id.tv_pip_menu_close_button)
- .setOnClickListener(this);
+
+ mCloseButton = mActionButtonsContainer.findViewById(R.id.tv_pip_menu_close_button);
+ mCloseButton.setOnClickListener(this);
+ mCloseButton.setIsCustomCloseAction(true);
+
mActionButtonsContainer.findViewById(R.id.tv_pip_menu_move_button)
.setOnClickListener(this);
mExpandButton = findViewById(R.id.tv_pip_menu_expand_button);
@@ -172,29 +177,43 @@ public class TvPipMenuView extends FrameLayout implements View.OnClickListener {
expanded ? R.string.pip_collapse : R.string.pip_expand);
}
- void show(boolean inMoveMode, int gravity) {
+ /**
+ * @param gravity for the arrow hints
+ */
+ void showMoveMenu(int gravity) {
if (DEBUG) {
- ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
- "%s: show(), inMoveMode: %b", TAG, inMoveMode);
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, "%s: showMoveMenu()", TAG);
}
- if (inMoveMode) {
- showMovementHints(gravity);
- } else {
- animateAlphaTo(1, mActionButtonsContainer);
+ showMenuButtons(false);
+ showMovementHints(gravity);
+ showMenuFrame(true);
+ }
+
+ void showButtonMenu() {
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, "%s: showButtonMenu()", TAG);
}
- animateAlphaTo(1, mMenuFrameView);
+ showMenuButtons(true);
+ hideMovementHints();
+ showMenuFrame(true);
}
- void hide() {
+ /**
+ * Hides all menu views, including the menu frame.
+ */
+ void hideAll() {
if (DEBUG) {
- ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, "%s: hide()", TAG);
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, "%s: hideAll()", TAG);
}
- animateAlphaTo(0, mActionButtonsContainer);
- animateAlphaTo(0, mMenuFrameView);
+ showMenuButtons(false);
hideMovementHints();
+ showMenuFrame(false);
}
private void animateAlphaTo(float alpha, View view) {
+ if (view.getAlpha() == alpha) {
+ return;
+ }
view.animate()
.alpha(alpha)
.setInterpolator(alpha == 0f ? TvPipInterpolators.EXIT : TvPipInterpolators.ENTER)
@@ -220,12 +239,24 @@ public class TvPipMenuView extends FrameLayout implements View.OnClickListener {
|| mArrowLeft.getAlpha() != 0f;
}
- void setAdditionalActions(List<RemoteAction> actions, Handler mainHandler) {
+ void setAdditionalActions(List<RemoteAction> actions, RemoteAction closeAction,
+ Handler mainHandler) {
if (DEBUG) {
ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
"%s: setAdditionalActions()", TAG);
}
+ // Replace system close action with custom close action if available
+ if (closeAction != null) {
+ setActionForButton(closeAction, mCloseButton, mainHandler);
+ } else {
+ mCloseButton.setTextAndDescription(R.string.pip_close);
+ mCloseButton.setImageResource(R.drawable.pip_ic_close_white);
+ }
+ mCloseButton.setIsCustomCloseAction(closeAction != null);
+ // Make sure the close action is always enabled
+ mCloseButton.setEnabled(true);
+
// Make sure we exactly as many additional buttons as we have actions to display.
final int actionsNumber = actions.size();
int buttonsNumber = mAdditionalButtons.size();
@@ -256,14 +287,37 @@ public class TvPipMenuView extends FrameLayout implements View.OnClickListener {
for (int index = 0; index < actionsNumber; index++) {
final RemoteAction action = actions.get(index);
final TvPipMenuActionButton button = mAdditionalButtons.get(index);
- button.setVisibility(View.VISIBLE); // Ensure the button is visible.
- button.setTextAndDescription(action.getContentDescription());
- button.setEnabled(action.isEnabled());
- button.setTag(action);
- action.getIcon().loadDrawableAsync(mContext, button::setImageDrawable, mainHandler);
+
+ // Remove action if it matches the custom close action.
+ if (actionsMatch(action, closeAction)) {
+ button.setVisibility(GONE);
+ continue;
+ }
+ setActionForButton(action, button, mainHandler);
}
}
+ /**
+ * Checks whether title, description and intent match.
+ * Comparing icons would be good, but using equals causes false negatives
+ */
+ private boolean actionsMatch(RemoteAction action1, RemoteAction action2) {
+ if (action1 == action2) return true;
+ if (action1 == null) return false;
+ return Objects.equals(action1.getTitle(), action2.getTitle())
+ && Objects.equals(action1.getContentDescription(), action2.getContentDescription())
+ && Objects.equals(action1.getActionIntent(), action2.getActionIntent());
+ }
+
+ private void setActionForButton(RemoteAction action, TvPipMenuActionButton button,
+ Handler mainHandler) {
+ button.setVisibility(View.VISIBLE); // Ensure the button is visible.
+ button.setTextAndDescription(action.getContentDescription());
+ button.setEnabled(action.isEnabled());
+ button.setTag(action);
+ action.getIcon().loadDrawableAsync(mContext, button::setImageDrawable, mainHandler);
+ }
+
@Nullable
SurfaceControl getWindowSurfaceControl() {
final ViewRootImpl root = getViewRootImpl();
@@ -379,6 +433,10 @@ public class TvPipMenuView extends FrameLayout implements View.OnClickListener {
animateAlphaTo(show ? 1 : 0, mActionButtonsContainer);
}
+ private void showMenuFrame(boolean show) {
+ animateAlphaTo(show ? 1 : 0, mMenuFrameView);
+ }
+
interface Listener {
void onBackPress();
@@ -386,7 +444,10 @@ public class TvPipMenuView extends FrameLayout implements View.OnClickListener {
void onEnterMoveMode();
/**
- * @return whether move mode was exited
+ * Called when a button for exiting move mode was pressed.
+ *
+ * @return true if the event was handled or false if the key event should be handled by the
+ * next receiver.
*/
boolean onExitMoveMode();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipNotificationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipNotificationController.java
index 7bd3ce9c45b2..4033f030b702 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipNotificationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipNotificationController.java
@@ -56,6 +56,10 @@ public class TvPipNotificationController {
"com.android.wm.shell.pip.tv.notification.action.SHOW_PIP_MENU";
private static final String ACTION_CLOSE_PIP =
"com.android.wm.shell.pip.tv.notification.action.CLOSE_PIP";
+ private static final String ACTION_MOVE_PIP =
+ "com.android.wm.shell.pip.tv.notification.action.MOVE_PIP";
+ private static final String ACTION_TOGGLE_EXPANDED_PIP =
+ "com.android.wm.shell.pip.tv.notification.action.TOGGLE_EXPANDED_PIP";
private final Context mContext;
private final PackageManager mPackageManager;
@@ -222,6 +226,8 @@ public class TvPipNotificationController {
mIntentFilter = new IntentFilter();
mIntentFilter.addAction(ACTION_CLOSE_PIP);
mIntentFilter.addAction(ACTION_SHOW_PIP_MENU);
+ mIntentFilter.addAction(ACTION_MOVE_PIP);
+ mIntentFilter.addAction(ACTION_TOGGLE_EXPANDED_PIP);
}
boolean mRegistered = false;
@@ -252,6 +258,10 @@ public class TvPipNotificationController {
mDelegate.showPictureInPictureMenu();
} else if (ACTION_CLOSE_PIP.equals(action)) {
mDelegate.closePip();
+ } else if (ACTION_MOVE_PIP.equals(action)) {
+ mDelegate.enterPipMovementMenu();
+ } else if (ACTION_TOGGLE_EXPANDED_PIP.equals(action)) {
+ mDelegate.togglePipExpansion();
}
}
}
@@ -259,5 +269,7 @@ public class TvPipNotificationController {
interface Delegate {
void showPictureInPictureMenu();
void closePip();
+ void enterPipMovementMenu();
+ void togglePipExpansion();
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java
index f0fb69f43499..b6c8cffb9699 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java
@@ -301,8 +301,6 @@ public class SplashscreenContentDrawer {
Color.TRANSPARENT);
attrs.mSplashScreenIcon = safeReturnAttrDefault((def) -> typedArray.getDrawable(
R.styleable.Window_windowSplashScreenAnimatedIcon), null);
- attrs.mAnimationDuration = safeReturnAttrDefault((def) -> typedArray.getInt(
- R.styleable.Window_windowSplashScreenAnimationDuration, def), 0);
attrs.mBrandingImage = safeReturnAttrDefault((def) -> typedArray.getDrawable(
R.styleable.Window_windowSplashScreenBrandingImage), null);
attrs.mIconBgColor = safeReturnAttrDefault((def) -> typedArray.getColor(
@@ -310,9 +308,8 @@ public class SplashscreenContentDrawer {
Color.TRANSPARENT);
typedArray.recycle();
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_STARTING_WINDOW,
- "getWindowAttrs: window attributes color: %s, replace icon: %b, avd duration: %d",
- Integer.toHexString(attrs.mWindowBgColor), attrs.mSplashScreenIcon != null,
- attrs.mAnimationDuration);
+ "getWindowAttrs: window attributes color: %s, replace icon: %b",
+ Integer.toHexString(attrs.mWindowBgColor), attrs.mSplashScreenIcon != null);
}
/** Creates the wrapper with system theme to avoid unexpected styles from app. */
@@ -327,7 +324,6 @@ public class SplashscreenContentDrawer {
private Drawable mSplashScreenIcon = null;
private Drawable mBrandingImage = null;
private int mIconBgColor = Color.TRANSPARENT;
- private int mAnimationDuration = 0;
}
/**
@@ -401,16 +397,13 @@ public class SplashscreenContentDrawer {
SplashScreenView build() {
Drawable iconDrawable;
- final long animationDuration;
if (mSuggestType == STARTING_WINDOW_TYPE_SOLID_COLOR_SPLASH_SCREEN
|| mSuggestType == STARTING_WINDOW_TYPE_LEGACY_SPLASH_SCREEN) {
// empty or legacy splash screen case
- animationDuration = 0;
mFinalIconSize = 0;
} else if (mTmpAttrs.mSplashScreenIcon != null) {
// Using the windowSplashScreenAnimatedIcon attribute
iconDrawable = mTmpAttrs.mSplashScreenIcon;
- animationDuration = mTmpAttrs.mAnimationDuration;
// There is no background below the icon, so scale the icon up
if (mTmpAttrs.mIconBgColor == Color.TRANSPARENT
@@ -440,11 +433,9 @@ public class SplashscreenContentDrawer {
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
createIconDrawable(new BitmapDrawable(bitmap), true);
}
- animationDuration = 0;
}
- return fillViewWithIcon(mFinalIconSize, mFinalIconDrawables, animationDuration,
- mUiThreadInitTask);
+ return fillViewWithIcon(mFinalIconSize, mFinalIconDrawables, mUiThreadInitTask);
}
private class ShapeIconFactory extends BaseIconFactory {
@@ -460,7 +451,7 @@ public class SplashscreenContentDrawer {
} else {
mFinalIconDrawables = SplashscreenIconDrawableFactory.makeIconDrawable(
mTmpAttrs.mIconBgColor, mThemeColor, iconDrawable, mDefaultIconSize,
- mFinalIconSize, mSplashscreenWorkerHandler, mSplashScreenExecutor);
+ mFinalIconSize, mSplashscreenWorkerHandler);
}
}
@@ -520,7 +511,7 @@ public class SplashscreenContentDrawer {
}
private SplashScreenView fillViewWithIcon(int iconSize, @Nullable Drawable[] iconDrawable,
- long animationDuration, Consumer<Runnable> uiThreadInitTask) {
+ Consumer<Runnable> uiThreadInitTask) {
Drawable foreground = null;
Drawable background = null;
if (iconDrawable != null) {
@@ -536,7 +527,6 @@ public class SplashscreenContentDrawer {
.setIconSize(iconSize)
.setIconBackground(background)
.setCenterViewDrawable(foreground)
- .setAnimationDurationMillis(animationDuration)
.setUiThreadInitConsumer(uiThreadInitTask)
.setAllowHandleSolidColor(mAllowHandleSolidColor);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenIconDrawableFactory.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenIconDrawableFactory.java
index fdd5a1578f41..5f52071bf950 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenIconDrawableFactory.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenIconDrawableFactory.java
@@ -44,7 +44,6 @@ import android.util.PathParser;
import android.window.SplashScreenView;
import com.android.internal.R;
-import com.android.wm.shell.common.ShellExecutor;
import java.util.function.LongConsumer;
@@ -63,15 +62,14 @@ public class SplashscreenIconDrawableFactory {
*/
static Drawable[] makeIconDrawable(@ColorInt int backgroundColor, @ColorInt int themeColor,
@NonNull Drawable foregroundDrawable, int srcIconSize, int iconSize,
- Handler splashscreenWorkerHandler, ShellExecutor splashScreenExecutor) {
+ Handler splashscreenWorkerHandler) {
Drawable foreground;
Drawable background = null;
boolean drawBackground =
backgroundColor != Color.TRANSPARENT && backgroundColor != themeColor;
if (foregroundDrawable instanceof Animatable) {
- foreground = new AnimatableIconAnimateListener(foregroundDrawable,
- splashScreenExecutor);
+ foreground = new AnimatableIconAnimateListener(foregroundDrawable);
} else if (foregroundDrawable instanceof AdaptiveIconDrawable) {
// If the icon is Adaptive, we already use the icon background.
drawBackground = false;
@@ -274,12 +272,9 @@ public class SplashscreenIconDrawableFactory {
private boolean mAnimationTriggered;
private AnimatorListenerAdapter mJankMonitoringListener;
private boolean mRunning;
- private long mDuration;
private LongConsumer mStartListener;
- private final ShellExecutor mSplashScreenExecutor;
- AnimatableIconAnimateListener(@NonNull Drawable foregroundDrawable,
- ShellExecutor splashScreenExecutor) {
+ AnimatableIconAnimateListener(@NonNull Drawable foregroundDrawable) {
super(foregroundDrawable);
Callback callback = new Callback() {
@Override
@@ -299,7 +294,6 @@ public class SplashscreenIconDrawableFactory {
}
};
mForegroundDrawable.setCallback(callback);
- mSplashScreenExecutor = splashScreenExecutor;
mAnimatableIcon = (Animatable) mForegroundDrawable;
}
@@ -309,9 +303,8 @@ public class SplashscreenIconDrawableFactory {
}
@Override
- public void prepareAnimate(long duration, LongConsumer startListener) {
+ public void prepareAnimate(LongConsumer startListener) {
stopAnimation();
- mDuration = duration;
mStartListener = startListener;
}
@@ -328,11 +321,11 @@ public class SplashscreenIconDrawableFactory {
mJankMonitoringListener.onAnimationCancel(null);
}
if (mStartListener != null) {
- mStartListener.accept(mDuration);
+ mStartListener.accept(0);
}
return;
}
- long animDuration = mDuration;
+ long animDuration = 0;
if (mAnimatableIcon instanceof AnimatedVectorDrawable
&& ((AnimatedVectorDrawable) mAnimatableIcon).getTotalDuration() > 0) {
animDuration = ((AnimatedVectorDrawable) mAnimatableIcon).getTotalDuration();
@@ -341,9 +334,8 @@ public class SplashscreenIconDrawableFactory {
animDuration = ((AnimationDrawable) mAnimatableIcon).getTotalDuration();
}
mRunning = true;
- mSplashScreenExecutor.executeDelayed(this::stopAnimation, animDuration);
if (mStartListener != null) {
- mStartListener.accept(Math.max(animDuration, 0));
+ mStartListener.accept(animDuration);
}
}
@@ -359,7 +351,6 @@ public class SplashscreenIconDrawableFactory {
@Override
public void stopAnimation() {
if (mRunning) {
- mSplashScreenExecutor.removeCallbacks(this::stopAnimation);
onAnimationEnd();
mJankMonitoringListener = null;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java
index 49f907b0a8ca..0d46199bde77 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java
@@ -535,7 +535,7 @@ public class TaskSnapshotWindow {
@Override
public void resized(ClientWindowFrames frames, boolean reportDraw,
MergedConfiguration mergedConfiguration, boolean forceLayout,
- boolean alwaysConsumeSystemBars, int displayId, int seqId) {
+ boolean alwaysConsumeSystemBars, int displayId, int seqId, int resizeMode) {
if (mOuter != null) {
mOuter.mSplashScreenExecutor.execute(() -> {
if (mergedConfiguration != null
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
index a225f4ec8349..b0e44a15b0da 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
@@ -189,7 +189,7 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
}
private void updateEnterpriseThumbnailDrawable() {
- mEnterpriseThumbnailDrawable = mDevicePolicyManager.getDrawable(
+ mEnterpriseThumbnailDrawable = mDevicePolicyManager.getResources().getDrawable(
WORK_PROFILE_ICON, OUTLINE, PROFILE_SWITCH_ANIMATION,
() -> mContext.getDrawable(R.drawable.ic_corp_badge));
}
@@ -434,6 +434,10 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
// If available use the background color provided through AnimationOptions
backgroundColorForTransition =
info.getAnimationOptions().getBackgroundColor();
+ } else if (a.getBackgroundColor() != 0) {
+ // Otherwise fallback on the background color provided through the animation
+ // definition.
+ backgroundColorForTransition = a.getBackgroundColor();
} else if (change.getBackgroundColor() != 0) {
// Otherwise default to the window's background color if provided through
// the theme as the background color for the animation - the top most window
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java
index 4607d8acc63e..596100dcdead 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java
@@ -143,9 +143,7 @@ public class CompatUIControllerTest extends ShellTestCase {
// Verify that the compat controls and letterbox education are updated with new size compat
// info.
- clearInvocations(mMockCompatLayout);
- clearInvocations(mMockLetterboxEduLayout);
- clearInvocations(mController);
+ clearInvocations(mMockCompatLayout, mMockLetterboxEduLayout, mController);
taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true,
CAMERA_COMPAT_CONTROL_TREATMENT_APPLIED);
mController.onCompatInfoChanged(taskInfo, mMockTaskListener);
@@ -156,9 +154,7 @@ public class CompatUIControllerTest extends ShellTestCase {
true);
// Verify that compat controls and letterbox education are removed with null task listener.
- clearInvocations(mMockCompatLayout);
- clearInvocations(mMockLetterboxEduLayout);
- clearInvocations(mController);
+ clearInvocations(mMockCompatLayout, mMockLetterboxEduLayout, mController);
mController.onCompatInfoChanged(createTaskInfo(DISPLAY_ID, TASK_ID,
/* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN),
/* taskListener= */ null);
@@ -181,9 +177,7 @@ public class CompatUIControllerTest extends ShellTestCase {
eq(mMockTaskListener));
// Verify that the layout is created again.
- clearInvocations(mMockCompatLayout);
- clearInvocations(mMockLetterboxEduLayout);
- clearInvocations(mController);
+ clearInvocations(mMockCompatLayout, mMockLetterboxEduLayout, mController);
mController.onCompatInfoChanged(taskInfo, mMockTaskListener);
verify(mMockCompatLayout, never()).updateCompatInfo(any(), any(), anyBoolean());
@@ -206,9 +200,7 @@ public class CompatUIControllerTest extends ShellTestCase {
verify(mController).createLetterboxEduWindowManager(any(), eq(taskInfo),
eq(mMockTaskListener));
- clearInvocations(mMockCompatLayout);
- clearInvocations(mMockLetterboxEduLayout);
- clearInvocations(mController);
+ clearInvocations(mMockCompatLayout, mMockLetterboxEduLayout, mController);
mController.onCompatInfoChanged(taskInfo, mMockTaskListener);
verify(mMockCompatLayout).updateCompatInfo(taskInfo, mMockTaskListener, /* canShow= */
@@ -217,9 +209,7 @@ public class CompatUIControllerTest extends ShellTestCase {
true);
// Verify that the layout is created again.
- clearInvocations(mMockCompatLayout);
- clearInvocations(mMockLetterboxEduLayout);
- clearInvocations(mController);
+ clearInvocations(mMockCompatLayout, mMockLetterboxEduLayout, mController);
mController.onCompatInfoChanged(taskInfo, mMockTaskListener);
verify(mMockCompatLayout, never()).updateCompatInfo(any(), any(), anyBoolean());
@@ -294,8 +284,7 @@ public class CompatUIControllerTest extends ShellTestCase {
verify(mMockLetterboxEduLayout).updateDisplayLayout(mMockDisplayLayout);
// No update if the insets state is the same.
- clearInvocations(mMockCompatLayout);
- clearInvocations(mMockLetterboxEduLayout);
+ clearInvocations(mMockCompatLayout, mMockLetterboxEduLayout);
mOnInsetsChangedListenerCaptor.getValue().insetsChanged(new InsetsState(insetsState));
verify(mMockCompatLayout, never()).updateDisplayLayout(mMockDisplayLayout);
verify(mMockLetterboxEduLayout, never()).updateDisplayLayout(mMockDisplayLayout);
@@ -368,8 +357,7 @@ public class CompatUIControllerTest extends ShellTestCase {
verify(mMockCompatLayout, times(2)).updateVisibility(false);
verify(mMockLetterboxEduLayout, times(2)).updateVisibility(false);
- clearInvocations(mMockCompatLayout);
- clearInvocations(mMockLetterboxEduLayout);
+ clearInvocations(mMockCompatLayout, mMockLetterboxEduLayout);
// Verify button remains hidden after keyguard becomes not showing since IME is showing.
mController.onKeyguardShowingChanged(false);
@@ -395,8 +383,7 @@ public class CompatUIControllerTest extends ShellTestCase {
verify(mMockCompatLayout, times(2)).updateVisibility(false);
verify(mMockLetterboxEduLayout, times(2)).updateVisibility(false);
- clearInvocations(mMockCompatLayout);
- clearInvocations(mMockLetterboxEduLayout);
+ clearInvocations(mMockCompatLayout, mMockLetterboxEduLayout);
// Verify button remains hidden after IME is hidden since keyguard is showing.
mController.onImeVisibilityChanged(DISPLAY_ID, /* isShowing= */ false);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduWindowManagerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduWindowManagerTest.java
index 7d51b521a9fb..f3a8cf45b7f8 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduWindowManagerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduWindowManagerTest.java
@@ -26,6 +26,7 @@ import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
@@ -75,6 +76,12 @@ import org.mockito.MockitoAnnotations;
@SmallTest
public class LetterboxEduWindowManagerTest extends ShellTestCase {
+ private static final int USER_ID_1 = 1;
+ private static final int USER_ID_2 = 2;
+
+ private static final String PREF_KEY_1 = String.valueOf(USER_ID_1);
+ private static final String PREF_KEY_2 = String.valueOf(USER_ID_2);
+
private static final int TASK_ID = 1;
private static final int TASK_WIDTH = 200;
@@ -98,9 +105,10 @@ public class LetterboxEduWindowManagerTest extends ShellTestCase {
@Mock private Runnable mOnDismissCallback;
private SharedPreferences mSharedPreferences;
- private String mPrefKey;
@Nullable
- private Boolean mInitialPrefValue = null;
+ private Boolean mInitialPrefValue1 = null;
+ @Nullable
+ private Boolean mInitialPrefValue2 = null;
@Before
public void setUp() {
@@ -109,20 +117,28 @@ public class LetterboxEduWindowManagerTest extends ShellTestCase {
mSharedPreferences = mContext.getSharedPreferences(
LetterboxEduWindowManager.HAS_SEEN_LETTERBOX_EDUCATION_PREF_NAME,
Context.MODE_PRIVATE);
- mPrefKey = String.valueOf(mContext.getUserId());
- if (mSharedPreferences.contains(mPrefKey)) {
- mInitialPrefValue = mSharedPreferences.getBoolean(mPrefKey, /* default= */ false);
- mSharedPreferences.edit().remove(mPrefKey).apply();
+ if (mSharedPreferences.contains(PREF_KEY_1)) {
+ mInitialPrefValue1 = mSharedPreferences.getBoolean(PREF_KEY_1, /* default= */ false);
+ mSharedPreferences.edit().remove(PREF_KEY_1).apply();
+ }
+ if (mSharedPreferences.contains(PREF_KEY_2)) {
+ mInitialPrefValue2 = mSharedPreferences.getBoolean(PREF_KEY_2, /* default= */ false);
+ mSharedPreferences.edit().remove(PREF_KEY_2).apply();
}
}
@After
public void tearDown() {
SharedPreferences.Editor editor = mSharedPreferences.edit();
- if (mInitialPrefValue == null) {
- editor.remove(mPrefKey);
+ if (mInitialPrefValue1 == null) {
+ editor.remove(PREF_KEY_1);
} else {
- editor.putBoolean(mPrefKey, mInitialPrefValue);
+ editor.putBoolean(PREF_KEY_1, mInitialPrefValue1);
+ }
+ if (mInitialPrefValue2 == null) {
+ editor.remove(PREF_KEY_2);
+ } else {
+ editor.putBoolean(PREF_KEY_2, mInitialPrefValue2);
}
editor.apply();
}
@@ -137,19 +153,9 @@ public class LetterboxEduWindowManagerTest extends ShellTestCase {
}
@Test
- public void testCreateLayout_alreadyShownToUser_doesNotCreateLayout() {
- LetterboxEduWindowManager windowManager = createWindowManager(/* eligible= */ true);
- mSharedPreferences.edit().putBoolean(mPrefKey, true).apply();
-
- assertFalse(windowManager.createLayout(/* canShow= */ true));
-
- assertNull(windowManager.mLayout);
- }
-
- @Test
public void testCreateLayout_taskBarEducationIsShowing_doesNotCreateLayout() {
LetterboxEduWindowManager windowManager = createWindowManager(/* eligible= */
- true, /* isTaskbarEduShowing= */ true);
+ true, USER_ID_1, /* isTaskbarEduShowing= */ true);
assertFalse(windowManager.createLayout(/* canShow= */ true));
@@ -162,7 +168,7 @@ public class LetterboxEduWindowManagerTest extends ShellTestCase {
assertTrue(windowManager.createLayout(/* canShow= */ false));
- assertFalse(mSharedPreferences.getBoolean(mPrefKey, /* default= */ false));
+ assertFalse(mSharedPreferences.getBoolean(PREF_KEY_1, /* default= */ false));
assertNull(windowManager.mLayout);
}
@@ -172,7 +178,6 @@ public class LetterboxEduWindowManagerTest extends ShellTestCase {
assertTrue(windowManager.createLayout(/* canShow= */ true));
- assertTrue(mSharedPreferences.getBoolean(mPrefKey, /* default= */ false));
LetterboxEduDialogLayout layout = windowManager.mLayout;
assertNotNull(layout);
verify(mViewHost).setView(eq(layout), mWindowAttrsCaptor.capture());
@@ -183,6 +188,8 @@ public class LetterboxEduWindowManagerTest extends ShellTestCase {
assertNotNull(dialogTitle);
spyOn(dialogTitle);
+ // The education shouldn't be marked as seen until enter animation is done.
+ assertFalse(mSharedPreferences.getBoolean(PREF_KEY_1, /* default= */ false));
// Clicking the layout does nothing until enter animation is done.
layout.performClick();
verify(mAnimationController, never()).startExitAnimation(any(), any());
@@ -191,6 +198,7 @@ public class LetterboxEduWindowManagerTest extends ShellTestCase {
verifyAndFinishEnterAnimation(layout);
+ assertTrue(mSharedPreferences.getBoolean(PREF_KEY_1, /* default= */ false));
verify(dialogTitle).sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
// Exit animation should start following a click on the layout.
layout.performClick();
@@ -208,12 +216,41 @@ public class LetterboxEduWindowManagerTest extends ShellTestCase {
}
@Test
+ public void testCreateLayout_alreadyShownToUser_createsLayoutForOtherUserOnly() {
+ LetterboxEduWindowManager windowManager = createWindowManager(/* eligible= */ true,
+ USER_ID_1, /* isTaskbarEduShowing= */ false);
+
+ assertTrue(windowManager.createLayout(/* canShow= */ true));
+
+ assertNotNull(windowManager.mLayout);
+ verifyAndFinishEnterAnimation(windowManager.mLayout);
+ assertTrue(mSharedPreferences.getBoolean(PREF_KEY_1, /* default= */ false));
+
+ windowManager.release();
+ windowManager = createWindowManager(/* eligible= */ true,
+ USER_ID_1, /* isTaskbarEduShowing= */ false);
+
+ assertFalse(windowManager.createLayout(/* canShow= */ true));
+ assertNull(windowManager.mLayout);
+
+ clearInvocations(mTransitions, mAnimationController);
+
+ windowManager = createWindowManager(/* eligible= */ true,
+ USER_ID_2, /* isTaskbarEduShowing= */ false);
+
+ assertTrue(windowManager.createLayout(/* canShow= */ true));
+
+ assertNotNull(windowManager.mLayout);
+ verifyAndFinishEnterAnimation(windowManager.mLayout);
+ assertTrue(mSharedPreferences.getBoolean(PREF_KEY_1, /* default= */ false));
+ }
+
+ @Test
public void testCreateLayout_windowManagerReleasedBeforeTransitionsIsIdle_doesNotStartAnim() {
LetterboxEduWindowManager windowManager = createWindowManager(/* eligible= */ true);
assertTrue(windowManager.createLayout(/* canShow= */ true));
-
- assertTrue(mSharedPreferences.getBoolean(mPrefKey, /* default= */ false));
+ assertNotNull(windowManager.mLayout);
verify(mTransitions).runOnIdle(mRunOnIdleCaptor.capture());
@@ -222,6 +259,7 @@ public class LetterboxEduWindowManagerTest extends ShellTestCase {
mRunOnIdleCaptor.getValue().run();
verify(mAnimationController, never()).startEnterAnimation(any(), any());
+ assertFalse(mSharedPreferences.getBoolean(PREF_KEY_1, /* default= */ false));
}
@Test
@@ -233,7 +271,7 @@ public class LetterboxEduWindowManagerTest extends ShellTestCase {
assertNotNull(layout);
assertTrue(windowManager.updateCompatInfo(
- createTaskInfo(/* eligible= */ true, new Rect(50, 25, 150, 75)),
+ createTaskInfo(/* eligible= */ true, USER_ID_1, new Rect(50, 25, 150, 75)),
mTaskListener, /* canShow= */ true));
verifyLayout(layout, layout.getLayoutParams(), /* expectedWidth= */ 100,
@@ -341,13 +379,13 @@ public class LetterboxEduWindowManagerTest extends ShellTestCase {
}
private LetterboxEduWindowManager createWindowManager(boolean eligible) {
- return createWindowManager(eligible, /* isTaskbarEduShowing= */ false);
+ return createWindowManager(eligible, USER_ID_1, /* isTaskbarEduShowing= */ false);
}
private LetterboxEduWindowManager createWindowManager(boolean eligible,
- boolean isTaskbarEduShowing) {
+ int userId, boolean isTaskbarEduShowing) {
LetterboxEduWindowManager windowManager = new LetterboxEduWindowManager(mContext,
- createTaskInfo(eligible), mSyncTransactionQueue, mTaskListener,
+ createTaskInfo(eligible, userId), mSyncTransactionQueue, mTaskListener,
createDisplayLayout(), mTransitions, mOnDismissCallback,
mAnimationController);
@@ -375,11 +413,16 @@ public class LetterboxEduWindowManagerTest extends ShellTestCase {
}
private static TaskInfo createTaskInfo(boolean eligible) {
- return createTaskInfo(eligible, new Rect(0, 0, TASK_WIDTH, TASK_HEIGHT));
+ return createTaskInfo(eligible, USER_ID_1);
+ }
+
+ private static TaskInfo createTaskInfo(boolean eligible, int userId) {
+ return createTaskInfo(eligible, userId, new Rect(0, 0, TASK_WIDTH, TASK_HEIGHT));
}
- private static TaskInfo createTaskInfo(boolean eligible, Rect bounds) {
+ private static TaskInfo createTaskInfo(boolean eligible, int userId, Rect bounds) {
ActivityManager.RunningTaskInfo taskInfo = new ActivityManager.RunningTaskInfo();
+ taskInfo.userId = userId;
taskInfo.taskId = TASK_ID;
taskInfo.topActivityEligibleForLetterboxEducation = eligible;
taskInfo.configuration.windowConfiguration.setBounds(bounds);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizerTest.java
index 78903dca7657..ff6dfdb748c4 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizerTest.java
@@ -49,7 +49,6 @@ import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayInsetsController;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.SyncTransactionQueue;
-import com.android.wm.shell.compatui.CompatUIController;
import com.android.wm.shell.startingsurface.StartingWindowController;
import org.junit.Before;
@@ -67,7 +66,6 @@ public class KidsModeTaskOrganizerTest {
@Mock private ITaskOrganizerController mTaskOrganizerController;
@Mock private Context mContext;
@Mock private Handler mHandler;
- @Mock private CompatUIController mCompatUI;
@Mock private SyncTransactionQueue mSyncTransactionQueue;
@Mock private ShellExecutor mTestExecutor;
@Mock private DisplayController mDisplayController;
@@ -86,9 +84,11 @@ public class KidsModeTaskOrganizerTest {
try {
doReturn(ParceledListSlice.<TaskAppearedInfo>emptyList())
.when(mTaskOrganizerController).registerTaskOrganizer(any());
- } catch (RemoteException e) { }
+ } catch (RemoteException e) {
+ }
+ // NOTE: KidsModeTaskOrganizer should have a null CompatUIController.
mOrganizer = spy(new KidsModeTaskOrganizer(mTaskOrganizerController, mTestExecutor,
- mHandler, mContext, mCompatUI, mSyncTransactionQueue, mDisplayController,
+ mHandler, mContext, mSyncTransactionQueue, mDisplayController,
mDisplayInsetsController, Optional.empty(), mObserver));
mOrganizer.initialize(mStartingWindowController);
doReturn(mTransaction).when(mOrganizer).getWindowContainerTransaction();