summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
Diffstat (limited to 'libs')
-rw-r--r--libs/WindowManager/Shell/res/raw/wm_shell_protolog.json6
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java40
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java238
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java19
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsHandler.java42
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java10
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java22
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMediaController.java9
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipController.java47
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipMenuActivity.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipNotification.java30
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTaskOrganizer.java74
-rw-r--r--libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/AndroidManifest.xml8
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsHandlerTest.java42
15 files changed, 309 insertions, 286 deletions
diff --git a/libs/WindowManager/Shell/res/raw/wm_shell_protolog.json b/libs/WindowManager/Shell/res/raw/wm_shell_protolog.json
index 02bf38504725..3f6ca0fc5246 100644
--- a/libs/WindowManager/Shell/res/raw/wm_shell_protolog.json
+++ b/libs/WindowManager/Shell/res/raw/wm_shell_protolog.json
@@ -31,12 +31,6 @@
"group": "WM_SHELL_TASK_ORG",
"at": "com\/android\/wm\/shell\/ShellTaskOrganizer.java"
},
- "-1312360667": {
- "message": "createRootTask() displayId=%d winMode=%d listener=%s",
- "level": "VERBOSE",
- "group": "WM_SHELL_TASK_ORG",
- "at": "com\/android\/wm\/shell\/ShellTaskOrganizer.java"
- },
"-880817403": {
"message": "Task vanished taskId=%d",
"level": "VERBOSE",
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java
index 4cb5fd139259..5bd693a9311e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java
@@ -20,7 +20,9 @@ import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_FULLSCR
import static com.android.wm.shell.ShellTaskOrganizer.taskListenerTypeToString;
import android.app.ActivityManager;
-import android.util.ArraySet;
+import android.content.res.Configuration;
+import android.graphics.Rect;
+import android.util.ArrayMap;
import android.util.Slog;
import android.view.SurfaceControl;
@@ -37,7 +39,7 @@ class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener {
private final SyncTransactionQueue mSyncQueue;
- private final ArraySet<Integer> mTasks = new ArraySet<>();
+ private final ArrayMap<Integer, SurfaceControl> mTasks = new ArrayMap<>();
FullscreenTaskListener(SyncTransactionQueue syncQueue) {
mSyncQueue = syncQueue;
@@ -46,16 +48,16 @@ class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener {
@Override
public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash) {
synchronized (mTasks) {
- if (mTasks.contains(taskInfo.taskId)) {
+ if (mTasks.containsKey(taskInfo.taskId)) {
throw new RuntimeException("Task appeared more than once: #" + taskInfo.taskId);
}
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Fullscreen Task Appeared: #%d",
taskInfo.taskId);
- mTasks.add(taskInfo.taskId);
+ mTasks.put(taskInfo.taskId, leash);
mSyncQueue.runInSync(t -> {
// Reset several properties back to fullscreen (PiP, for example, leaves all these
// properties in a bad state).
- t.setPosition(leash, 0, 0);
+ updateSurfacePosition(t, taskInfo, leash);
t.setWindowCrop(leash, null);
// TODO(shell-transitions): Eventually set everything in transition so there's no
// SF Transaction here.
@@ -71,7 +73,7 @@ class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener {
@Override
public void onTaskVanished(ActivityManager.RunningTaskInfo taskInfo) {
synchronized (mTasks) {
- if (!mTasks.remove(taskInfo.taskId)) {
+ if (mTasks.remove(taskInfo.taskId) == null) {
Slog.e(TAG, "Task already vanished: #" + taskInfo.taskId);
return;
}
@@ -81,6 +83,23 @@ class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener {
}
@Override
+ public void onTaskInfoChanged(ActivityManager.RunningTaskInfo taskInfo) {
+ synchronized (mTasks) {
+ if (!mTasks.containsKey(taskInfo.taskId)) {
+ Slog.e(TAG, "Changed Task wasn't appeared or already vanished: #"
+ + taskInfo.taskId);
+ return;
+ }
+ final SurfaceControl leash = mTasks.get(taskInfo.taskId);
+ mSyncQueue.runInSync(t -> {
+ // Reposition the task in case the bounds has been changed (such as Task level
+ // letterboxing).
+ updateSurfacePosition(t, taskInfo, leash);
+ });
+ }
+ }
+
+ @Override
public void dump(@NonNull PrintWriter pw, String prefix) {
final String innerPrefix = prefix + " ";
final String childPrefix = innerPrefix + " ";
@@ -92,4 +111,13 @@ class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener {
public String toString() {
return TAG + ":" + taskListenerTypeToString(TASK_LISTENER_TYPE_FULLSCREEN);
}
+
+ /** Places the Task surface to the latest position. */
+ private static void updateSurfacePosition(SurfaceControl.Transaction t,
+ ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash) {
+ // TODO(170725334) drop this after ag/12876439
+ final Configuration config = taskInfo.getConfiguration();
+ final Rect bounds = config.windowConfiguration.getBounds();
+ t.setPosition(leash, bounds.left, bounds.top);
+ }
}
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 8bd7193843f7..cbc1c8d6d310 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
@@ -105,6 +105,8 @@ public class ShellTaskOrganizer extends TaskOrganizer {
// TODO(shell-transitions): move to a more "global" Shell location as this isn't only for Tasks
private final Transitions mTransitions;
+ private final Object mLock = new Object();
+
public ShellTaskOrganizer(SyncTransactionQueue syncQueue, TransactionPool transactionPool,
ShellExecutor mainExecutor, ShellExecutor animExecutor) {
this(null, syncQueue, transactionPool, mainExecutor, animExecutor);
@@ -114,7 +116,7 @@ public class ShellTaskOrganizer extends TaskOrganizer {
ShellTaskOrganizer(ITaskOrganizerController taskOrganizerController,
SyncTransactionQueue syncQueue, TransactionPool transactionPool,
ShellExecutor mainExecutor, ShellExecutor animExecutor) {
- super(taskOrganizerController);
+ super(taskOrganizerController, mainExecutor);
addListenerForType(new FullscreenTaskListener(syncQueue), TASK_LISTENER_TYPE_FULLSCREEN);
mTransitions = new Transitions(this, transactionPool, mainExecutor, animExecutor);
if (Transitions.ENABLE_SHELL_TRANSITIONS) registerTransitionPlayer(mTransitions);
@@ -122,68 +124,62 @@ public class ShellTaskOrganizer extends TaskOrganizer {
@Override
public List<TaskAppearedInfo> registerOrganizer() {
- ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Registering organizer");
- final List<TaskAppearedInfo> taskInfos = super.registerOrganizer();
- for (int i = 0; i < taskInfos.size(); i++) {
- final TaskAppearedInfo info = taskInfos.get(i);
- ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Existing task: id=%d component=%s",
- info.getTaskInfo().taskId, info.getTaskInfo().baseIntent);
- onTaskAppeared(info);
+ synchronized (mLock) {
+ ProtoLog.v(WM_SHELL_TASK_ORG, "Registering organizer");
+ final List<TaskAppearedInfo> taskInfos = super.registerOrganizer();
+ for (int i = 0; i < taskInfos.size(); i++) {
+ final TaskAppearedInfo info = taskInfos.get(i);
+ ProtoLog.v(WM_SHELL_TASK_ORG, "Existing task: id=%d component=%s",
+ info.getTaskInfo().taskId, info.getTaskInfo().baseIntent);
+ onTaskAppeared(info);
+ }
+ return taskInfos;
}
- return taskInfos;
- }
-
- public TaskAppearedInfo createRootTask(
- int displayId, int windowingMode, TaskListener listener) {
- ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG,
- "createRootTask() displayId=%d winMode=%d listener=%s",
- displayId, windowingMode, listener.toString());
- final TaskAppearedInfo info = super.createRootTask(displayId, windowingMode);
-
- // Add the listener and send the task appeared signal
- mTaskListeners.put(info.getTaskInfo().taskId, listener);
- onTaskAppeared(info);
- return info;
}
/**
* Adds a listener for a specific task id.
*/
public void addListenerForTaskId(TaskListener listener, int taskId) {
- ProtoLog.v(WM_SHELL_TASK_ORG, "addListenerForTaskId taskId=%s", taskId);
- if (mTaskListeners.get(taskId) != null) {
- throw new IllegalArgumentException("Listener for taskId=" + taskId + " already exists");
- }
+ synchronized (mLock) {
+ ProtoLog.v(WM_SHELL_TASK_ORG, "addListenerForTaskId taskId=%s", taskId);
+ if (mTaskListeners.get(taskId) != null) {
+ throw new IllegalArgumentException(
+ "Listener for taskId=" + taskId + " already exists");
+ }
- final TaskAppearedInfo info = mTasks.get(taskId);
- if (info == null) {
- throw new IllegalArgumentException("addListenerForTaskId unknown taskId=" + taskId);
- }
+ final TaskAppearedInfo info = mTasks.get(taskId);
+ if (info == null) {
+ throw new IllegalArgumentException("addListenerForTaskId unknown taskId=" + taskId);
+ }
- final TaskListener oldListener = getTaskListener(info.getTaskInfo());
- mTaskListeners.put(taskId, listener);
- updateTaskListenerIfNeeded(info.getTaskInfo(), info.getLeash(), oldListener, listener);
+ final TaskListener oldListener = getTaskListener(info.getTaskInfo());
+ mTaskListeners.put(taskId, listener);
+ updateTaskListenerIfNeeded(info.getTaskInfo(), info.getLeash(), oldListener, listener);
+ }
}
/**
* Adds a listener for tasks with given types.
*/
public void addListenerForType(TaskListener listener, @TaskListenerType int... listenerTypes) {
- ProtoLog.v(WM_SHELL_TASK_ORG, "addListenerForType types=%s listener=%s",
- Arrays.toString(listenerTypes), listener);
- for (int listenerType : listenerTypes) {
- if (mTaskListeners.get(listenerType) != null) {
- throw new IllegalArgumentException("Listener for listenerType=" + listenerType
- + " already exists");
- }
- mTaskListeners.put(listenerType, listener);
-
- // Notify the listener of all existing tasks with the given type.
- for (int i = mTasks.size() - 1; i >= 0; --i) {
- final TaskAppearedInfo data = mTasks.valueAt(i);
- final TaskListener taskListener = getTaskListener(data.getTaskInfo());
- if (taskListener != listener) continue;
- listener.onTaskAppeared(data.getTaskInfo(), data.getLeash());
+ synchronized (mLock) {
+ ProtoLog.v(WM_SHELL_TASK_ORG, "addListenerForType types=%s listener=%s",
+ Arrays.toString(listenerTypes), listener);
+ for (int listenerType : listenerTypes) {
+ if (mTaskListeners.get(listenerType) != null) {
+ throw new IllegalArgumentException("Listener for listenerType=" + listenerType
+ + " already exists");
+ }
+ mTaskListeners.put(listenerType, listener);
+
+ // Notify the listener of all existing tasks with the given type.
+ for (int i = mTasks.size() - 1; i >= 0; --i) {
+ final TaskAppearedInfo data = mTasks.valueAt(i);
+ final TaskListener taskListener = getTaskListener(data.getTaskInfo());
+ if (taskListener != listener) continue;
+ listener.onTaskAppeared(data.getTaskInfo(), data.getLeash());
+ }
}
}
}
@@ -192,30 +188,32 @@ public class ShellTaskOrganizer extends TaskOrganizer {
* Removes a registered listener.
*/
public void removeListener(TaskListener listener) {
- ProtoLog.v(WM_SHELL_TASK_ORG, "Remove listener=%s", listener);
- final int index = mTaskListeners.indexOfValue(listener);
- if (index == -1) {
- Log.w(TAG, "No registered listener found");
- return;
- }
+ synchronized (mLock) {
+ ProtoLog.v(WM_SHELL_TASK_ORG, "Remove listener=%s", listener);
+ final int index = mTaskListeners.indexOfValue(listener);
+ if (index == -1) {
+ Log.w(TAG, "No registered listener found");
+ return;
+ }
- // Collect tasks associated with the listener we are about to remove.
- final ArrayList<TaskAppearedInfo> tasks = new ArrayList<>();
- for (int i = mTasks.size() - 1; i >= 0; --i) {
- final TaskAppearedInfo data = mTasks.valueAt(i);
- final TaskListener taskListener = getTaskListener(data.getTaskInfo());
- if (taskListener != listener) continue;
- tasks.add(data);
- }
+ // Collect tasks associated with the listener we are about to remove.
+ final ArrayList<TaskAppearedInfo> tasks = new ArrayList<>();
+ for (int i = mTasks.size() - 1; i >= 0; --i) {
+ final TaskAppearedInfo data = mTasks.valueAt(i);
+ final TaskListener taskListener = getTaskListener(data.getTaskInfo());
+ if (taskListener != listener) continue;
+ tasks.add(data);
+ }
- // Remove listener
- mTaskListeners.removeAt(index);
+ // Remove listener
+ mTaskListeners.removeAt(index);
- // Associate tasks with new listeners if needed.
- for (int i = tasks.size() - 1; i >= 0; --i) {
- final TaskAppearedInfo data = tasks.get(i);
- updateTaskListenerIfNeeded(data.getTaskInfo(), data.getLeash(),
- null /* oldListener already removed*/, getTaskListener(data.getTaskInfo()));
+ // Associate tasks with new listeners if needed.
+ for (int i = tasks.size() - 1; i >= 0; --i) {
+ final TaskAppearedInfo data = tasks.get(i);
+ updateTaskListenerIfNeeded(data.getTaskInfo(), data.getLeash(),
+ null /* oldListener already removed*/, getTaskListener(data.getTaskInfo()));
+ }
}
}
@@ -224,12 +222,16 @@ public class ShellTaskOrganizer extends TaskOrganizer {
* appears.
*/
public void setPendingLaunchCookieListener(IBinder cookie, TaskListener listener) {
- mLaunchCookieToListener.put(cookie, listener);
+ synchronized (mLock) {
+ mLaunchCookieToListener.put(cookie, listener);
+ }
}
@Override
public void onTaskAppeared(RunningTaskInfo taskInfo, SurfaceControl leash) {
- onTaskAppeared(new TaskAppearedInfo(taskInfo, leash));
+ synchronized (mLock) {
+ onTaskAppeared(new TaskAppearedInfo(taskInfo, leash));
+ }
}
private void onTaskAppeared(TaskAppearedInfo info) {
@@ -245,35 +247,41 @@ public class ShellTaskOrganizer extends TaskOrganizer {
@Override
public void onTaskInfoChanged(RunningTaskInfo taskInfo) {
- ProtoLog.v(WM_SHELL_TASK_ORG, "Task info changed taskId=%d", taskInfo.taskId);
- final TaskAppearedInfo data = mTasks.get(taskInfo.taskId);
- final TaskListener oldListener = getTaskListener(data.getTaskInfo());
- final TaskListener newListener = getTaskListener(taskInfo);
- mTasks.put(taskInfo.taskId, new TaskAppearedInfo(taskInfo, data.getLeash()));
- final boolean updated = updateTaskListenerIfNeeded(
- taskInfo, data.getLeash(), oldListener, newListener);
- if (!updated && newListener != null) {
- newListener.onTaskInfoChanged(taskInfo);
+ synchronized (mLock) {
+ ProtoLog.v(WM_SHELL_TASK_ORG, "Task info changed taskId=%d", taskInfo.taskId);
+ final TaskAppearedInfo data = mTasks.get(taskInfo.taskId);
+ final TaskListener oldListener = getTaskListener(data.getTaskInfo());
+ final TaskListener newListener = getTaskListener(taskInfo);
+ mTasks.put(taskInfo.taskId, new TaskAppearedInfo(taskInfo, data.getLeash()));
+ final boolean updated = updateTaskListenerIfNeeded(
+ taskInfo, data.getLeash(), oldListener, newListener);
+ if (!updated && newListener != null) {
+ newListener.onTaskInfoChanged(taskInfo);
+ }
}
}
@Override
public void onBackPressedOnTaskRoot(RunningTaskInfo taskInfo) {
- ProtoLog.v(WM_SHELL_TASK_ORG, "Task root back pressed taskId=%d", taskInfo.taskId);
- final TaskListener listener = getTaskListener(taskInfo);
- if (listener != null) {
- listener.onBackPressedOnTaskRoot(taskInfo);
+ synchronized (mLock) {
+ ProtoLog.v(WM_SHELL_TASK_ORG, "Task root back pressed taskId=%d", taskInfo.taskId);
+ final TaskListener listener = getTaskListener(taskInfo);
+ if (listener != null) {
+ listener.onBackPressedOnTaskRoot(taskInfo);
+ }
}
}
@Override
public void onTaskVanished(RunningTaskInfo taskInfo) {
- ProtoLog.v(WM_SHELL_TASK_ORG, "Task vanished taskId=%d", taskInfo.taskId);
- final int taskId = taskInfo.taskId;
- final TaskListener listener = getTaskListener(mTasks.get(taskId).getTaskInfo());
- mTasks.remove(taskId);
- if (listener != null) {
- listener.onTaskVanished(taskInfo);
+ synchronized (mLock) {
+ ProtoLog.v(WM_SHELL_TASK_ORG, "Task vanished taskId=%d", taskInfo.taskId);
+ final int taskId = taskInfo.taskId;
+ final TaskListener listener = getTaskListener(mTasks.get(taskId).getTaskInfo());
+ mTasks.remove(taskId);
+ if (listener != null) {
+ listener.onTaskVanished(taskInfo);
+ }
}
}
@@ -368,32 +376,34 @@ public class ShellTaskOrganizer extends TaskOrganizer {
}
public void dump(@NonNull PrintWriter pw, String prefix) {
- final String innerPrefix = prefix + " ";
- final String childPrefix = innerPrefix + " ";
- pw.println(prefix + TAG);
- pw.println(innerPrefix + mTaskListeners.size() + " Listeners");
- for (int i = mTaskListeners.size() - 1; i >= 0; --i) {
- final int key = mTaskListeners.keyAt(i);
- final TaskListener listener = mTaskListeners.valueAt(i);
- pw.println(innerPrefix + "#" + i + " " + taskListenerTypeToString(key));
- listener.dump(pw, childPrefix);
- }
+ synchronized (mLock) {
+ final String innerPrefix = prefix + " ";
+ final String childPrefix = innerPrefix + " ";
+ pw.println(prefix + TAG);
+ pw.println(innerPrefix + mTaskListeners.size() + " Listeners");
+ for (int i = mTaskListeners.size() - 1; i >= 0; --i) {
+ final int key = mTaskListeners.keyAt(i);
+ final TaskListener listener = mTaskListeners.valueAt(i);
+ pw.println(innerPrefix + "#" + i + " " + taskListenerTypeToString(key));
+ listener.dump(pw, childPrefix);
+ }
- pw.println();
- pw.println(innerPrefix + mTasks.size() + " Tasks");
- for (int i = mTasks.size() - 1; i >= 0; --i) {
- final int key = mTasks.keyAt(i);
- final TaskAppearedInfo info = mTasks.valueAt(i);
- final TaskListener listener = getTaskListener(info.getTaskInfo());
- pw.println(innerPrefix + "#" + i + " task=" + key + " listener=" + listener);
- }
+ pw.println();
+ pw.println(innerPrefix + mTasks.size() + " Tasks");
+ for (int i = mTasks.size() - 1; i >= 0; --i) {
+ final int key = mTasks.keyAt(i);
+ final TaskAppearedInfo info = mTasks.valueAt(i);
+ final TaskListener listener = getTaskListener(info.getTaskInfo());
+ pw.println(innerPrefix + "#" + i + " task=" + key + " listener=" + listener);
+ }
- pw.println();
- pw.println(innerPrefix + mLaunchCookieToListener.size() + " Launch Cookies");
- for (int i = mLaunchCookieToListener.size() - 1; i >= 0; --i) {
- final IBinder key = mLaunchCookieToListener.keyAt(i);
- final TaskListener listener = mLaunchCookieToListener.valueAt(i);
- pw.println(innerPrefix + "#" + i + " cookie=" + key + " listener=" + listener);
+ pw.println();
+ pw.println(innerPrefix + mLaunchCookieToListener.size() + " Launch Cookies");
+ for (int i = mLaunchCookieToListener.size() - 1; i >= 0; --i) {
+ final IBinder key = mLaunchCookieToListener.keyAt(i);
+ final TaskListener listener = mLaunchCookieToListener.valueAt(i);
+ pw.println(innerPrefix + "#" + i + " cookie=" + key + " listener=" + listener);
+ }
}
}
}
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 eaf5d7960aa9..24381d937e2f 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
@@ -270,25 +270,6 @@ public class SystemWindows {
mDisplayId = displayId;
}
- @Override
- public int relayout(IWindow window, WindowManager.LayoutParams attrs,
- int requestedWidth, int requestedHeight, int viewVisibility, int flags,
- long frameNumber, ClientWindowFrames outFrames,
- MergedConfiguration mergedConfiguration,
- SurfaceControl outSurfaceControl, InsetsState outInsetsState,
- InsetsSourceControl[] outActiveControls, Point outSurfaceSize) {
- int res = super.relayout(window, attrs, requestedWidth, requestedHeight,
- viewVisibility, flags, frameNumber, outFrames,
- mergedConfiguration, outSurfaceControl, outInsetsState,
- outActiveControls, outSurfaceSize);
- if (res != 0) {
- return res;
- }
- DisplayLayout dl = mDisplayController.getDisplayLayout(mDisplayId);
- outFrames.stableInsets.set(dl.stableInsets());
- return 0;
- }
-
void updateConfiguration(Configuration configuration) {
setConfiguration(configuration);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsHandler.java
index 6d6cc204538a..08318186a105 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsHandler.java
@@ -60,7 +60,6 @@ public class PipBoundsHandler {
private float mDefaultAspectRatio;
private float mMinAspectRatio;
private float mMaxAspectRatio;
- private float mAspectRatio;
private int mDefaultStackGravity;
private int mDefaultMinSize;
private Point mScreenEdgeInsets;
@@ -80,7 +79,7 @@ public class PipBoundsHandler {
// Initialize the aspect ratio to the default aspect ratio. Don't do this in reload
// resources as it would clobber mAspectRatio when entering PiP from fullscreen which
// triggers a configuration change and the resources to be reloaded.
- mAspectRatio = mDefaultAspectRatio;
+ mPipBoundsState.setAspectRatio(mDefaultAspectRatio);
}
/**
@@ -133,10 +132,6 @@ public class PipBoundsHandler {
mCurrentMinSize = minEdgeSize;
}
- protected float getAspectRatio() {
- return mAspectRatio;
- }
-
/**
* Sets both shelf visibility and its height if applicable.
* @return {@code true} if the internal shelf state is changed, {@code false} otherwise.
@@ -172,8 +167,8 @@ public class PipBoundsHandler {
if (animatingBounds.isEmpty()) {
animatingBounds.set(defaultBounds);
}
- if (isValidPictureInPictureAspectRatio(mAspectRatio)) {
- transformBoundsToAspectRatio(normalBounds, mAspectRatio,
+ if (isValidPictureInPictureAspectRatio(mPipBoundsState.getAspectRatio())) {
+ transformBoundsToAspectRatio(normalBounds, mPipBoundsState.getAspectRatio(),
false /* useCurrentMinEdgeSize */, false /* useCurrentSize */);
}
displayInfo.copyFrom(mDisplayInfo);
@@ -212,27 +207,16 @@ public class PipBoundsHandler {
}
/**
- * Responds to IPinnedStackListener on resetting aspect ratio for the pinned window.
- * It will normally follow up with a
- * {@link #onMovementBoundsChanged(Rect, Rect, Rect, DisplayInfo)} callback.
- */
- public void onAspectRatioChanged(float aspectRatio) {
- mAspectRatio = aspectRatio;
- }
-
- /**
- * See {@link #getDestinationBounds(float, Rect, Size, boolean)}
+ * See {@link #getDestinationBounds(Rect, Size, boolean)}
*/
- public Rect getDestinationBounds(float aspectRatio, Rect bounds, Size minimalSize) {
- return getDestinationBounds(aspectRatio, bounds, minimalSize,
- false /* useCurrentMinEdgeSize */);
+ public Rect getDestinationBounds(Rect bounds, Size minimalSize) {
+ return getDestinationBounds(bounds, minimalSize, false /* useCurrentMinEdgeSize */);
}
/**
* @return {@link Rect} of the destination PiP window bounds.
*/
- public Rect getDestinationBounds(float aspectRatio, Rect bounds,
- Size minimalSize, boolean useCurrentMinEdgeSize) {
+ public Rect getDestinationBounds(Rect bounds, Size minimalSize, boolean useCurrentMinEdgeSize) {
boolean isReentryBounds = false;
final Rect destinationBounds;
if (bounds == null) {
@@ -255,11 +239,10 @@ public class PipBoundsHandler {
// Just adjusting bounds (e.g. on aspect ratio changed).
destinationBounds = new Rect(bounds);
}
- if (isValidPictureInPictureAspectRatio(aspectRatio)) {
- transformBoundsToAspectRatio(destinationBounds, aspectRatio, useCurrentMinEdgeSize,
- isReentryBounds);
+ if (isValidPictureInPictureAspectRatio(mPipBoundsState.getAspectRatio())) {
+ transformBoundsToAspectRatio(destinationBounds, mPipBoundsState.getAspectRatio(),
+ useCurrentMinEdgeSize, isReentryBounds);
}
- mAspectRatio = aspectRatio;
return destinationBounds;
}
@@ -368,8 +351,8 @@ public class PipBoundsHandler {
* @param stackBounds
*/
public void transformBoundsToAspectRatio(Rect stackBounds) {
- transformBoundsToAspectRatio(stackBounds, mAspectRatio, true /* useCurrentMinEdgeSize */,
- true /* useCurrentSize */);
+ transformBoundsToAspectRatio(stackBounds, mPipBoundsState.getAspectRatio(),
+ true /* useCurrentMinEdgeSize */, true /* useCurrentSize */);
}
/**
@@ -514,7 +497,6 @@ public class PipBoundsHandler {
pw.println(innerPrefix + "mDefaultAspectRatio=" + mDefaultAspectRatio);
pw.println(innerPrefix + "mMinAspectRatio=" + mMinAspectRatio);
pw.println(innerPrefix + "mMaxAspectRatio=" + mMaxAspectRatio);
- pw.println(innerPrefix + "mAspectRatio=" + mAspectRatio);
pw.println(innerPrefix + "mDefaultStackGravity=" + mDefaultStackGravity);
pw.println(innerPrefix + "mIsImeShowing=" + mIsImeShowing);
pw.println(innerPrefix + "mImeHeight=" + mImeHeight);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java
index 2625f16fac46..aba2a3a29fe2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java
@@ -34,6 +34,7 @@ public final class PipBoundsState {
private static final String TAG = PipBoundsState.class.getSimpleName();
private final @NonNull Rect mBounds = new Rect();
+ private float mAspectRatio;
private PipReentryState mPipReentryState;
private ComponentName mLastPipComponentName;
@@ -46,6 +47,14 @@ public final class PipBoundsState {
return new Rect(mBounds);
}
+ public void setAspectRatio(float aspectRatio) {
+ mAspectRatio = aspectRatio;
+ }
+
+ public float getAspectRatio() {
+ return mAspectRatio;
+ }
+
/**
* Save the reentry state to restore to when re-entering PIP mode.
*
@@ -120,6 +129,7 @@ public final class PipBoundsState {
pw.println(prefix + TAG);
pw.println(innerPrefix + "mBounds=" + mBounds);
pw.println(innerPrefix + "mLastPipComponentName=" + mLastPipComponentName);
+ pw.println(innerPrefix + "mAspectRatio=" + mAspectRatio);
if (mPipReentryState == null) {
pw.println(innerPrefix + "mPipReentryState=null");
} else {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
index cd5d35bf0c4c..a7bf9aea46bc 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
@@ -341,9 +341,9 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
mShouldIgnoreEnteringPipTransition = true;
mState = State.ENTERING_PIP;
mPipBoundsState.setLastPipComponentName(componentName);
- return mPipBoundsHandler.getDestinationBounds(
- getAspectRatioOrDefault(pictureInPictureParams),
- null /* bounds */, getMinimalSize(activityInfo));
+ mPipBoundsState.setAspectRatio(getAspectRatioOrDefault(pictureInPictureParams));
+ return mPipBoundsHandler.getDestinationBounds(null /* bounds */,
+ getMinimalSize(activityInfo));
}
/**
@@ -514,9 +514,9 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
return;
}
- final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(
- getAspectRatioOrDefault(mPictureInPictureParams),
- null /* bounds */, getMinimalSize(mTaskInfo.topActivityInfo));
+ mPipBoundsState.setAspectRatio(getAspectRatioOrDefault(mPictureInPictureParams));
+ final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(null /* bounds */,
+ getMinimalSize(mTaskInfo.topActivityInfo));
Objects.requireNonNull(destinationBounds, "Missing destination bounds");
final Rect currentBounds = mTaskInfo.configuration.windowConfiguration.getBounds();
@@ -717,8 +717,8 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
Log.d(TAG, "Ignored onTaskInfoChanged with PiP param: " + newParams);
return;
}
+ // Aspect ratio changed, re-calculate destination bounds.
final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(
- getAspectRatioOrDefault(newParams),
mPipBoundsState.getBounds(), getMinimalSize(info.topActivityInfo),
true /* userCurrentMinEdgeSize */);
Objects.requireNonNull(destinationBounds, "Missing destination bounds");
@@ -735,7 +735,6 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
public void onFixedRotationFinished(int displayId) {
if (mShouldDeferEnteringPip && mState.isInPip()) {
final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(
- getAspectRatioOrDefault(mPictureInPictureParams),
null /* bounds */, getMinimalSize(mTaskInfo.topActivityInfo));
// schedule a regular animation to ensure all the callbacks are still being sent
enterPipWithAlphaAnimation(destinationBounds, 0 /* durationMs */);
@@ -808,9 +807,8 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
return;
}
- final Rect newDestinationBounds = mPipBoundsHandler.getDestinationBounds(
- getAspectRatioOrDefault(mPictureInPictureParams),
- null /* bounds */, getMinimalSize(mTaskInfo.topActivityInfo));
+ final Rect newDestinationBounds = mPipBoundsHandler.getDestinationBounds(null /* bounds */,
+ getMinimalSize(mTaskInfo.topActivityInfo));
if (newDestinationBounds.equals(currentDestinationBounds)) return;
if (animator.getAnimationType() == ANIM_TYPE_BOUNDS) {
animator.updateEndValue(newDestinationBounds);
@@ -831,7 +829,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
params.getAspectRatioRational());
mPictureInPictureParams = params;
if (aspectRatioChanged) {
- mPipBoundsHandler.onAspectRatioChanged(params.getAspectRatio());
+ mPipBoundsState.setAspectRatio(params.getAspectRatio());
}
return aspectRatioChanged;
}
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 a08983740f9a..edc68e5221f1 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
@@ -197,8 +197,10 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
@Override
public void onAspectRatioChanged(float aspectRatio) {
+ // TODO(b/169373982): Remove this callback as it is redundant with PipTaskOrg params
+ // change.
mHandler.post(() -> {
- mPipBoundsHandler.onAspectRatioChanged(aspectRatio);
+ mPipBoundsState.setAspectRatio(aspectRatio);
mTouchHandler.onAspectRatioChanged();
});
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMediaController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMediaController.java
index 22c05fb8acd9..64e3758fd81a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMediaController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMediaController.java
@@ -16,6 +16,7 @@
package com.android.wm.shell.pip.phone;
+import static android.app.PendingIntent.FLAG_IMMUTABLE;
import static android.app.PendingIntent.FLAG_UPDATE_CURRENT;
import android.app.IActivityManager;
@@ -180,25 +181,25 @@ public class PipMediaController {
mPauseAction = new RemoteAction(Icon.createWithResource(mContext,
R.drawable.pip_ic_pause_white), pauseDescription, pauseDescription,
PendingIntent.getBroadcast(mContext, 0, new Intent(ACTION_PAUSE),
- FLAG_UPDATE_CURRENT));
+ FLAG_UPDATE_CURRENT | FLAG_IMMUTABLE));
String playDescription = mContext.getString(R.string.pip_play);
mPlayAction = new RemoteAction(Icon.createWithResource(mContext,
R.drawable.pip_ic_play_arrow_white), playDescription, playDescription,
PendingIntent.getBroadcast(mContext, 0, new Intent(ACTION_PLAY),
- FLAG_UPDATE_CURRENT));
+ FLAG_UPDATE_CURRENT | FLAG_IMMUTABLE));
String nextDescription = mContext.getString(R.string.pip_skip_to_next);
mNextAction = new RemoteAction(Icon.createWithResource(mContext,
R.drawable.pip_ic_skip_next_white), nextDescription, nextDescription,
PendingIntent.getBroadcast(mContext, 0, new Intent(ACTION_NEXT),
- FLAG_UPDATE_CURRENT));
+ FLAG_UPDATE_CURRENT | FLAG_IMMUTABLE));
String prevDescription = mContext.getString(R.string.pip_skip_to_prev);
mPrevAction = new RemoteAction(Icon.createWithResource(mContext,
R.drawable.pip_ic_skip_previous_white), prevDescription, prevDescription,
PendingIntent.getBroadcast(mContext, 0, new Intent(ACTION_PREV),
- FLAG_UPDATE_CURRENT));
+ FLAG_UPDATE_CURRENT | FLAG_IMMUTABLE));
}
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipController.java
index 8eac005425bc..4f2d4e50f76d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipController.java
@@ -19,6 +19,10 @@ package com.android.wm.shell.pip.tv;
import static android.app.ActivityTaskManager.INVALID_STACK_ID;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+import static android.content.Intent.ACTION_MEDIA_RESOURCE_GRANTED;
+
+import static com.android.wm.shell.pip.tv.PipNotification.ACTION_CLOSE;
+import static com.android.wm.shell.pip.tv.PipNotification.ACTION_MENU;
import android.app.ActivityManager;
import android.app.ActivityTaskManager;
@@ -140,17 +144,26 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- if (Intent.ACTION_MEDIA_RESOURCE_GRANTED.equals(action)) {
- String[] packageNames = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
- int resourceType = intent.getIntExtra(Intent.EXTRA_MEDIA_RESOURCE_TYPE,
- INVALID_RESOURCE_TYPE);
- if (packageNames != null && packageNames.length > 0
- && resourceType == Intent.EXTRA_MEDIA_RESOURCE_TYPE_VIDEO_CODEC) {
- handleMediaResourceGranted(packageNames);
- }
+ if (DEBUG) {
+ Log.d(TAG, "mBroadcastReceiver, action: " + intent.getAction());
+ }
+ switch (intent.getAction()) {
+ case ACTION_MENU:
+ showPictureInPictureMenu();
+ break;
+ case ACTION_CLOSE:
+ closePip();
+ break;
+ case ACTION_MEDIA_RESOURCE_GRANTED:
+ String[] packageNames = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
+ int resourceType = intent.getIntExtra(Intent.EXTRA_MEDIA_RESOURCE_TYPE,
+ INVALID_RESOURCE_TYPE);
+ if (packageNames != null && packageNames.length > 0
+ && resourceType == Intent.EXTRA_MEDIA_RESOURCE_TYPE_VIDEO_CODEC) {
+ handleMediaResourceGranted(packageNames);
+ }
+ break;
}
-
}
};
private final MediaSessionManager.OnActiveSessionsChangedListener mActiveMediaSessionListener =
@@ -233,8 +246,11 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
mPipTaskOrganizer = pipTaskOrganizer;
mPipTaskOrganizer.registerPipTransitionCallback(this);
mActivityTaskManager = ActivityTaskManager.getService();
- IntentFilter intentFilter = new IntentFilter();
- intentFilter.addAction(Intent.ACTION_MEDIA_RESOURCE_GRANTED);
+
+ final IntentFilter intentFilter = new IntentFilter();
+ intentFilter.addAction(ACTION_CLOSE);
+ intentFilter.addAction(ACTION_MENU);
+ intentFilter.addAction(ACTION_MEDIA_RESOURCE_GRANTED);
mContext.registerReceiver(mBroadcastReceiver, intentFilter, UserHandle.USER_ALL);
// Initialize the last orientation and apply the current configuration
@@ -249,10 +265,10 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
} catch (RemoteException e) {
Log.e(TAG, "Failed to register pinned stack listener", e);
}
- }
- // TODO(b/169395392) Refactor PipMenuActivity to PipMenuView
- PipMenuActivity.setPipController(this);
+ // TODO(b/169395392) Refactor PipMenuActivity to PipMenuView
+ PipMenuActivity.setPipController(this);
+ }
}
private void loadConfigurationsAndApply(Configuration newConfig) {
@@ -564,6 +580,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
} catch (RemoteException e) {
Log.e(TAG, "getRootTaskInfo failed", e);
}
+ if (DEBUG) Log.d(TAG, "getPinnedTaskInfo(), taskInfo=" + taskInfo);
return taskInfo;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipMenuActivity.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipMenuActivity.java
index 06d2408c95f4..e185a9604449 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipMenuActivity.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipMenuActivity.java
@@ -35,7 +35,7 @@ import java.util.Collections;
*/
public class PipMenuActivity extends Activity implements PipController.Listener {
private static final String TAG = "PipMenuActivity";
- private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+ private static final boolean DEBUG = PipController.DEBUG;
static final String EXTRA_CUSTOM_ACTIONS = "custom_actions";
@@ -51,7 +51,7 @@ public class PipMenuActivity extends Activity implements PipController.Listener
if (DEBUG) Log.d(TAG, "onCreate()");
super.onCreate(bundle);
- if (sPipController == null || sPipController.isPipShown()) {
+ if (sPipController == null) {
finish();
}
setContentView(R.layout.tv_pip_menu);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipNotification.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipNotification.java
index 7433085e6fcb..f5bbd23fa1d6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipNotification.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipNotification.java
@@ -20,10 +20,8 @@ import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.RemoteAction;
-import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
-import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ParceledListSlice;
@@ -32,9 +30,7 @@ import android.graphics.Bitmap;
import android.media.MediaMetadata;
import android.media.session.MediaController;
import android.media.session.PlaybackState;
-import android.os.UserHandle;
import android.text.TextUtils;
-import android.util.Log;
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.wm.shell.R;
@@ -49,8 +45,8 @@ public class PipNotification {
private static final String NOTIFICATION_TAG = PipNotification.class.getSimpleName();
private static final boolean DEBUG = PipController.DEBUG;
- private static final String ACTION_MENU = "PipNotification.menu";
- private static final String ACTION_CLOSE = "PipNotification.close";
+ static final String ACTION_MENU = "PipNotification.menu";
+ static final String ACTION_CLOSE = "PipNotification.close";
public static final String NOTIFICATION_CHANNEL_TVPIP = "TPP";
@@ -147,23 +143,6 @@ public class PipNotification {
}
};
- private final BroadcastReceiver mEventReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (DEBUG) {
- Log.d(TAG, "Received " + intent.getAction() + " from the notification UI");
- }
- switch (intent.getAction()) {
- case ACTION_MENU:
- mPipController.showPictureInPictureMenu();
- break;
- case ACTION_CLOSE:
- mPipController.closePip();
- break;
- }
- }
- };
-
public PipNotification(Context context, PipController pipController) {
mPackageManager = context.getPackageManager();
@@ -182,11 +161,6 @@ public class PipNotification {
pipController.addListener(mPipListener);
pipController.addMediaListener(mPipMediaListener);
- IntentFilter intentFilter = new IntentFilter();
- intentFilter.addAction(ACTION_MENU);
- intentFilter.addAction(ACTION_CLOSE);
- context.registerReceiver(mEventReceiver, intentFilter, UserHandle.USER_ALL);
-
onConfigurationChanged(context);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTaskOrganizer.java
index 0a1aadc90a62..f763d6d714c4 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTaskOrganizer.java
@@ -33,7 +33,6 @@ import android.util.Log;
import android.view.Display;
import android.view.SurfaceControl;
import android.view.SurfaceSession;
-import android.window.TaskAppearedInfo;
import androidx.annotation.NonNull;
@@ -69,15 +68,10 @@ class SplitScreenTaskOrganizer implements ShellTaskOrganizer.TaskListener {
void init() throws RemoteException {
synchronized (this) {
try {
- final TaskAppearedInfo primary = mTaskOrganizer.createRootTask(
- Display.DEFAULT_DISPLAY, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, this);
- final TaskAppearedInfo secondary = mTaskOrganizer.createRootTask(
- Display.DEFAULT_DISPLAY, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, this);
- mPrimary = primary.getTaskInfo();
- mPrimarySurface = primary.getLeash();
- mSecondary = secondary.getTaskInfo();
- mSecondarySurface = secondary.getLeash();
- enableSplitScreenSupportIfNeeded();
+ mPrimary = mTaskOrganizer.createRootTask(Display.DEFAULT_DISPLAY,
+ WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
+ mSecondary = mTaskOrganizer.createRootTask(Display.DEFAULT_DISPLAY,
+ WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
} catch (Exception e) {
// teardown to prevent callbacks
mTaskOrganizer.removeListener(this);
@@ -98,29 +92,43 @@ class SplitScreenTaskOrganizer implements ShellTaskOrganizer.TaskListener {
mSplitScreenController.mTransactionPool.release(t);
}
- private void enableSplitScreenSupportIfNeeded() {
- if (mSplitScreenSupported || mPrimarySurface == null || mSecondarySurface == null) return;
-
- mSplitScreenSupported = true;
-
- // Initialize dim surfaces:
- mPrimaryDim = new SurfaceControl.Builder(mSurfaceSession)
- .setParent(mPrimarySurface).setColorLayer()
- .setName("Primary Divider Dim")
- .setCallsite("SplitScreenTaskOrganizer.onTaskAppeared")
- .build();
- mSecondaryDim = new SurfaceControl.Builder(mSurfaceSession)
- .setParent(mSecondarySurface).setColorLayer()
- .setName("Secondary Divider Dim")
- .setCallsite("SplitScreenTaskOrganizer.onTaskAppeared")
- .build();
- SurfaceControl.Transaction t = getTransaction();
- t.setLayer(mPrimaryDim, Integer.MAX_VALUE);
- t.setColor(mPrimaryDim, new float[]{0f, 0f, 0f});
- t.setLayer(mSecondaryDim, Integer.MAX_VALUE);
- t.setColor(mSecondaryDim, new float[]{0f, 0f, 0f});
- t.apply();
- releaseTransaction(t);
+ @Override
+ public void onTaskAppeared(RunningTaskInfo taskInfo, SurfaceControl leash) {
+ synchronized (this) {
+ if (mPrimary == null || mSecondary == null) {
+ Log.w(TAG, "Received onTaskAppeared before creating root tasks " + taskInfo);
+ return;
+ }
+
+ if (taskInfo.token.equals(mPrimary.token)) {
+ mPrimarySurface = leash;
+ } else if (taskInfo.token.equals(mSecondary.token)) {
+ mSecondarySurface = leash;
+ }
+
+ if (!mSplitScreenSupported && mPrimarySurface != null && mSecondarySurface != null) {
+ mSplitScreenSupported = true;
+
+ // Initialize dim surfaces:
+ mPrimaryDim = new SurfaceControl.Builder(mSurfaceSession)
+ .setParent(mPrimarySurface).setColorLayer()
+ .setName("Primary Divider Dim")
+ .setCallsite("SplitScreenTaskOrganizer.onTaskAppeared")
+ .build();
+ mSecondaryDim = new SurfaceControl.Builder(mSurfaceSession)
+ .setParent(mSecondarySurface).setColorLayer()
+ .setName("Secondary Divider Dim")
+ .setCallsite("SplitScreenTaskOrganizer.onTaskAppeared")
+ .build();
+ SurfaceControl.Transaction t = getTransaction();
+ t.setLayer(mPrimaryDim, Integer.MAX_VALUE);
+ t.setColor(mPrimaryDim, new float[]{0f, 0f, 0f});
+ t.setLayer(mSecondaryDim, Integer.MAX_VALUE);
+ t.setColor(mSecondaryDim, new float[]{0f, 0f, 0f});
+ t.apply();
+ releaseTransaction(t);
+ }
+ }
}
@Override
diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/AndroidManifest.xml b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/AndroidManifest.xml
index 3b66c58414e0..7f8321f3fa3d 100644
--- a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/AndroidManifest.xml
+++ b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/AndroidManifest.xml
@@ -32,6 +32,10 @@
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.LEANBACK_LAUNCHER"/>
+ </intent-filter>
</activity>
<activity android:name=".ImeActivity"
android:taskAffinity="com.android.wm.shell.flicker.testapp.ImeActivity"
@@ -41,6 +45,10 @@
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.LEANBACK_LAUNCHER"/>
+ </intent-filter>
</activity>
</application>
</manifest>
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsHandlerTest.java
index e0ac8e24756d..39117bb5912b 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsHandlerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsHandlerTest.java
@@ -123,7 +123,8 @@ public class PipBoundsHandlerTest extends PipTestCase {
(MAX_ASPECT_RATIO + DEFAULT_ASPECT_RATIO) / 2
};
for (float aspectRatio : aspectRatios) {
- final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(aspectRatio,
+ mPipBoundsState.setAspectRatio(aspectRatio);
+ final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(
EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
final float actualAspectRatio =
destinationBounds.width() / (destinationBounds.height() * 1f);
@@ -139,7 +140,8 @@ public class PipBoundsHandlerTest extends PipTestCase {
MAX_ASPECT_RATIO * 2
};
for (float aspectRatio : invalidAspectRatios) {
- final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(aspectRatio,
+ mPipBoundsState.setAspectRatio(aspectRatio);
+ final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(
EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
final float actualAspectRatio =
destinationBounds.width() / (destinationBounds.height() * 1f);
@@ -155,8 +157,9 @@ public class PipBoundsHandlerTest extends PipTestCase {
final Rect currentBounds = new Rect(0, 0, 0, 100);
currentBounds.right = (int) (currentBounds.height() * aspectRatio) + currentBounds.left;
- final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(aspectRatio,
- currentBounds, EMPTY_MINIMAL_SIZE);
+ mPipBoundsState.setAspectRatio(aspectRatio);
+ final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(currentBounds,
+ EMPTY_MINIMAL_SIZE);
final float actualAspectRatio =
destinationBounds.width() / (destinationBounds.height() * 1f);
@@ -179,7 +182,8 @@ public class PipBoundsHandlerTest extends PipTestCase {
for (int i = 0; i < aspectRatios.length; i++) {
final float aspectRatio = aspectRatios[i];
final Size minimalSize = minimalSizes[i];
- final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(aspectRatio,
+ mPipBoundsState.setAspectRatio(aspectRatio);
+ final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(
EMPTY_CURRENT_BOUNDS, minimalSize);
assertTrue("Destination bounds is no smaller than minimal requirement",
(destinationBounds.width() == minimalSize.getWidth()
@@ -200,7 +204,8 @@ public class PipBoundsHandlerTest extends PipTestCase {
currentBounds.right = (int) (currentBounds.height() * aspectRatio) + currentBounds.left;
final Size minSize = new Size(currentBounds.width() / 2, currentBounds.height() / 2);
- final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(aspectRatio,
+ mPipBoundsState.setAspectRatio(aspectRatio);
+ final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(
currentBounds, minSize);
assertTrue("Destination bounds ignores minimal size",
@@ -210,13 +215,14 @@ public class PipBoundsHandlerTest extends PipTestCase {
@Test
public void getDestinationBounds_reentryStateExists_restoreLastSize() {
- final Rect reentryBounds = mPipBoundsHandler.getDestinationBounds(DEFAULT_ASPECT_RATIO,
+ mPipBoundsState.setAspectRatio(DEFAULT_ASPECT_RATIO);
+ final Rect reentryBounds = mPipBoundsHandler.getDestinationBounds(
EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
reentryBounds.scale(1.25f);
final float reentrySnapFraction = mPipBoundsHandler.getSnapFraction(reentryBounds);
mPipBoundsState.saveReentryState(reentryBounds, reentrySnapFraction);
- final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(DEFAULT_ASPECT_RATIO,
+ final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(
EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
assertEquals(reentryBounds.width(), destinationBounds.width());
@@ -225,14 +231,15 @@ public class PipBoundsHandlerTest extends PipTestCase {
@Test
public void getDestinationBounds_reentryStateExists_restoreLastPosition() {
- final Rect reentryBounds = mPipBoundsHandler.getDestinationBounds(DEFAULT_ASPECT_RATIO,
+ mPipBoundsState.setAspectRatio(DEFAULT_ASPECT_RATIO);
+ final Rect reentryBounds = mPipBoundsHandler.getDestinationBounds(
EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
reentryBounds.offset(0, -100);
final float reentrySnapFraction = mPipBoundsHandler.getSnapFraction(reentryBounds);
mPipBoundsState.saveReentryState(reentryBounds, reentrySnapFraction);
- final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(DEFAULT_ASPECT_RATIO,
+ final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(
EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
assertBoundsInclusionWithMargin("restoreLastPosition", reentryBounds, destinationBounds);
@@ -241,11 +248,12 @@ public class PipBoundsHandlerTest extends PipTestCase {
@Test
public void setShelfHeight_offsetBounds() {
final int shelfHeight = 100;
- final Rect oldPosition = mPipBoundsHandler.getDestinationBounds(DEFAULT_ASPECT_RATIO,
+ mPipBoundsState.setAspectRatio(DEFAULT_ASPECT_RATIO);
+ final Rect oldPosition = mPipBoundsHandler.getDestinationBounds(
EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
mPipBoundsHandler.setShelfHeight(true, shelfHeight);
- final Rect newPosition = mPipBoundsHandler.getDestinationBounds(DEFAULT_ASPECT_RATIO,
+ final Rect newPosition = mPipBoundsHandler.getDestinationBounds(
EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
oldPosition.offset(0, -shelfHeight);
@@ -255,11 +263,12 @@ public class PipBoundsHandlerTest extends PipTestCase {
@Test
public void onImeVisibilityChanged_offsetBounds() {
final int imeHeight = 100;
- final Rect oldPosition = mPipBoundsHandler.getDestinationBounds(DEFAULT_ASPECT_RATIO,
+ mPipBoundsState.setAspectRatio(DEFAULT_ASPECT_RATIO);
+ final Rect oldPosition = mPipBoundsHandler.getDestinationBounds(
EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
mPipBoundsHandler.onImeVisibilityChanged(true, imeHeight);
- final Rect newPosition = mPipBoundsHandler.getDestinationBounds(DEFAULT_ASPECT_RATIO,
+ final Rect newPosition = mPipBoundsHandler.getDestinationBounds(
EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
oldPosition.offset(0, -imeHeight);
@@ -268,12 +277,13 @@ public class PipBoundsHandlerTest extends PipTestCase {
@Test
public void getDestinationBounds_noReentryState_useDefaultBounds() {
- final Rect defaultBounds = mPipBoundsHandler.getDestinationBounds(DEFAULT_ASPECT_RATIO,
+ mPipBoundsState.setAspectRatio(DEFAULT_ASPECT_RATIO);
+ final Rect defaultBounds = mPipBoundsHandler.getDestinationBounds(
EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
mPipBoundsState.clearReentryState();
- final Rect actualBounds = mPipBoundsHandler.getDestinationBounds(DEFAULT_ASPECT_RATIO,
+ final Rect actualBounds = mPipBoundsHandler.getDestinationBounds(
EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
assertBoundsInclusionWithMargin("useDefaultBounds", defaultBounds, actualBounds);