FileDocCategorySizeDatePackage
CastControllerImpl.javaAPI DocAndroid 5.1 API12391Thu Mar 12 22:22:42 GMT 2015com.android.systemui.statusbar.policy

CastControllerImpl

public class CastControllerImpl extends Object implements CastController
Platform implementation of the cast controller.

Fields Summary
private static final String
TAG
private static final boolean
DEBUG
private final android.content.Context
mContext
private final ArrayList
mCallbacks
private final android.media.MediaRouter
mMediaRouter
private final android.util.ArrayMap
mRoutes
private final Object
mDiscoveringLock
private final android.media.projection.MediaProjectionManager
mProjectionManager
private final Object
mProjectionLock
private boolean
mDiscovering
private boolean
mCallbackRegistered
private android.media.projection.MediaProjectionInfo
mProjection
private final MediaRouter.SimpleCallback
mMediaCallback
private final MediaProjectionManager.Callback
mProjectionCallback
Constructors Summary
public CastControllerImpl(android.content.Context context)


       
        mContext = context;
        mMediaRouter = (MediaRouter) context.getSystemService(Context.MEDIA_ROUTER_SERVICE);
        mProjectionManager = (MediaProjectionManager)
                context.getSystemService(Context.MEDIA_PROJECTION_SERVICE);
        mProjection = mProjectionManager.getActiveProjectionInfo();
        mProjectionManager.addCallback(mProjectionCallback, new Handler());
        if (DEBUG) Log.d(TAG, "new CastController()");
    
Methods Summary
public voidaddCallback(Callback callback)

        mCallbacks.add(callback);
        fireOnCastDevicesChanged(callback);
        synchronized (mDiscoveringLock) {
            handleDiscoveryChangeLocked();
        }
    
public voiddump(java.io.FileDescriptor fd, java.io.PrintWriter pw, java.lang.String[] args)

        pw.println("CastController state:");
        pw.print("  mDiscovering="); pw.println(mDiscovering);
        pw.print("  mCallbackRegistered="); pw.println(mCallbackRegistered);
        pw.print("  mCallbacks.size="); pw.println(mCallbacks.size());
        pw.print("  mRoutes.size="); pw.println(mRoutes.size());
        for (int i = 0; i < mRoutes.size(); i++) {
            final RouteInfo route = mRoutes.valueAt(i);
            pw.print("    "); pw.println(routeToString(route));
        }
        pw.print("  mProjection="); pw.println(mProjection);
    
private voidensureTagExists(android.media.MediaRouter.RouteInfo route)

        if (route.getTag() == null) {
            route.setTag(UUID.randomUUID().toString());
        }
    
private voidfireOnCastDevicesChanged()

        for (Callback callback : mCallbacks) {
            fireOnCastDevicesChanged(callback);
        }
    
private voidfireOnCastDevicesChanged(Callback callback)

        callback.onCastDevicesChanged();
    
private java.lang.StringgetAppName(java.lang.String packageName)

        final PackageManager pm = mContext.getPackageManager();
        try {
            final ApplicationInfo appInfo = pm.getApplicationInfo(packageName, 0);
            if (appInfo != null) {
                final CharSequence label = appInfo.loadLabel(pm);
                if (!TextUtils.isEmpty(label)) {
                    return label.toString();
                }
            }
            Log.w(TAG, "No label found for package: " + packageName);
        } catch (NameNotFoundException e) {
            Log.w(TAG, "Error getting appName for package: " + packageName, e);
        }
        return packageName;
    
public java.util.SetgetCastDevices()

        final ArraySet<CastDevice> devices = new ArraySet<CastDevice>();
        synchronized (mProjectionLock) {
            if (mProjection != null) {
                final CastDevice device = new CastDevice();
                device.id = mProjection.getPackageName();
                device.name = getAppName(mProjection.getPackageName());
                device.description = mContext.getString(R.string.quick_settings_casting);
                device.state = CastDevice.STATE_CONNECTED;
                device.tag = mProjection;
                devices.add(device);
                return devices;
            }
        }
        synchronized(mRoutes) {
            for (RouteInfo route : mRoutes.values()) {
                final CastDevice device = new CastDevice();
                device.id = route.getTag().toString();
                final CharSequence name = route.getName(mContext);
                device.name = name != null ? name.toString() : null;
                final CharSequence description = route.getDescription();
                device.description = description != null ? description.toString() : null;
                device.state = route.isConnecting() ? CastDevice.STATE_CONNECTING
                        : route.isSelected() ? CastDevice.STATE_CONNECTED
                        : CastDevice.STATE_DISCONNECTED;
                device.tag = route;
                devices.add(device);
            }
        }
        return devices;
    
