/*
 * Copyright 2018 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 com.android.support.mediarouter.media;

import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.util.ObjectsCompat;
import android.util.Log;

/**
 * A helper class for playing media on remote routes using the remote playback protocol
 * defined by {@link MediaControlIntent}.
 * <p>
 * The client maintains session state and offers a simplified interface for issuing
 * remote playback media control intents to a single route.
 * </p>
 */
public class RemotePlaybackClient {
    static final String TAG = "RemotePlaybackClient";
    static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);

    private final Context mContext;
    private final MediaRouter.RouteInfo mRoute;
    private final ActionReceiver mActionReceiver;
    private final PendingIntent mItemStatusPendingIntent;
    private final PendingIntent mSessionStatusPendingIntent;
    private final PendingIntent mMessagePendingIntent;

    private boolean mRouteSupportsRemotePlayback;
    private boolean mRouteSupportsQueuing;
    private boolean mRouteSupportsSessionManagement;
    private boolean mRouteSupportsMessaging;

    String mSessionId;
    StatusCallback mStatusCallback;
    OnMessageReceivedListener mOnMessageReceivedListener;

    /**
     * Creates a remote playback client for a route.
     *
     * @param route The media route.
     */
    public RemotePlaybackClient(Context context, MediaRouter.RouteInfo route) {
        if (context == null) {
            throw new IllegalArgumentException("context must not be null");
        }
        if (route == null) {
            throw new IllegalArgumentException("route must not be null");
        }

        mContext = context;
        mRoute = route;

        IntentFilter actionFilter = new IntentFilter();
        actionFilter.addAction(ActionReceiver.ACTION_ITEM_STATUS_CHANGED);
        actionFilter.addAction(ActionReceiver.ACTION_SESSION_STATUS_CHANGED);
        actionFilter.addAction(ActionReceiver.ACTION_MESSAGE_RECEIVED);
        mActionReceiver = new ActionReceiver();
        context.registerReceiver(mActionReceiver, actionFilter);

        Intent itemStatusIntent = new Intent(ActionReceiver.ACTION_ITEM_STATUS_CHANGED);
        itemStatusIntent.setPackage(context.getPackageName());
        mItemStatusPendingIntent = PendingIntent.getBroadcast(
                context, 0, itemStatusIntent, 0);

        Intent sessionStatusIntent = new Intent(ActionReceiver.ACTION_SESSION_STATUS_CHANGED);
        sessionStatusIntent.setPackage(context.getPackageName());
        mSessionStatusPendingIntent = PendingIntent.getBroadcast(
                context, 0, sessionStatusIntent, 0);

        Intent messageIntent = new Intent(ActionReceiver.ACTION_MESSAGE_RECEIVED);
        messageIntent.setPackage(context.getPackageName());
        mMessagePendingIntent = PendingIntent.getBroadcast(
                context, 0, messageIntent, 0);
        detectFeatures();
    }

    /**
     * Releases resources owned by the client.
     */
    public void release() {
        mContext.unregisterReceiver(mActionReceiver);
    }

    /**
     * Returns true if the route supports remote playback.
     * <p>
     * If the route does not support remote playback, then none of the functionality
     * offered by the client will be available.
     * </p><p>
     * This method returns true if the route supports all of the following
     * actions: {@link MediaControlIntent#ACTION_PLAY play},
     * {@link MediaControlIntent#ACTION_SEEK seek},
     * {@link MediaControlIntent#ACTION_GET_STATUS get status},
     * {@link MediaControlIntent#ACTION_PAUSE pause},
     * {@link MediaControlIntent#ACTION_RESUME resume},
     * {@link MediaControlIntent#ACTION_STOP stop}.
     * </p>
     *
     * @return True if remote playback is supported.
     */
    public boolean isRemotePlaybackSupported() {
        return mRouteSupportsRemotePlayback;
    }

    /**
     * Returns true if the route supports queuing features.
     * <p>
     * If the route does not support queuing, then at most one media item can be played
     * at a time and the {@link #enqueue} method will not be available.
     * </p><p>
     * This method returns true if the route supports all of the basic remote playback
     * actions and all of the following actions:
     * {@link MediaControlIntent#ACTION_ENQUEUE enqueue},
     * {@link MediaControlIntent#ACTION_REMOVE remove}.
     * </p>
     *
     * @return True if queuing is supported.  Implies {@link #isRemotePlaybackSupported}
     * is also true.
     *
     * @see #isRemotePlaybackSupported
     */
    public boolean isQueuingSupported() {
        return mRouteSupportsQueuing;
    }

    /**
     * Returns true if the route supports session management features.
     * <p>
     * If the route does not support session management, then the session will
     * not be created until the first media item is played.
     * </p><p>
     * This method returns true if the route supports all of the basic remote playback
     * actions and all of the following actions:
     * {@link MediaControlIntent#ACTION_START_SESSION start session},
     * {@link MediaControlIntent#ACTION_GET_SESSION_STATUS get session status},
     * {@link MediaControlIntent#ACTION_END_SESSION end session}.
     * </p>
     *
     * @return True if session management is supported.
     * Implies {@link #isRemotePlaybackSupported} is also true.
     *
     * @see #isRemotePlaybackSupported
     */
    public boolean isSessionManagementSupported() {
        return mRouteSupportsSessionManagement;
    }

    /**
     * Returns true if the route supports messages.
     * <p>
     * This method returns true if the route supports all of the basic remote playback
     * actions and all of the following actions:
     * {@link MediaControlIntent#ACTION_START_SESSION start session},
     * {@link MediaControlIntent#ACTION_SEND_MESSAGE send message},
     * {@link MediaControlIntent#ACTION_END_SESSION end session}.
     * </p>
     *
     * @return True if session management is supported.
     * Implies {@link #isRemotePlaybackSupported} is also true.
     *
     * @see #isRemotePlaybackSupported
     */
    public boolean isMessagingSupported() {
        return mRouteSupportsMessaging;
    }

    /**
     * Gets the current session id if there is one.
     *
     * @return The current session id, or null if none.
     */
    public String getSessionId() {
        return mSessionId;
    }

    /**
     * Sets the current session id.
     * <p>
     * It is usually not necessary to set the session id explicitly since
     * it is created as a side-effect of other requests such as
     * {@link #play}, {@link #enqueue}, and {@link #startSession}.
     * </p>
     *
     * @param sessionId The new session id, or null if none.
     */
    public void setSessionId(String sessionId) {
        if (!ObjectsCompat.equals(mSessionId, sessionId)) {
            if (DEBUG) {
                Log.d(TAG, "Session id is now: " + sessionId);
            }
            mSessionId = sessionId;
            if (mStatusCallback != null) {
                mStatusCallback.onSessionChanged(sessionId);
            }
        }
    }

    /**
     * Returns true if the client currently has a session.
     * <p>
     * Equivalent to checking whether {@link #getSessionId} returns a non-null result.
     * </p>
     *
     * @return True if there is a current session.
     */
    public boolean hasSession() {
        return mSessionId != null;
    }

    /**
     * Sets a callback that should receive status updates when the state of
     * media sessions or media items created by this instance of the remote
     * playback client changes.
     * <p>
     * The callback should be set before the session is created or any play
     * commands are issued.
     * </p>
     *
     * @param callback The callback to set.  May be null to remove the previous callback.
     */
    public void setStatusCallback(StatusCallback callback) {
        mStatusCallback = callback;
    }

    /**
     * Sets a callback that should receive messages when a message is sent from
     * media sessions created by this instance of the remote playback client changes.
     * <p>
     * The callback should be set before the session is created.
     * </p>
     *
     * @param listener The callback to set.  May be null to remove the previous callback.
     */
    public void setOnMessageReceivedListener(OnMessageReceivedListener listener) {
        mOnMessageReceivedListener = listener;
    }

    /**
     * Sends a request to play a media item.
     * <p>
     * Clears the queue and starts playing the new item immediately.  If the queue
     * was previously paused, then it is resumed as a side-effect of this request.
     * </p><p>
     * The request is issued in the current session.  If no session is available, then
     * one is created implicitly.
     * </p><p>
     * Please refer to {@link MediaControlIntent#ACTION_PLAY ACTION_PLAY} for
     * more information about the semantics of this request.
     * </p>
     *
     * @param contentUri The content Uri to play.
     * @param mimeType The mime type of the content, or null if unknown.
     * @param positionMillis The initial content position for the item in milliseconds,
     * or <code>0</code> to start at the beginning.
     * @param metadata The media item metadata bundle, or null if none.
     * @param extras A bundle of extra arguments to be added to the
     * {@link MediaControlIntent#ACTION_PLAY} intent, or null if none.
     * @param callback A callback to invoke when the request has been
     * processed, or null if none.
     *
     * @throws UnsupportedOperationException if the route does not support remote playback.
     *
     * @see MediaControlIntent#ACTION_PLAY
     * @see #isRemotePlaybackSupported
     */
    public void play(Uri contentUri, String mimeType, Bundle metadata,
            long positionMillis, Bundle extras, ItemActionCallback callback) {
        playOrEnqueue(contentUri, mimeType, metadata, positionMillis,
                extras, callback, MediaControlIntent.ACTION_PLAY);
    }

    /**
     * Sends a request to enqueue a media item.
     * <p>
     * Enqueues a new item to play.  If the queue was previously paused, then will
     * remain paused.
     * </p><p>
     * The request is issued in the current session.  If no session is available, then
     * one is created implicitly.
     * </p><p>
     * Please refer to {@link MediaControlIntent#ACTION_ENQUEUE ACTION_ENQUEUE} for
     * more information about the semantics of this request.
     * </p>
     *
     * @param contentUri The content Uri to enqueue.
     * @param mimeType The mime type of the content, or null if unknown.
     * @param positionMillis The initial content position for the item in milliseconds,
     * or <code>0</code> to start at the beginning.
     * @param metadata The media item metadata bundle, or null if none.
     * @param extras A bundle of extra arguments to be added to the
     * {@link MediaControlIntent#ACTION_ENQUEUE} intent, or null if none.
     * @param callback A callback to invoke when the request has been
     * processed, or null if none.
     *
     * @throws UnsupportedOperationException if the route does not support queuing.
     *
     * @see MediaControlIntent#ACTION_ENQUEUE
     * @see #isRemotePlaybackSupported
     * @see #isQueuingSupported
     */
    public void enqueue(Uri contentUri, String mimeType, Bundle metadata,
            long positionMillis, Bundle extras, ItemActionCallback callback) {
        playOrEnqueue(contentUri, mimeType, metadata, positionMillis,
                extras, callback, MediaControlIntent.ACTION_ENQUEUE);
    }

    private void playOrEnqueue(Uri contentUri, String mimeType, Bundle metadata,
            long positionMillis, Bundle extras,
            final ItemActionCallback callback, String action) {
        if (contentUri == null) {
            throw new IllegalArgumentException("contentUri must not be null");
        }
        throwIfRemotePlaybackNotSupported();
        if (action.equals(MediaControlIntent.ACTION_ENQUEUE)) {
            throwIfQueuingNotSupported();
        }

        Intent intent = new Intent(action);
        intent.setDataAndType(contentUri, mimeType);
        intent.putExtra(MediaControlIntent.EXTRA_ITEM_STATUS_UPDATE_RECEIVER,
                mItemStatusPendingIntent);
        if (metadata != null) {
            intent.putExtra(MediaControlIntent.EXTRA_ITEM_METADATA, metadata);
        }
        if (positionMillis != 0) {
            intent.putExtra(MediaControlIntent.EXTRA_ITEM_CONTENT_POSITION, positionMillis);
        }
        performItemAction(intent, mSessionId, null, extras, callback);
    }

    /**
     * Sends a request to seek to a new position in a media item.
     * <p>
     * Seeks to a new position.  If the queue was previously paused then it
     * remains paused but the item's new position is still remembered.
     * </p><p>
     * The request is issued in the current session.
     * </p><p>
     * Please refer to {@link MediaControlIntent#ACTION_SEEK ACTION_SEEK} for
     * more information about the semantics of this request.
     * </p>
     *
     * @param itemId The item id.
     * @param positionMillis The new content position for the item in milliseconds,
     * or <code>0</code> to start at the beginning.
     * @param extras A bundle of extra arguments to be added to the
     * {@link MediaControlIntent#ACTION_SEEK} intent, or null if none.
     * @param callback A callback to invoke when the request has been
     * processed, or null if none.
     *
     * @throws IllegalStateException if there is no current session.
     *
     * @see MediaControlIntent#ACTION_SEEK
     * @see #isRemotePlaybackSupported
     */
    public void seek(String itemId, long positionMillis, Bundle extras,
            ItemActionCallback callback) {
        if (itemId == null) {
            throw new IllegalArgumentException("itemId must not be null");
        }
        throwIfNoCurrentSession();

        Intent intent = new Intent(MediaControlIntent.ACTION_SEEK);
        intent.putExtra(MediaControlIntent.EXTRA_ITEM_CONTENT_POSITION, positionMillis);
        performItemAction(intent, mSessionId, itemId, extras, callback);
    }

    /**
     * Sends a request to get the status of a media item.
     * <p>
     * The request is issued in the current session.
     * </p><p>
     * Please refer to {@link MediaControlIntent#ACTION_GET_STATUS ACTION_GET_STATUS} for
     * more information about the semantics of this request.
     * </p>
     *
     * @param itemId The item id.
     * @param extras A bundle of extra arguments to be added to the
     * {@link MediaControlIntent#ACTION_GET_STATUS} intent, or null if none.
     * @param callback A callback to invoke when the request has been
     * processed, or null if none.
     *
     * @throws IllegalStateException if there is no current session.
     *
     * @see MediaControlIntent#ACTION_GET_STATUS
     * @see #isRemotePlaybackSupported
     */
    public void getStatus(String itemId, Bundle extras, ItemActionCallback callback) {
        if (itemId == null) {
            throw new IllegalArgumentException("itemId must not be null");
        }
        throwIfNoCurrentSession();

        Intent intent = new Intent(MediaControlIntent.ACTION_GET_STATUS);
        performItemAction(intent, mSessionId, itemId, extras, callback);
    }

    /**
     * Sends a request to remove a media item from the queue.
     * <p>
     * The request is issued in the current session.
     * </p><p>
     * Please refer to {@link MediaControlIntent#ACTION_REMOVE ACTION_REMOVE} for
     * more information about the semantics of this request.
     * </p>
     *
     * @param itemId The item id.
     * @param extras A bundle of extra arguments to be added to the
     * {@link MediaControlIntent#ACTION_REMOVE} intent, or null if none.
     * @param callback A callback to invoke when the request has been
     * processed, or null if none.
     *
     * @throws IllegalStateException if there is no current session.
     * @throws UnsupportedOperationException if the route does not support queuing.
     *
     * @see MediaControlIntent#ACTION_REMOVE
     * @see #isRemotePlaybackSupported
     * @see #isQueuingSupported
     */
    public void remove(String itemId, Bundle extras, ItemActionCallback callback) {
        if (itemId == null) {
            throw new IllegalArgumentException("itemId must not be null");
        }
        throwIfQueuingNotSupported();
        throwIfNoCurrentSession();

        Intent intent = new Intent(MediaControlIntent.ACTION_REMOVE);
        performItemAction(intent, mSessionId, itemId, extras, callback);
    }

    /**
     * Sends a request to pause media playback.
     * <p>
     * The request is issued in the current session.  If playback is already paused
     * then the request has no effect.
     * </p><p>
     * Please refer to {@link MediaControlIntent#ACTION_PAUSE ACTION_PAUSE} for
     * more information about the semantics of this request.
     * </p>
     *
     * @param extras A bundle of extra arguments to be added to the
     * {@link MediaControlIntent#ACTION_PAUSE} intent, or null if none.
     * @param callback A callback to invoke when the request has been
     * processed, or null if none.
     *
     * @throws IllegalStateException if there is no current session.
     *
     * @see MediaControlIntent#ACTION_PAUSE
     * @see #isRemotePlaybackSupported
     */
    public void pause(Bundle extras, SessionActionCallback callback) {
        throwIfNoCurrentSession();

        Intent intent = new Intent(MediaControlIntent.ACTION_PAUSE);
        performSessionAction(intent, mSessionId, extras, callback);
    }

    /**
     * Sends a request to resume (unpause) media playback.
     * <p>
     * The request is issued in the current session.  If playback is not paused
     * then the request has no effect.
     * </p><p>
     * Please refer to {@link MediaControlIntent#ACTION_RESUME ACTION_RESUME} for
     * more information about the semantics of this request.
     * </p>
     *
     * @param extras A bundle of extra arguments to be added to the
     * {@link MediaControlIntent#ACTION_RESUME} intent, or null if none.
     * @param callback A callback to invoke when the request has been
     * processed, or null if none.
     *
     * @throws IllegalStateException if there is no current session.
     *
     * @see MediaControlIntent#ACTION_RESUME
     * @see #isRemotePlaybackSupported
     */
    public void resume(Bundle extras, SessionActionCallback callback) {
        throwIfNoCurrentSession();

        Intent intent = new Intent(MediaControlIntent.ACTION_RESUME);
        performSessionAction(intent, mSessionId, extras, callback);
    }

    /**
     * Sends a request to stop media playback and clear the media playback queue.
     * <p>
     * The request is issued in the current session.  If the queue is already
     * empty then the request has no effect.
     * </p><p>
     * Please refer to {@link MediaControlIntent#ACTION_STOP ACTION_STOP} for
     * more information about the semantics of this request.
     * </p>
     *
     * @param extras A bundle of extra arguments to be added to the
     * {@link MediaControlIntent#ACTION_STOP} intent, or null if none.
     * @param callback A callback to invoke when the request has been
     * processed, or null if none.
     *
     * @throws IllegalStateException if there is no current session.
     *
     * @see MediaControlIntent#ACTION_STOP
     * @see #isRemotePlaybackSupported
     */
    public void stop(Bundle extras, SessionActionCallback callback) {
        throwIfNoCurrentSession();

        Intent intent = new Intent(MediaControlIntent.ACTION_STOP);
        performSessionAction(intent, mSessionId, extras, callback);
    }

    /**
     * Sends a request to start a new media playback session.
     * <p>
     * The application must wait for the callback to indicate that this request
     * is complete before issuing other requests that affect the session.  If this
     * request is successful then the previous session will be invalidated.
     * </p><p>
     * Please refer to {@link MediaControlIntent#ACTION_START_SESSION ACTION_START_SESSION}
     * for more information about the semantics of this request.
     * </p>
     *
     * @param extras A bundle of extra arguments to be added to the
     * {@link MediaControlIntent#ACTION_START_SESSION} intent, or null if none.
     * @param callback A callback to invoke when the request has been
     * processed, or null if none.
     *
     * @throws UnsupportedOperationException if the route does not support session management.
     *
     * @see MediaControlIntent#ACTION_START_SESSION
     * @see #isRemotePlaybackSupported
     * @see #isSessionManagementSupported
     */
    public void startSession(Bundle extras, SessionActionCallback callback) {
        throwIfSessionManagementNotSupported();

        Intent intent = new Intent(MediaControlIntent.ACTION_START_SESSION);
        intent.putExtra(MediaControlIntent.EXTRA_SESSION_STATUS_UPDATE_RECEIVER,
                mSessionStatusPendingIntent);
        if (mRouteSupportsMessaging) {
            intent.putExtra(MediaControlIntent.EXTRA_MESSAGE_RECEIVER, mMessagePendingIntent);
        }
        performSessionAction(intent, null, extras, callback);
    }

    /**
     * Sends a message.
     * <p>
     * The request is issued in the current session.
     * </p><p>
     * Please refer to {@link MediaControlIntent#ACTION_SEND_MESSAGE} for
     * more information about the semantics of this request.
     * </p>
     *
     * @param message A bundle message denoting {@link MediaControlIntent#EXTRA_MESSAGE}.
     * @param callback A callback to invoke when the request has been processed, or null if none.
     *
     * @throws IllegalStateException if there is no current session.
     * @throws UnsupportedOperationException if the route does not support messages.
     *
     * @see MediaControlIntent#ACTION_SEND_MESSAGE
     * @see #isMessagingSupported
     */
    public void sendMessage(Bundle message, SessionActionCallback callback) {
        throwIfNoCurrentSession();
        throwIfMessageNotSupported();

        Intent intent = new Intent(MediaControlIntent.ACTION_SEND_MESSAGE);
        performSessionAction(intent, mSessionId, message, callback);
    }

    /**
     * Sends a request to get the status of the media playback session.
     * <p>
     * The request is issued in the current session.
     * </p><p>
     * Please refer to {@link MediaControlIntent#ACTION_GET_SESSION_STATUS
     * ACTION_GET_SESSION_STATUS} for more information about the semantics of this request.
     * </p>
     *
     * @param extras A bundle of extra arguments to be added to the
     * {@link MediaControlIntent#ACTION_GET_SESSION_STATUS} intent, or null if none.
     * @param callback A callback to invoke when the request has been
     * processed, or null if none.
     *
     * @throws IllegalStateException if there is no current session.
     * @throws UnsupportedOperationException if the route does not support session management.
     *
     * @see MediaControlIntent#ACTION_GET_SESSION_STATUS
     * @see #isRemotePlaybackSupported
     * @see #isSessionManagementSupported
     */
    public void getSessionStatus(Bundle extras, SessionActionCallback callback) {
        throwIfSessionManagementNotSupported();
        throwIfNoCurrentSession();

        Intent intent = new Intent(MediaControlIntent.ACTION_GET_SESSION_STATUS);
        performSessionAction(intent, mSessionId, extras, callback);
    }

    /**
     * Sends a request to end the media playback session.
     * <p>
     * The request is issued in the current session.  If this request is successful,
     * the {@link #getSessionId session id property} will be set to null after
     * the callback is invoked.
     * </p><p>
     * Please refer to {@link MediaControlIntent#ACTION_END_SESSION ACTION_END_SESSION}
     * for more information about the semantics of this request.
     * </p>
     *
     * @param extras A bundle of extra arguments to be added to the
     * {@link MediaControlIntent#ACTION_END_SESSION} intent, or null if none.
     * @param callback A callback to invoke when the request has been
     * processed, or null if none.
     *
     * @throws IllegalStateException if there is no current session.
     * @throws UnsupportedOperationException if the route does not support session management.
     *
     * @see MediaControlIntent#ACTION_END_SESSION
     * @see #isRemotePlaybackSupported
     * @see #isSessionManagementSupported
     */
    public void endSession(Bundle extras, SessionActionCallback callback) {
        throwIfSessionManagementNotSupported();
        throwIfNoCurrentSession();

        Intent intent = new Intent(MediaControlIntent.ACTION_END_SESSION);
        performSessionAction(intent, mSessionId, extras, callback);
    }

    private void performItemAction(final Intent intent,
            final String sessionId, final String itemId,
            Bundle extras, final ItemActionCallback callback) {
        intent.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK);
        if (sessionId != null) {
            intent.putExtra(MediaControlIntent.EXTRA_SESSION_ID, sessionId);
        }
        if (itemId != null) {
            intent.putExtra(MediaControlIntent.EXTRA_ITEM_ID, itemId);
        }
        if (extras != null) {
            intent.putExtras(extras);
        }
        logRequest(intent);
        mRoute.sendControlRequest(intent, new MediaRouter.ControlRequestCallback() {
            @Override
            public void onResult(Bundle data) {
                if (data != null) {
                    String sessionIdResult = inferMissingResult(sessionId,
                            data.getString(MediaControlIntent.EXTRA_SESSION_ID));
                    MediaSessionStatus sessionStatus = MediaSessionStatus.fromBundle(
                            data.getBundle(MediaControlIntent.EXTRA_SESSION_STATUS));
                    String itemIdResult = inferMissingResult(itemId,
                            data.getString(MediaControlIntent.EXTRA_ITEM_ID));
                    MediaItemStatus itemStatus = MediaItemStatus.fromBundle(
                            data.getBundle(MediaControlIntent.EXTRA_ITEM_STATUS));
                    adoptSession(sessionIdResult);
                    if (sessionIdResult != null && itemIdResult != null && itemStatus != null) {
                        if (DEBUG) {
                            Log.d(TAG, "Received result from " + intent.getAction()
                                    + ": data=" + bundleToString(data)
                                    + ", sessionId=" + sessionIdResult
                                    + ", sessionStatus=" + sessionStatus
                                    + ", itemId=" + itemIdResult
                                    + ", itemStatus=" + itemStatus);
                        }
                        callback.onResult(data, sessionIdResult, sessionStatus,
                                itemIdResult, itemStatus);
                        return;
                    }
                }
                handleInvalidResult(intent, callback, data);
            }

            @Override
            public void onError(String error, Bundle data) {
                handleError(intent, callback, error, data);
            }
        });
    }

    private void performSessionAction(final Intent intent, final String sessionId,
            Bundle extras, final SessionActionCallback callback) {
        intent.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK);
        if (sessionId != null) {
            intent.putExtra(MediaControlIntent.EXTRA_SESSION_ID, sessionId);
        }
        if (extras != null) {
            intent.putExtras(extras);
        }
        logRequest(intent);
        mRoute.sendControlRequest(intent, new MediaRouter.ControlRequestCallback() {
            @Override
            public void onResult(Bundle data) {
                if (data != null) {
                    String sessionIdResult = inferMissingResult(sessionId,
                            data.getString(MediaControlIntent.EXTRA_SESSION_ID));
                    MediaSessionStatus sessionStatus = MediaSessionStatus.fromBundle(
                            data.getBundle(MediaControlIntent.EXTRA_SESSION_STATUS));
                    adoptSession(sessionIdResult);
                    if (sessionIdResult != null) {
                        if (DEBUG) {
                            Log.d(TAG, "Received result from " + intent.getAction()
                                    + ": data=" + bundleToString(data)
                                    + ", sessionId=" + sessionIdResult
                                    + ", sessionStatus=" + sessionStatus);
                        }
                        try {
                            callback.onResult(data, sessionIdResult, sessionStatus);
                        } finally {
                            if (intent.getAction().equals(MediaControlIntent.ACTION_END_SESSION)
                                    && sessionIdResult.equals(mSessionId)) {
                                setSessionId(null);
                            }
                        }
                        return;
                    }
                }
                handleInvalidResult(intent, callback, data);
            }

            @Override
            public void onError(String error, Bundle data) {
                handleError(intent, callback, error, data);
            }
        });
    }

    void adoptSession(String sessionId) {
        if (sessionId != null) {
            setSessionId(sessionId);
        }
    }

    void handleInvalidResult(Intent intent, ActionCallback callback,
            Bundle data) {
        Log.w(TAG, "Received invalid result data from " + intent.getAction()
                + ": data=" + bundleToString(data));
        callback.onError(null, MediaControlIntent.ERROR_UNKNOWN, data);
    }

    void handleError(Intent intent, ActionCallback callback,
            String error, Bundle data) {
        final int code;
        if (data != null) {
            code = data.getInt(MediaControlIntent.EXTRA_ERROR_CODE,
                    MediaControlIntent.ERROR_UNKNOWN);
        } else {
            code = MediaControlIntent.ERROR_UNKNOWN;
        }
        if (DEBUG) {
            Log.w(TAG, "Received error from " + intent.getAction()
                    + ": error=" + error
                    + ", code=" + code
                    + ", data=" + bundleToString(data));
        }
        callback.onError(error, code, data);
    }

    private void detectFeatures() {
        mRouteSupportsRemotePlayback = routeSupportsAction(MediaControlIntent.ACTION_PLAY)
                && routeSupportsAction(MediaControlIntent.ACTION_SEEK)
                && routeSupportsAction(MediaControlIntent.ACTION_GET_STATUS)
                && routeSupportsAction(MediaControlIntent.ACTION_PAUSE)
                && routeSupportsAction(MediaControlIntent.ACTION_RESUME)
                && routeSupportsAction(MediaControlIntent.ACTION_STOP);
        mRouteSupportsQueuing = mRouteSupportsRemotePlayback
                && routeSupportsAction(MediaControlIntent.ACTION_ENQUEUE)
                && routeSupportsAction(MediaControlIntent.ACTION_REMOVE);
        mRouteSupportsSessionManagement = mRouteSupportsRemotePlayback
                && routeSupportsAction(MediaControlIntent.ACTION_START_SESSION)
                && routeSupportsAction(MediaControlIntent.ACTION_GET_SESSION_STATUS)
                && routeSupportsAction(MediaControlIntent.ACTION_END_SESSION);
        mRouteSupportsMessaging = doesRouteSupportMessaging();
    }

    private boolean routeSupportsAction(String action) {
        return mRoute.supportsControlAction(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK, action);
    }

    private boolean doesRouteSupportMessaging() {
        for (IntentFilter filter : mRoute.getControlFilters()) {
            if (filter.hasAction(MediaControlIntent.ACTION_SEND_MESSAGE)) {
                return true;
            }
        }
        return false;
    }

    private void throwIfRemotePlaybackNotSupported() {
        if (!mRouteSupportsRemotePlayback) {
            throw new UnsupportedOperationException("The route does not support remote playback.");
        }
    }

    private void throwIfQueuingNotSupported() {
        if (!mRouteSupportsQueuing) {
            throw new UnsupportedOperationException("The route does not support queuing.");
        }
    }

    private void throwIfSessionManagementNotSupported() {
        if (!mRouteSupportsSessionManagement) {
            throw new UnsupportedOperationException("The route does not support "
                    + "session management.");
        }
    }

    private void throwIfMessageNotSupported() {
        if (!mRouteSupportsMessaging) {
            throw new UnsupportedOperationException("The route does not support message.");
        }
    }

    private void throwIfNoCurrentSession() {
        if (mSessionId == null) {
            throw new IllegalStateException("There is no current session.");
        }
    }

    static String inferMissingResult(String request, String result) {
        if (result == null) {
            // Result is missing.
            return request;
        }
        if (request == null || request.equals(result)) {
            // Request didn't specify a value or result matches request.
            return result;
        }
        // Result conflicts with request.
        return null;
    }

    private static void logRequest(Intent intent) {
        if (DEBUG) {
            Log.d(TAG, "Sending request: " + intent);
        }
    }

    static String bundleToString(Bundle bundle) {
        if (bundle != null) {
            bundle.size(); // force bundle to be unparcelled
            return bundle.toString();
        }
        return "null";
    }

    private final class ActionReceiver extends BroadcastReceiver {
        public static final String ACTION_ITEM_STATUS_CHANGED =
                "android.support.v7.media.actions.ACTION_ITEM_STATUS_CHANGED";
        public static final String ACTION_SESSION_STATUS_CHANGED =
                "android.support.v7.media.actions.ACTION_SESSION_STATUS_CHANGED";
        public static final String ACTION_MESSAGE_RECEIVED =
                "android.support.v7.media.actions.ACTION_MESSAGE_RECEIVED";

        ActionReceiver() {
        }

        @Override
        public void onReceive(Context context, Intent intent) {
            String sessionId = intent.getStringExtra(MediaControlIntent.EXTRA_SESSION_ID);
            if (sessionId == null || !sessionId.equals(mSessionId)) {
                Log.w(TAG, "Discarding spurious status callback "
                        + "with missing or invalid session id: sessionId=" + sessionId);
                return;
            }

            MediaSessionStatus sessionStatus = MediaSessionStatus.fromBundle(
                    intent.getBundleExtra(MediaControlIntent.EXTRA_SESSION_STATUS));
            String action = intent.getAction();
            if (action.equals(ACTION_ITEM_STATUS_CHANGED)) {
                String itemId = intent.getStringExtra(MediaControlIntent.EXTRA_ITEM_ID);
                if (itemId == null) {
                    Log.w(TAG, "Discarding spurious status callback with missing item id.");
                    return;
                }

                MediaItemStatus itemStatus = MediaItemStatus.fromBundle(
                        intent.getBundleExtra(MediaControlIntent.EXTRA_ITEM_STATUS));
                if (itemStatus == null) {
                    Log.w(TAG, "Discarding spurious status callback with missing item status.");
                    return;
                }

                if (DEBUG) {
                    Log.d(TAG, "Received item status callback: sessionId=" + sessionId
                            + ", sessionStatus=" + sessionStatus
                            + ", itemId=" + itemId
                            + ", itemStatus=" + itemStatus);
                }

                if (mStatusCallback != null) {
                    mStatusCallback.onItemStatusChanged(intent.getExtras(),
                            sessionId, sessionStatus, itemId, itemStatus);
                }
            } else if (action.equals(ACTION_SESSION_STATUS_CHANGED)) {
                if (sessionStatus == null) {
                    Log.w(TAG, "Discarding spurious media status callback with "
                            +"missing session status.");
                    return;
                }

                if (DEBUG) {
                    Log.d(TAG, "Received session status callback: sessionId=" + sessionId
                            + ", sessionStatus=" + sessionStatus);
                }

                if (mStatusCallback != null) {
                    mStatusCallback.onSessionStatusChanged(intent.getExtras(),
                            sessionId, sessionStatus);
                }
            } else if (action.equals(ACTION_MESSAGE_RECEIVED)) {
                if (DEBUG) {
                    Log.d(TAG, "Received message callback: sessionId=" + sessionId);
                }

                if (mOnMessageReceivedListener != null) {
                    mOnMessageReceivedListener.onMessageReceived(sessionId,
                            intent.getBundleExtra(MediaControlIntent.EXTRA_MESSAGE));
                }
            }
        }
    }

    /**
     * A callback that will receive media status updates.
     */
    public static abstract class StatusCallback {
        /**
         * Called when the status of a media item changes.
         *
         * @param data The result data bundle.
         * @param sessionId The session id.
         * @param sessionStatus The session status, or null if unknown.
         * @param itemId The item id.
         * @param itemStatus The item status.
         */
        public void onItemStatusChanged(Bundle data,
                String sessionId, MediaSessionStatus sessionStatus,
                String itemId, MediaItemStatus itemStatus) {
        }

        /**
         * Called when the status of a media session changes.
         *
         * @param data The result data bundle.
         * @param sessionId The session id.
         * @param sessionStatus The session status, or null if unknown.
         */
        public void onSessionStatusChanged(Bundle data,
                String sessionId, MediaSessionStatus sessionStatus) {
        }

        /**
         * Called when the session of the remote playback client changes.
         *
         * @param sessionId The new session id.
         */
        public void onSessionChanged(String sessionId) {
        }
    }

    /**
     * Base callback type for remote playback requests.
     */
    public static abstract class ActionCallback {
        /**
         * Called when a media control request fails.
         *
         * @param error A localized error message which may be shown to the user, or null
         * if the cause of the error is unclear.
         * @param code The error code, or {@link MediaControlIntent#ERROR_UNKNOWN} if unknown.
         * @param data The error data bundle, or null if none.
         */
        public void onError(String error, int code, Bundle data) {
        }
    }

    /**
     * Callback for remote playback requests that operate on items.
     */
    public static abstract class ItemActionCallback extends ActionCallback {
        /**
         * Called when the request succeeds.
         *
         * @param data The result data bundle.
         * @param sessionId The session id.
         * @param sessionStatus The session status, or null if unknown.
         * @param itemId The item id.
         * @param itemStatus The item status.
         */
        public void onResult(Bundle data, String sessionId, MediaSessionStatus sessionStatus,
                String itemId, MediaItemStatus itemStatus) {
        }
    }

    /**
     * Callback for remote playback requests that operate on sessions.
     */
    public static abstract class SessionActionCallback extends ActionCallback {
        /**
         * Called when the request succeeds.
         *
         * @param data The result data bundle.
         * @param sessionId The session id.
         * @param sessionStatus The session status, or null if unknown.
         */
        public void onResult(Bundle data, String sessionId, MediaSessionStatus sessionStatus) {
        }
    }

    /**
     * A callback that will receive messages from media sessions.
     */
    public interface OnMessageReceivedListener {
        /**
         * Called when a message received.
         *
         * @param sessionId The session id.
         * @param message A bundle message denoting {@link MediaControlIntent#EXTRA_MESSAGE}.
         */
        void onMessageReceived(String sessionId, Bundle message);
    }
}
