Merge "Introduce DisplayWindowPolicyController for display across devices"

This commit is contained in:
Chilun Huang
2021-11-23 02:55:13 +00:00
committed by Android (Google) Code Review
4 changed files with 147 additions and 2 deletions

View File

@@ -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;
@@ -378,6 +379,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.
*

View File

@@ -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);
}
}

View File

@@ -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

View File

@@ -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