Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ace875a9 authored by Chilun Huang's avatar Chilun Huang Committed by Android (Google) Code Review
Browse files

Merge "Introduce DisplayWindowPolicyController for display across devices"

parents a77e02d5 f068982d
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -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.
     *
+84 −0
Original line number Diff line number Diff line
/*
 * 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);
    }
}
+38 −2
Original line number Diff line number Diff line
@@ -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
+16 −0
Original line number Diff line number Diff line
@@ -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