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

Commit df4d309a authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Automerger Merge Worker
Browse files

Merge "[MediaProjection] Secure aidl interfaces with permission checks" into udc-dev am: b2a66917

parents e051a7b2 b2a66917
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -23,22 +23,32 @@ import android.os.IBinder;
interface IMediaProjection {
    void start(IMediaProjectionCallback callback);
    void stop();

    boolean canProjectAudio();
    boolean canProjectVideo();
    boolean canProjectSecureVideo();

    @JavaPassthrough(annotation = "@android.annotation.RequiresPermission(android.Manifest"
            + ".permission.MANAGE_MEDIA_PROJECTION)")
    int applyVirtualDisplayFlags(int flags);

    void registerCallback(IMediaProjectionCallback callback);

    void unregisterCallback(IMediaProjectionCallback callback);

    /**
     * Returns the {@link android.os.IBinder} identifying the task to record, or {@code null} if
     * there is none.
     */
    @JavaPassthrough(annotation = "@android.annotation.RequiresPermission(android.Manifest"
            + ".permission.MANAGE_MEDIA_PROJECTION)")
    IBinder getLaunchCookie();

    /**
     * Updates the {@link android.os.IBinder} identifying the task to record, or {@code null} if
     * there is none.
     */
    @JavaPassthrough(annotation = "@android.annotation.RequiresPermission(android.Manifest"
            + ".permission.MANAGE_MEDIA_PROJECTION)")
    void setLaunchCookie(in IBinder launchCookie);
}
+11 −0
Original line number Diff line number Diff line
@@ -28,11 +28,20 @@ interface IMediaProjectionManager {
    @UnsupportedAppUsage
    boolean hasProjectionPermission(int uid, String packageName);

    /**
     * Returns a new {@link IMediaProjection} instance associated with the given package.
     */
    @JavaPassthrough(annotation = "@android.annotation.RequiresPermission(android.Manifest"
            + ".permission.MANAGE_MEDIA_PROJECTION)")
    IMediaProjection createProjection(int uid, String packageName, int type,
            boolean permanentGrant);

    /**
     * Returns {@code true} if the given {@link IMediaProjection} corresponds to the current
     * projection, or {@code false} otherwise.
     */
    @JavaPassthrough(annotation = "@android.annotation.RequiresPermission(android.Manifest"
            + ".permission.MANAGE_MEDIA_PROJECTION)")
    boolean isCurrentProjection(IMediaProjection projection);

    @JavaPassthrough(annotation = "@android.annotation.RequiresPermission(android.Manifest"
@@ -67,6 +76,8 @@ interface IMediaProjectionManager {
     * @param incomingSession the nullable incoming content recording session
     * @param projection      the non-null projection the session describes
     */
  @JavaPassthrough(annotation = "@android.annotation.RequiresPermission(android.Manifest"
            + ".permission.MANAGE_MEDIA_PROJECTION)")
    void setContentRecordingSession(in ContentRecordingSession incomingSession,
            in IMediaProjection projection);
}
+3 −0
Original line number Diff line number Diff line
@@ -11602,6 +11602,7 @@ public class AudioService extends IAudioService.Stub
            return false;
        }
        final long token = Binder.clearCallingIdentity();
        try {
            if (!projectionService.isCurrentProjection(projection)) {
                Log.w(TAG, "App passed invalid MediaProjection token");
@@ -11611,6 +11612,8 @@ public class AudioService extends IAudioService.Stub
            Log.e(TAG, "Can't call .isCurrentProjection() on IMediaProjectionManager"
                    + projectionService.asBinder(), e);
            return false;
        } finally {
            Binder.restoreCallingIdentity(token);
        }
        try {
+5 −2
Original line number Diff line number Diff line
@@ -1419,6 +1419,7 @@ public final class DisplayManagerService extends SystemService {
        }

        if (projection != null) {
            final long firstToken = Binder.clearCallingIdentity();
            try {
                if (!getProjectionService().isCurrentProjection(projection)) {
                    throw new SecurityException("Cannot create VirtualDisplay with "
@@ -1427,6 +1428,8 @@ public final class DisplayManagerService extends SystemService {
                flags = projection.applyVirtualDisplayFlags(flags);
            } catch (RemoteException e) {
                throw new SecurityException("unable to validate media projection or flags");
            } finally {
                Binder.restoreCallingIdentity(firstToken);
            }
        }

@@ -1494,7 +1497,7 @@ public final class DisplayManagerService extends SystemService {
            throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission");
        }

        final long token = Binder.clearCallingIdentity();
        final long secondToken = Binder.clearCallingIdentity();
        try {
            final int displayId;
            synchronized (mSyncRoot) {
@@ -1566,7 +1569,7 @@ public final class DisplayManagerService extends SystemService {

            return displayId;
        } finally {
            Binder.restoreCallingIdentity(token);
            Binder.restoreCallingIdentity(secondToken);
        }
    }

+33 −12
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.server.media.projection;

import static android.Manifest.permission.MANAGE_MEDIA_PROJECTION;
import static android.app.ActivityManagerInternal.MEDIA_PROJECTION_TOKEN_EVENT_CREATED;
import static android.app.ActivityManagerInternal.MEDIA_PROJECTION_TOKEN_EVENT_DESTROYED;

@@ -282,7 +283,7 @@ public final class MediaProjectionManagerService extends SystemService
        @Override // Binder call
        public IMediaProjection createProjection(int uid, String packageName, int type,
                boolean isPermanentGrant) {
            if (mContext.checkCallingPermission(Manifest.permission.MANAGE_MEDIA_PROJECTION)
            if (mContext.checkCallingPermission(MANAGE_MEDIA_PROJECTION)
                        != PackageManager.PERMISSION_GRANTED) {
                throw new SecurityException("Requires MANAGE_MEDIA_PROJECTION in order to grant "
                        + "projection permission");
@@ -314,16 +315,21 @@ public final class MediaProjectionManagerService extends SystemService

        @Override // Binder call
        public boolean isCurrentProjection(IMediaProjection projection) {
            if (mContext.checkCallingOrSelfPermission(MANAGE_MEDIA_PROJECTION)
                    != PackageManager.PERMISSION_GRANTED) {
                throw new SecurityException("Requires MANAGE_MEDIA_PROJECTION in order to check "
                        + "if the given projection is current.");
            }
            return MediaProjectionManagerService.this.isCurrentProjection(
                    projection == null ? null : projection.asBinder());
        }

        @Override // Binder call
        public MediaProjectionInfo getActiveProjectionInfo() {
            if (mContext.checkCallingPermission(Manifest.permission.MANAGE_MEDIA_PROJECTION)
            if (mContext.checkCallingPermission(MANAGE_MEDIA_PROJECTION)
                        != PackageManager.PERMISSION_GRANTED) {
                throw new SecurityException("Requires MANAGE_MEDIA_PROJECTION in order to add "
                        + "projection callbacks");
                throw new SecurityException("Requires MANAGE_MEDIA_PROJECTION in order to get "
                        + "active projection info");
            }
            final long token = Binder.clearCallingIdentity();
            try {
@@ -335,10 +341,10 @@ public final class MediaProjectionManagerService extends SystemService

        @Override // Binder call
        public void stopActiveProjection() {
            if (mContext.checkCallingOrSelfPermission(Manifest.permission.MANAGE_MEDIA_PROJECTION)
            if (mContext.checkCallingOrSelfPermission(MANAGE_MEDIA_PROJECTION)
                    != PackageManager.PERMISSION_GRANTED) {
                throw new SecurityException("Requires MANAGE_MEDIA_PROJECTION in order to add "
                        + "projection callbacks");
                throw new SecurityException("Requires MANAGE_MEDIA_PROJECTION in order to stop "
                        + "the active projection");
            }
            final long token = Binder.clearCallingIdentity();
            try {
@@ -352,7 +358,7 @@ public final class MediaProjectionManagerService extends SystemService

        @Override // Binder call
        public void notifyActiveProjectionCapturedContentResized(int width, int height) {
            if (mContext.checkCallingOrSelfPermission(Manifest.permission.MANAGE_MEDIA_PROJECTION)
            if (mContext.checkCallingOrSelfPermission(MANAGE_MEDIA_PROJECTION)
                    != PackageManager.PERMISSION_GRANTED) {
                throw new SecurityException("Requires MANAGE_MEDIA_PROJECTION in order to notify "
                        + "on captured content resize");
@@ -372,10 +378,10 @@ public final class MediaProjectionManagerService extends SystemService

        @Override
        public void notifyActiveProjectionCapturedContentVisibilityChanged(boolean isVisible) {
            if (mContext.checkCallingOrSelfPermission(Manifest.permission.MANAGE_MEDIA_PROJECTION)
            if (mContext.checkCallingOrSelfPermission(MANAGE_MEDIA_PROJECTION)
                    != PackageManager.PERMISSION_GRANTED) {
                throw new SecurityException("Requires MANAGE_MEDIA_PROJECTION in order to notify "
                        + "on captured content resize");
                        + "on captured content visibility changed");
            }
            if (!isCurrentProjection(mProjectionGrant)) {
                return;
@@ -392,7 +398,7 @@ public final class MediaProjectionManagerService extends SystemService

        @Override //Binder call
        public void addCallback(final IMediaProjectionWatcherCallback callback) {
            if (mContext.checkCallingPermission(Manifest.permission.MANAGE_MEDIA_PROJECTION)
            if (mContext.checkCallingPermission(MANAGE_MEDIA_PROJECTION)
                        != PackageManager.PERMISSION_GRANTED) {
                throw new SecurityException("Requires MANAGE_MEDIA_PROJECTION in order to add "
                        + "projection callbacks");
@@ -407,7 +413,7 @@ public final class MediaProjectionManagerService extends SystemService

        @Override
        public void removeCallback(IMediaProjectionWatcherCallback callback) {
            if (mContext.checkCallingPermission(Manifest.permission.MANAGE_MEDIA_PROJECTION)
            if (mContext.checkCallingPermission(MANAGE_MEDIA_PROJECTION)
                        != PackageManager.PERMISSION_GRANTED) {
                throw new SecurityException("Requires MANAGE_MEDIA_PROJECTION in order to remove "
                        + "projection callbacks");
@@ -512,6 +518,11 @@ public final class MediaProjectionManagerService extends SystemService

        @Override // Binder call
        public int applyVirtualDisplayFlags(int flags) {
            if (mContext.checkCallingOrSelfPermission(MANAGE_MEDIA_PROJECTION)
                    != PackageManager.PERMISSION_GRANTED) {
                throw new SecurityException("Requires MANAGE_MEDIA_PROJECTION to apply virtual "
                        + "display flags.");
            }
            if (mType == MediaProjectionManager.TYPE_SCREEN_CAPTURE) {
                flags &= ~DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY;
                flags |= DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR
@@ -660,11 +671,21 @@ public final class MediaProjectionManagerService extends SystemService

        @Override // Binder call
        public void setLaunchCookie(IBinder launchCookie) {
            if (mContext.checkCallingOrSelfPermission(MANAGE_MEDIA_PROJECTION)
                    != PackageManager.PERMISSION_GRANTED) {
                throw new SecurityException("Requires MANAGE_MEDIA_PROJECTION to set launch "
                        + "cookie.");
            }
            mLaunchCookie = launchCookie;
        }

        @Override // Binder call
        public IBinder getLaunchCookie() {
            if (mContext.checkCallingOrSelfPermission(MANAGE_MEDIA_PROJECTION)
                    != PackageManager.PERMISSION_GRANTED) {
                throw new SecurityException("Requires MANAGE_MEDIA_PROJECTION to get launch "
                        + "cookie.");
            }
            return mLaunchCookie;
        }