FileDocCategorySizeDatePackage
MediaProjectionManagerService.javaAPI DocAndroid 5.1 API23990Thu Mar 12 22:22:42 GMT 2015com.android.server.media.projection

MediaProjectionManagerService

public final class MediaProjectionManagerService extends com.android.server.SystemService implements Watchdog.Monitor
Manages MediaProjection sessions. The {@link MediaProjectionManagerService} manages the creation and lifetime of MediaProjections, as well as the capabilities they grant. Any service using MediaProjection tokens as permission grants must validate the token before use by calling {@link IMediaProjectionService#isValidMediaProjection}.

Fields Summary
private static final String
TAG
private final Object
mLock
private final Map
mDeathEaters
private final CallbackDelegate
mCallbackDelegate
private final android.content.Context
mContext
private final android.app.AppOpsManager
mAppOps
private final android.media.MediaRouter
mMediaRouter
private final MediaRouterCallback
mMediaRouterCallback
private MediaRouter.RouteInfo
mMediaRouteInfo
private android.os.IBinder
mProjectionToken
private MediaProjection
mProjectionGrant
Constructors Summary
public MediaProjectionManagerService(android.content.Context context)


       
        super(context);
        mContext = context;
        mDeathEaters = new ArrayMap<IBinder, IBinder.DeathRecipient>();
        mCallbackDelegate = new CallbackDelegate();
        mAppOps = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
        mMediaRouter = (MediaRouter) mContext.getSystemService(Context.MEDIA_ROUTER_SERVICE);
        mMediaRouterCallback = new MediaRouterCallback();
        Watchdog.getInstance().addMonitor(this);
    
Methods Summary
private voidaddCallback(android.media.projection.IMediaProjectionWatcherCallback callback)

        IBinder.DeathRecipient deathRecipient = new IBinder.DeathRecipient() {
            @Override
            public void binderDied() {
                synchronized (mLock) {
                    removeCallback(callback);
                }
            }
        };
        synchronized (mLock) {
            mCallbackDelegate.add(callback);
            linkDeathRecipientLocked(callback, deathRecipient);
        }
    
private voiddispatchStart(com.android.server.media.projection.MediaProjectionManagerService$MediaProjection projection)

        mCallbackDelegate.dispatchStart(projection);
    
private voiddispatchStop(com.android.server.media.projection.MediaProjectionManagerService$MediaProjection projection)

        mCallbackDelegate.dispatchStop(projection);
    
private voiddump(java.io.PrintWriter pw)

        pw.println("MEDIA PROJECTION MANAGER (dumpsys media_projection)");
        synchronized (mLock) {
            pw.println("Media Projection: ");
            if (mProjectionGrant != null ) {
                mProjectionGrant.dump(pw);
            } else {
                pw.println("null");
            }
        }
    
private android.media.projection.MediaProjectionInfogetActiveProjectionInfo()

        synchronized (mLock) {
            if (mProjectionGrant == null) {
                return null;
            }
            return mProjectionGrant.getProjectionInfo();
        }
    
private booleanisValidMediaProjection(android.os.IBinder token)

        synchronized (mLock) {
            if (mProjectionToken != null) {
                return mProjectionToken.equals(token);
            }
            return false;
        }
    
private voidlinkDeathRecipientLocked(android.media.projection.IMediaProjectionWatcherCallback callback, android.os.IBinder.DeathRecipient deathRecipient)

        try {
            final IBinder token = callback.asBinder();
            token.linkToDeath(deathRecipient, 0);
            mDeathEaters.put(token, deathRecipient);
        } catch (RemoteException e) {
            Slog.e(TAG, "Unable to link to death for media projection monitoring callback", e);
        }
    
public voidmonitor()

        synchronized (mLock) { /* check for deadlock */ }
    
public voidonStart()

        publishBinderService(Context.MEDIA_PROJECTION_SERVICE, new BinderService(),
                false /*allowIsolated*/);
        mMediaRouter.addCallback(MediaRouter.ROUTE_TYPE_REMOTE_DISPLAY, mMediaRouterCallback,
                MediaRouter.CALLBACK_FLAG_PASSIVE_DISCOVERY);
    
public voidonSwitchUser(int userId)

        mMediaRouter.rebindAsUser(userId);
        synchronized (mLock) {
            if (mProjectionGrant != null) {
                mProjectionGrant.stop();
            }
        }
    
private voidremoveCallback(android.media.projection.IMediaProjectionWatcherCallback callback)

        synchronized (mLock) {
            unlinkDeathRecipientLocked(callback);
            mCallbackDelegate.remove(callback);
        }
    
private voidstartProjectionLocked(com.android.server.media.projection.MediaProjectionManagerService$MediaProjection projection)

        if (mProjectionGrant != null) {
            mProjectionGrant.stop();
        }
        if (mMediaRouteInfo != null) {
            mMediaRouter.getDefaultRoute().select();
        }
        mProjectionToken = projection.asBinder();
        mProjectionGrant = projection;
        dispatchStart(projection);
    
private voidstopProjectionLocked(com.android.server.media.projection.MediaProjectionManagerService$MediaProjection projection)

        mProjectionToken = null;
        mProjectionGrant = null;
        dispatchStop(projection);
    
private static java.lang.StringtypeToString(int type)

        switch (type) {
            case MediaProjectionManager.TYPE_SCREEN_CAPTURE:
                return "TYPE_SCREEN_CAPTURE";
            case MediaProjectionManager.TYPE_MIRRORING:
                return "TYPE_MIRRORING";
            case MediaProjectionManager.TYPE_PRESENTATION:
                return "TYPE_PRESENTATION";
        }
        return Integer.toString(type);
    
private voidunlinkDeathRecipientLocked(android.media.projection.IMediaProjectionWatcherCallback callback)

        final IBinder token = callback.asBinder();
        IBinder.DeathRecipient deathRecipient = mDeathEaters.remove(token);
        if (deathRecipient != null) {
            token.unlinkToDeath(deathRecipient, 0);
        }