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

Commit adc8fc9b authored by Daniel Akinola's avatar Daniel Akinola Committed by Android (Google) Code Review
Browse files

Merge "Check for target activity with taskid and launch cookie" into main

parents c1c4902b bd161c0d
Loading
Loading
Loading
Loading
+75 −22
Original line number Diff line number Diff line
@@ -58,6 +58,15 @@ public final class ContentRecordingSession implements Parcelable {
    /** Can't report (e.g. side loaded app). */
    public static final int TARGET_UID_UNKNOWN = -2;

    /** Task id is not set either because full screen capture or launching a new app */
    public static final int TASK_ID_UNKNOWN = -1;

    /**
     * Id of Task that is launched to be captured for a single app capture session. The value may be
     * {@link #TASK_ID_UNKNOWN} if the session is not for a single app capture.
     */
    private int mTaskId = TASK_ID_UNKNOWN;

    /**
     * Unique logical identifier of the {@link android.hardware.display.VirtualDisplay} that has
     * recorded content rendered to its surface.
@@ -115,16 +124,16 @@ public final class ContentRecordingSession implements Parcelable {
    /** Returns an instance initialized for task recording. */
    public static ContentRecordingSession createTaskSession(
            @NonNull IBinder taskWindowContainerToken) {
        return createTaskSession(taskWindowContainerToken, TARGET_UID_UNKNOWN);
        return createTaskSession(taskWindowContainerToken, TASK_ID_UNKNOWN);
    }

    /** Returns an instance initialized for task recording. */
    public static ContentRecordingSession createTaskSession(
            @NonNull IBinder taskWindowContainerToken, int targetUid) {
            @NonNull IBinder taskWindowContainerToken, int taskId) {
        return new ContentRecordingSession()
                .setContentToRecord(RECORD_CONTENT_TASK)
                .setTokenToRecord(taskWindowContainerToken)
                .setTargetUid(targetUid);
                .setTaskId(taskId);
    }

    /**
@@ -211,12 +220,14 @@ public final class ContentRecordingSession implements Parcelable {

    @DataClass.Generated.Member
    /* package-private */ ContentRecordingSession(
            int taskId,
            int virtualDisplayId,
            @RecordContent int contentToRecord,
            int displayToRecord,
            @Nullable IBinder tokenToRecord,
            boolean waitingForConsent,
            int targetUid) {
        this.mTaskId = taskId;
        this.mVirtualDisplayId = virtualDisplayId;
        this.mContentToRecord = contentToRecord;

@@ -236,6 +247,15 @@ public final class ContentRecordingSession implements Parcelable {
        // onConstructed(); // You can define this method to get a callback
    }

    /**
     * Id of Task that is launched to be captured for a single app capture session. The value may be
     * {@link #TASK_ID_UNKNOWN} if the session is not for a single app capture.
     */
    @DataClass.Generated.Member
    public int getTaskId() {
        return mTaskId;
    }

    /**
     * Unique logical identifier of the {@link android.hardware.display.VirtualDisplay} that has
     * recorded content rendered to its surface.
@@ -294,6 +314,16 @@ public final class ContentRecordingSession implements Parcelable {
        return mTargetUid;
    }

    /**
     * Id of Task that is launched to be captured for a single app capture session. The value may be
     * {@link #TASK_ID_UNKNOWN} if the session is not for a single app capture.
     */
    @DataClass.Generated.Member
    public @NonNull ContentRecordingSession setTaskId( int value) {
        mTaskId = value;
        return this;
    }

    /**
     * Unique logical identifier of the {@link android.hardware.display.VirtualDisplay} that has
     * recorded content rendered to its surface.
@@ -374,6 +404,7 @@ public final class ContentRecordingSession implements Parcelable {
        // String fieldNameToString() { ... }

        return "ContentRecordingSession { " +
                "taskId = " + mTaskId + ", " +
                "virtualDisplayId = " + mVirtualDisplayId + ", " +
                "contentToRecord = " + recordContentToString(mContentToRecord) + ", " +
                "displayToRecord = " + mDisplayToRecord + ", " +
@@ -396,6 +427,7 @@ public final class ContentRecordingSession implements Parcelable {
        ContentRecordingSession that = (ContentRecordingSession) o;
        //noinspection PointlessBooleanExpression
        return true
                && mTaskId == that.mTaskId
                && mVirtualDisplayId == that.mVirtualDisplayId
                && mContentToRecord == that.mContentToRecord
                && mDisplayToRecord == that.mDisplayToRecord
@@ -411,6 +443,7 @@ public final class ContentRecordingSession implements Parcelable {
        // int fieldNameHashCode() { ... }

        int _hash = 1;
        _hash = 31 * _hash + mTaskId;
        _hash = 31 * _hash + mVirtualDisplayId;
        _hash = 31 * _hash + mContentToRecord;
        _hash = 31 * _hash + mDisplayToRecord;
@@ -427,9 +460,10 @@ public final class ContentRecordingSession implements Parcelable {
        // void parcelFieldName(Parcel dest, int flags) { ... }

        byte flg = 0;
        if (mWaitingForConsent) flg |= 0x10;
        if (mTokenToRecord != null) flg |= 0x8;
        if (mWaitingForConsent) flg |= 0x20;
        if (mTokenToRecord != null) flg |= 0x10;
        dest.writeByte(flg);
        dest.writeInt(mTaskId);
        dest.writeInt(mVirtualDisplayId);
        dest.writeInt(mContentToRecord);
        dest.writeInt(mDisplayToRecord);
@@ -449,13 +483,15 @@ public final class ContentRecordingSession implements Parcelable {
        // static FieldType unparcelFieldName(Parcel in) { ... }

        byte flg = in.readByte();
        boolean waitingForConsent = (flg & 0x10) != 0;
        boolean waitingForConsent = (flg & 0x20) != 0;
        int taskId = in.readInt();
        int virtualDisplayId = in.readInt();
        int contentToRecord = in.readInt();
        int displayToRecord = in.readInt();
        IBinder tokenToRecord = (flg & 0x8) == 0 ? null : (IBinder) in.readStrongBinder();
        IBinder tokenToRecord = (flg & 0x10) == 0 ? null : (IBinder) in.readStrongBinder();
        int targetUid = in.readInt();

        this.mTaskId = taskId;
        this.mVirtualDisplayId = virtualDisplayId;
        this.mContentToRecord = contentToRecord;

@@ -496,6 +532,7 @@ public final class ContentRecordingSession implements Parcelable {
    @DataClass.Generated.Member
    public static final class Builder {

        private int mTaskId;
        private int mVirtualDisplayId;
        private @RecordContent int mContentToRecord;
        private int mDisplayToRecord;
@@ -508,6 +545,18 @@ public final class ContentRecordingSession implements Parcelable {
        public Builder() {
        }

        /**
         * Id of Task that is launched to be captured for a single app capture session. The value may be
         * {@link #TASK_ID_UNKNOWN} if the session is not for a single app capture.
         */
        @DataClass.Generated.Member
        public @NonNull Builder setTaskId(int value) {
            checkNotUsed();
            mBuilderFieldsSet |= 0x1;
            mTaskId = value;
            return this;
        }

        /**
         * Unique logical identifier of the {@link android.hardware.display.VirtualDisplay} that has
         * recorded content rendered to its surface.
@@ -515,7 +564,7 @@ public final class ContentRecordingSession implements Parcelable {
        @DataClass.Generated.Member
        public @NonNull Builder setVirtualDisplayId(int value) {
            checkNotUsed();
            mBuilderFieldsSet |= 0x1;
            mBuilderFieldsSet |= 0x2;
            mVirtualDisplayId = value;
            return this;
        }
@@ -526,7 +575,7 @@ public final class ContentRecordingSession implements Parcelable {
        @DataClass.Generated.Member
        public @NonNull Builder setContentToRecord(@RecordContent int value) {
            checkNotUsed();
            mBuilderFieldsSet |= 0x2;
            mBuilderFieldsSet |= 0x4;
            mContentToRecord = value;
            return this;
        }
@@ -540,7 +589,7 @@ public final class ContentRecordingSession implements Parcelable {
        @DataClass.Generated.Member
        public @NonNull Builder setDisplayToRecord(int value) {
            checkNotUsed();
            mBuilderFieldsSet |= 0x4;
            mBuilderFieldsSet |= 0x8;
            mDisplayToRecord = value;
            return this;
        }
@@ -554,7 +603,7 @@ public final class ContentRecordingSession implements Parcelable {
        @DataClass.Generated.Member
        public @NonNull Builder setTokenToRecord(@NonNull IBinder value) {
            checkNotUsed();
            mBuilderFieldsSet |= 0x8;
            mBuilderFieldsSet |= 0x10;
            mTokenToRecord = value;
            return this;
        }
@@ -568,7 +617,7 @@ public final class ContentRecordingSession implements Parcelable {
        @DataClass.Generated.Member
        public @NonNull Builder setWaitingForConsent(boolean value) {
            checkNotUsed();
            mBuilderFieldsSet |= 0x10;
            mBuilderFieldsSet |= 0x20;
            mWaitingForConsent = value;
            return this;
        }
@@ -579,7 +628,7 @@ public final class ContentRecordingSession implements Parcelable {
        @DataClass.Generated.Member
        public @NonNull Builder setTargetUid(int value) {
            checkNotUsed();
            mBuilderFieldsSet |= 0x20;
            mBuilderFieldsSet |= 0x40;
            mTargetUid = value;
            return this;
        }
@@ -587,27 +636,31 @@ public final class ContentRecordingSession implements Parcelable {
        /** Builds the instance. This builder should not be touched after calling this! */
        public @NonNull ContentRecordingSession build() {
            checkNotUsed();
            mBuilderFieldsSet |= 0x40; // Mark builder used
            mBuilderFieldsSet |= 0x80; // Mark builder used

            if ((mBuilderFieldsSet & 0x1) == 0) {
                mVirtualDisplayId = INVALID_DISPLAY;
                mTaskId = TASK_ID_UNKNOWN;
            }
            if ((mBuilderFieldsSet & 0x2) == 0) {
                mContentToRecord = RECORD_CONTENT_DISPLAY;
                mVirtualDisplayId = INVALID_DISPLAY;
            }
            if ((mBuilderFieldsSet & 0x4) == 0) {
                mDisplayToRecord = INVALID_DISPLAY;
                mContentToRecord = RECORD_CONTENT_DISPLAY;
            }
            if ((mBuilderFieldsSet & 0x8) == 0) {
                mTokenToRecord = null;
                mDisplayToRecord = INVALID_DISPLAY;
            }
            if ((mBuilderFieldsSet & 0x10) == 0) {
                mWaitingForConsent = false;
                mTokenToRecord = null;
            }
            if ((mBuilderFieldsSet & 0x20) == 0) {
                mWaitingForConsent = false;
            }
            if ((mBuilderFieldsSet & 0x40) == 0) {
                mTargetUid = TARGET_UID_UNKNOWN;
            }
            ContentRecordingSession o = new ContentRecordingSession(
                    mTaskId,
                    mVirtualDisplayId,
                    mContentToRecord,
                    mDisplayToRecord,
@@ -618,7 +671,7 @@ public final class ContentRecordingSession implements Parcelable {
        }

        private void checkNotUsed() {
            if ((mBuilderFieldsSet & 0x40) != 0) {
            if ((mBuilderFieldsSet & 0x80) != 0) {
                throw new IllegalStateException(
                        "This Builder should not be reused. Use a new Builder instance instead");
            }
@@ -626,10 +679,10 @@ public final class ContentRecordingSession implements Parcelable {
    }

    @DataClass.Generated(
            time = 1697456140720L,
            time = 1716481148184L,
            codegenVersion = "1.0.23",
            sourceFile = "frameworks/base/core/java/android/view/ContentRecordingSession.java",
            inputSignatures = "public static final  int RECORD_CONTENT_DISPLAY\npublic static final  int RECORD_CONTENT_TASK\npublic static final  int TARGET_UID_FULL_SCREEN\npublic static final  int TARGET_UID_UNKNOWN\nprivate  int mVirtualDisplayId\nprivate @android.view.ContentRecordingSession.RecordContent int mContentToRecord\nprivate  int mDisplayToRecord\nprivate @android.annotation.Nullable android.os.IBinder mTokenToRecord\nprivate  boolean mWaitingForConsent\nprivate  int mTargetUid\npublic static  android.view.ContentRecordingSession createDisplaySession(int)\npublic static  android.view.ContentRecordingSession createTaskSession(android.os.IBinder)\npublic static  android.view.ContentRecordingSession createTaskSession(android.os.IBinder,int)\npublic static  boolean isValid(android.view.ContentRecordingSession)\npublic static  boolean isProjectionOnSameDisplay(android.view.ContentRecordingSession,android.view.ContentRecordingSession)\nclass ContentRecordingSession extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genConstructor=false, genToString=true, genSetters=true, genEqualsHashCode=true)")
            inputSignatures = "public static final  int RECORD_CONTENT_DISPLAY\npublic static final  int RECORD_CONTENT_TASK\npublic static final  int TARGET_UID_FULL_SCREEN\npublic static final  int TARGET_UID_UNKNOWN\npublic static final  int TASK_ID_UNKNOWN\nprivate  int mTaskId\nprivate  int mVirtualDisplayId\nprivate @android.view.ContentRecordingSession.RecordContent int mContentToRecord\nprivate  int mDisplayToRecord\nprivate @android.annotation.Nullable android.os.IBinder mTokenToRecord\nprivate  boolean mWaitingForConsent\nprivate  int mTargetUid\npublic static  android.view.ContentRecordingSession createDisplaySession(int)\npublic static  android.view.ContentRecordingSession createTaskSession(android.os.IBinder)\npublic static  android.view.ContentRecordingSession createTaskSession(android.os.IBinder,int)\npublic static  boolean isValid(android.view.ContentRecordingSession)\npublic static  boolean isProjectionOnSameDisplay(android.view.ContentRecordingSession,android.view.ContentRecordingSession)\nclass ContentRecordingSession extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genConstructor=false, genToString=true, genSetters=true, genEqualsHashCode=true)")
    @Deprecated
    private void __metadata() {}

+13 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package android.view;

import static android.view.ContentRecordingSession.RECORD_CONTENT_DISPLAY;
import static android.view.ContentRecordingSession.RECORD_CONTENT_TASK;
import static android.view.ContentRecordingSession.TASK_ID_UNKNOWN;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;

@@ -45,6 +46,7 @@ import org.junit.runner.RunWith;
@Presubmit
public class ContentRecordingSessionTest {
    private static final int DISPLAY_ID = 1;
    private static final int TASK_ID = 123;
    private static final IBinder WINDOW_TOKEN = new Binder("DisplayContentWindowToken");

    @Test
@@ -65,6 +67,16 @@ public class ContentRecordingSessionTest {
        ContentRecordingSession session = ContentRecordingSession.createTaskSession(WINDOW_TOKEN);
        assertThat(session.getContentToRecord()).isEqualTo(RECORD_CONTENT_TASK);
        assertThat(session.getTokenToRecord()).isEqualTo(WINDOW_TOKEN);
        assertThat(session.getTaskId()).isEqualTo(TASK_ID_UNKNOWN);
    }

    @Test
    public void testSecondaryTaskConstructor() {
        ContentRecordingSession session =
                ContentRecordingSession.createTaskSession(WINDOW_TOKEN, TASK_ID);
        assertThat(session.getContentToRecord()).isEqualTo(RECORD_CONTENT_TASK);
        assertThat(session.getTokenToRecord()).isEqualTo(WINDOW_TOKEN);
        assertThat(session.getTaskId()).isEqualTo(TASK_ID);
    }

    @Test
@@ -73,6 +85,7 @@ public class ContentRecordingSessionTest {
                DEFAULT_DISPLAY);
        assertThat(session.getContentToRecord()).isEqualTo(RECORD_CONTENT_DISPLAY);
        assertThat(session.getTokenToRecord()).isNull();
        assertThat(session.getTaskId()).isEqualTo(TASK_ID_UNKNOWN);
    }

    @Test
+21 −4
Original line number Diff line number Diff line
@@ -39,8 +39,8 @@ interface IMediaProjection {
    void unregisterCallback(IMediaProjectionCallback callback);

    /**
     * Returns the {@link LaunchCookie} identifying the task to record, or {@code null} if
     * there is none.
     * Returns the {@link LaunchCookie} identifying the task to record. Will always be set
     * regardless of starting a new task or recent task
     */
    @EnforcePermission("MANAGE_MEDIA_PROJECTION")
    @JavaPassthrough(annotation = "@android.annotation.RequiresPermission(android.Manifest"
@@ -48,14 +48,31 @@ interface IMediaProjection {
    LaunchCookie getLaunchCookie();

    /**
     * Updates the {@link LaunchCookie} identifying the task to record, or {@code null} if
     * there is none.
     * Returns the taskId identifying the task to record. Will only be set in the case of
     * launching a recent task, otherwise set to -1.
     */
    @EnforcePermission("MANAGE_MEDIA_PROJECTION")
    @JavaPassthrough(annotation = "@android.annotation.RequiresPermission(android.Manifest"
            + ".permission.MANAGE_MEDIA_PROJECTION)")
    int getTaskId();

    /**
     * Updates the {@link LaunchCookie} identifying the task to record.
     */
    @EnforcePermission("MANAGE_MEDIA_PROJECTION")
    @JavaPassthrough(annotation = "@android.annotation.RequiresPermission(android.Manifest"
            + ".permission.MANAGE_MEDIA_PROJECTION)")
    void setLaunchCookie(in LaunchCookie launchCookie);

    /**
     * Updates the taskId identifying the task to record.
     */
    @EnforcePermission("MANAGE_MEDIA_PROJECTION")
    @JavaPassthrough(annotation = "@android.annotation.RequiresPermission(android.Manifest"
            + ".permission.MANAGE_MEDIA_PROJECTION)")
    void setTaskId(in int taskId);


    /**
     * Returns {@code true} if this token is still valid. A token is valid as long as the token
     * hasn't timed out before it was used, and the token is only used once.
+15 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.os.RemoteException;
 * outside the test it is implemented by the system server.
 */
public final class FakeIMediaProjection extends IMediaProjection.Stub {
    int mTaskId = -1;
    boolean mIsStarted = false;
    LaunchCookie mLaunchCookie = null;
    IMediaProjectionCallback mIMediaProjectionCallback = null;
@@ -85,6 +86,13 @@ public final class FakeIMediaProjection extends IMediaProjection.Stub {
        return mLaunchCookie;
    }

    @Override
    @EnforcePermission(MANAGE_MEDIA_PROJECTION)
    public int getTaskId() throws RemoteException {
        getTaskId_enforcePermission();
        return mTaskId;
    }

    @Override
    @EnforcePermission(MANAGE_MEDIA_PROJECTION)
    public void setLaunchCookie(LaunchCookie launchCookie) throws RemoteException {
@@ -92,6 +100,13 @@ public final class FakeIMediaProjection extends IMediaProjection.Stub {
        mLaunchCookie = launchCookie;
    }

    @Override
    @EnforcePermission(MANAGE_MEDIA_PROJECTION)
    public void setTaskId(int taskId) throws RemoteException {
        setTaskId_enforcePermission();
        mTaskId = taskId;
    }

    @Override
    @EnforcePermission(MANAGE_MEDIA_PROJECTION)
    public boolean isValid() throws RemoteException {
+6 −4
Original line number Diff line number Diff line
@@ -21,15 +21,17 @@ import android.os.Parcel
import android.os.Parcelable

/**
 * Class that represents an area that should be captured. Currently it has only a launch cookie that
 * represents a task but we potentially could add more identifiers e.g. for a pair of tasks.
 * Class that represents an area that should be captured. Currently it has only a launch cookie and
 * id that represents a task but we potentially could add more identifiers e.g. for a pair of tasks.
 */
data class MediaProjectionCaptureTarget(val launchCookie: LaunchCookie?) : Parcelable {
data class MediaProjectionCaptureTarget(val launchCookie: LaunchCookie?, val taskId: Int) :
    Parcelable {

    constructor(parcel: Parcel) : this(LaunchCookie.readFromParcel(parcel))
    constructor(parcel: Parcel) : this(LaunchCookie.readFromParcel(parcel), parcel.readInt())

    override fun writeToParcel(dest: Parcel, flags: Int) {
        LaunchCookie.writeToParcel(launchCookie, dest)
        dest.writeInt(taskId)
    }

    override fun describeContents(): Int = 0
Loading