/*
 * Copyright (C) 2012 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.media;

import android.Manifest;
import android.annotation.DrawableRes;
import android.annotation.NonNull;
import android.app.ActivityThread;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.hardware.display.DisplayManager;
import android.hardware.display.WifiDisplay;
import android.hardware.display.WifiDisplayStatus;
import android.media.session.MediaSession;
import android.os.Handler;
import android.os.IBinder;
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.text.TextUtils;
import android.util.Log;
import android.view.Display;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * MediaRouter allows applications to control the routing of media channels
 * and streams from the current device to external speakers and destination devices.
 *
 * <p>A MediaRouter is retrieved through {@link Context#getSystemService(String)
 * Context.getSystemService()} of a {@link Context#MEDIA_ROUTER_SERVICE
 * Context.MEDIA_ROUTER_SERVICE}.
 *
 * <p>The media router API is not thread-safe; all interactions with it must be
 * done from the main thread of the process.</p>
 */
public class MediaRouter {
    private static final String TAG = "MediaRouter";
    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);

    static class Static implements DisplayManager.DisplayListener {
        final Context mAppContext;
        final Resources mResources;
        final IAudioService mAudioService;
        final DisplayManager mDisplayService;
        final IMediaRouterService mMediaRouterService;
        final Handler mHandler;
        final CopyOnWriteArrayList<CallbackInfo> mCallbacks =
                new CopyOnWriteArrayList<CallbackInfo>();

        final ArrayList<RouteInfo> mRoutes = new ArrayList<RouteInfo>();
        final ArrayList<RouteCategory> mCategories = new ArrayList<RouteCategory>();

        final RouteCategory mSystemCategory;

        final AudioRoutesInfo mCurAudioRoutesInfo = new AudioRoutesInfo();

        RouteInfo mDefaultAudioVideo;
        RouteInfo mBluetoothA2dpRoute;

        RouteInfo mSelectedRoute;

        final boolean mCanConfigureWifiDisplays;
        boolean mActivelyScanningWifiDisplays;
        String mPreviousActiveWifiDisplayAddress;

        int mDiscoveryRequestRouteTypes;
        boolean mDiscoverRequestActiveScan;

        int mCurrentUserId = -1;
        IMediaRouterClient mClient;
        MediaRouterClientState mClientState;

        final IAudioRoutesObserver.Stub mAudioRoutesObserver = new IAudioRoutesObserver.Stub() {
            @Override
            public void dispatchAudioRoutesChanged(final AudioRoutesInfo newRoutes) {
                mHandler.post(new Runnable() {
                    @Override public void run() {
                        updateAudioRoutes(newRoutes);
                    }
                });
            }
        };

        Static(Context appContext) {
            mAppContext = appContext;
            mResources = Resources.getSystem();
            mHandler = new Handler(appContext.getMainLooper());

            IBinder b = ServiceManager.getService(Context.AUDIO_SERVICE);
            mAudioService = IAudioService.Stub.asInterface(b);

            mDisplayService = (DisplayManager) appContext.getSystemService(Context.DISPLAY_SERVICE);

            mMediaRouterService = IMediaRouterService.Stub.asInterface(
                    ServiceManager.getService(Context.MEDIA_ROUTER_SERVICE));

            mSystemCategory = new RouteCategory(
                    com.android.internal.R.string.default_audio_route_category_name,
                    ROUTE_TYPE_LIVE_AUDIO | ROUTE_TYPE_LIVE_VIDEO, false);
            mSystemCategory.mIsSystem = true;

            // Only the system can configure wifi displays.  The display manager
            // enforces this with a permission check.  Set a flag here so that we
            // know whether this process is actually allowed to scan and connect.
            mCanConfigureWifiDisplays = appContext.checkPermission(
                    Manifest.permission.CONFIGURE_WIFI_DISPLAY,
                    Process.myPid(), Process.myUid()) == PackageManager.PERMISSION_GRANTED;
        }

        // Called after sStatic is initialized
        void startMonitoringRoutes(Context appContext) {
            mDefaultAudioVideo = new RouteInfo(mSystemCategory);
            mDefaultAudioVideo.mNameResId = com.android.internal.R.string.default_audio_route_name;
            mDefaultAudioVideo.mSupportedTypes = ROUTE_TYPE_LIVE_AUDIO | ROUTE_TYPE_LIVE_VIDEO;
            mDefaultAudioVideo.updatePresentationDisplay();
            addRouteStatic(mDefaultAudioVideo);

            // This will select the active wifi display route if there is one.
            updateWifiDisplayStatus(mDisplayService.getWifiDisplayStatus());

            appContext.registerReceiver(new WifiDisplayStatusChangedReceiver(),
                    new IntentFilter(DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED));
            appContext.registerReceiver(new VolumeChangeReceiver(),
                    new IntentFilter(AudioManager.VOLUME_CHANGED_ACTION));

            mDisplayService.registerDisplayListener(this, mHandler);

            AudioRoutesInfo newAudioRoutes = null;
            try {
                newAudioRoutes = mAudioService.startWatchingRoutes(mAudioRoutesObserver);
            } catch (RemoteException e) {
            }
            if (newAudioRoutes != null) {
                // This will select the active BT route if there is one and the current
                // selected route is the default system route, or if there is no selected
                // route yet.
                updateAudioRoutes(newAudioRoutes);
            }

            // Bind to the media router service.
            rebindAsUser(UserHandle.myUserId());

            // Select the default route if the above didn't sync us up
            // appropriately with relevant system state.
            if (mSelectedRoute == null) {
                selectDefaultRouteStatic();
            }
        }

        void updateAudioRoutes(AudioRoutesInfo newRoutes) {
            if (newRoutes.mainType != mCurAudioRoutesInfo.mainType) {
                mCurAudioRoutesInfo.mainType = newRoutes.mainType;
                int name;
                if ((newRoutes.mainType&AudioRoutesInfo.MAIN_HEADPHONES) != 0
                        || (newRoutes.mainType&AudioRoutesInfo.MAIN_HEADSET) != 0) {
                    name = com.android.internal.R.string.default_audio_route_name_headphones;
                } else if ((newRoutes.mainType&AudioRoutesInfo.MAIN_DOCK_SPEAKERS) != 0) {
                    name = com.android.internal.R.string.default_audio_route_name_dock_speakers;
                } else if ((newRoutes.mainType&AudioRoutesInfo.MAIN_HDMI) != 0) {
                    name = com.android.internal.R.string.default_media_route_name_hdmi;
                } else {
                    name = com.android.internal.R.string.default_audio_route_name;
                }
                sStatic.mDefaultAudioVideo.mNameResId = name;
                dispatchRouteChanged(sStatic.mDefaultAudioVideo);
            }

            final int mainType = mCurAudioRoutesInfo.mainType;

            if (!TextUtils.equals(newRoutes.bluetoothName, mCurAudioRoutesInfo.bluetoothName)) {
                mCurAudioRoutesInfo.bluetoothName = newRoutes.bluetoothName;
                if (mCurAudioRoutesInfo.bluetoothName != null) {
                    if (sStatic.mBluetoothA2dpRoute == null) {
                        final RouteInfo info = new RouteInfo(sStatic.mSystemCategory);
                        info.mName = mCurAudioRoutesInfo.bluetoothName;
                        info.mDescription = sStatic.mResources.getText(
                                com.android.internal.R.string.bluetooth_a2dp_audio_route_name);
                        info.mSupportedTypes = ROUTE_TYPE_LIVE_AUDIO;
                        sStatic.mBluetoothA2dpRoute = info;
                        addRouteStatic(sStatic.mBluetoothA2dpRoute);
                    } else {
                        sStatic.mBluetoothA2dpRoute.mName = mCurAudioRoutesInfo.bluetoothName;
                        dispatchRouteChanged(sStatic.mBluetoothA2dpRoute);
                    }
                } else if (sStatic.mBluetoothA2dpRoute != null) {
                    removeRouteStatic(sStatic.mBluetoothA2dpRoute);
                    sStatic.mBluetoothA2dpRoute = null;
                }
            }

            if (mBluetoothA2dpRoute != null) {
                final boolean a2dpEnabled = isBluetoothA2dpOn();
                if (mainType != AudioRoutesInfo.MAIN_SPEAKER &&
                        mSelectedRoute == mBluetoothA2dpRoute && !a2dpEnabled) {
                    selectRouteStatic(ROUTE_TYPE_LIVE_AUDIO, mDefaultAudioVideo, false);
                } else if ((mSelectedRoute == mDefaultAudioVideo || mSelectedRoute == null) &&
                        a2dpEnabled) {
                    selectRouteStatic(ROUTE_TYPE_LIVE_AUDIO, mBluetoothA2dpRoute, false);
                }
            }
        }

        boolean isBluetoothA2dpOn() {
            try {
                return mAudioService.isBluetoothA2dpOn();
            } catch (RemoteException e) {
                Log.e(TAG, "Error querying Bluetooth A2DP state", e);
                return false;
            }
        }

        void updateDiscoveryRequest() {
            // What are we looking for today?
            int routeTypes = 0;
            int passiveRouteTypes = 0;
            boolean activeScan = false;
            boolean activeScanWifiDisplay = false;
            final int count = mCallbacks.size();
            for (int i = 0; i < count; i++) {
                CallbackInfo cbi = mCallbacks.get(i);
                if ((cbi.flags & (CALLBACK_FLAG_PERFORM_ACTIVE_SCAN
                        | CALLBACK_FLAG_REQUEST_DISCOVERY)) != 0) {
                    // Discovery explicitly requested.
                    routeTypes |= cbi.type;
                } else if ((cbi.flags & CALLBACK_FLAG_PASSIVE_DISCOVERY) != 0) {
                    // Discovery only passively requested.
                    passiveRouteTypes |= cbi.type;
                } else {
                    // Legacy case since applications don't specify the discovery flag.
                    // Unfortunately we just have to assume they always need discovery
                    // whenever they have a callback registered.
                    routeTypes |= cbi.type;
                }
                if ((cbi.flags & CALLBACK_FLAG_PERFORM_ACTIVE_SCAN) != 0) {
                    activeScan = true;
                    if ((cbi.type & ROUTE_TYPE_REMOTE_DISPLAY) != 0) {
                        activeScanWifiDisplay = true;
                    }
                }
            }
            if (routeTypes != 0 || activeScan) {
                // If someone else requests discovery then enable the passive listeners.
                // This is used by the MediaRouteButton and MediaRouteActionProvider since
                // they don't receive lifecycle callbacks from the Activity.
                routeTypes |= passiveRouteTypes;
            }

            // Update wifi display scanning.
            // TODO: All of this should be managed by the media router service.
            if (mCanConfigureWifiDisplays) {
                if (mSelectedRoute != null
                        && mSelectedRoute.matchesTypes(ROUTE_TYPE_REMOTE_DISPLAY)) {
                    // Don't scan while already connected to a remote display since
                    // it may interfere with the ongoing transmission.
                    activeScanWifiDisplay = false;
                }
                if (activeScanWifiDisplay) {
                    if (!mActivelyScanningWifiDisplays) {
                        mActivelyScanningWifiDisplays = true;
                        mDisplayService.startWifiDisplayScan();
                    }
                } else {
                    if (mActivelyScanningWifiDisplays) {
                        mActivelyScanningWifiDisplays = false;
                        mDisplayService.stopWifiDisplayScan();
                    }
                }
            }

            // Tell the media router service all about it.
            if (routeTypes != mDiscoveryRequestRouteTypes
                    || activeScan != mDiscoverRequestActiveScan) {
                mDiscoveryRequestRouteTypes = routeTypes;
                mDiscoverRequestActiveScan = activeScan;
                publishClientDiscoveryRequest();
            }
        }

        @Override
        public void onDisplayAdded(int displayId) {
            updatePresentationDisplays(displayId);
        }

        @Override
        public void onDisplayChanged(int displayId) {
            updatePresentationDisplays(displayId);
        }

        @Override
        public void onDisplayRemoved(int displayId) {
            updatePresentationDisplays(displayId);
        }

        public Display[] getAllPresentationDisplays() {
            return mDisplayService.getDisplays(DisplayManager.DISPLAY_CATEGORY_PRESENTATION);
        }

        private void updatePresentationDisplays(int changedDisplayId) {
            final int count = mRoutes.size();
            for (int i = 0; i < count; i++) {
                final RouteInfo route = mRoutes.get(i);
                if (route.updatePresentationDisplay() || (route.mPresentationDisplay != null
                        && route.mPresentationDisplay.getDisplayId() == changedDisplayId)) {
                    dispatchRoutePresentationDisplayChanged(route);
                }
            }
        }

        void setSelectedRoute(RouteInfo info, boolean explicit) {
            // Must be non-reentrant.
            mSelectedRoute = info;
            publishClientSelectedRoute(explicit);
        }

        void rebindAsUser(int userId) {
            if (mCurrentUserId != userId || userId < 0 || mClient == null) {
                if (mClient != null) {
                    try {
                        mMediaRouterService.unregisterClient(mClient);
                    } catch (RemoteException ex) {
                        Log.e(TAG, "Unable to unregister media router client.", ex);
                    }
                    mClient = null;
                }

                mCurrentUserId = userId;

                try {
                    Client client = new Client();
                    mMediaRouterService.registerClientAsUser(client,
                            mAppContext.getPackageName(), userId);
                    mClient = client;
                } catch (RemoteException ex) {
                    Log.e(TAG, "Unable to register media router client.", ex);
                }

                publishClientDiscoveryRequest();
                publishClientSelectedRoute(false);
                updateClientState();
            }
        }

        void publishClientDiscoveryRequest() {
            if (mClient != null) {
                try {
                    mMediaRouterService.setDiscoveryRequest(mClient,
                            mDiscoveryRequestRouteTypes, mDiscoverRequestActiveScan);
                } catch (RemoteException ex) {
                    Log.e(TAG, "Unable to publish media router client discovery request.", ex);
                }
            }
        }

        void publishClientSelectedRoute(boolean explicit) {
            if (mClient != null) {
                try {
                    mMediaRouterService.setSelectedRoute(mClient,
                            mSelectedRoute != null ? mSelectedRoute.mGlobalRouteId : null,
                            explicit);
                } catch (RemoteException ex) {
                    Log.e(TAG, "Unable to publish media router client selected route.", ex);
                }
            }
        }

        void updateClientState() {
            // Update the client state.
            mClientState = null;
            if (mClient != null) {
                try {
                    mClientState = mMediaRouterService.getState(mClient);
                } catch (RemoteException ex) {
                    Log.e(TAG, "Unable to retrieve media router client state.", ex);
                }
            }
            final ArrayList<MediaRouterClientState.RouteInfo> globalRoutes =
                    mClientState != null ? mClientState.routes : null;
            final String globallySelectedRouteId = mClientState != null ?
                    mClientState.globallySelectedRouteId : null;

            // Add or update routes.
            final int globalRouteCount = globalRoutes != null ? globalRoutes.size() : 0;
            for (int i = 0; i < globalRouteCount; i++) {
                final MediaRouterClientState.RouteInfo globalRoute = globalRoutes.get(i);
                RouteInfo route = findGlobalRoute(globalRoute.id);
                if (route == null) {
                    route = makeGlobalRoute(globalRoute);
                    addRouteStatic(route);
                } else {
                    updateGlobalRoute(route, globalRoute);
                }
            }

            // Synchronize state with the globally selected route.
            if (globallySelectedRouteId != null) {
                final RouteInfo route = findGlobalRoute(globallySelectedRouteId);
                if (route == null) {
                    Log.w(TAG, "Could not find new globally selected route: "
                            + globallySelectedRouteId);
                } else if (route != mSelectedRoute) {
                    if (DEBUG) {
                        Log.d(TAG, "Selecting new globally selected route: " + route);
                    }
                    selectRouteStatic(route.mSupportedTypes, route, false);
                }
            } else if (mSelectedRoute != null && mSelectedRoute.mGlobalRouteId != null) {
                if (DEBUG) {
                    Log.d(TAG, "Unselecting previous globally selected route: " + mSelectedRoute);
                }
                selectDefaultRouteStatic();
            }

            // Remove defunct routes.
            outer: for (int i = mRoutes.size(); i-- > 0; ) {
                final RouteInfo route = mRoutes.get(i);
                final String globalRouteId = route.mGlobalRouteId;
                if (globalRouteId != null) {
                    for (int j = 0; j < globalRouteCount; j++) {
                        MediaRouterClientState.RouteInfo globalRoute = globalRoutes.get(j);
                        if (globalRouteId.equals(globalRoute.id)) {
                            continue outer; // found
                        }
                    }
                    // not found
                    removeRouteStatic(route);
                }
            }
        }

        void requestSetVolume(RouteInfo route, int volume) {
            if (route.mGlobalRouteId != null && mClient != null) {
                try {
                    mMediaRouterService.requestSetVolume(mClient,
                            route.mGlobalRouteId, volume);
                } catch (RemoteException ex) {
                    Log.w(TAG, "Unable to request volume change.", ex);
                }
            }
        }

        void requestUpdateVolume(RouteInfo route, int direction) {
            if (route.mGlobalRouteId != null && mClient != null) {
                try {
                    mMediaRouterService.requestUpdateVolume(mClient,
                            route.mGlobalRouteId, direction);
                } catch (RemoteException ex) {
                    Log.w(TAG, "Unable to request volume change.", ex);
                }
            }
        }

        RouteInfo makeGlobalRoute(MediaRouterClientState.RouteInfo globalRoute) {
            RouteInfo route = new RouteInfo(sStatic.mSystemCategory);
            route.mGlobalRouteId = globalRoute.id;
            route.mName = globalRoute.name;
            route.mDescription = globalRoute.description;
            route.mSupportedTypes = globalRoute.supportedTypes;
            route.mEnabled = globalRoute.enabled;
            route.setRealStatusCode(globalRoute.statusCode);
            route.mPlaybackType = globalRoute.playbackType;
            route.mPlaybackStream = globalRoute.playbackStream;
            route.mVolume = globalRoute.volume;
            route.mVolumeMax = globalRoute.volumeMax;
            route.mVolumeHandling = globalRoute.volumeHandling;
            route.mPresentationDisplayId = globalRoute.presentationDisplayId;
            route.updatePresentationDisplay();
            return route;
        }

        void updateGlobalRoute(RouteInfo route, MediaRouterClientState.RouteInfo globalRoute) {
            boolean changed = false;
            boolean volumeChanged = false;
            boolean presentationDisplayChanged = false;

            if (!Objects.equals(route.mName, globalRoute.name)) {
                route.mName = globalRoute.name;
                changed = true;
            }
            if (!Objects.equals(route.mDescription, globalRoute.description)) {
                route.mDescription = globalRoute.description;
                changed = true;
            }
            final int oldSupportedTypes = route.mSupportedTypes;
            if (oldSupportedTypes != globalRoute.supportedTypes) {
                route.mSupportedTypes = globalRoute.supportedTypes;
                changed = true;
            }
            if (route.mEnabled != globalRoute.enabled) {
                route.mEnabled = globalRoute.enabled;
                changed = true;
            }
            if (route.mRealStatusCode != globalRoute.statusCode) {
                route.setRealStatusCode(globalRoute.statusCode);
                changed = true;
            }
            if (route.mPlaybackType != globalRoute.playbackType) {
                route.mPlaybackType = globalRoute.playbackType;
                changed = true;
            }
            if (route.mPlaybackStream != globalRoute.playbackStream) {
                route.mPlaybackStream = globalRoute.playbackStream;
                changed = true;
            }
            if (route.mVolume != globalRoute.volume) {
                route.mVolume = globalRoute.volume;
                changed = true;
                volumeChanged = true;
            }
            if (route.mVolumeMax != globalRoute.volumeMax) {
                route.mVolumeMax = globalRoute.volumeMax;
                changed = true;
                volumeChanged = true;
            }
            if (route.mVolumeHandling != globalRoute.volumeHandling) {
                route.mVolumeHandling = globalRoute.volumeHandling;
                changed = true;
                volumeChanged = true;
            }
            if (route.mPresentationDisplayId != globalRoute.presentationDisplayId) {
                route.mPresentationDisplayId = globalRoute.presentationDisplayId;
                route.updatePresentationDisplay();
                changed = true;
                presentationDisplayChanged = true;
            }

            if (changed) {
                dispatchRouteChanged(route, oldSupportedTypes);
            }
            if (volumeChanged) {
                dispatchRouteVolumeChanged(route);
            }
            if (presentationDisplayChanged) {
                dispatchRoutePresentationDisplayChanged(route);
            }
        }

        RouteInfo findGlobalRoute(String globalRouteId) {
            final int count = mRoutes.size();
            for (int i = 0; i < count; i++) {
                final RouteInfo route = mRoutes.get(i);
                if (globalRouteId.equals(route.mGlobalRouteId)) {
                    return route;
                }
            }
            return null;
        }

        final class Client extends IMediaRouterClient.Stub {
            @Override
            public void onStateChanged() {
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        if (Client.this == mClient) {
                            updateClientState();
                        }
                    }
                });
            }
        }
    }

    static Static sStatic;

    /**
     * Route type flag for live audio.
     *
     * <p>A device that supports live audio routing will allow the media audio stream
     * to be routed to supported destinations. This can include internal speakers or
     * audio jacks on the device itself, A2DP devices, and more.</p>
     *
     * <p>Once initiated this routing is transparent to the application. All audio
     * played on the media stream will be routed to the selected destination.</p>
     */
    public static final int ROUTE_TYPE_LIVE_AUDIO = 1 << 0;

    /**
     * Route type flag for live video.
     *
     * <p>A device that supports live video routing will allow a mirrored version
     * of the device's primary display or a customized
     * {@link android.app.Presentation Presentation} to be routed to supported destinations.</p>
     *
     * <p>Once initiated, display mirroring is transparent to the application.
     * While remote routing is active the application may use a
     * {@link android.app.Presentation Presentation} to replace the mirrored view
     * on the external display with different content.</p>
     *
     * @see RouteInfo#getPresentationDisplay()
     * @see android.app.Presentation
     */
    public static final int ROUTE_TYPE_LIVE_VIDEO = 1 << 1;

    /**
     * Temporary interop constant to identify remote displays.
     * @hide To be removed when media router API is updated.
     */
    public static final int ROUTE_TYPE_REMOTE_DISPLAY = 1 << 2;

    /**
     * Route type flag for application-specific usage.
     *
     * <p>Unlike other media route types, user routes are managed by the application.
     * The MediaRouter will manage and dispatch events for user routes, but the application
     * is expected to interpret the meaning of these events and perform the requested
     * routing tasks.</p>
     */
    public static final int ROUTE_TYPE_USER = 1 << 23;

    static final int ROUTE_TYPE_ANY = ROUTE_TYPE_LIVE_AUDIO | ROUTE_TYPE_LIVE_VIDEO
            | ROUTE_TYPE_REMOTE_DISPLAY | ROUTE_TYPE_USER;

    /**
     * Flag for {@link #addCallback}: Actively scan for routes while this callback
     * is registered.
     * <p>
     * When this flag is specified, the media router will actively scan for new
     * routes.  Certain routes, such as wifi display routes, may not be discoverable
     * except when actively scanning.  This flag is typically used when the route picker
     * dialog has been opened by the user to ensure that the route information is
     * up to date.
     * </p><p>
     * Active scanning may consume a significant amount of power and may have intrusive
     * effects on wireless connectivity.  Therefore it is important that active scanning
     * only be requested when it is actually needed to satisfy a user request to
     * discover and select a new route.
     * </p>
     */
    public static final int CALLBACK_FLAG_PERFORM_ACTIVE_SCAN = 1 << 0;

    /**
     * Flag for {@link #addCallback}: Do not filter route events.
     * <p>
     * When this flag is specified, the callback will be invoked for event that affect any
     * route even if they do not match the callback's filter.
     * </p>
     */
    public static final int CALLBACK_FLAG_UNFILTERED_EVENTS = 1 << 1;

    /**
     * Explicitly requests discovery.
     *
     * @hide Future API ported from support library.  Revisit this later.
     */
    public static final int CALLBACK_FLAG_REQUEST_DISCOVERY = 1 << 2;

    /**
     * Requests that discovery be performed but only if there is some other active
     * callback already registered.
     *
     * @hide Compatibility workaround for the fact that applications do not currently
     * request discovery explicitly (except when using the support library API).
     */
    public static final int CALLBACK_FLAG_PASSIVE_DISCOVERY = 1 << 3;

    /**
     * Flag for {@link #isRouteAvailable}: Ignore the default route.
     * <p>
     * This flag is used to determine whether a matching non-default route is available.
     * This constraint may be used to decide whether to offer the route chooser dialog
     * to the user.  There is no point offering the chooser if there are no
     * non-default choices.
     * </p>
     *
     * @hide Future API ported from support library.  Revisit this later.
     */
    public static final int AVAILABILITY_FLAG_IGNORE_DEFAULT_ROUTE = 1 << 0;

    // Maps application contexts
    static final HashMap<Context, MediaRouter> sRouters = new HashMap<Context, MediaRouter>();

    static String typesToString(int types) {
        final StringBuilder result = new StringBuilder();
        if ((types & ROUTE_TYPE_LIVE_AUDIO) != 0) {
            result.append("ROUTE_TYPE_LIVE_AUDIO ");
        }
        if ((types & ROUTE_TYPE_LIVE_VIDEO) != 0) {
            result.append("ROUTE_TYPE_LIVE_VIDEO ");
        }
        if ((types & ROUTE_TYPE_REMOTE_DISPLAY) != 0) {
            result.append("ROUTE_TYPE_REMOTE_DISPLAY ");
        }
        if ((types & ROUTE_TYPE_USER) != 0) {
            result.append("ROUTE_TYPE_USER ");
        }
        return result.toString();
    }

    /** @hide */
    public MediaRouter(Context context) {
        synchronized (Static.class) {
            if (sStatic == null) {
                final Context appContext = context.getApplicationContext();
                sStatic = new Static(appContext);
                sStatic.startMonitoringRoutes(appContext);
            }
        }
    }

    /**
     * Gets the default route for playing media content on the system.
     * <p>
     * The system always provides a default route.
     * </p>
     *
     * @return The default route, which is guaranteed to never be null.
     */
    public RouteInfo getDefaultRoute() {
        return sStatic.mDefaultAudioVideo;
    }

    /**
     * @hide for use by framework routing UI
     */
    public RouteCategory getSystemCategory() {
        return sStatic.mSystemCategory;
    }

    /** @hide */
    public RouteInfo getSelectedRoute() {
        return getSelectedRoute(ROUTE_TYPE_ANY);
    }

    /**
     * Return the currently selected route for any of the given types
     *
     * @param type route types
     * @return the selected route
     */
    public RouteInfo getSelectedRoute(int type) {
        if (sStatic.mSelectedRoute != null &&
                (sStatic.mSelectedRoute.mSupportedTypes & type) != 0) {
            // If the selected route supports any of the types supplied, it's still considered
            // 'selected' for that type.
            return sStatic.mSelectedRoute;
        } else if (type == ROUTE_TYPE_USER) {
            // The caller specifically asked for a user route and the currently selected route
            // doesn't qualify.
            return null;
        }
        // If the above didn't match and we're not specifically asking for a user route,
        // consider the default selected.
        return sStatic.mDefaultAudioVideo;
    }

    /**
     * Returns true if there is a route that matches the specified types.
     * <p>
     * This method returns true if there are any available routes that match the types
     * regardless of whether they are enabled or disabled.  If the
     * {@link #AVAILABILITY_FLAG_IGNORE_DEFAULT_ROUTE} flag is specified, then
     * the method will only consider non-default routes.
     * </p>
     *
     * @param types The types to match.
     * @param flags Flags to control the determination of whether a route may be available.
     * May be zero or {@link #AVAILABILITY_FLAG_IGNORE_DEFAULT_ROUTE}.
     * @return True if a matching route may be available.
     *
     * @hide Future API ported from support library.  Revisit this later.
     */
    public boolean isRouteAvailable(int types, int flags) {
        final int count = sStatic.mRoutes.size();
        for (int i = 0; i < count; i++) {
            RouteInfo route = sStatic.mRoutes.get(i);
            if (route.matchesTypes(types)) {
                if ((flags & AVAILABILITY_FLAG_IGNORE_DEFAULT_ROUTE) == 0
                        || route != sStatic.mDefaultAudioVideo) {
                    return true;
                }
            }
        }

        // It doesn't look like we can find a matching route right now.
        return false;
    }

    /**
     * Add a callback to listen to events about specific kinds of media routes.
     * If the specified callback is already registered, its registration will be updated for any
     * additional route types specified.
     * <p>
     * This is a convenience method that has the same effect as calling
     * {@link #addCallback(int, Callback, int)} without flags.
     * </p>
     *
     * @param types Types of routes this callback is interested in
     * @param cb Callback to add
     */
    public void addCallback(int types, Callback cb) {
        addCallback(types, cb, 0);
    }

    /**
     * Add a callback to listen to events about specific kinds of media routes.
     * If the specified callback is already registered, its registration will be updated for any
     * additional route types specified.
     * <p>
     * By default, the callback will only be invoked for events that affect routes
     * that match the specified selector.  The filtering may be disabled by specifying
     * the {@link #CALLBACK_FLAG_UNFILTERED_EVENTS} flag.
     * </p>
     *
     * @param types Types of routes this callback is interested in
     * @param cb Callback to add
     * @param flags Flags to control the behavior of the callback.
     * May be zero or a combination of {@link #CALLBACK_FLAG_PERFORM_ACTIVE_SCAN} and
     * {@link #CALLBACK_FLAG_UNFILTERED_EVENTS}.
     */
    public void addCallback(int types, Callback cb, int flags) {
        CallbackInfo info;
        int index = findCallbackInfo(cb);
        if (index >= 0) {
            info = sStatic.mCallbacks.get(index);
            info.type |= types;
            info.flags |= flags;
        } else {
            info = new CallbackInfo(cb, types, flags, this);
            sStatic.mCallbacks.add(info);
        }
        sStatic.updateDiscoveryRequest();
    }

    /**
     * Remove the specified callback. It will no longer receive events about media routing.
     *
     * @param cb Callback to remove
     */
    public void removeCallback(Callback cb) {
        int index = findCallbackInfo(cb);
        if (index >= 0) {
            sStatic.mCallbacks.remove(index);
            sStatic.updateDiscoveryRequest();
        } else {
            Log.w(TAG, "removeCallback(" + cb + "): callback not registered");
        }
    }

    private int findCallbackInfo(Callback cb) {
        final int count = sStatic.mCallbacks.size();
        for (int i = 0; i < count; i++) {
            final CallbackInfo info = sStatic.mCallbacks.get(i);
            if (info.cb == cb) {
                return i;
            }
        }
        return -1;
    }

    /**
     * Select the specified route to use for output of the given media types.
     * <p class="note">
     * As API version 18, this function may be used to select any route.
     * In prior versions, this function could only be used to select user
     * routes and would ignore any attempt to select a system route.
     * </p>
     *
     * @param types type flags indicating which types this route should be used for.
     *              The route must support at least a subset.
     * @param route Route to select
     * @throws IllegalArgumentException if the given route is {@code null}
     */
    public void selectRoute(int types, @NonNull RouteInfo route) {
        if (route == null) {
            throw new IllegalArgumentException("Route cannot be null.");
        }
        selectRouteStatic(types, route, true);
    }

    /**
     * @hide internal use
     */
    public void selectRouteInt(int types, RouteInfo route, boolean explicit) {
        selectRouteStatic(types, route, explicit);
    }

    static void selectRouteStatic(int types, @NonNull RouteInfo route, boolean explicit) {
        assert(route != null);
        final RouteInfo oldRoute = sStatic.mSelectedRoute;
        if (oldRoute == route) return;
        if (!route.matchesTypes(types)) {
            Log.w(TAG, "selectRoute ignored; cannot select route with supported types " +
                    typesToString(route.getSupportedTypes()) + " into route types " +
                    typesToString(types));
            return;
        }

        final RouteInfo btRoute = sStatic.mBluetoothA2dpRoute;
        if (btRoute != null && (types & ROUTE_TYPE_LIVE_AUDIO) != 0 &&
                (route == btRoute || route == sStatic.mDefaultAudioVideo)) {
            try {
                sStatic.mAudioService.setBluetoothA2dpOn(route == btRoute);
            } catch (RemoteException e) {
                Log.e(TAG, "Error changing Bluetooth A2DP state", e);
            }
        }

        final WifiDisplay activeDisplay =
                sStatic.mDisplayService.getWifiDisplayStatus().getActiveDisplay();
        final boolean oldRouteHasAddress = oldRoute != null && oldRoute.mDeviceAddress != null;
        final boolean newRouteHasAddress = route.mDeviceAddress != null;
        if (activeDisplay != null || oldRouteHasAddress || newRouteHasAddress) {
            if (newRouteHasAddress && !matchesDeviceAddress(activeDisplay, route)) {
                if (sStatic.mCanConfigureWifiDisplays) {
                    sStatic.mDisplayService.connectWifiDisplay(route.mDeviceAddress);
                } else {
                    Log.e(TAG, "Cannot connect to wifi displays because this process "
                            + "is not allowed to do so.");
                }
            } else if (activeDisplay != null && !newRouteHasAddress) {
                sStatic.mDisplayService.disconnectWifiDisplay();
            }
        }

        sStatic.setSelectedRoute(route, explicit);

        if (oldRoute != null) {
            dispatchRouteUnselected(types & oldRoute.getSupportedTypes(), oldRoute);
            if (oldRoute.resolveStatusCode()) {
                dispatchRouteChanged(oldRoute);
            }
        }
        if (route != null) {
            if (route.resolveStatusCode()) {
                dispatchRouteChanged(route);
            }
            dispatchRouteSelected(types & route.getSupportedTypes(), route);
        }

        // The behavior of active scans may depend on the currently selected route.
        sStatic.updateDiscoveryRequest();
    }

    static void selectDefaultRouteStatic() {
        // TODO: Be smarter about the route types here; this selects for all valid.
        if (sStatic.mSelectedRoute != sStatic.mBluetoothA2dpRoute
                && sStatic.mBluetoothA2dpRoute != null && sStatic.isBluetoothA2dpOn()) {
            selectRouteStatic(ROUTE_TYPE_ANY, sStatic.mBluetoothA2dpRoute, false);
        } else {
            selectRouteStatic(ROUTE_TYPE_ANY, sStatic.mDefaultAudioVideo, false);
        }
    }

    /**
     * Compare the device address of a display and a route.
     * Nulls/no device address will match another null/no address.
     */
    static boolean matchesDeviceAddress(WifiDisplay display, RouteInfo info) {
        final boolean routeHasAddress = info != null && info.mDeviceAddress != null;
        if (display == null && !routeHasAddress) {
            return true;
        }

        if (display != null && routeHasAddress) {
            return display.getDeviceAddress().equals(info.mDeviceAddress);
        }
        return false;
    }

    /**
     * Add an app-specified route for media to the MediaRouter.
     * App-specified route definitions are created using {@link #createUserRoute(RouteCategory)}
     *
     * @param info Definition of the route to add
     * @see #createUserRoute(RouteCategory)
     * @see #removeUserRoute(UserRouteInfo)
     */
    public void addUserRoute(UserRouteInfo info) {
        addRouteStatic(info);
    }

    /**
     * @hide Framework use only
     */
    public void addRouteInt(RouteInfo info) {
        addRouteStatic(info);
    }

    static void addRouteStatic(RouteInfo info) {
        final RouteCategory cat = info.getCategory();
        if (!sStatic.mCategories.contains(cat)) {
            sStatic.mCategories.add(cat);
        }
        if (cat.isGroupable() && !(info instanceof RouteGroup)) {
            // Enforce that any added route in a groupable category must be in a group.
            final RouteGroup group = new RouteGroup(info.getCategory());
            group.mSupportedTypes = info.mSupportedTypes;
            sStatic.mRoutes.add(group);
            dispatchRouteAdded(group);
            group.addRoute(info);

            info = group;
        } else {
            sStatic.mRoutes.add(info);
            dispatchRouteAdded(info);
        }
    }

    /**
     * Remove an app-specified route for media from the MediaRouter.
     *
     * @param info Definition of the route to remove
     * @see #addUserRoute(UserRouteInfo)
     */
    public void removeUserRoute(UserRouteInfo info) {
        removeRouteStatic(info);
    }

    /**
     * Remove all app-specified routes from the MediaRouter.
     *
     * @see #removeUserRoute(UserRouteInfo)
     */
    public void clearUserRoutes() {
        for (int i = 0; i < sStatic.mRoutes.size(); i++) {
            final RouteInfo info = sStatic.mRoutes.get(i);
            // TODO Right now, RouteGroups only ever contain user routes.
            // The code below will need to change if this assumption does.
            if (info instanceof UserRouteInfo || info instanceof RouteGroup) {
                removeRouteStatic(info);
                i--;
            }
        }
    }

    /**
     * @hide internal use only
     */
    public void removeRouteInt(RouteInfo info) {
        removeRouteStatic(info);
    }

    static void removeRouteStatic(RouteInfo info) {
        if (sStatic.mRoutes.remove(info)) {
            final RouteCategory removingCat = info.getCategory();
            final int count = sStatic.mRoutes.size();
            boolean found = false;
            for (int i = 0; i < count; i++) {
                final RouteCategory cat = sStatic.mRoutes.get(i).getCategory();
                if (removingCat == cat) {
                    found = true;
                    break;
                }
            }
            if (info.isSelected()) {
                // Removing the currently selected route? Select the default before we remove it.
                selectDefaultRouteStatic();
            }
            if (!found) {
                sStatic.mCategories.remove(removingCat);
            }
            dispatchRouteRemoved(info);
        }
    }

    /**
     * Return the number of {@link MediaRouter.RouteCategory categories} currently
     * represented by routes known to this MediaRouter.
     *
     * @return the number of unique categories represented by this MediaRouter's known routes
     */
    public int getCategoryCount() {
        return sStatic.mCategories.size();
    }

    /**
     * Return the {@link MediaRouter.RouteCategory category} at the given index.
     * Valid indices are in the range [0-getCategoryCount).
     *
     * @param index which category to return
     * @return the category at index
     */
    public RouteCategory getCategoryAt(int index) {
        return sStatic.mCategories.get(index);
    }

    /**
     * Return the number of {@link MediaRouter.RouteInfo routes} currently known
     * to this MediaRouter.
     *
     * @return the number of routes tracked by this router
     */
    public int getRouteCount() {
        return sStatic.mRoutes.size();
    }

    /**
     * Return the route at the specified index.
     *
     * @param index index of the route to return
     * @return the route at index
     */
    public RouteInfo getRouteAt(int index) {
        return sStatic.mRoutes.get(index);
    }

    static int getRouteCountStatic() {
        return sStatic.mRoutes.size();
    }

    static RouteInfo getRouteAtStatic(int index) {
        return sStatic.mRoutes.get(index);
    }

    /**
     * Create a new user route that may be modified and registered for use by the application.
     *
     * @param category The category the new route will belong to
     * @return A new UserRouteInfo for use by the application
     *
     * @see #addUserRoute(UserRouteInfo)
     * @see #removeUserRoute(UserRouteInfo)
     * @see #createRouteCategory(CharSequence, boolean)
     */
    public UserRouteInfo createUserRoute(RouteCategory category) {
        return new UserRouteInfo(category);
    }

    /**
     * Create a new route category. Each route must belong to a category.
     *
     * @param name Name of the new category
     * @param isGroupable true if routes in this category may be grouped with one another
     * @return the new RouteCategory
     */
    public RouteCategory createRouteCategory(CharSequence name, boolean isGroupable) {
        return new RouteCategory(name, ROUTE_TYPE_USER, isGroupable);
    }

    /**
     * Create a new route category. Each route must belong to a category.
     *
     * @param nameResId Resource ID of the name of the new category
     * @param isGroupable true if routes in this category may be grouped with one another
     * @return the new RouteCategory
     */
    public RouteCategory createRouteCategory(int nameResId, boolean isGroupable) {
        return new RouteCategory(nameResId, ROUTE_TYPE_USER, isGroupable);
    }

    /**
     * Rebinds the media router to handle routes that belong to the specified user.
     * Requires the interact across users permission to access the routes of another user.
     * <p>
     * This method is a complete hack to work around the singleton nature of the
     * media router when running inside of singleton processes like QuickSettings.
     * This mechanism should be burned to the ground when MediaRouter is redesigned.
     * Ideally the current user would be pulled from the Context but we need to break
     * down MediaRouter.Static before we can get there.
     * </p>
     *
     * @hide
     */
    public void rebindAsUser(int userId) {
        sStatic.rebindAsUser(userId);
    }

    static void updateRoute(final RouteInfo info) {
        dispatchRouteChanged(info);
    }

    static void dispatchRouteSelected(int type, RouteInfo info) {
        for (CallbackInfo cbi : sStatic.mCallbacks) {
            if (cbi.filterRouteEvent(info)) {
                cbi.cb.onRouteSelected(cbi.router, type, info);
            }
        }
    }

    static void dispatchRouteUnselected(int type, RouteInfo info) {
        for (CallbackInfo cbi : sStatic.mCallbacks) {
            if (cbi.filterRouteEvent(info)) {
                cbi.cb.onRouteUnselected(cbi.router, type, info);
            }
        }
    }

    static void dispatchRouteChanged(RouteInfo info) {
        dispatchRouteChanged(info, info.mSupportedTypes);
    }

    static void dispatchRouteChanged(RouteInfo info, int oldSupportedTypes) {
        final int newSupportedTypes = info.mSupportedTypes;
        for (CallbackInfo cbi : sStatic.mCallbacks) {
            // Reconstruct some of the history for callbacks that may not have observed
            // all of the events needed to correctly interpret the current state.
            // FIXME: This is a strong signal that we should deprecate route type filtering
            // completely in the future because it can lead to inconsistencies in
            // applications.
            final boolean oldVisibility = cbi.filterRouteEvent(oldSupportedTypes);
            final boolean newVisibility = cbi.filterRouteEvent(newSupportedTypes);
            if (!oldVisibility && newVisibility) {
                cbi.cb.onRouteAdded(cbi.router, info);
                if (info.isSelected()) {
                    cbi.cb.onRouteSelected(cbi.router, newSupportedTypes, info);
                }
            }
            if (oldVisibility || newVisibility) {
                cbi.cb.onRouteChanged(cbi.router, info);
            }
            if (oldVisibility && !newVisibility) {
                if (info.isSelected()) {
                    cbi.cb.onRouteUnselected(cbi.router, oldSupportedTypes, info);
                }
                cbi.cb.onRouteRemoved(cbi.router, info);
            }
        }
    }

    static void dispatchRouteAdded(RouteInfo info) {
        for (CallbackInfo cbi : sStatic.mCallbacks) {
            if (cbi.filterRouteEvent(info)) {
                cbi.cb.onRouteAdded(cbi.router, info);
            }
        }
    }

    static void dispatchRouteRemoved(RouteInfo info) {
        for (CallbackInfo cbi : sStatic.mCallbacks) {
            if (cbi.filterRouteEvent(info)) {
                cbi.cb.onRouteRemoved(cbi.router, info);
            }
        }
    }

    static void dispatchRouteGrouped(RouteInfo info, RouteGroup group, int index) {
        for (CallbackInfo cbi : sStatic.mCallbacks) {
            if (cbi.filterRouteEvent(group)) {
                cbi.cb.onRouteGrouped(cbi.router, info, group, index);
            }
        }
    }

    static void dispatchRouteUngrouped(RouteInfo info, RouteGroup group) {
        for (CallbackInfo cbi : sStatic.mCallbacks) {
            if (cbi.filterRouteEvent(group)) {
                cbi.cb.onRouteUngrouped(cbi.router, info, group);
            }
        }
    }

    static void dispatchRouteVolumeChanged(RouteInfo info) {
        for (CallbackInfo cbi : sStatic.mCallbacks) {
            if (cbi.filterRouteEvent(info)) {
                cbi.cb.onRouteVolumeChanged(cbi.router, info);
            }
        }
    }

    static void dispatchRoutePresentationDisplayChanged(RouteInfo info) {
        for (CallbackInfo cbi : sStatic.mCallbacks) {
            if (cbi.filterRouteEvent(info)) {
                cbi.cb.onRoutePresentationDisplayChanged(cbi.router, info);
            }
        }
    }

    static void systemVolumeChanged(int newValue) {
        final RouteInfo selectedRoute = sStatic.mSelectedRoute;
        if (selectedRoute == null) return;

        if (selectedRoute == sStatic.mBluetoothA2dpRoute ||
                selectedRoute == sStatic.mDefaultAudioVideo) {
            dispatchRouteVolumeChanged(selectedRoute);
        } else if (sStatic.mBluetoothA2dpRoute != null) {
            try {
                dispatchRouteVolumeChanged(sStatic.mAudioService.isBluetoothA2dpOn() ?
                        sStatic.mBluetoothA2dpRoute : sStatic.mDefaultAudioVideo);
            } catch (RemoteException e) {
                Log.e(TAG, "Error checking Bluetooth A2DP state to report volume change", e);
            }
        } else {
            dispatchRouteVolumeChanged(sStatic.mDefaultAudioVideo);
        }
    }

    static void updateWifiDisplayStatus(WifiDisplayStatus status) {
        WifiDisplay[] displays;
        WifiDisplay activeDisplay;
        if (status.getFeatureState() == WifiDisplayStatus.FEATURE_STATE_ON) {
            displays = status.getDisplays();
            activeDisplay = status.getActiveDisplay();

            // Only the system is able to connect to wifi display routes.
            // The display manager will enforce this with a permission check but it
            // still publishes information about all available displays.
            // Filter the list down to just the active display.
            if (!sStatic.mCanConfigureWifiDisplays) {
                if (activeDisplay != null) {
                    displays = new WifiDisplay[] { activeDisplay };
                } else {
                    displays = WifiDisplay.EMPTY_ARRAY;
                }
            }
        } else {
            displays = WifiDisplay.EMPTY_ARRAY;
            activeDisplay = null;
        }
        String activeDisplayAddress = activeDisplay != null ?
                activeDisplay.getDeviceAddress() : null;

        // Add or update routes.
        for (int i = 0; i < displays.length; i++) {
            final WifiDisplay d = displays[i];
            if (shouldShowWifiDisplay(d, activeDisplay)) {
                RouteInfo route = findWifiDisplayRoute(d);
                if (route == null) {
                    route = makeWifiDisplayRoute(d, status);
                    addRouteStatic(route);
                } else {
                    String address = d.getDeviceAddress();
                    boolean disconnected = !address.equals(activeDisplayAddress)
                            && address.equals(sStatic.mPreviousActiveWifiDisplayAddress);
                    updateWifiDisplayRoute(route, d, status, disconnected);
                }
                if (d.equals(activeDisplay)) {
                    selectRouteStatic(route.getSupportedTypes(), route, false);
                }
            }
        }

        // Remove stale routes.
        for (int i = sStatic.mRoutes.size(); i-- > 0; ) {
            RouteInfo route = sStatic.mRoutes.get(i);
            if (route.mDeviceAddress != null) {
                WifiDisplay d = findWifiDisplay(displays, route.mDeviceAddress);
                if (d == null || !shouldShowWifiDisplay(d, activeDisplay)) {
                    removeRouteStatic(route);
                }
            }
        }

        // Remember the current active wifi display address so that we can infer disconnections.
        // TODO: This hack will go away once all of this is moved into the media router service.
        sStatic.mPreviousActiveWifiDisplayAddress = activeDisplayAddress;
    }

    private static boolean shouldShowWifiDisplay(WifiDisplay d, WifiDisplay activeDisplay) {
        return d.isRemembered() || d.equals(activeDisplay);
    }

    static int getWifiDisplayStatusCode(WifiDisplay d, WifiDisplayStatus wfdStatus) {
        int newStatus;
        if (wfdStatus.getScanState() == WifiDisplayStatus.SCAN_STATE_SCANNING) {
            newStatus = RouteInfo.STATUS_SCANNING;
        } else if (d.isAvailable()) {
            newStatus = d.canConnect() ?
                    RouteInfo.STATUS_AVAILABLE: RouteInfo.STATUS_IN_USE;
        } else {
            newStatus = RouteInfo.STATUS_NOT_AVAILABLE;
        }

        if (d.equals(wfdStatus.getActiveDisplay())) {
            final int activeState = wfdStatus.getActiveDisplayState();
            switch (activeState) {
                case WifiDisplayStatus.DISPLAY_STATE_CONNECTED:
                    newStatus = RouteInfo.STATUS_CONNECTED;
                    break;
                case WifiDisplayStatus.DISPLAY_STATE_CONNECTING:
                    newStatus = RouteInfo.STATUS_CONNECTING;
                    break;
                case WifiDisplayStatus.DISPLAY_STATE_NOT_CONNECTED:
                    Log.e(TAG, "Active display is not connected!");
                    break;
            }
        }

        return newStatus;
    }

    static boolean isWifiDisplayEnabled(WifiDisplay d, WifiDisplayStatus wfdStatus) {
        return d.isAvailable() && (d.canConnect() || d.equals(wfdStatus.getActiveDisplay()));
    }

    static RouteInfo makeWifiDisplayRoute(WifiDisplay display, WifiDisplayStatus wfdStatus) {
        final RouteInfo newRoute = new RouteInfo(sStatic.mSystemCategory);
        newRoute.mDeviceAddress = display.getDeviceAddress();
        newRoute.mSupportedTypes = ROUTE_TYPE_LIVE_AUDIO | ROUTE_TYPE_LIVE_VIDEO
                | ROUTE_TYPE_REMOTE_DISPLAY;
        newRoute.mVolumeHandling = RouteInfo.PLAYBACK_VOLUME_FIXED;
        newRoute.mPlaybackType = RouteInfo.PLAYBACK_TYPE_REMOTE;

        newRoute.setRealStatusCode(getWifiDisplayStatusCode(display, wfdStatus));
        newRoute.mEnabled = isWifiDisplayEnabled(display, wfdStatus);
        newRoute.mName = display.getFriendlyDisplayName();
        newRoute.mDescription = sStatic.mResources.getText(
                com.android.internal.R.string.wireless_display_route_description);
        newRoute.updatePresentationDisplay();
        return newRoute;
    }

    private static void updateWifiDisplayRoute(
            RouteInfo route, WifiDisplay display, WifiDisplayStatus wfdStatus,
            boolean disconnected) {
        boolean changed = false;
        final String newName = display.getFriendlyDisplayName();
        if (!route.getName().equals(newName)) {
            route.mName = newName;
            changed = true;
        }

        boolean enabled = isWifiDisplayEnabled(display, wfdStatus);
        changed |= route.mEnabled != enabled;
        route.mEnabled = enabled;

        changed |= route.setRealStatusCode(getWifiDisplayStatusCode(display, wfdStatus));

        if (changed) {
            dispatchRouteChanged(route);
        }

        if ((!enabled || disconnected) && route.isSelected()) {
            // Oops, no longer available. Reselect the default.
            selectDefaultRouteStatic();
        }
    }

    private static WifiDisplay findWifiDisplay(WifiDisplay[] displays, String deviceAddress) {
        for (int i = 0; i < displays.length; i++) {
            final WifiDisplay d = displays[i];
            if (d.getDeviceAddress().equals(deviceAddress)) {
                return d;
            }
        }
        return null;
    }

    private static RouteInfo findWifiDisplayRoute(WifiDisplay d) {
        final int count = sStatic.mRoutes.size();
        for (int i = 0; i < count; i++) {
            final RouteInfo info = sStatic.mRoutes.get(i);
            if (d.getDeviceAddress().equals(info.mDeviceAddress)) {
                return info;
            }
        }
        return null;
    }

    /**
     * Information about a media route.
     */
    public static class RouteInfo {
        CharSequence mName;
        int mNameResId;
        CharSequence mDescription;
        private CharSequence mStatus;
        int mSupportedTypes;
        RouteGroup mGroup;
        final RouteCategory mCategory;
        Drawable mIcon;
        // playback information
        int mPlaybackType = PLAYBACK_TYPE_LOCAL;
        int mVolumeMax = RemoteControlClient.DEFAULT_PLAYBACK_VOLUME;
        int mVolume = RemoteControlClient.DEFAULT_PLAYBACK_VOLUME;
        int mVolumeHandling = RemoteControlClient.DEFAULT_PLAYBACK_VOLUME_HANDLING;
        int mPlaybackStream = AudioManager.STREAM_MUSIC;
        VolumeCallbackInfo mVcb;
        Display mPresentationDisplay;
        int mPresentationDisplayId = -1;

        String mDeviceAddress;
        boolean mEnabled = true;

        // An id by which the route is known to the media router service.
        // Null if this route only exists as an artifact within this process.
        String mGlobalRouteId;

        // A predetermined connection status that can override mStatus
        private int mRealStatusCode;
        private int mResolvedStatusCode;

        /** @hide */ public static final int STATUS_NONE = 0;
        /** @hide */ public static final int STATUS_SCANNING = 1;
        /** @hide */ public static final int STATUS_CONNECTING = 2;
        /** @hide */ public static final int STATUS_AVAILABLE = 3;
        /** @hide */ public static final int STATUS_NOT_AVAILABLE = 4;
        /** @hide */ public static final int STATUS_IN_USE = 5;
        /** @hide */ public static final int STATUS_CONNECTED = 6;

        private Object mTag;

        /**
         * The default playback type, "local", indicating the presentation of the media is happening
         * on the same device (e&#46;g&#46; a phone, a tablet) as where it is controlled from.
         * @see #getPlaybackType()
         */
        public final static int PLAYBACK_TYPE_LOCAL = 0;
        /**
         * A playback type indicating the presentation of the media is happening on
         * a different device (i&#46;e&#46; the remote device) than where it is controlled from.
         * @see #getPlaybackType()
         */
        public final static int PLAYBACK_TYPE_REMOTE = 1;
        /**
         * Playback information indicating the playback volume is fixed, i&#46;e&#46; it cannot be
         * controlled from this object. An example of fixed playback volume is a remote player,
         * playing over HDMI where the user prefers to control the volume on the HDMI sink, rather
         * than attenuate at the source.
         * @see #getVolumeHandling()
         */
        public final static int PLAYBACK_VOLUME_FIXED = 0;
        /**
         * Playback information indicating the playback volume is variable and can be controlled
         * from this object.
         * @see #getVolumeHandling()
         */
        public final static int PLAYBACK_VOLUME_VARIABLE = 1;

        RouteInfo(RouteCategory category) {
            mCategory = category;
        }

        /**
         * Gets the user-visible name of the route.
         * <p>
         * The route name identifies the destination represented by the route.
         * It may be a user-supplied name, an alias, or device serial number.
         * </p>
         *
         * @return The user-visible name of a media route.  This is the string presented
         * to users who may select this as the active route.
         */
        public CharSequence getName() {
            return getName(sStatic.mResources);
        }

        /**
         * Return the properly localized/resource user-visible name of this route.
         * <p>
         * The route name identifies the destination represented by the route.
         * It may be a user-supplied name, an alias, or device serial number.
         * </p>
         *
         * @param context Context used to resolve the correct configuration to load
         * @return The user-visible name of a media route.  This is the string presented
         * to users who may select this as the active route.
         */
        public CharSequence getName(Context context) {
            return getName(context.getResources());
        }

        CharSequence getName(Resources res) {
            if (mNameResId != 0) {
                return mName = res.getText(mNameResId);
            }
            return mName;
        }

        /**
         * Gets the user-visible description of the route.
         * <p>
         * The route description describes the kind of destination represented by the route.
         * It may be a user-supplied string, a model number or brand of device.
         * </p>
         *
         * @return The description of the route, or null if none.
         */
        public CharSequence getDescription() {
            return mDescription;
        }

        /**
         * @return The user-visible status for a media route. This may include a description
         * of the currently playing media, if available.
         */
        public CharSequence getStatus() {
            return mStatus;
        }

        /**
         * Set this route's status by predetermined status code. If the caller
         * should dispatch a route changed event this call will return true;
         */
        boolean setRealStatusCode(int statusCode) {
            if (mRealStatusCode != statusCode) {
                mRealStatusCode = statusCode;
                return resolveStatusCode();
            }
            return false;
        }

        /**
         * Resolves the status code whenever the real status code or selection state
         * changes.
         */
        boolean resolveStatusCode() {
            int statusCode = mRealStatusCode;
            if (isSelected()) {
                switch (statusCode) {
                    // If the route is selected and its status appears to be between states
                    // then report it as connecting even though it has not yet had a chance
                    // to officially move into the CONNECTING state.  Note that routes in
                    // the NONE state are assumed to not require an explicit connection
                    // lifecycle whereas those that are AVAILABLE are assumed to have
                    // to eventually proceed to CONNECTED.
                    case STATUS_AVAILABLE:
                    case STATUS_SCANNING:
                        statusCode = STATUS_CONNECTING;
                        break;
                }
            }
            if (mResolvedStatusCode == statusCode) {
                return false;
            }

            mResolvedStatusCode = statusCode;
            int resId;
            switch (statusCode) {
                case STATUS_SCANNING:
                    resId = com.android.internal.R.string.media_route_status_scanning;
                    break;
                case STATUS_CONNECTING:
                    resId = com.android.internal.R.string.media_route_status_connecting;
                    break;
                case STATUS_AVAILABLE:
                    resId = com.android.internal.R.string.media_route_status_available;
                    break;
                case STATUS_NOT_AVAILABLE:
                    resId = com.android.internal.R.string.media_route_status_not_available;
                    break;
                case STATUS_IN_USE:
                    resId = com.android.internal.R.string.media_route_status_in_use;
                    break;
                case STATUS_CONNECTED:
                case STATUS_NONE:
                default:
                    resId = 0;
                    break;
            }
            mStatus = resId != 0 ? sStatic.mResources.getText(resId) : null;
            return true;
        }

        /**
         * @hide
         */
        public int getStatusCode() {
            return mResolvedStatusCode;
        }

        /**
         * @return A media type flag set describing which types this route supports.
         */
        public int getSupportedTypes() {
            return mSupportedTypes;
        }

        /** @hide */
        public boolean matchesTypes(int types) {
            return (mSupportedTypes & types) != 0;
        }

        /**
         * @return The group that this route belongs to.
         */
        public RouteGroup getGroup() {
            return mGroup;
        }

        /**
         * @return the category this route belongs to.
         */
        public RouteCategory getCategory() {
            return mCategory;
        }

        /**
         * Get the icon representing this route.
         * This icon will be used in picker UIs if available.
         *
         * @return the icon representing this route or null if no icon is available
         */
        public Drawable getIconDrawable() {
            return mIcon;
        }

        /**
         * Set an application-specific tag object for this route.
         * The application may use this to store arbitrary data associated with the
         * route for internal tracking.
         *
         * <p>Note that the lifespan of a route may be well past the lifespan of
         * an Activity or other Context; take care that objects you store here
         * will not keep more data in memory alive than you intend.</p>
         *
         * @param tag Arbitrary, app-specific data for this route to hold for later use
         */
        public void setTag(Object tag) {
            mTag = tag;
            routeUpdated();
        }

        /**
         * @return The tag object previously set by the application
         * @see #setTag(Object)
         */
        public Object getTag() {
            return mTag;
        }

        /**
         * @return the type of playback associated with this route
         * @see UserRouteInfo#setPlaybackType(int)
         */
        public int getPlaybackType() {
            return mPlaybackType;
        }

        /**
         * @return the stream over which the playback associated with this route is performed
         * @see UserRouteInfo#setPlaybackStream(int)
         */
        public int getPlaybackStream() {
            return mPlaybackStream;
        }

        /**
         * Return the current volume for this route. Depending on the route, this may only
         * be valid if the route is currently selected.
         *
         * @return the volume at which the playback associated with this route is performed
         * @see UserRouteInfo#setVolume(int)
         */
        public int getVolume() {
            if (mPlaybackType == PLAYBACK_TYPE_LOCAL) {
                int vol = 0;
                try {
                    vol = sStatic.mAudioService.getStreamVolume(mPlaybackStream);
                } catch (RemoteException e) {
                    Log.e(TAG, "Error getting local stream volume", e);
                }
                return vol;
            } else {
                return mVolume;
            }
        }

        /**
         * Request a volume change for this route.
         * @param volume value between 0 and getVolumeMax
         */
        public void requestSetVolume(int volume) {
            if (mPlaybackType == PLAYBACK_TYPE_LOCAL) {
                try {
                    sStatic.mAudioService.setStreamVolume(mPlaybackStream, volume, 0,
                            ActivityThread.currentPackageName());
                } catch (RemoteException e) {
                    Log.e(TAG, "Error setting local stream volume", e);
                }
            } else {
                sStatic.requestSetVolume(this, volume);
            }
        }

        /**
         * Request an incremental volume update for this route.
         * @param direction Delta to apply to the current volume
         */
        public void requestUpdateVolume(int direction) {
            if (mPlaybackType == PLAYBACK_TYPE_LOCAL) {
                try {
                    final int volume =
                            Math.max(0, Math.min(getVolume() + direction, getVolumeMax()));
                    sStatic.mAudioService.setStreamVolume(mPlaybackStream, volume, 0,
                            ActivityThread.currentPackageName());
                } catch (RemoteException e) {
                    Log.e(TAG, "Error setting local stream volume", e);
                }
            } else {
                sStatic.requestUpdateVolume(this, direction);
            }
        }

        /**
         * @return the maximum volume at which the playback associated with this route is performed
         * @see UserRouteInfo#setVolumeMax(int)
         */
        public int getVolumeMax() {
            if (mPlaybackType == PLAYBACK_TYPE_LOCAL) {
                int volMax = 0;
                try {
                    volMax = sStatic.mAudioService.getStreamMaxVolume(mPlaybackStream);
                } catch (RemoteException e) {
                    Log.e(TAG, "Error getting local stream volume", e);
                }
                return volMax;
            } else {
                return mVolumeMax;
            }
        }

        /**
         * @return how volume is handling on the route
         * @see UserRouteInfo#setVolumeHandling(int)
         */
        public int getVolumeHandling() {
            return mVolumeHandling;
        }

        /**
         * Gets the {@link Display} that should be used by the application to show
         * a {@link android.app.Presentation} on an external display when this route is selected.
         * Depending on the route, this may only be valid if the route is currently
         * selected.
         * <p>
         * The preferred presentation display may change independently of the route
         * being selected or unselected.  For example, the presentation display
         * of the default system route may change when an external HDMI display is connected
         * or disconnected even though the route itself has not changed.
         * </p><p>
         * This method may return null if there is no external display associated with
         * the route or if the display is not ready to show UI yet.
         * </p><p>
         * The application should listen for changes to the presentation display
         * using the {@link Callback#onRoutePresentationDisplayChanged} callback and
         * show or dismiss its {@link android.app.Presentation} accordingly when the display
         * becomes available or is removed.
         * </p><p>
         * This method only makes sense for {@link #ROUTE_TYPE_LIVE_VIDEO live video} routes.
         * </p>
         *
         * @return The preferred presentation display to use when this route is
         * selected or null if none.
         *
         * @see #ROUTE_TYPE_LIVE_VIDEO
         * @see android.app.Presentation
         */
        public Display getPresentationDisplay() {
            return mPresentationDisplay;
        }

        boolean updatePresentationDisplay() {
            Display display = choosePresentationDisplay();
            if (mPresentationDisplay != display) {
                mPresentationDisplay = display;
                return true;
            }
            return false;
        }

        private Display choosePresentationDisplay() {
            if ((mSupportedTypes & ROUTE_TYPE_LIVE_VIDEO) != 0) {
                Display[] displays = sStatic.getAllPresentationDisplays();

                // Ensure that the specified display is valid for presentations.
                // This check will normally disallow the default display unless it was
                // configured as a presentation display for some reason.
                if (mPresentationDisplayId >= 0) {
                    for (Display display : displays) {
                        if (display.getDisplayId() == mPresentationDisplayId) {
                            return display;
                        }
                    }
                    return null;
                }

                // Find the indicated Wifi display by its address.
                if (mDeviceAddress != null) {
                    for (Display display : displays) {
                        if (display.getType() == Display.TYPE_WIFI
                                && mDeviceAddress.equals(display.getAddress())) {
                            return display;
                        }
                    }
                    return null;
                }

                // For the default route, choose the first presentation display from the list.
                if (this == sStatic.mDefaultAudioVideo && displays.length > 0) {
                    return displays[0];
                }
            }
            return null;
        }

        /** @hide */
        public String getDeviceAddress() {
            return mDeviceAddress;
        }

        /**
         * Returns true if this route is enabled and may be selected.
         *
         * @return True if this route is enabled.
         */
        public boolean isEnabled() {
            return mEnabled;
        }

        /**
         * Returns true if the route is in the process of connecting and is not
         * yet ready for use.
         *
         * @return True if this route is in the process of connecting.
         */
        public boolean isConnecting() {
            return mResolvedStatusCode == STATUS_CONNECTING;
        }

        /** @hide */
        public boolean isSelected() {
            return this == sStatic.mSelectedRoute;
        }

        /** @hide */
        public boolean isDefault() {
            return this == sStatic.mDefaultAudioVideo;
        }

        /** @hide */
        public void select() {
            selectRouteStatic(mSupportedTypes, this, true);
        }

        void setStatusInt(CharSequence status) {
            if (!status.equals(mStatus)) {
                mStatus = status;
                if (mGroup != null) {
                    mGroup.memberStatusChanged(this, status);
                }
                routeUpdated();
            }
        }

        final IRemoteVolumeObserver.Stub mRemoteVolObserver = new IRemoteVolumeObserver.Stub() {
            @Override
            public void dispatchRemoteVolumeUpdate(final int direction, final int value) {
                sStatic.mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        if (mVcb != null) {
                            if (direction != 0) {
                                mVcb.vcb.onVolumeUpdateRequest(mVcb.route, direction);
                            } else {
                                mVcb.vcb.onVolumeSetRequest(mVcb.route, value);
                            }
                        }
                    }
                });
            }
        };

        void routeUpdated() {
            updateRoute(this);
        }

        @Override
        public String toString() {
            String supportedTypes = typesToString(getSupportedTypes());
            return getClass().getSimpleName() + "{ name=" + getName() +
                    ", description=" + getDescription() +
                    ", status=" + getStatus() +
                    ", category=" + getCategory() +
                    ", supportedTypes=" + supportedTypes +
                    ", presentationDisplay=" + mPresentationDisplay + " }";
        }
    }

    /**
     * Information about a route that the application may define and modify.
     * A user route defaults to {@link RouteInfo#PLAYBACK_TYPE_REMOTE} and
     * {@link RouteInfo#PLAYBACK_VOLUME_FIXED}.
     *
     * @see MediaRouter.RouteInfo
     */
    public static class UserRouteInfo extends RouteInfo {
        RemoteControlClient mRcc;
        SessionVolumeProvider mSvp;

        UserRouteInfo(RouteCategory category) {
            super(category);
            mSupportedTypes = ROUTE_TYPE_USER;
            mPlaybackType = PLAYBACK_TYPE_REMOTE;
            mVolumeHandling = PLAYBACK_VOLUME_FIXED;
        }

        /**
         * Set the user-visible name of this route.
         * @param name Name to display to the user to describe this route
         */
        public void setName(CharSequence name) {
            mName = name;
            routeUpdated();
        }

        /**
         * Set the user-visible name of this route.
         * <p>
         * The route name identifies the destination represented by the route.
         * It may be a user-supplied name, an alias, or device serial number.
         * </p>
         *
         * @param resId Resource ID of the name to display to the user to describe this route
         */
        public void setName(int resId) {
            mNameResId = resId;
            mName = null;
            routeUpdated();
        }

        /**
         * Set the user-visible description of this route.
         * <p>
         * The route description describes the kind of destination represented by the route.
         * It may be a user-supplied string, a model number or brand of device.
         * </p>
         *
         * @param description The description of the route, or null if none.
         */
        public void setDescription(CharSequence description) {
            mDescription = description;
            routeUpdated();
        }

        /**
         * Set the current user-visible status for this route.
         * @param status Status to display to the user to describe what the endpoint
         * of this route is currently doing
         */
        public void setStatus(CharSequence status) {
            setStatusInt(status);
        }

        /**
         * Set the RemoteControlClient responsible for reporting playback info for this
         * user route.
         *
         * <p>If this route manages remote playback, the data exposed by this
         * RemoteControlClient will be used to reflect and update information
         * such as route volume info in related UIs.</p>
         *
         * <p>The RemoteControlClient must have been previously registered with
         * {@link AudioManager#registerRemoteControlClient(RemoteControlClient)}.</p>
         *
         * @param rcc RemoteControlClient associated with this route
         */
        public void setRemoteControlClient(RemoteControlClient rcc) {
            mRcc = rcc;
            updatePlaybackInfoOnRcc();
        }

        /**
         * Retrieve the RemoteControlClient associated with this route, if one has been set.
         *
         * @return the RemoteControlClient associated with this route
         * @see #setRemoteControlClient(RemoteControlClient)
         */
        public RemoteControlClient getRemoteControlClient() {
            return mRcc;
        }

        /**
         * Set an icon that will be used to represent this route.
         * The system may use this icon in picker UIs or similar.
         *
         * @param icon icon drawable to use to represent this route
         */
        public void setIconDrawable(Drawable icon) {
            mIcon = icon;
        }

        /**
         * Set an icon that will be used to represent this route.
         * The system may use this icon in picker UIs or similar.
         *
         * @param resId Resource ID of an icon drawable to use to represent this route
         */
        public void setIconResource(@DrawableRes int resId) {
            setIconDrawable(sStatic.mResources.getDrawable(resId));
        }

        /**
         * Set a callback to be notified of volume update requests
         * @param vcb
         */
        public void setVolumeCallback(VolumeCallback vcb) {
            mVcb = new VolumeCallbackInfo(vcb, this);
        }

        /**
         * Defines whether playback associated with this route is "local"
         *    ({@link RouteInfo#PLAYBACK_TYPE_LOCAL}) or "remote"
         *    ({@link RouteInfo#PLAYBACK_TYPE_REMOTE}).
         * @param type
         */
        public void setPlaybackType(int type) {
            if (mPlaybackType != type) {
                mPlaybackType = type;
                configureSessionVolume();
            }
        }

        /**
         * Defines whether volume for the playback associated with this route is fixed
         * ({@link RouteInfo#PLAYBACK_VOLUME_FIXED}) or can modified
         * ({@link RouteInfo#PLAYBACK_VOLUME_VARIABLE}).
         * @param volumeHandling
         */
        public void setVolumeHandling(int volumeHandling) {
            if (mVolumeHandling != volumeHandling) {
                mVolumeHandling = volumeHandling;
                configureSessionVolume();
            }
        }

        /**
         * Defines at what volume the playback associated with this route is performed (for user
         * feedback purposes). This information is only used when the playback is not local.
         * @param volume
         */
        public void setVolume(int volume) {
            volume = Math.max(0, Math.min(volume, getVolumeMax()));
            if (mVolume != volume) {
                mVolume = volume;
                if (mSvp != null) {
                    mSvp.setCurrentVolume(mVolume);
                }
                dispatchRouteVolumeChanged(this);
                if (mGroup != null) {
                    mGroup.memberVolumeChanged(this);
                }
            }
        }

        @Override
        public void requestSetVolume(int volume) {
            if (mVolumeHandling == PLAYBACK_VOLUME_VARIABLE) {
                if (mVcb == null) {
                    Log.e(TAG, "Cannot requestSetVolume on user route - no volume callback set");
                    return;
                }
                mVcb.vcb.onVolumeSetRequest(this, volume);
            }
        }

        @Override
        public void requestUpdateVolume(int direction) {
            if (mVolumeHandling == PLAYBACK_VOLUME_VARIABLE) {
                if (mVcb == null) {
                    Log.e(TAG, "Cannot requestChangeVolume on user route - no volumec callback set");
                    return;
                }
                mVcb.vcb.onVolumeUpdateRequest(this, direction);
            }
        }

        /**
         * Defines the maximum volume at which the playback associated with this route is performed
         * (for user feedback purposes). This information is only used when the playback is not
         * local.
         * @param volumeMax
         */
        public void setVolumeMax(int volumeMax) {
            if (mVolumeMax != volumeMax) {
                mVolumeMax = volumeMax;
                configureSessionVolume();
            }
        }

        /**
         * Defines over what stream type the media is presented.
         * @param stream
         */
        public void setPlaybackStream(int stream) {
            if (mPlaybackStream != stream) {
                mPlaybackStream = stream;
                configureSessionVolume();
            }
        }

        private void updatePlaybackInfoOnRcc() {
            configureSessionVolume();
        }

        private void configureSessionVolume() {
            if (mRcc == null) {
                if (DEBUG) {
                    Log.d(TAG, "No Rcc to configure volume for route " + mName);
                }
                return;
            }
            MediaSession session = mRcc.getMediaSession();
            if (session == null) {
                if (DEBUG) {
                    Log.d(TAG, "Rcc has no session to configure volume");
                }
                return;
            }
            if (mPlaybackType == RemoteControlClient.PLAYBACK_TYPE_REMOTE) {
                int volumeControl = VolumeProvider.VOLUME_CONTROL_FIXED;
                switch (mVolumeHandling) {
                    case RemoteControlClient.PLAYBACK_VOLUME_VARIABLE:
                        volumeControl = VolumeProvider.VOLUME_CONTROL_ABSOLUTE;
                        break;
                    case RemoteControlClient.PLAYBACK_VOLUME_FIXED:
                    default:
                        break;
                }
                // Only register a new listener if necessary
                if (mSvp == null || mSvp.getVolumeControl() != volumeControl
                        || mSvp.getMaxVolume() != mVolumeMax) {
                    mSvp = new SessionVolumeProvider(volumeControl, mVolumeMax, mVolume);
                    session.setPlaybackToRemote(mSvp);
                }
            } else {
                // We only know how to handle local and remote, fall back to local if not remote.
                AudioAttributes.Builder bob = new AudioAttributes.Builder();
                bob.setLegacyStreamType(mPlaybackStream);
                session.setPlaybackToLocal(bob.build());
                mSvp = null;
            }
        }

        class SessionVolumeProvider extends VolumeProvider {

            public SessionVolumeProvider(int volumeControl, int maxVolume, int currentVolume) {
                super(volumeControl, maxVolume, currentVolume);
            }

            @Override
            public void onSetVolumeTo(final int volume) {
                sStatic.mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        if (mVcb != null) {
                            mVcb.vcb.onVolumeSetRequest(mVcb.route, volume);
                        }
                    }
                });
            }

            @Override
            public void onAdjustVolume(final int direction) {
                sStatic.mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        if (mVcb != null) {
                            mVcb.vcb.onVolumeUpdateRequest(mVcb.route, direction);
                        }
                    }
                });
            }
        }
    }

    /**
     * Information about a route that consists of multiple other routes in a group.
     */
    public static class RouteGroup extends RouteInfo {
        final ArrayList<RouteInfo> mRoutes = new ArrayList<RouteInfo>();
        private boolean mUpdateName;

        RouteGroup(RouteCategory category) {
            super(category);
            mGroup = this;
            mVolumeHandling = PLAYBACK_VOLUME_FIXED;
        }

        @Override
        CharSequence getName(Resources res) {
            if (mUpdateName) updateName();
            return super.getName(res);
        }

        /**
         * Add a route to this group. The route must not currently belong to another group.
         *
         * @param route route to add to this group
         */
        public void addRoute(RouteInfo route) {
            if (route.getGroup() != null) {
                throw new IllegalStateException("Route " + route + " is already part of a group.");
            }
            if (route.getCategory() != mCategory) {
                throw new IllegalArgumentException(
                        "Route cannot be added to a group with a different category. " +
                            "(Route category=" + route.getCategory() +
                            " group category=" + mCategory + ")");
            }
            final int at = mRoutes.size();
            mRoutes.add(route);
            route.mGroup = this;
            mUpdateName = true;
            updateVolume();
            routeUpdated();
            dispatchRouteGrouped(route, this, at);
        }

        /**
         * Add a route to this group before the specified index.
         *
         * @param route route to add
         * @param insertAt insert the new route before this index
         */
        public void addRoute(RouteInfo route, int insertAt) {
            if (route.getGroup() != null) {
                throw new IllegalStateException("Route " + route + " is already part of a group.");
            }
            if (route.getCategory() != mCategory) {
                throw new IllegalArgumentException(
                        "Route cannot be added to a group with a different category. " +
                            "(Route category=" + route.getCategory() +
                            " group category=" + mCategory + ")");
            }
            mRoutes.add(insertAt, route);
            route.mGroup = this;
            mUpdateName = true;
            updateVolume();
            routeUpdated();
            dispatchRouteGrouped(route, this, insertAt);
        }

        /**
         * Remove a route from this group.
         *
         * @param route route to remove
         */
        public void removeRoute(RouteInfo route) {
            if (route.getGroup() != this) {
                throw new IllegalArgumentException("Route " + route +
                        " is not a member of this group.");
            }
            mRoutes.remove(route);
            route.mGroup = null;
            mUpdateName = true;
            updateVolume();
            dispatchRouteUngrouped(route, this);
            routeUpdated();
        }

        /**
         * Remove the route at the specified index from this group.
         *
         * @param index index of the route to remove
         */
        public void removeRoute(int index) {
            RouteInfo route = mRoutes.remove(index);
            route.mGroup = null;
            mUpdateName = true;
            updateVolume();
            dispatchRouteUngrouped(route, this);
            routeUpdated();
        }

        /**
         * @return The number of routes in this group
         */
        public int getRouteCount() {
            return mRoutes.size();
        }

        /**
         * Return the route in this group at the specified index
         *
         * @param index Index to fetch
         * @return The route at index
         */
        public RouteInfo getRouteAt(int index) {
            return mRoutes.get(index);
        }

        /**
         * Set an icon that will be used to represent this group.
         * The system may use this icon in picker UIs or similar.
         *
         * @param icon icon drawable to use to represent this group
         */
        public void setIconDrawable(Drawable icon) {
            mIcon = icon;
        }

        /**
         * Set an icon that will be used to represent this group.
         * The system may use this icon in picker UIs or similar.
         *
         * @param resId Resource ID of an icon drawable to use to represent this group
         */
        public void setIconResource(@DrawableRes int resId) {
            setIconDrawable(sStatic.mResources.getDrawable(resId));
        }

        @Override
        public void requestSetVolume(int volume) {
            final int maxVol = getVolumeMax();
            if (maxVol == 0) {
                return;
            }

            final float scaledVolume = (float) volume / maxVol;
            final int routeCount = getRouteCount();
            for (int i = 0; i < routeCount; i++) {
                final RouteInfo route = getRouteAt(i);
                final int routeVol = (int) (scaledVolume * route.getVolumeMax());
                route.requestSetVolume(routeVol);
            }
            if (volume != mVolume) {
                mVolume = volume;
                dispatchRouteVolumeChanged(this);
            }
        }

        @Override
        public void requestUpdateVolume(int direction) {
            final int maxVol = getVolumeMax();
            if (maxVol == 0) {
                return;
            }

            final int routeCount = getRouteCount();
            int volume = 0;
            for (int i = 0; i < routeCount; i++) {
                final RouteInfo route = getRouteAt(i);
                route.requestUpdateVolume(direction);
                final int routeVol = route.getVolume();
                if (routeVol > volume) {
                    volume = routeVol;
                }
            }
            if (volume != mVolume) {
                mVolume = volume;
                dispatchRouteVolumeChanged(this);
            }
        }

        void memberNameChanged(RouteInfo info, CharSequence name) {
            mUpdateName = true;
            routeUpdated();
        }

        void memberStatusChanged(RouteInfo info, CharSequence status) {
            setStatusInt(status);
        }

        void memberVolumeChanged(RouteInfo info) {
            updateVolume();
        }

        void updateVolume() {
            // A group always represents the highest component volume value.
            final int routeCount = getRouteCount();
            int volume = 0;
            for (int i = 0; i < routeCount; i++) {
                final int routeVol = getRouteAt(i).getVolume();
                if (routeVol > volume) {
                    volume = routeVol;
                }
            }
            if (volume != mVolume) {
                mVolume = volume;
                dispatchRouteVolumeChanged(this);
            }
        }

        @Override
        void routeUpdated() {
            int types = 0;
            final int count = mRoutes.size();
            if (count == 0) {
                // Don't keep empty groups in the router.
                MediaRouter.removeRouteStatic(this);
                return;
            }

            int maxVolume = 0;
            boolean isLocal = true;
            boolean isFixedVolume = true;
            for (int i = 0; i < count; i++) {
                final RouteInfo route = mRoutes.get(i);
                types |= route.mSupportedTypes;
                final int routeMaxVolume = route.getVolumeMax();
                if (routeMaxVolume > maxVolume) {
                    maxVolume = routeMaxVolume;
                }
                isLocal &= route.getPlaybackType() == PLAYBACK_TYPE_LOCAL;
                isFixedVolume &= route.getVolumeHandling() == PLAYBACK_VOLUME_FIXED;
            }
            mPlaybackType = isLocal ? PLAYBACK_TYPE_LOCAL : PLAYBACK_TYPE_REMOTE;
            mVolumeHandling = isFixedVolume ? PLAYBACK_VOLUME_FIXED : PLAYBACK_VOLUME_VARIABLE;
            mSupportedTypes = types;
            mVolumeMax = maxVolume;
            mIcon = count == 1 ? mRoutes.get(0).getIconDrawable() : null;
            super.routeUpdated();
        }

        void updateName() {
            final StringBuilder sb = new StringBuilder();
            final int count = mRoutes.size();
            for (int i = 0; i < count; i++) {
                final RouteInfo info = mRoutes.get(i);
                // TODO: There's probably a much more correct way to localize this.
                if (i > 0) sb.append(", ");
                sb.append(info.mName);
            }
            mName = sb.toString();
            mUpdateName = false;
        }

        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder(super.toString());
            sb.append('[');
            final int count = mRoutes.size();
            for (int i = 0; i < count; i++) {
                if (i > 0) sb.append(", ");
                sb.append(mRoutes.get(i));
            }
            sb.append(']');
            return sb.toString();
        }
    }

    /**
     * Definition of a category of routes. All routes belong to a category.
     */
    public static class RouteCategory {
        CharSequence mName;
        int mNameResId;
        int mTypes;
        final boolean mGroupable;
        boolean mIsSystem;

        RouteCategory(CharSequence name, int types, boolean groupable) {
            mName = name;
            mTypes = types;
            mGroupable = groupable;
        }

        RouteCategory(int nameResId, int types, boolean groupable) {
            mNameResId = nameResId;
            mTypes = types;
            mGroupable = groupable;
        }

        /**
         * @return the name of this route category
         */
        public CharSequence getName() {
            return getName(sStatic.mResources);
        }

        /**
         * Return the properly localized/configuration dependent name of this RouteCategory.
         *
         * @param context Context to resolve name resources
         * @return the name of this route category
         */
        public CharSequence getName(Context context) {
            return getName(context.getResources());
        }

        CharSequence getName(Resources res) {
            if (mNameResId != 0) {
                return res.getText(mNameResId);
            }
            return mName;
        }

        /**
         * Return the current list of routes in this category that have been added
         * to the MediaRouter.
         *
         * <p>This list will not include routes that are nested within RouteGroups.
         * A RouteGroup is treated as a single route within its category.</p>
         *
         * @param out a List to fill with the routes in this category. If this parameter is
         *            non-null, it will be cleared, filled with the current routes with this
         *            category, and returned. If this parameter is null, a new List will be
         *            allocated to report the category's current routes.
         * @return A list with the routes in this category that have been added to the MediaRouter.
         */
        public List<RouteInfo> getRoutes(List<RouteInfo> out) {
            if (out == null) {
                out = new ArrayList<RouteInfo>();
            } else {
                out.clear();
            }

            final int count = getRouteCountStatic();
            for (int i = 0; i < count; i++) {
                final RouteInfo route = getRouteAtStatic(i);
                if (route.mCategory == this) {
                    out.add(route);
                }
            }
            return out;
        }

        /**
         * @return Flag set describing the route types supported by this category
         */
        public int getSupportedTypes() {
            return mTypes;
        }

        /**
         * Return whether or not this category supports grouping.
         *
         * <p>If this method returns true, all routes obtained from this category
         * via calls to {@link #getRouteAt(int)} will be {@link MediaRouter.RouteGroup}s.</p>
         *
         * @return true if this category supports
         */
        public boolean isGroupable() {
            return mGroupable;
        }

        /**
         * @return true if this is the category reserved for system routes.
         * @hide
         */
        public boolean isSystem() {
            return mIsSystem;
        }

        @Override
        public String toString() {
            return "RouteCategory{ name=" + mName + " types=" + typesToString(mTypes) +
                    " groupable=" + mGroupable + " }";
        }
    }

    static class CallbackInfo {
        public int type;
        public int flags;
        public final Callback cb;
        public final MediaRouter router;

        public CallbackInfo(Callback cb, int type, int flags, MediaRouter router) {
            this.cb = cb;
            this.type = type;
            this.flags = flags;
            this.router = router;
        }

        public boolean filterRouteEvent(RouteInfo route) {
            return filterRouteEvent(route.mSupportedTypes);
        }

        public boolean filterRouteEvent(int supportedTypes) {
            return (flags & CALLBACK_FLAG_UNFILTERED_EVENTS) != 0
                    || (type & supportedTypes) != 0;
        }
    }

    /**
     * Interface for receiving events about media routing changes.
     * All methods of this interface will be called from the application's main thread.
     * <p>
     * A Callback will only receive events relevant to routes that the callback
     * was registered for unless the {@link MediaRouter#CALLBACK_FLAG_UNFILTERED_EVENTS}
     * flag was specified in {@link MediaRouter#addCallback(int, Callback, int)}.
     * </p>
     *
     * @see MediaRouter#addCallback(int, Callback, int)
     * @see MediaRouter#removeCallback(Callback)
     */
    public static abstract class Callback {
        /**
         * Called when the supplied route becomes selected as the active route
         * for the given route type.
         *
         * @param router the MediaRouter reporting the event
         * @param type Type flag set indicating the routes that have been selected
         * @param info Route that has been selected for the given route types
         */
        public abstract void onRouteSelected(MediaRouter router, int type, RouteInfo info);

        /**
         * Called when the supplied route becomes unselected as the active route
         * for the given route type.
         *
         * @param router the MediaRouter reporting the event
         * @param type Type flag set indicating the routes that have been unselected
         * @param info Route that has been unselected for the given route types
         */
        public abstract void onRouteUnselected(MediaRouter router, int type, RouteInfo info);

        /**
         * Called when a route for the specified type was added.
         *
         * @param router the MediaRouter reporting the event
         * @param info Route that has become available for use
         */
        public abstract void onRouteAdded(MediaRouter router, RouteInfo info);

        /**
         * Called when a route for the specified type was removed.
         *
         * @param router the MediaRouter reporting the event
         * @param info Route that has been removed from availability
         */
        public abstract void onRouteRemoved(MediaRouter router, RouteInfo info);

        /**
         * Called when an aspect of the indicated route has changed.
         *
         * <p>This will not indicate that the types supported by this route have
         * changed, only that cosmetic info such as name or status have been updated.</p>
         *
         * @param router the MediaRouter reporting the event
         * @param info The route that was changed
         */
        public abstract void onRouteChanged(MediaRouter router, RouteInfo info);

        /**
         * Called when a route is added to a group.
         *
         * @param router the MediaRouter reporting the event
         * @param info The route that was added
         * @param group The group the route was added to
         * @param index The route index within group that info was added at
         */
        public abstract void onRouteGrouped(MediaRouter router, RouteInfo info, RouteGroup group,
                int index);

        /**
         * Called when a route is removed from a group.
         *
         * @param router the MediaRouter reporting the event
         * @param info The route that was removed
         * @param group The group the route was removed from
         */
        public abstract void onRouteUngrouped(MediaRouter router, RouteInfo info, RouteGroup group);

        /**
         * Called when a route's volume changes.
         *
         * @param router the MediaRouter reporting the event
         * @param info The route with altered volume
         */
        public abstract void onRouteVolumeChanged(MediaRouter router, RouteInfo info);

        /**
         * Called when a route's presentation display changes.
         * <p>
         * This method is called whenever the route's presentation display becomes
         * available, is removes or has changes to some of its properties (such as its size).
         * </p>
         *
         * @param router the MediaRouter reporting the event
         * @param info The route whose presentation display changed
         *
         * @see RouteInfo#getPresentationDisplay()
         */
        public void onRoutePresentationDisplayChanged(MediaRouter router, RouteInfo info) {
        }
    }

    /**
     * Stub implementation of {@link MediaRouter.Callback}.
     * Each abstract method is defined as a no-op. Override just the ones
     * you need.
     */
    public static class SimpleCallback extends Callback {

        @Override
        public void onRouteSelected(MediaRouter router, int type, RouteInfo info) {
        }

        @Override
        public void onRouteUnselected(MediaRouter router, int type, RouteInfo info) {
        }

        @Override
        public void onRouteAdded(MediaRouter router, RouteInfo info) {
        }

        @Override
        public void onRouteRemoved(MediaRouter router, RouteInfo info) {
        }

        @Override
        public void onRouteChanged(MediaRouter router, RouteInfo info) {
        }

        @Override
        public void onRouteGrouped(MediaRouter router, RouteInfo info, RouteGroup group,
                int index) {
        }

        @Override
        public void onRouteUngrouped(MediaRouter router, RouteInfo info, RouteGroup group) {
        }

        @Override
        public void onRouteVolumeChanged(MediaRouter router, RouteInfo info) {
        }
    }

    static class VolumeCallbackInfo {
        public final VolumeCallback vcb;
        public final RouteInfo route;

        public VolumeCallbackInfo(VolumeCallback vcb, RouteInfo route) {
            this.vcb = vcb;
            this.route = route;
        }
    }

    /**
     * Interface for receiving events about volume changes.
     * All methods of this interface will be called from the application's main thread.
     *
     * <p>A VolumeCallback will only receive events relevant to routes that the callback
     * was registered for.</p>
     *
     * @see UserRouteInfo#setVolumeCallback(VolumeCallback)
     */
    public static abstract class VolumeCallback {
        /**
         * Called when the volume for the route should be increased or decreased.
         * @param info the route affected by this event
         * @param direction an integer indicating whether the volume is to be increased
         *     (positive value) or decreased (negative value).
         *     For bundled changes, the absolute value indicates the number of changes
         *     in the same direction, e.g. +3 corresponds to three "volume up" changes.
         */
        public abstract void onVolumeUpdateRequest(RouteInfo info, int direction);
        /**
         * Called when the volume for the route should be set to the given value
         * @param info the route affected by this event
         * @param volume an integer indicating the new volume value that should be used, always
         *     between 0 and the value set by {@link UserRouteInfo#setVolumeMax(int)}.
         */
        public abstract void onVolumeSetRequest(RouteInfo info, int volume);
    }

    static class VolumeChangeReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(AudioManager.VOLUME_CHANGED_ACTION)) {
                final int streamType = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE,
                        -1);
                if (streamType != AudioManager.STREAM_MUSIC) {
                    return;
                }

                final int newVolume = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, 0);
                final int oldVolume = intent.getIntExtra(
                        AudioManager.EXTRA_PREV_VOLUME_STREAM_VALUE, 0);
                if (newVolume != oldVolume) {
                    systemVolumeChanged(newVolume);
                }
            }
        }
    }

    static class WifiDisplayStatusChangedReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED)) {
                updateWifiDisplayStatus((WifiDisplayStatus) intent.getParcelableExtra(
                        DisplayManager.EXTRA_WIFI_DISPLAY_STATUS));
            }
        }
    }
}
