Introduce DisplayArea organizer
Similar to task organizer this allows for the organization of display
areas.
Test: they pass!
Bug: 147406652
Bug: 152113464
Bug: 152117221
Change-Id: Id0dbec20f0aedc5162f4ff7be81b2dafb0c8f3c9
diff --git a/core/java/android/window/IDisplayAreaOrganizer.aidl b/core/java/android/window/IDisplayAreaOrganizer.aidl
new file mode 100644
index 0000000..1045ab2
--- /dev/null
+++ b/core/java/android/window/IDisplayAreaOrganizer.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.window;
+
+import android.window.IWindowContainer;
+
+/**
+ * Interface for WindowManager to delegate control of display areas.
+ * {@hide}
+ */
+oneway interface IDisplayAreaOrganizer {
+ void onDisplayAreaAppeared(in IWindowContainer displayArea);
+ void onDisplayAreaVanished(in IWindowContainer displayArea);
+}
diff --git a/core/java/android/window/IDisplayAreaOrganizerController.aidl b/core/java/android/window/IDisplayAreaOrganizerController.aidl
new file mode 100644
index 0000000..fc6fbef
--- /dev/null
+++ b/core/java/android/window/IDisplayAreaOrganizerController.aidl
@@ -0,0 +1,26 @@
+/**
+ * Copyright (c) 2020, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.window;
+
+import android.window.IDisplayAreaOrganizer;
+
+/** @hide */
+interface IDisplayAreaOrganizerController {
+
+ /** Register a DisplayAreaOrganizer to manage display areas for a given feature. */
+ void registerOrganizer(in IDisplayAreaOrganizer organizer, int displayAreaFeature);
+}
diff --git a/core/java/android/window/ITaskOrganizer.aidl b/core/java/android/window/ITaskOrganizer.aidl
index 0a04462..fcf4830 100644
--- a/core/java/android/window/ITaskOrganizer.aidl
+++ b/core/java/android/window/ITaskOrganizer.aidl
@@ -25,8 +25,8 @@
* {@hide}
*/
oneway interface ITaskOrganizer {
- void taskAppeared(in ActivityManager.RunningTaskInfo taskInfo);
- void taskVanished(in ActivityManager.RunningTaskInfo taskInfo);
+ void onTaskAppeared(in ActivityManager.RunningTaskInfo taskInfo);
+ void onTaskVanished(in ActivityManager.RunningTaskInfo taskInfo);
/**
* Will fire when core attributes of a Task's info change. Relevant properties include the
diff --git a/core/java/android/window/IWindowOrganizerController.aidl b/core/java/android/window/IWindowOrganizerController.aidl
index 4b47924..7f4b26d 100644
--- a/core/java/android/window/IWindowOrganizerController.aidl
+++ b/core/java/android/window/IWindowOrganizerController.aidl
@@ -16,6 +16,7 @@
package android.window;
+import android.window.IDisplayAreaOrganizerController;
import android.window.ITaskOrganizerController;
import android.window.IWindowContainerTransactionCallback;
import android.window.WindowContainerTransaction;
@@ -43,4 +44,7 @@
/** @return An interface enabling the management of task organizers. */
ITaskOrganizerController getTaskOrganizerController();
+
+ /** @return An interface enabling the management of display area organizers. */
+ IDisplayAreaOrganizerController getDisplayAreaOrganizerController();
}
diff --git a/core/java/android/window/WindowOrganizer.java b/core/java/android/window/WindowOrganizer.java
index b8969c1..4bd5b29 100644
--- a/core/java/android/window/WindowOrganizer.java
+++ b/core/java/android/window/WindowOrganizer.java
@@ -152,6 +152,50 @@
}
}
};
+ }
+
+ /** Class for organizing display areas. */
+ public static class DisplayAreaOrganizer {
+
+ public static final int FEATURE_UNDEFINED = -1;
+ public static final int FEATURE_SYSTEM_FIRST = 0;
+ // The Root display area on a display
+ public static final int FEATURE_ROOT = FEATURE_SYSTEM_FIRST;
+ // Display area hosting the task container.
+ public static final int FEATURE_TASK_CONTAINER = FEATURE_SYSTEM_FIRST + 1;
+ // Display area hosting non-activity window tokens.
+ public static final int FEATURE_WINDOW_TOKENS = FEATURE_SYSTEM_FIRST + 2;
+
+ public static final int FEATURE_SYSTEM_LAST = 10_000;
+
+ // Vendor specific display area definition can start with this value.
+ public static final int FEATURE_VENDOR_FIRST = FEATURE_SYSTEM_LAST + 1;
+
+ /** @hide */
+ @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
+ public static void registerOrganizer(
+ IDisplayAreaOrganizer organizer, int displayAreaFeature) throws RemoteException {
+ getController().registerOrganizer(organizer, displayAreaFeature);
+ }
+
+ /** @hide */
+ private static IDisplayAreaOrganizerController getController() {
+ return IDisplayAreaOrganizerControllerSingleton.get();
+ }
+
+ private static final Singleton<IDisplayAreaOrganizerController>
+ IDisplayAreaOrganizerControllerSingleton =
+ new Singleton<IDisplayAreaOrganizerController>() {
+ @Override
+ protected IDisplayAreaOrganizerController create() {
+ try {
+ return getWindowOrganizerController()
+ .getDisplayAreaOrganizerController();
+ } catch (RemoteException e) {
+ return null;
+ }
+ }
+ };
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java
index 7f14645..9a57683 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java
@@ -210,7 +210,7 @@
}
@Override
- public void taskAppeared(ActivityManager.RunningTaskInfo info) {
+ public void onTaskAppeared(ActivityManager.RunningTaskInfo info) {
Objects.requireNonNull(info, "Requires RunningTaskInfo");
final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(
getAspectRatioOrDefault(info.pictureInPictureParams),
@@ -243,7 +243,7 @@
}
@Override
- public void taskVanished(ActivityManager.RunningTaskInfo info) {
+ public void onTaskVanished(ActivityManager.RunningTaskInfo info) {
IWindowContainer token = info.token;
Objects.requireNonNull(token, "Requires valid IWindowContainer");
if (token.asBinder() != mToken.asBinder()) {
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java b/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java
index 8bbb548..c4089e5 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java
@@ -82,11 +82,11 @@
}
@Override
- public void taskAppeared(RunningTaskInfo taskInfo) {
+ public void onTaskAppeared(RunningTaskInfo taskInfo) {
}
@Override
- public void taskVanished(RunningTaskInfo taskInfo) {
+ public void onTaskVanished(RunningTaskInfo taskInfo) {
}
@Override
diff --git a/services/core/java/com/android/server/wm/DisplayArea.java b/services/core/java/com/android/server/wm/DisplayArea.java
index d9e41af..8cac487 100644
--- a/services/core/java/com/android/server/wm/DisplayArea.java
+++ b/services/core/java/com/android/server/wm/DisplayArea.java
@@ -21,6 +21,9 @@
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
import static android.view.WindowManager.TRANSIT_KEYGUARD_UNOCCLUDE;
import static android.view.WindowManagerPolicyConstants.APPLICATION_LAYER;
+import static android.window.WindowOrganizer.DisplayAreaOrganizer.FEATURE_ROOT;
+import static android.window.WindowOrganizer.DisplayAreaOrganizer.FEATURE_UNDEFINED;
+import static android.window.WindowOrganizer.DisplayAreaOrganizer.FEATURE_WINDOW_TOKENS;
import static com.android.internal.util.Preconditions.checkState;
import static com.android.server.wm.DisplayAreaProto.NAME;
@@ -28,13 +31,16 @@
import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ORIENTATION;
import static com.android.server.wm.WindowContainerChildProto.DISPLAY_AREA;
+import android.graphics.Point;
import android.graphics.Rect;
import android.util.proto.ProtoOutputStream;
+import android.window.IDisplayAreaOrganizer;
import com.android.server.policy.WindowManagerPolicy;
import com.android.server.protolog.common.ProtoLog;
import java.util.Comparator;
+import java.util.function.Consumer;
import java.util.function.Predicate;
/**
@@ -57,13 +63,24 @@
protected final Type mType;
private final String mName;
+ final int mFeatureId;
+ private final DisplayAreaOrganizerController mOrganizerController;
+ IDisplayAreaOrganizer mOrganizer;
DisplayArea(WindowManagerService wms, Type type, String name) {
+ this(wms, type, name, FEATURE_UNDEFINED);
+ }
+
+ DisplayArea(WindowManagerService wms, Type type, String name, int featureId) {
super(wms);
// TODO(display-area): move this up to ConfigurationContainer
mOrientation = SCREEN_ORIENTATION_UNSET;
mType = type;
mName = name;
+ mFeatureId = featureId;
+ mRemoteToken = new RemoteToken(this);
+ mOrganizerController =
+ wms.mAtmService.mWindowOrganizerController.mDisplayAreaOrganizerController;
}
@Override
@@ -116,6 +133,33 @@
return DISPLAY_AREA;
}
+ void forAllDisplayAreas(Consumer<DisplayArea> callback) {
+ super.forAllDisplayAreas(callback);
+ callback.accept(this);
+ }
+
+ void setOrganizer(IDisplayAreaOrganizer organizer) {
+ if (mOrganizer == organizer) return;
+ sendDisplayAreaVanished();
+ mOrganizer = organizer;
+ sendDisplayAreaAppeared();
+ }
+
+ void sendDisplayAreaAppeared() {
+ if (mOrganizer == null) return;
+ mOrganizerController.onDisplayAreaAppeared(mOrganizer, this);
+ }
+
+ void sendDisplayAreaVanished() {
+ if (mOrganizer == null) return;
+ mOrganizerController.onDisplayAreaVanished(mOrganizer, this);
+ }
+
+ @Override
+ boolean isOrganized() {
+ return mOrganizer != null;
+ }
+
/**
* DisplayArea that contains WindowTokens, and orders them according to their type.
*/
@@ -152,7 +196,7 @@
};
Tokens(WindowManagerService wms, Type type, String name) {
- super(wms, type, name);
+ super(wms, type, name, FEATURE_WINDOW_TOKENS);
}
void addChild(WindowToken token) {
@@ -191,7 +235,7 @@
private final Rect mTmpDimBoundsRect = new Rect();
Root(WindowManagerService wms) {
- super(wms, Type.ANY, "DisplayArea.Root");
+ super(wms, Type.ANY, "DisplayArea.Root", FEATURE_ROOT);
}
@Override
diff --git a/services/core/java/com/android/server/wm/DisplayAreaOrganizerController.java b/services/core/java/com/android/server/wm/DisplayAreaOrganizerController.java
new file mode 100644
index 0000000..464b127
--- /dev/null
+++ b/services/core/java/com/android/server/wm/DisplayAreaOrganizerController.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
+
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.window.IDisplayAreaOrganizer;
+import android.window.IDisplayAreaOrganizerController;
+
+import java.util.HashMap;
+
+public class DisplayAreaOrganizerController extends IDisplayAreaOrganizerController.Stub {
+ private static final String TAG = "DisplayAreaOrganizerController";
+
+ final ActivityTaskManagerService mService;
+ private final WindowManagerGlobalLock mGlobalLock;
+ private final HashMap<Integer, IDisplayAreaOrganizer> mOrganizersByFeatureIds = new HashMap();
+
+ private class DeathRecipient implements IBinder.DeathRecipient {
+ int mFeature;
+ IDisplayAreaOrganizer mOrganizer;
+
+ DeathRecipient(IDisplayAreaOrganizer organizer, int feature) {
+ mOrganizer = organizer;
+ mFeature = feature;
+ }
+
+ @Override
+ public void binderDied() {
+ synchronized (mGlobalLock) {
+ mOrganizersByFeatureIds.remove(mFeature);
+ mService.mRootWindowContainer.forAllDisplayAreas((da) -> {
+ if (da.mOrganizer != mOrganizer) return;
+ da.setOrganizer(null);
+ });
+ }
+ }
+ }
+
+ DisplayAreaOrganizerController(ActivityTaskManagerService atm) {
+ mService = atm;
+ mGlobalLock = atm.mGlobalLock;
+ }
+
+ private void enforceStackPermission(String func) {
+ mService.mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, func);
+ }
+
+ @Override
+ public void registerOrganizer(IDisplayAreaOrganizer organizer, int feature) {
+ enforceStackPermission("registerOrganizer()");
+ final long origId = Binder.clearCallingIdentity();
+ try {
+ synchronized (mGlobalLock) {
+ if (mOrganizersByFeatureIds.get(feature) != null) {
+ throw new IllegalStateException(
+ "Replacing existing organizer currently unsupported");
+ }
+
+ final DeathRecipient dr = new DeathRecipient(organizer, feature);
+ try {
+ organizer.asBinder().linkToDeath(dr, 0);
+ } catch (RemoteException e) {
+ // Oh well...
+ }
+ mService.mRootWindowContainer.forAllDisplayAreas((da) -> {
+ if (da.mFeatureId != feature) return;
+ da.setOrganizer(organizer);
+ });
+
+ mOrganizersByFeatureIds.put(feature, organizer);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(origId);
+ }
+ }
+
+ void onDisplayAreaAppeared(IDisplayAreaOrganizer organizer, DisplayArea da) {
+ try {
+ organizer.onDisplayAreaAppeared(da.mRemoteToken);
+ } catch (RemoteException e) {
+ // Oh well...
+ }
+ }
+
+ void onDisplayAreaVanished(IDisplayAreaOrganizer organizer, DisplayArea da) {
+ try {
+ organizer.onDisplayAreaVanished(da.mRemoteToken);
+ } catch (RemoteException e) {
+ // Oh well...
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/wm/DisplayAreaPolicyBuilder.java b/services/core/java/com/android/server/wm/DisplayAreaPolicyBuilder.java
index 885456a..0c6e483 100644
--- a/services/core/java/com/android/server/wm/DisplayAreaPolicyBuilder.java
+++ b/services/core/java/com/android/server/wm/DisplayAreaPolicyBuilder.java
@@ -73,16 +73,36 @@
*/
static class Feature {
private final String mName;
+ private final int mId;
private final boolean[] mWindowLayers;
- private Feature(String name, boolean[] windowLayers) {
+ private Feature(String name, int id, boolean[] windowLayers) {
mName = name;
+ mId = id;
mWindowLayers = windowLayers;
}
+ /**
+ * Returns the id of the feature.
+ *
+ * Must be unique among the features added to a {@link DisplayAreaPolicyBuilder}.
+ *
+ * @see android.window.WindowOrganizer.DisplayAreaOrganizer#FEATURE_SYSTEM_FIRST
+ * @see android.window.WindowOrganizer.DisplayAreaOrganizer#FEATURE_VENDOR_FIRST
+ */
+ public int getId() {
+ return mId;
+ }
+
+ @Override
+ public String toString() {
+ return "Feature(\"" + mName + "\", " + mId + '}';
+ }
+
static class Builder {
private final WindowManagerPolicy mPolicy;
private final String mName;
+ private final int mId;
private final boolean[] mLayers;
/**
@@ -96,10 +116,12 @@
* The builder starts out with the feature not applying to any types.
*
* @param name the name of the feature.
+ * @param id of the feature. {@see Feature#getId}
*/
- Builder(WindowManagerPolicy policy, String name) {
+ Builder(WindowManagerPolicy policy, String name, int id) {
mPolicy = policy;
mName = name;
+ mId = id;
mLayers = new boolean[mPolicy.getMaxWindowLayer()];
}
@@ -147,7 +169,7 @@
}
Feature build() {
- return new Feature(mName, mLayers.clone());
+ return new Feature(mName, mId, mLayers.clone());
}
private void set(int type, boolean value) {
@@ -364,7 +386,7 @@
return leaf;
} else {
return new DisplayArea(parent.mWmService, type, mFeature.mName + ":"
- + mMinLayer + ":" + mMaxLayer);
+ + mMinLayer + ":" + mMaxLayer, mFeature.mId);
}
}
}
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 236a62b7..cb5e84c 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -79,6 +79,7 @@
import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN;
import static android.view.WindowManager.TRANSIT_TASK_OPEN;
import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT;
+import static android.window.WindowOrganizer.DisplayAreaOrganizer.FEATURE_TASK_CONTAINER;
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG;
@@ -4293,7 +4294,7 @@
private ActivityStack mRootSplitScreenPrimaryTask = null;
TaskContainers(WindowManagerService service) {
- super(service, Type.ANY, "TaskContainers");
+ super(service, Type.ANY, "TaskContainers", FEATURE_TASK_CONTAINER);
}
/**
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index e2c7d52..88cdd17 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -301,7 +301,7 @@
* we may have some issues with modal-windows, but I guess we can
* cross that bridge when we come to implementing full-screen TaskOrg
*/
- if (child.getTask() != null && child.getTask().isControlledByTaskOrganizer()) {
+ if (child.getTask() != null && child.getTask().isOrganized()) {
inputWindowHandle.replaceTouchableRegionWithCrop(null /* Use this surfaces crop */);
}
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index eca7d2e..55dc694 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -509,22 +509,6 @@
_voiceSession, _voiceInteractor, stack);
}
- class TaskToken extends RemoteToken {
- TaskToken(WindowContainer container) {
- super(container);
- }
-
- @Override
- public SurfaceControl getLeash() {
- // We need to copy the SurfaceControl instead of returning the original
- // because the Parcel FLAGS PARCELABLE_WRITE_RETURN_VALUE cause SurfaceControls
- // to release themselves.
- SurfaceControl sc = new SurfaceControl();
- sc.copyFrom(getSurfaceControl());
- return sc;
- }
- }
-
/** Don't use constructor directly. This is only used by XML parser. */
Task(ActivityTaskManagerService atmService, int _taskId, Intent _intent, Intent _affinityIntent,
String _affinity, String _rootAffinity, ComponentName _realActivity,
@@ -550,7 +534,7 @@
mTaskDescription = _lastTaskDescription;
// Tasks have no set orientation value (including SCREEN_ORIENTATION_UNSPECIFIED).
setOrientation(SCREEN_ORIENTATION_UNSET);
- mRemoteToken = new TaskToken(this);
+ mRemoteToken = new RemoteToken(this);
affinityIntent = _affinityIntent;
affinity = _affinity;
rootAffinity = _rootAffinity;
@@ -3110,7 +3094,7 @@
/**
* Animations are handled by the TaskOrganizer implementation.
*/
- if (isControlledByTaskOrganizer()) {
+ if (isOrganized()) {
return false;
}
// Don't animate while the task runs recents animation but only if we are in the mode
@@ -4014,7 +3998,8 @@
}
}
- boolean isControlledByTaskOrganizer() {
+ @Override
+ boolean isOrganized() {
final Task rootTask = getRootTask();
// if the rootTask is a "child" of a tile, then don't consider it a root task.
// TODO: remove this along with removing tile.
@@ -4030,7 +4015,7 @@
* Avoid yanking back control from the TaskOrganizer, which has presumably reparented the
* Surface in to its own hierarchy.
*/
- if (isControlledByTaskOrganizer()) {
+ if (isOrganized()) {
return;
}
super.reparentSurfaceControl(t, newParent);
@@ -4117,27 +4102,6 @@
sendTaskAppeared();
}
- @Override
- public void updateSurfacePosition() {
- // Avoid fighting with the TaskOrganizer over Surface position.
- if (isControlledByTaskOrganizer()) {
- return;
- } else {
- super.updateSurfacePosition();
- }
- }
-
- @Override
- void getRelativeDisplayedPosition(Point outPos) {
- // In addition to updateSurfacePosition, we keep other code that sets
- // position from fighting with the TaskOrganizer
- if (isControlledByTaskOrganizer()) {
- outPos.set(0, 0);
- return;
- }
- super.getRelativeDisplayedPosition(outPos);
- }
-
/**
* @return true if the task is currently focused.
*/
diff --git a/services/core/java/com/android/server/wm/TaskOrganizerController.java b/services/core/java/com/android/server/wm/TaskOrganizerController.java
index fc58ee7..5523678 100644
--- a/services/core/java/com/android/server/wm/TaskOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskOrganizerController.java
@@ -111,7 +111,7 @@
void addTask(Task t) {
mOrganizedTasks.add(t);
try {
- mOrganizer.taskAppeared(t.getTaskInfo());
+ mOrganizer.onTaskAppeared(t.getTaskInfo());
} catch (Exception e) {
Slog.e(TAG, "Exception sending taskAppeared callback" + e);
}
@@ -119,7 +119,7 @@
void removeTask(Task t) {
try {
- mOrganizer.taskVanished(t.getTaskInfo());
+ mOrganizer.onTaskVanished(t.getTaskInfo());
} catch (Exception e) {
Slog.e(TAG, "Exception sending taskVanished callback" + e);
}
diff --git a/services/core/java/com/android/server/wm/TaskTile.java b/services/core/java/com/android/server/wm/TaskTile.java
index 822f840..51142b1 100644
--- a/services/core/java/com/android/server/wm/TaskTile.java
+++ b/services/core/java/com/android/server/wm/TaskTile.java
@@ -218,7 +218,7 @@
static TaskTile forToken(IBinder token) {
try {
- return (TaskTile) ((TaskToken) token).getContainer();
+ return (TaskTile) ((RemoteToken) token).getContainer();
} catch (ClassCastException e) {
Slog.w(TAG, "Bad tile token: " + token, e);
return null;
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 6c69dc6..b60cd99 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -1608,6 +1608,12 @@
return null;
}
+ void forAllDisplayAreas(Consumer<DisplayArea> callback) {
+ for (int i = mChildren.size() - 1; i >= 0; --i) {
+ mChildren.get(i).forAllDisplayAreas(callback);
+ }
+ }
+
/**
* Returns 1, 0, or -1 depending on if this container is greater than, equal to, or lesser than
* the input container in terms of z-order.
@@ -2321,6 +2327,9 @@
}
void updateSurfacePosition() {
+ // Avoid fighting with the organizer over Surface position.
+ if (isOrganized()) return;
+
if (mSurfaceControl == null) {
return;
}
@@ -2370,6 +2379,13 @@
}
void getRelativeDisplayedPosition(Point outPos) {
+ // In addition to updateSurfacePosition, we keep other code that sets
+ // position from fighting with the organizer
+ if (isOrganized()) {
+ outPos.set(0, 0);
+ return;
+ }
+
final Rect dispBounds = getDisplayedBounds();
outPos.set(dispBounds.left, dispBounds.top);
final WindowContainer parent = getParent();
@@ -2410,8 +2426,12 @@
return null;
}
- RemoteToken getRemoteToken() {
- return mRemoteToken;
+ /**
+ * @return {@code true} if window container is manage by a
+ * {@link android.window.WindowOrganizer}
+ */
+ boolean isOrganized() {
+ return false;
}
static WindowContainer fromBinder(IBinder binder) {
@@ -2435,7 +2455,14 @@
@Override
public SurfaceControl getLeash() {
- throw new RuntimeException("Not implemented");
+ final WindowContainer wc = getContainer();
+ if (wc == null) return null;
+ // We need to copy the SurfaceControl instead of returning the original
+ // because the Parcel FLAGS PARCELABLE_WRITE_RETURN_VALUE cause SurfaceControls
+ // to release themselves.
+ SurfaceControl sc = new SurfaceControl();
+ sc.copyFrom(wc.getSurfaceControl());
+ return sc;
}
@Override
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index ebfe109..e416e80 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -33,6 +33,7 @@
import android.util.ArraySet;
import android.util.Slog;
import android.view.SurfaceControl;
+import android.window.IDisplayAreaOrganizerController;
import android.window.ITaskOrganizerController;
import android.window.IWindowContainerTransactionCallback;
import android.window.IWindowOrganizerController;
@@ -76,11 +77,13 @@
mTransactionCallbacksByPendingSyncId = new HashMap();
final TaskOrganizerController mTaskOrganizerController;
+ final DisplayAreaOrganizerController mDisplayAreaOrganizerController;
WindowOrganizerController(ActivityTaskManagerService atm) {
mService = atm;
mGlobalLock = atm.mGlobalLock;
mTaskOrganizerController = new TaskOrganizerController(mService);
+ mDisplayAreaOrganizerController = new DisplayAreaOrganizerController(mService);
}
@Override
@@ -318,6 +321,12 @@
return mTaskOrganizerController;
}
+ @Override
+ public IDisplayAreaOrganizerController getDisplayAreaOrganizerController() {
+ enforceStackPermission("getDisplayAreaOrganizerController()");
+ return mDisplayAreaOrganizerController;
+ }
+
int startSyncWithOrganizer(IWindowContainerTransactionCallback callback) {
int id = mBLASTSyncEngine.startSyncSet(this);
mTransactionCallbacksByPendingSyncId.put(id, callback);
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
index 658ba1b..6ec0f91 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
@@ -1020,10 +1020,10 @@
mSecondary = TaskTile.forToken(secondary.asBinder());
}
@Override
- public void taskAppeared(ActivityManager.RunningTaskInfo info) {
+ public void onTaskAppeared(ActivityManager.RunningTaskInfo info) {
}
@Override
- public void taskVanished(ActivityManager.RunningTaskInfo info) {
+ public void onTaskVanished(ActivityManager.RunningTaskInfo info) {
}
@Override
public void onTaskInfoChanged(ActivityManager.RunningTaskInfo info) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyBuilderTest.java b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyBuilderTest.java
index cc9173a..12bdec6 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyBuilderTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyBuilderTest.java
@@ -78,11 +78,11 @@
final Feature bar;
DisplayAreaPolicyBuilder.Result policy = new DisplayAreaPolicyBuilder()
- .addFeature(foo = new Feature.Builder(mPolicy, "Foo")
+ .addFeature(foo = new Feature.Builder(mPolicy, "Foo", 0)
.upTo(TYPE_STATUS_BAR)
.and(TYPE_NAVIGATION_BAR)
.build())
- .addFeature(bar = new Feature.Builder(mPolicy, "Bar")
+ .addFeature(bar = new Feature.Builder(mPolicy, "Bar", 1)
.all()
.except(TYPE_STATUS_BAR)
.build())
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskOrganizerTests.java
index 5359bd3..a96f401 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskOrganizerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskOrganizerTests.java
@@ -60,7 +60,6 @@
import android.util.ArrayMap;
import android.util.Rational;
import android.view.Display;
-import android.view.SurfaceControl;
import android.window.ITaskOrganizer;
import android.window.WindowContainerTransaction;
@@ -103,10 +102,10 @@
final ITaskOrganizer organizer = registerMockOrganizer();
task.setTaskOrganizer(organizer);
- verify(organizer).taskAppeared(any());
+ verify(organizer).onTaskAppeared(any());
task.removeImmediately();
- verify(organizer).taskVanished(any());
+ verify(organizer).onTaskVanished(any());
}
@Test
@@ -117,10 +116,10 @@
final ITaskOrganizer organizer2 = registerMockOrganizer(WINDOWING_MODE_PINNED);
task.setTaskOrganizer(organizer);
- verify(organizer).taskAppeared(any());
+ verify(organizer).onTaskAppeared(any());
task.setTaskOrganizer(organizer2);
- verify(organizer).taskVanished(any());
- verify(organizer2).taskAppeared(any());
+ verify(organizer).onTaskVanished(any());
+ verify(organizer2).onTaskAppeared(any());
}
@Test
@@ -131,10 +130,10 @@
final ITaskOrganizer organizer2 = registerMockOrganizer(WINDOWING_MODE_PINNED);
stack.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
- verify(organizer).taskAppeared(any());
+ verify(organizer).onTaskAppeared(any());
stack.setWindowingMode(WINDOWING_MODE_PINNED);
- verify(organizer).taskVanished(any());
- verify(organizer2).taskAppeared(any());
+ verify(organizer).onTaskVanished(any());
+ verify(organizer2).onTaskAppeared(any());
}
@Test
@@ -144,12 +143,12 @@
final ITaskOrganizer organizer = registerMockOrganizer();
stack.setTaskOrganizer(organizer);
- verify(organizer).taskAppeared(any());
- assertTrue(stack.isControlledByTaskOrganizer());
+ verify(organizer).onTaskAppeared(any());
+ assertTrue(stack.isOrganized());
stack.setTaskOrganizer(null);
- verify(organizer).taskVanished(any());
- assertFalse(stack.isControlledByTaskOrganizer());
+ verify(organizer).onTaskVanished(any());
+ assertFalse(stack.isOrganized());
}
@Test
@@ -159,12 +158,12 @@
final ITaskOrganizer organizer = registerMockOrganizer();
stack.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
- verify(organizer).taskAppeared(any());
- assertTrue(stack.isControlledByTaskOrganizer());
+ verify(organizer).onTaskAppeared(any());
+ assertTrue(stack.isOrganized());
mWm.mAtmService.mTaskOrganizerController.unregisterTaskOrganizer(organizer);
- verify(organizer).taskVanished(any());
- assertFalse(stack.isControlledByTaskOrganizer());
+ verify(organizer).onTaskVanished(any());
+ assertFalse(stack.isOrganized());
}
@Test
@@ -179,23 +178,23 @@
// First organizer is registered, verify a task appears when changing windowing mode
stack.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
- verify(organizer, times(1)).taskAppeared(any());
- assertTrue(stack.isControlledByTaskOrganizer());
+ verify(organizer, times(1)).onTaskAppeared(any());
+ assertTrue(stack.isOrganized());
// Now we replace the registration and1 verify the new organizer receives tasks
// newly entering the windowing mode.
final ITaskOrganizer organizer2 = registerMockOrganizer(WINDOWING_MODE_MULTI_WINDOW);
stack2.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
- verify(organizer2).taskAppeared(any());
- assertTrue(stack2.isControlledByTaskOrganizer());
+ verify(organizer2).onTaskAppeared(any());
+ assertTrue(stack2.isOrganized());
// Now we unregister the second one, the first one should automatically be reregistered
// so we verify that it's now seeing changes.
mWm.mAtmService.mTaskOrganizerController.unregisterTaskOrganizer(organizer2);
stack3.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
- verify(organizer, times(2)).taskAppeared(any());
- assertTrue(stack3.isControlledByTaskOrganizer());
+ verify(organizer, times(2)).onTaskAppeared(any());
+ assertTrue(stack3.isOrganized());
}
@Test
@@ -206,10 +205,10 @@
final Task task = createTaskInStack(stack, 0 /* userId */);
final Task task2 = createTaskInStack(stack, 0 /* userId */);
stack.setWindowingMode(WINDOWING_MODE_PINNED);
- verify(organizer, times(1)).taskAppeared(any());
+ verify(organizer, times(1)).onTaskAppeared(any());
stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
- verify(organizer, times(1)).taskVanished(any());
+ verify(organizer, times(1)).onTaskVanished(any());
}
@Test
@@ -219,7 +218,7 @@
stack.setWindowingMode(WINDOWING_MODE_PINNED);
final ITaskOrganizer organizer = registerMockOrganizer(WINDOWING_MODE_PINNED);
- verify(organizer, times(1)).taskAppeared(any());
+ verify(organizer, times(1)).onTaskAppeared(any());
}
@Test
@@ -396,10 +395,10 @@
final boolean[] called = {false};
ITaskOrganizer listener = new ITaskOrganizer.Stub() {
@Override
- public void taskAppeared(RunningTaskInfo taskInfo) { }
+ public void onTaskAppeared(RunningTaskInfo taskInfo) { }
@Override
- public void taskVanished(RunningTaskInfo container) { }
+ public void onTaskVanished(RunningTaskInfo container) { }
@Override
public void onTaskInfoChanged(RunningTaskInfo info) throws RemoteException {
@@ -447,10 +446,10 @@
final ArrayMap<IBinder, RunningTaskInfo> lastReportedTiles = new ArrayMap<>();
ITaskOrganizer listener = new ITaskOrganizer.Stub() {
@Override
- public void taskAppeared(RunningTaskInfo taskInfo) { }
+ public void onTaskAppeared(RunningTaskInfo taskInfo) { }
@Override
- public void taskVanished(RunningTaskInfo container) { }
+ public void onTaskVanished(RunningTaskInfo container) { }
@Override
public void onTaskInfoChanged(RunningTaskInfo info) {
@@ -667,11 +666,11 @@
RunningTaskInfo mInfo;
@Override
- public void taskAppeared(RunningTaskInfo info) {
+ public void onTaskAppeared(RunningTaskInfo info) {
mInfo = info;
}
@Override
- public void taskVanished(RunningTaskInfo info) {
+ public void onTaskVanished(RunningTaskInfo info) {
}
@Override
public void onTaskInfoChanged(RunningTaskInfo info) {
diff --git a/tests/TaskOrganizerTest/src/com/android/test/taskembed/TaskOrganizerMultiWindowTest.java b/tests/TaskOrganizerTest/src/com/android/test/taskembed/TaskOrganizerMultiWindowTest.java
index f186ed3..5afd39e 100644
--- a/tests/TaskOrganizerTest/src/com/android/test/taskembed/TaskOrganizerMultiWindowTest.java
+++ b/tests/TaskOrganizerTest/src/com/android/test/taskembed/TaskOrganizerMultiWindowTest.java
@@ -150,7 +150,7 @@
};
@Override
- public void taskAppeared(ActivityManager.RunningTaskInfo ti) {
+ public void onTaskAppeared(ActivityManager.RunningTaskInfo ti) {
if (!gotFirstTask) {
mTaskView1.reparentTask(ti.token);
gotFirstTask = true;
@@ -158,7 +158,7 @@
mTaskView2.reparentTask(ti.token);
}
}
- public void taskVanished(ActivityManager.RunningTaskInfo ti) {
+ public void onTaskVanished(ActivityManager.RunningTaskInfo ti) {
}
@Override
public void onTaskInfoChanged(ActivityManager.RunningTaskInfo info) {
diff --git a/tests/TaskOrganizerTest/src/com/android/test/taskembed/TaskOrganizerPipTest.java b/tests/TaskOrganizerTest/src/com/android/test/taskembed/TaskOrganizerPipTest.java
index a2f40dc..520bc25 100644
--- a/tests/TaskOrganizerTest/src/com/android/test/taskembed/TaskOrganizerPipTest.java
+++ b/tests/TaskOrganizerTest/src/com/android/test/taskembed/TaskOrganizerPipTest.java
@@ -38,7 +38,7 @@
TaskView mTaskView;
class Organizer extends ITaskOrganizer.Stub {
- public void taskAppeared(ActivityManager.RunningTaskInfo ti) {
+ public void onTaskAppeared(ActivityManager.RunningTaskInfo ti) {
mTaskView.reparentTask(ti.token);
final WindowContainerTransaction wct = new WindowContainerTransaction();
@@ -48,7 +48,7 @@
} catch (Exception e) {
}
}
- public void taskVanished(ActivityManager.RunningTaskInfo ti) {
+ public void onTaskVanished(ActivityManager.RunningTaskInfo ti) {
}
public void onTaskInfoChanged(ActivityManager.RunningTaskInfo info) {
}