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

Commit 27655e1f authored by Naomi Musgrave's avatar Naomi Musgrave
Browse files

MediaProjection sets content recording details in WM directly.

Content recording relies upon a class describing current state.
rather than passing around details from media > display > wm.
WMService keeps track of the session in ContentRecordingController.
ContentRecordingController manages hand-off between different
DisplayContent instances, as the session details are changed.

Manually tested that fold/unfold handling when screen recording
from QS tile still works, and that taking over a screen cast
with a screen recording works.

Refactoring logic from DisplayContent into new recording
delegate will come in a future change.

Bug: 216756854
Test: atest FrameworksCoreTests:ContentRecordingSessionTest
Test: atest WmTests:DisplayContentTests
Test: atest WmTests:ContentRecordingControllerTests
Change-Id: Ib4f125dd703d362ac13fcbe469d00b345827e706
parent cc9e1675
Loading
Loading
Loading
Loading
+5 −13
Original line number Diff line number Diff line
@@ -21,7 +21,6 @@ import android.annotation.Nullable;
import android.graphics.Point;
import android.hardware.SensorManager;
import android.os.Handler;
import android.os.IBinder;
import android.os.PowerManager;
import android.util.IntArray;
import android.util.Slog;
@@ -351,24 +350,17 @@ public abstract class DisplayManagerInternal {
    public abstract List<RefreshRateLimitation> getRefreshRateLimitations(int displayId);

    /**
     * Returns the window token of the level of the WindowManager hierarchy to mirror. Returns null
     * if layer mirroring by SurfaceFlinger should not be performed for the given displayId.
     * For now, only used for mirroring started from MediaProjection.
     */
    public abstract IBinder getWindowTokenClientToMirror(int displayId);

    /**
     * For the given displayId, updates the window token of the level of the WindowManager hierarchy
     * to mirror. If windowToken is null, then SurfaceFlinger performs no layer mirroring to the
     * For the given displayId, updates if WindowManager is responsible for mirroring on that
     * display. If {@code false}, then SurfaceFlinger performs no layer mirroring to the
     * given display.
     * For now, only used for mirroring started from MediaProjection.
     * Only used for mirroring started from MediaProjection.
     */
    public abstract void setWindowTokenClientToMirror(int displayId, IBinder windowToken);
    public abstract void setWindowManagerMirroring(int displayId, boolean isMirroring);

    /**
     * Returns the default size of the surface associated with the display, or null if the surface
     * is not provided for layer mirroring by SurfaceFlinger.
     * For now, only used for mirroring started from MediaProjection.
     * Only used for mirroring started from MediaProjection.
     */
    public abstract Point getDisplaySurfaceDefaultSize(int displayId);

+21 −24
Original line number Diff line number Diff line
@@ -24,7 +24,6 @@ import android.annotation.Nullable;
import android.hardware.display.DisplayManager.VirtualDisplayFlag;
import android.media.projection.MediaProjection;
import android.os.Handler;
import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
import android.view.Surface;
@@ -95,11 +94,10 @@ public final class VirtualDisplayConfig implements Parcelable {
    private int mDisplayIdToMirror = DEFAULT_DISPLAY;

    /**
     * The window token of the level of the WindowManager hierarchy to mirror, or null if mirroring
     * should not be performed.
     * Indicates if WindowManager is responsible for mirroring content to this VirtualDisplay, or
     * if DisplayManager should record contents instead.
     */
    @Nullable
    private IBinder mWindowTokenClientToMirror = null;
    private boolean mWindowManagerMirroring = false;



@@ -126,7 +124,7 @@ public final class VirtualDisplayConfig implements Parcelable {
            @Nullable Surface surface,
            @Nullable String uniqueId,
            int displayIdToMirror,
            @Nullable IBinder windowTokenClientToMirror) {
            boolean windowManagerMirroring) {
        this.mName = name;
        com.android.internal.util.AnnotationValidations.validate(
                NonNull.class, null, mName);
@@ -148,7 +146,7 @@ public final class VirtualDisplayConfig implements Parcelable {
        this.mSurface = surface;
        this.mUniqueId = uniqueId;
        this.mDisplayIdToMirror = displayIdToMirror;
        this.mWindowTokenClientToMirror = windowTokenClientToMirror;
        this.mWindowManagerMirroring = windowManagerMirroring;

        // onConstructed(); // You can define this method to get a callback
    }
@@ -227,12 +225,12 @@ public final class VirtualDisplayConfig implements Parcelable {
    }

    /**
     * The window token of the level of the WindowManager hierarchy to mirror, or null if mirroring
     * should not be performed.
     * Indicates if WindowManager is responsible for mirroring content to this VirtualDisplay, or
     * if DisplayManager should record contents instead.
     */
    @DataClass.Generated.Member
    public @Nullable IBinder getWindowTokenClientToMirror() {
        return mWindowTokenClientToMirror;
    public boolean isWindowManagerMirroring() {
        return mWindowManagerMirroring;
    }

    @Override
@@ -242,9 +240,9 @@ public final class VirtualDisplayConfig implements Parcelable {
        // void parcelFieldName(Parcel dest, int flags) { ... }

        int flg = 0;
        if (mWindowManagerMirroring) flg |= 0x100;
        if (mSurface != null) flg |= 0x20;
        if (mUniqueId != null) flg |= 0x40;
        if (mWindowTokenClientToMirror != null) flg |= 0x100;
        dest.writeInt(flg);
        dest.writeString(mName);
        dest.writeInt(mWidth);
@@ -254,7 +252,6 @@ public final class VirtualDisplayConfig implements Parcelable {
        if (mSurface != null) dest.writeTypedObject(mSurface, flags);
        if (mUniqueId != null) dest.writeString(mUniqueId);
        dest.writeInt(mDisplayIdToMirror);
        if (mWindowTokenClientToMirror != null) dest.writeStrongBinder(mWindowTokenClientToMirror);
    }

    @Override
@@ -269,6 +266,7 @@ public final class VirtualDisplayConfig implements Parcelable {
        // static FieldType unparcelFieldName(Parcel in) { ... }

        int flg = in.readInt();
        boolean windowManagerMirroring = (flg & 0x100) != 0;
        String name = in.readString();
        int width = in.readInt();
        int height = in.readInt();
@@ -277,7 +275,6 @@ public final class VirtualDisplayConfig implements Parcelable {
        Surface surface = (flg & 0x20) == 0 ? null : (Surface) in.readTypedObject(Surface.CREATOR);
        String uniqueId = (flg & 0x40) == 0 ? null : in.readString();
        int displayIdToMirror = in.readInt();
        IBinder windowTokenClientToMirror = (flg & 0x100) == 0 ? null : (IBinder) in.readStrongBinder();

        this.mName = name;
        com.android.internal.util.AnnotationValidations.validate(
@@ -300,7 +297,7 @@ public final class VirtualDisplayConfig implements Parcelable {
        this.mSurface = surface;
        this.mUniqueId = uniqueId;
        this.mDisplayIdToMirror = displayIdToMirror;
        this.mWindowTokenClientToMirror = windowTokenClientToMirror;
        this.mWindowManagerMirroring = windowManagerMirroring;

        // onConstructed(); // You can define this method to get a callback
    }
@@ -334,7 +331,7 @@ public final class VirtualDisplayConfig implements Parcelable {
        private @Nullable Surface mSurface;
        private @Nullable String mUniqueId;
        private int mDisplayIdToMirror;
        private @Nullable IBinder mWindowTokenClientToMirror;
        private boolean mWindowManagerMirroring;

        private long mBuilderFieldsSet = 0L;

@@ -470,14 +467,14 @@ public final class VirtualDisplayConfig implements Parcelable {
        }

        /**
         * The window token of the level of the WindowManager hierarchy to mirror, or null if mirroring
         * should not be performed.
         * Indicates if WindowManager is responsible for mirroring content to this VirtualDisplay, or
         * if DisplayManager should record contents instead.
         */
        @DataClass.Generated.Member
        public @NonNull Builder setWindowTokenClientToMirror(@NonNull IBinder value) {
        public @NonNull Builder setWindowManagerMirroring(boolean value) {
            checkNotUsed();
            mBuilderFieldsSet |= 0x100;
            mWindowTokenClientToMirror = value;
            mWindowManagerMirroring = value;
            return this;
        }

@@ -499,7 +496,7 @@ public final class VirtualDisplayConfig implements Parcelable {
                mDisplayIdToMirror = DEFAULT_DISPLAY;
            }
            if ((mBuilderFieldsSet & 0x100) == 0) {
                mWindowTokenClientToMirror = null;
                mWindowManagerMirroring = false;
            }
            VirtualDisplayConfig o = new VirtualDisplayConfig(
                    mName,
@@ -510,7 +507,7 @@ public final class VirtualDisplayConfig implements Parcelable {
                    mSurface,
                    mUniqueId,
                    mDisplayIdToMirror,
                    mWindowTokenClientToMirror);
                    mWindowManagerMirroring);
            return o;
        }

@@ -523,10 +520,10 @@ public final class VirtualDisplayConfig implements Parcelable {
    }

    @DataClass.Generated(
            time = 1643938791506L,
            time = 1646227247934L,
            codegenVersion = "1.0.23",
            sourceFile = "frameworks/base/core/java/android/hardware/display/VirtualDisplayConfig.java",
            inputSignatures = "private @android.annotation.NonNull java.lang.String mName\nprivate @android.annotation.IntRange int mWidth\nprivate @android.annotation.IntRange int mHeight\nprivate @android.annotation.IntRange int mDensityDpi\nprivate @android.hardware.display.DisplayManager.VirtualDisplayFlag int mFlags\nprivate @android.annotation.Nullable android.view.Surface mSurface\nprivate @android.annotation.Nullable java.lang.String mUniqueId\nprivate  int mDisplayIdToMirror\nprivate @android.annotation.Nullable android.os.IBinder mWindowTokenClientToMirror\nclass VirtualDisplayConfig extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genParcelable=true, genAidl=true, genBuilder=true)")
            inputSignatures = "private @android.annotation.NonNull java.lang.String mName\nprivate @android.annotation.IntRange int mWidth\nprivate @android.annotation.IntRange int mHeight\nprivate @android.annotation.IntRange int mDensityDpi\nprivate @android.hardware.display.DisplayManager.VirtualDisplayFlag int mFlags\nprivate @android.annotation.Nullable android.view.Surface mSurface\nprivate @android.annotation.Nullable java.lang.String mUniqueId\nprivate  int mDisplayIdToMirror\nprivate  boolean mWindowManagerMirroring\nclass VirtualDisplayConfig extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genParcelable=true, genAidl=true, genBuilder=true)")
    @Deprecated
    private void __metadata() {}

+19 −0
Original line number Diff line number Diff line
/**
 * Copyright (c) 2022, 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.view;

parcelable ContentRecordingSession;
+447 −0

File added.

Preview size limit exceeded, changes collapsed.

+12 −0
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ import android.graphics.Region;
import android.os.Bundle;
import android.os.IRemoteCallback;
import android.os.ParcelFileDescriptor;
import android.view.ContentRecordingSession;
import android.view.DisplayCutout;
import android.view.DisplayInfo;
import android.view.IAppTransitionAnimationSpecsFuture;
@@ -878,6 +879,17 @@ interface IWindowManager
     */
    void detachWindowContextFromWindowContainer(IBinder clientToken);

    /**
     * Updates the content recording session. If a different session is already in progress, then
     * the pre-existing session is stopped, and the new incoming session takes over.
     *
     * The DisplayContent for the new session will begin recording when
     * {@link RootWindowContainer#onDisplayChanged} is invoked for the new {@link VirtualDisplay}.
     *
     * @param incomingSession the nullable incoming content recording session
     */
    void setContentRecordingSession(in ContentRecordingSession incomingSession);

    /**
     * Registers a listener, which is to be called whenever cross-window blur is enabled/disabled.
     *
Loading