private voidhandleDiscoveryChangeLocked()

        if (mCallbackRegistered) {
            mMediaRouter.removeCallback(mMediaCallback);
            mCallbackRegistered = false;
        }
        if (mDiscovering) {
            mMediaRouter.addCallback(ROUTE_TYPE_REMOTE_DISPLAY, mMediaCallback,
                    MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY);
            mCallbackRegistered = true;
        } else if (mCallbacks.size() != 0) {
            mMediaRouter.addCallback(ROUTE_TYPE_REMOTE_DISPLAY, mMediaCallback,
                    MediaRouter.CALLBACK_FLAG_PASSIVE_DISCOVERY);
            mCallbackRegistered = true;
        }
    
public voidremoveCallback(Callback callback)

        mCallbacks.remove(callback);
        synchronized (mDiscoveringLock) {
            handleDiscoveryChangeLocked();
        }
    
private static java.lang.StringrouteToString(android.media.MediaRouter.RouteInfo route)

        if (route == null) return null;
        final StringBuilder sb = new StringBuilder().append(route.getName()).append('/")
                .append(route.getDescription()).append('@").append(route.getDeviceAddress())
                .append(",status=").append(route.getStatus());
        if (route.isDefault()) sb.append(",default");
        if (route.isEnabled()) sb.append(",enabled");
        if (route.isConnecting()) sb.append(",connecting");
        if (route.isSelected()) sb.append(",selected");
        return sb.append(",id=").append(route.getTag()).toString();
    
public voidsetCurrentUserId(int currentUserId)

        mMediaRouter.rebindAsUser(currentUserId);
    
public voidsetDiscovering(boolean request)

        synchronized (mDiscoveringLock) {
            if (mDiscovering == request) return;
            mDiscovering = request;
            if (DEBUG) Log.d(TAG, "setDiscovering: " + request);
            handleDiscoveryChangeLocked();
        }
    
private voidsetProjection(android.media.projection.MediaProjectionInfo projection, boolean started)

        boolean changed = false;
        final MediaProjectionInfo oldProjection = mProjection;
        synchronized (mProjectionLock) {
            final boolean isCurrent = Objects.equals(projection, mProjection);
            if (started && !isCurrent) {
                mProjection = projection;
                changed = true;
            } else if (!started && isCurrent) {
                mProjection = null;
                changed = true;
            }
        }
        if (changed) {
            if (DEBUG) Log.d(TAG, "setProjection: " + oldProjection + " -> " + mProjection);
            fireOnCastDevicesChanged();
        }
    
public voidstartCasting(CastDevice device)

        if (device == null || device.tag == null) return;
        final RouteInfo route = (RouteInfo) device.tag;
        if (DEBUG) Log.d(TAG, "startCasting: " + routeToString(route));
        mMediaRouter.selectRoute(ROUTE_TYPE_REMOTE_DISPLAY, route);
    
public voidstopCasting(CastDevice device)

        final boolean isProjection = device.tag instanceof MediaProjectionInfo;
        if (DEBUG) Log.d(TAG, "stopCasting isProjection=" + isProjection);
        if (isProjection) {
            final MediaProjectionInfo projection = (MediaProjectionInfo) device.tag;
            if (Objects.equals(mProjectionManager.getActiveProjectionInfo(), projection)) {
                mProjectionManager.stopActiveProjection();
            } else {
                Log.w(TAG, "Projection is no longer active: " + projection);
            }
        } else {
            mMediaRouter.getDefaultRoute().select();
        }
    
private voidupdateRemoteDisplays()

        synchronized(mRoutes) {
            mRoutes.clear();
            final int n = mMediaRouter.getRouteCount();
            for (int i = 0; i < n; i++) {
                final RouteInfo route = mMediaRouter.getRouteAt(i);
                if (!route.isEnabled()) continue;
                if (!route.matchesTypes(ROUTE_TYPE_REMOTE_DISPLAY)) continue;
                ensureTagExists(route);
                mRoutes.put(route.getTag().toString(), route);
            }
            final RouteInfo selected = mMediaRouter.getSelectedRoute(ROUTE_TYPE_REMOTE_DISPLAY);
            if (selected != null && !selected.isDefault()) {
                ensureTagExists(selected);
                mRoutes.put(selected.getTag().toString(), selected);
            }
        }
        fireOnCastDevicesChanged();