summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Chilun Huang <chilunhuang@google.com> 2021-11-23 02:55:13 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2021-11-23 02:55:13 +0000
commitace875a951d6c12a0b603d4f286ee07db2c6f8ec (patch)
tree64e89f03626553d0393780a26e8e746d6a3b9442
parenta77e02d511ce0c75b8c2d3b7c0578715e85d8ce6 (diff)
parentf068982d86cb185720f2b9b357e4f37e0a173cdc (diff)
Merge "Introduce DisplayWindowPolicyController for display across devices"
-rw-r--r--core/java/android/hardware/display/DisplayManagerInternal.java9
-rw-r--r--core/java/android/window/DisplayWindowPolicyController.java84
-rw-r--r--services/core/java/com/android/server/display/DisplayManagerService.java40
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java16
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