diff options
| author | 2020-03-22 09:45:00 -0700 | |
|---|---|---|
| committer | 2020-03-24 06:30:13 -0700 | |
| commit | dec3408b508bad0b9af1c562489632221d80c41e (patch) | |
| tree | f0c92234dc34ed6f908a7178d7ec5bc845f917fa | |
| parent | 568f9f41c63f34a74c4e9e225ace29b124277a81 (diff) | |
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
22 files changed, 379 insertions, 101 deletions
diff --git a/core/java/android/window/IDisplayAreaOrganizer.aidl b/core/java/android/window/IDisplayAreaOrganizer.aidl new file mode 100644 index 000000000000..1045ab2fb509 --- /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 000000000000..fc6fbef39ce2 --- /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 0a04462c4209..fcf4830fba60 100644 --- a/core/java/android/window/ITaskOrganizer.aidl +++ b/core/java/android/window/ITaskOrganizer.aidl @@ -25,8 +25,8 @@ import android.window.IWindowContainer; * {@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 4b47924dc5a6..7f4b26dba479 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 @@ interface IWindowOrganizerController { /** @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 b8969c162309..4bd5b29f98ac 100644 --- a/core/java/android/window/WindowOrganizer.java +++ b/core/java/android/window/WindowOrganizer.java @@ -152,6 +152,50 @@ public class WindowOrganizer { } } }; + } + + /** 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 7f14645424da..9a57683deb61 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 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub { } @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 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub { } @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 8bbb548b0ecf..c4089e5dd070 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 @@ class SplitScreenTaskOrganizer extends ITaskOrganizer.Stub { } @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 d9e41afa9141..8cac487f50b9 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_UNSET; 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.DisplayAreaProto.WINDOW_CONTAINER; 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 @@ public class DisplayArea<T extends WindowContainer> extends WindowContainer<T> { 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 @@ public class DisplayArea<T extends WindowContainer> extends WindowContainer<T> { 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 @@ public class DisplayArea<T extends WindowContainer> extends WindowContainer<T> { }; 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 @@ public class DisplayArea<T extends WindowContainer> extends WindowContainer<T> { 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 000000000000..464b127a5e37 --- /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 885456a8488c..0c6e48314c48 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 @@ class DisplayAreaPolicyBuilder { */ 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 @@ class DisplayAreaPolicyBuilder { * 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 @@ class DisplayAreaPolicyBuilder { } 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 @@ class DisplayAreaPolicyBuilder { 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 236a62b7a05d..cb5e84c9fca5 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.LayoutParams.TYPE_WALLPAPER; 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 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo 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 e2c7d52fa673..88cdd1781aee 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 @@ final class InputMonitor { * 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 eca7d2e19288..55dc694bb611 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 @@ class Task extends WindowContainer<WindowContainer> { _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 @@ class Task extends WindowContainer<WindowContainer> { 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 @@ class Task extends WindowContainer<WindowContainer> { /** * 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 @@ class Task extends WindowContainer<WindowContainer> { } } - 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 @@ class Task extends WindowContainer<WindowContainer> { * 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 @@ class Task extends WindowContainer<WindowContainer> { 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 fc58ee785cf8..552367801678 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 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { 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 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { 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 822f840005b7..51142b1d2eb1 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 @@ public class TaskTile extends ActivityStack { 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 6c69dc625a70..b60cd99e8f0c 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 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< 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 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< } void updateSurfacePosition() { + // Avoid fighting with the organizer over Surface position. + if (isOrganized()) return; + if (mSurfaceControl == null) { return; } @@ -2370,6 +2379,13 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< } 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 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< 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 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< @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 ebfe1096540e..e416e8073a75 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.os.RemoteException; 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 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub 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 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub 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 658ba1ba8a4a..6ec0f919ced7 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 @@ public class ActivityStarterTests extends ActivityTestsBase { 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 cc9173ad12ad..12bdec6ec1e1 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 @@ public class DisplayAreaPolicyBuilderTest { 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 5359bd33e70f..a96f40143e0f 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.platform.test.annotations.Presubmit; 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 @@ public class TaskOrganizerTests extends WindowTestsBase { 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 @@ public class TaskOrganizerTests extends WindowTestsBase { 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 @@ public class TaskOrganizerTests extends WindowTestsBase { 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 @@ public class TaskOrganizerTests extends WindowTestsBase { 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 @@ public class TaskOrganizerTests extends WindowTestsBase { 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 @@ public class TaskOrganizerTests extends WindowTestsBase { // 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 @@ public class TaskOrganizerTests extends WindowTestsBase { 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 @@ public class TaskOrganizerTests extends WindowTestsBase { 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 @@ public class TaskOrganizerTests extends WindowTestsBase { 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 @@ public class TaskOrganizerTests extends WindowTestsBase { 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 @@ public class TaskOrganizerTests extends WindowTestsBase { 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 f186ed3b75cf..5afd39ea9de1 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 @@ public class TaskOrganizerMultiWindowTest extends Activity { }; @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 @@ public class TaskOrganizerMultiWindowTest extends Activity { 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 a2f40dc0fd6f..520bc255499b 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 @@ public class TaskOrganizerPipTest extends Service { 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 @@ public class TaskOrganizerPipTest extends Service { } catch (Exception e) { } } - public void taskVanished(ActivityManager.RunningTaskInfo ti) { + public void onTaskVanished(ActivityManager.RunningTaskInfo ti) { } public void onTaskInfoChanged(ActivityManager.RunningTaskInfo info) { } |