diff options
| author | 2021-11-23 02:55:13 +0000 | |
|---|---|---|
| committer | 2021-11-23 02:55:13 +0000 | |
| commit | ace875a951d6c12a0b603d4f286ee07db2c6f8ec (patch) | |
| tree | 64e89f03626553d0393780a26e8e746d6a3b9442 | |
| parent | a77e02d511ce0c75b8c2d3b7c0578715e85d8ce6 (diff) | |
| parent | f068982d86cb185720f2b9b357e4f37e0a173cdc (diff) | |
Merge "Introduce DisplayWindowPolicyController for display across devices"
4 files changed, 147 insertions, 2 deletions
diff --git a/core/java/android/hardware/display/DisplayManagerInternal.java b/core/java/android/hardware/display/DisplayManagerInternal.java index fd34fa4c9c7f..83e1061d8143 100644 --- a/core/java/android/hardware/display/DisplayManagerInternal.java +++ b/core/java/android/hardware/display/DisplayManagerInternal.java @@ -30,6 +30,7 @@ import android.view.Display; import android.view.DisplayInfo; import android.view.SurfaceControl; import android.view.SurfaceControl.Transaction; +import android.window.DisplayWindowPolicyController; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -379,6 +380,14 @@ public abstract class DisplayManagerInternal { public abstract void onEarlyInteractivityChange(boolean interactive); /** + * Get {@link DisplayWindowPolicyController} associated to the {@link DisplayInfo#displayId} + * + * @param displayId The id of the display. + * @return The associated {@link DisplayWindowPolicyController}. + */ + public abstract DisplayWindowPolicyController getDisplayWindowPolicyController(int displayId); + + /** * Describes the requested power state of the display. * * This object is intended to describe the general characteristics of the diff --git a/core/java/android/window/DisplayWindowPolicyController.java b/core/java/android/window/DisplayWindowPolicyController.java new file mode 100644 index 000000000000..7677b89dff96 --- /dev/null +++ b/core/java/android/window/DisplayWindowPolicyController.java @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2021 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.annotation.NonNull; +import android.content.ComponentName; +import android.content.pm.ActivityInfo; + +import java.io.PrintWriter; +import java.util.List; + +/** + * Abstract class to control the policies of the windows that can be displayed on the virtual + * display. + * + * @hide + */ +public abstract class DisplayWindowPolicyController { + /** + * The window flags that we are interested in. + * @see android.view.WindowManager.LayoutParams + * @see #keepActivityOnWindowFlagsChanged + */ + private int mWindowFlags; + + /** + * Returns {@code true} if the given window flags contain the flags that we're interested in. + */ + public final boolean isInterestedWindowFlags(int windowFlags) { + return (mWindowFlags & windowFlags) != 0; + } + + /** + * Sets the window flags that we’re interested in and expected + * #keepActivityOnWindowFlagsChanged to be called if any changes. + */ + public final void setInterestedWindowFlags(int windowFlags) { + mWindowFlags = windowFlags; + } + + /** + * Returns {@code true} if the given activities can be displayed on this virtual display. + */ + public abstract boolean canContainActivities(@NonNull List<ActivityInfo> activities); + + /** + * Called when an Activity window is layouted with the new changes where contains the + * window flags that we’re interested in. + * Returns {@code false} if the Activity cannot remain on the display and the activity task will + * be moved back to default display. + */ + public abstract boolean keepActivityOnWindowFlagsChanged( + ActivityInfo activityInfo, int windowFlags); + + /** + * This is called when the top activity of the display is changed. + */ + public void onTopActivityChanged(ComponentName topActivity, int uid) {} + + /** + * This is called when the apps that contains running activities on the display has changed. + */ + public void onRunningAppsChanged(int[] runningUids) {} + + /** Dump debug data */ + public void dump(String prefix, final PrintWriter pw) { + pw.println(prefix + "DisplayWindowPolicyController{" + super.toString() + "}"); + pw.println(prefix + " mWindowFlags=" + mWindowFlags); + } +} diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index e4bed3d06714..1c62699f349c 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -110,6 +110,7 @@ import android.view.DisplayEventReceiver; import android.view.DisplayInfo; import android.view.Surface; import android.view.SurfaceControl; +import android.window.DisplayWindowPolicyController; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; @@ -239,6 +240,10 @@ public final class DisplayManagerService extends SystemService { public final SparseArray<CallbackRecord> mCallbacks = new SparseArray<CallbackRecord>(); + /** All {@link DisplayWindowPolicyController}s indexed by {@link DisplayInfo#displayId}. */ + final SparseArray<DisplayWindowPolicyController> mDisplayWindowPolicyController = + new SparseArray<>(); + // List of all currently registered display adapters. private final ArrayList<DisplayAdapter> mDisplayAdapters = new ArrayList<DisplayAdapter>(); @@ -1117,7 +1122,8 @@ public final class DisplayManagerService extends SystemService { private int createVirtualDisplayInternal(IVirtualDisplayCallback callback, IMediaProjection projection, int callingUid, String packageName, Surface surface, - int flags, VirtualDisplayConfig virtualDisplayConfig) { + int flags, VirtualDisplayConfig virtualDisplayConfig, + DisplayWindowPolicyController controller) { synchronized (mSyncRoot) { if (mVirtualDisplayAdapter == null) { Slog.w(TAG, "Rejecting request to create private virtual display " @@ -1145,6 +1151,9 @@ public final class DisplayManagerService extends SystemService { final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(device); if (display != null) { + if (controller != null) { + mDisplayWindowPolicyController.put(display.getDisplayIdLocked(), controller); + } return display.getDisplayIdLocked(); } @@ -1188,6 +1197,10 @@ public final class DisplayManagerService extends SystemService { DisplayDevice device = mVirtualDisplayAdapter.releaseVirtualDisplayLocked(appToken); if (device != null) { + final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(device); + if (display != null) { + mDisplayWindowPolicyController.delete(display.getDisplayIdLocked()); + } // TODO: multi-display - handle virtual displays the same as other display adapters. mDisplayDeviceRepo.onDisplayDeviceEvent(device, DisplayAdapter.DISPLAY_DEVICE_EVENT_REMOVED); @@ -2139,6 +2152,15 @@ public final class DisplayManagerService extends SystemService { } pw.println(); mPersistentDataStore.dump(pw); + + final int displayWindowPolicyControllerCount = mDisplayWindowPolicyController.size(); + pw.println(); + pw.println("Display Window Policy Controllers: size=" + + displayWindowPolicyControllerCount); + for (int i = 0; i < displayWindowPolicyControllerCount; i++) { + pw.print("Display " + mDisplayWindowPolicyController.keyAt(i) + ":"); + mDisplayWindowPolicyController.valueAt(i).dump(" ", pw); + } } pw.println(); mDisplayModeDirector.dump(pw); @@ -2704,6 +2726,13 @@ public final class DisplayManagerService extends SystemService { @Override // Binder call public int createVirtualDisplay(VirtualDisplayConfig virtualDisplayConfig, IVirtualDisplayCallback callback, IMediaProjection projection, String packageName) { + return createVirtualDisplay(virtualDisplayConfig, callback, projection, packageName, + null /* controller */); + } + + public int createVirtualDisplay(VirtualDisplayConfig virtualDisplayConfig, + IVirtualDisplayCallback callback, IMediaProjection projection, String packageName, + DisplayWindowPolicyController controller) { final int callingUid = Binder.getCallingUid(); if (!validatePackageName(callingUid, packageName)) { throw new SecurityException("packageName must match the calling uid"); @@ -2803,7 +2832,7 @@ public final class DisplayManagerService extends SystemService { final long token = Binder.clearCallingIdentity(); try { return createVirtualDisplayInternal(callback, projection, callingUid, packageName, - surface, flags, virtualDisplayConfig); + surface, flags, virtualDisplayConfig, controller); } finally { Binder.restoreCallingIdentity(token); } @@ -3624,6 +3653,13 @@ public final class DisplayManagerService extends SystemService { public void onEarlyInteractivityChange(boolean interactive) { mLogicalDisplayMapper.onEarlyInteractivityChange(interactive); } + + @Override + public DisplayWindowPolicyController getDisplayWindowPolicyController(int displayId) { + synchronized (mSyncRoot) { + return mDisplayWindowPolicyController.get(displayId); + } + } } class DesiredDisplayModeSpecsObserver diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 42c81248da34..55acfb668859 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -218,6 +218,7 @@ import android.view.WindowInsets; import android.view.WindowManager; import android.view.WindowManager.DisplayImePolicy; import android.view.WindowManagerPolicyConstants.PointerEventListener; +import android.window.DisplayWindowPolicyController; import android.window.IDisplayAreaOrganizer; import com.android.internal.annotations.VisibleForTesting; @@ -696,6 +697,14 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp // well and thus won't change the top resumed / focused record boolean mDontMoveToTop; + /** + * The policy controller of the windows that can be displayed on the virtual display. + * + * @see DisplayWindowPolicyController + */ + @Nullable + DisplayWindowPolicyController mDisplayWindowPolicyController; + private final Consumer<WindowState> mUpdateWindowsForAnimator = w -> { WindowStateAnimator winAnimator = w.mWinAnimator; final ActivityRecord activity = w.mActivityRecord; @@ -2739,6 +2748,9 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp if (newDisplayInfo != null) { mDisplayInfo.copyFrom(newDisplayInfo); } + + mDisplayWindowPolicyController = + displayManagerInternal.getDisplayWindowPolicyController(mDisplayId); } updateBaseDisplayMetrics(mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight, @@ -3420,6 +3432,10 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp mInputMonitor.dump(pw, " "); pw.println(); mInsetsStateController.dump(prefix, pw); + if (mDisplayWindowPolicyController != null) { + pw.println(); + mDisplayWindowPolicyController.dump(prefix, pw); + } } @Override |