/*
 * Copyright (C) 2011 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.app.PendingIntent;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
import android.content.Intent;
import android.graphics.Bitmap;
import android.media.session.MediaSession;
import android.media.session.MediaSessionLegacyHelper;
import android.media.session.PlaybackState;
import android.os.Bundle;
import android.os.Looper;
import android.os.SystemClock;
import android.util.Log;

/**
 * RemoteControlClient enables exposing information meant to be consumed by remote controls
 * capable of displaying metadata, artwork and media transport control buttons.
 *
 * <p>A remote control client object is associated with a media button event receiver. This
 * event receiver must have been previously registered with
 * {@link AudioManager#registerMediaButtonEventReceiver(ComponentName)} before the
 * RemoteControlClient can be registered through
 * {@link AudioManager#registerRemoteControlClient(RemoteControlClient)}.
 *
 * <p>Here is an example of creating a RemoteControlClient instance after registering a media
 * button event receiver:
 * <pre>ComponentName myEventReceiver = new ComponentName(getPackageName(), MyRemoteControlEventReceiver.class.getName());
 * AudioManager myAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
 * myAudioManager.registerMediaButtonEventReceiver(myEventReceiver);
 * // build the PendingIntent for the remote control client
 * Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
 * mediaButtonIntent.setComponent(myEventReceiver);
 * PendingIntent mediaPendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, mediaButtonIntent, 0);
 * // create and register the remote control client
 * RemoteControlClient myRemoteControlClient = new RemoteControlClient(mediaPendingIntent);
 * myAudioManager.registerRemoteControlClient(myRemoteControlClient);</pre>
 *
 * @deprecated Use {@link MediaSession} instead.
 */
@Deprecated public class RemoteControlClient
{
    private final static String TAG = "RemoteControlClient";
    private final static boolean DEBUG = false;

    /**
     * Playback state of a RemoteControlClient which is stopped.
     *
     * @see #setPlaybackState(int)
     */
    public final static int PLAYSTATE_STOPPED            = 1;
    /**
     * Playback state of a RemoteControlClient which is paused.
     *
     * @see #setPlaybackState(int)
     */
    public final static int PLAYSTATE_PAUSED             = 2;
    /**
     * Playback state of a RemoteControlClient which is playing media.
     *
     * @see #setPlaybackState(int)
     */
    public final static int PLAYSTATE_PLAYING            = 3;
    /**
     * Playback state of a RemoteControlClient which is fast forwarding in the media
     *    it is currently playing.
     *
     * @see #setPlaybackState(int)
     */
    public final static int PLAYSTATE_FAST_FORWARDING    = 4;
    /**
     * Playback state of a RemoteControlClient which is fast rewinding in the media
     *    it is currently playing.
     *
     * @see #setPlaybackState(int)
     */
    public final static int PLAYSTATE_REWINDING          = 5;
    /**
     * Playback state of a RemoteControlClient which is skipping to the next
     *    logical chapter (such as a song in a playlist) in the media it is currently playing.
     *
     * @see #setPlaybackState(int)
     */
    public final static int PLAYSTATE_SKIPPING_FORWARDS  = 6;
    /**
     * Playback state of a RemoteControlClient which is skipping back to the previous
     *    logical chapter (such as a song in a playlist) in the media it is currently playing.
     *
     * @see #setPlaybackState(int)
     */
    public final static int PLAYSTATE_SKIPPING_BACKWARDS = 7;
    /**
     * Playback state of a RemoteControlClient which is buffering data to play before it can
     *    start or resume playback.
     *
     * @see #setPlaybackState(int)
     */
    public final static int PLAYSTATE_BUFFERING          = 8;
    /**
     * Playback state of a RemoteControlClient which cannot perform any playback related
     *    operation because of an internal error. Examples of such situations are no network
     *    connectivity when attempting to stream data from a server, or expired user credentials
     *    when trying to play subscription-based content.
     *
     * @see #setPlaybackState(int)
     */
    public final static int PLAYSTATE_ERROR              = 9;
    /**
     * @hide
     * The value of a playback state when none has been declared.
     * Intentionally hidden as an application shouldn't set such a playback state value.
     */
    public final static int PLAYSTATE_NONE               = 0;

    /**
     * @hide
     * The default playback type, "local", indicating the presentation of the media is happening on
     * the same device (e.g. a phone, a tablet) as where it is controlled from.
     */
    public final static int PLAYBACK_TYPE_LOCAL = 0;
    /**
     * @hide
     * A playback type indicating the presentation of the media is happening on
     * a different device (i.e. the remote device) than where it is controlled from.
     */
    public final static int PLAYBACK_TYPE_REMOTE = 1;
    private final static int PLAYBACK_TYPE_MIN = PLAYBACK_TYPE_LOCAL;
    private final static int PLAYBACK_TYPE_MAX = PLAYBACK_TYPE_REMOTE;
    /**
     * @hide
     * Playback information indicating the playback volume is fixed, i.e. it cannot be controlled
     * from this object. An example of fixed playback volume is a remote player, playing over HDMI
     * where the user prefer to control the volume on the HDMI sink, rather than attenuate at the
     * source.
     * @see #PLAYBACKINFO_VOLUME_HANDLING.
     */
    public final static int PLAYBACK_VOLUME_FIXED = 0;
    /**
     * @hide
     * Playback information indicating the playback volume is variable and can be controlled from
     * this object.
     * @see #PLAYBACKINFO_VOLUME_HANDLING.
     */
    public final static int PLAYBACK_VOLUME_VARIABLE = 1;
    /**
     * @hide (to be un-hidden)
     * The playback information value indicating the value of a given information type is invalid.
     * @see #PLAYBACKINFO_VOLUME_HANDLING.
     */
    public final static int PLAYBACKINFO_INVALID_VALUE = Integer.MIN_VALUE;

    /**
     * @hide
     * An unknown or invalid playback position value.
     */
    public final static long PLAYBACK_POSITION_INVALID = -1;
    /**
     * @hide
     * An invalid playback position value associated with the use of {@link #setPlaybackState(int)}
     * used to indicate that playback position will remain unknown.
     */
    public final static long PLAYBACK_POSITION_ALWAYS_UNKNOWN = 0x8019771980198300L;
    /**
     * @hide
     * The default playback speed, 1x.
     */
    public final static float PLAYBACK_SPEED_1X = 1.0f;

    //==========================================
    // Public keys for playback information
    /**
     * @hide
     * Playback information that defines the type of playback associated with this
     * RemoteControlClient. See {@link #PLAYBACK_TYPE_LOCAL} and {@link #PLAYBACK_TYPE_REMOTE}.
     */
    public final static int PLAYBACKINFO_PLAYBACK_TYPE = 1;
    /**
     * @hide
     * Playback information that defines at what volume the playback associated with this
     * RemoteControlClient is performed. This information is only used when the playback type is not
     * local (see {@link #PLAYBACKINFO_PLAYBACK_TYPE}).
     */
    public final static int PLAYBACKINFO_VOLUME = 2;
    /**
     * @hide
     * Playback information that defines the maximum volume volume value that is supported
     * by the playback associated with this RemoteControlClient. This information is only used
     * when the playback type is not local (see {@link #PLAYBACKINFO_PLAYBACK_TYPE}).
     */
    public final static int PLAYBACKINFO_VOLUME_MAX = 3;
    /**
     * @hide
     * Playback information that defines how volume is handled for the presentation of the media.
     * @see #PLAYBACK_VOLUME_FIXED
     * @see #PLAYBACK_VOLUME_VARIABLE
     */
    public final static int PLAYBACKINFO_VOLUME_HANDLING = 4;
    /**
     * @hide
     * Playback information that defines over what stream type the media is presented.
     */
    public final static int PLAYBACKINFO_USES_STREAM = 5;

    //==========================================
    // Public flags for the supported transport control capabilities
    /**
     * Flag indicating a RemoteControlClient makes use of the "previous" media key.
     *
     * @see #setTransportControlFlags(int)
     * @see android.view.KeyEvent#KEYCODE_MEDIA_PREVIOUS
     */
    public final static int FLAG_KEY_MEDIA_PREVIOUS = 1 << 0;
    /**
     * Flag indicating a RemoteControlClient makes use of the "rewind" media key.
     *
     * @see #setTransportControlFlags(int)
     * @see android.view.KeyEvent#KEYCODE_MEDIA_REWIND
     */
    public final static int FLAG_KEY_MEDIA_REWIND = 1 << 1;
    /**
     * Flag indicating a RemoteControlClient makes use of the "play" media key.
     *
     * @see #setTransportControlFlags(int)
     * @see android.view.KeyEvent#KEYCODE_MEDIA_PLAY
     */
    public final static int FLAG_KEY_MEDIA_PLAY = 1 << 2;
    /**
     * Flag indicating a RemoteControlClient makes use of the "play/pause" media key.
     *
     * @see #setTransportControlFlags(int)
     * @see android.view.KeyEvent#KEYCODE_MEDIA_PLAY_PAUSE
     */
    public final static int FLAG_KEY_MEDIA_PLAY_PAUSE = 1 << 3;
    /**
     * Flag indicating a RemoteControlClient makes use of the "pause" media key.
     *
     * @see #setTransportControlFlags(int)
     * @see android.view.KeyEvent#KEYCODE_MEDIA_PAUSE
     */
    public final static int FLAG_KEY_MEDIA_PAUSE = 1 << 4;
    /**
     * Flag indicating a RemoteControlClient makes use of the "stop" media key.
     *
     * @see #setTransportControlFlags(int)
     * @see android.view.KeyEvent#KEYCODE_MEDIA_STOP
     */
    public final static int FLAG_KEY_MEDIA_STOP = 1 << 5;
    /**
     * Flag indicating a RemoteControlClient makes use of the "fast forward" media key.
     *
     * @see #setTransportControlFlags(int)
     * @see android.view.KeyEvent#KEYCODE_MEDIA_FAST_FORWARD
     */
    public final static int FLAG_KEY_MEDIA_FAST_FORWARD = 1 << 6;
    /**
     * Flag indicating a RemoteControlClient makes use of the "next" media key.
     *
     * @see #setTransportControlFlags(int)
     * @see android.view.KeyEvent#KEYCODE_MEDIA_NEXT
     */
    public final static int FLAG_KEY_MEDIA_NEXT = 1 << 7;
    /**
     * Flag indicating a RemoteControlClient can receive changes in the media playback position
     * through the {@link OnPlaybackPositionUpdateListener} interface. This flag must be set
     * in order for components that display the RemoteControlClient information, to display and
     * let the user control media playback position.
     * @see #setTransportControlFlags(int)
     * @see #setOnGetPlaybackPositionListener(OnGetPlaybackPositionListener)
     * @see #setPlaybackPositionUpdateListener(OnPlaybackPositionUpdateListener)
     */
    public final static int FLAG_KEY_MEDIA_POSITION_UPDATE = 1 << 8;
    /**
     * Flag indicating a RemoteControlClient supports ratings.
     * This flag must be set in order for components that display the RemoteControlClient
     * information, to display ratings information, and, if ratings are declared editable
     * (by calling {@link MediaMetadataEditor#addEditableKey(int)} with the
     * {@link MediaMetadataEditor#RATING_KEY_BY_USER} key), it will enable the user to rate
     * the media, with values being received through the interface set with
     * {@link #setMetadataUpdateListener(OnMetadataUpdateListener)}.
     * @see #setTransportControlFlags(int)
     */
    public final static int FLAG_KEY_MEDIA_RATING = 1 << 9;

    /**
     * @hide
     * The flags for when no media keys are declared supported.
     * Intentionally hidden as an application shouldn't set the transport control flags
     *     to this value.
     */
    public final static int FLAGS_KEY_MEDIA_NONE = 0;

    /**
     * @hide
     * Flag used to signal some type of metadata exposed by the RemoteControlClient is requested.
     */
    public final static int FLAG_INFORMATION_REQUEST_METADATA = 1 << 0;
    /**
     * @hide
     * Flag used to signal that the transport control buttons supported by the
     *     RemoteControlClient are requested.
     * This can for instance happen when playback is at the end of a playlist, and the "next"
     * operation is not supported anymore.
     */
    public final static int FLAG_INFORMATION_REQUEST_KEY_MEDIA = 1 << 1;
    /**
     * @hide
     * Flag used to signal that the playback state of the RemoteControlClient is requested.
     */
    public final static int FLAG_INFORMATION_REQUEST_PLAYSTATE = 1 << 2;
    /**
     * @hide
     * Flag used to signal that the album art for the RemoteControlClient is requested.
     */
    public final static int FLAG_INFORMATION_REQUEST_ALBUM_ART = 1 << 3;

    private MediaSession mSession;

    /**
     * Class constructor.
     * @param mediaButtonIntent The intent that will be sent for the media button events sent
     *     by remote controls.
     *     This intent needs to have been constructed with the {@link Intent#ACTION_MEDIA_BUTTON}
     *     action, and have a component that will handle the intent (set with
     *     {@link Intent#setComponent(ComponentName)}) registered with
     *     {@link AudioManager#registerMediaButtonEventReceiver(ComponentName)}
     *     before this new RemoteControlClient can itself be registered with
     *     {@link AudioManager#registerRemoteControlClient(RemoteControlClient)}.
     * @see AudioManager#registerMediaButtonEventReceiver(ComponentName)
     * @see AudioManager#registerRemoteControlClient(RemoteControlClient)
     */
    public RemoteControlClient(PendingIntent mediaButtonIntent) {
        mRcMediaIntent = mediaButtonIntent;
    }

    /**
     * Class constructor for a remote control client whose internal event handling
     * happens on a user-provided Looper.
     * @param mediaButtonIntent The intent that will be sent for the media button events sent
     *     by remote controls.
     *     This intent needs to have been constructed with the {@link Intent#ACTION_MEDIA_BUTTON}
     *     action, and have a component that will handle the intent (set with
     *     {@link Intent#setComponent(ComponentName)}) registered with
     *     {@link AudioManager#registerMediaButtonEventReceiver(ComponentName)}
     *     before this new RemoteControlClient can itself be registered with
     *     {@link AudioManager#registerRemoteControlClient(RemoteControlClient)}.
     * @param looper The Looper running the event loop.
     * @see AudioManager#registerMediaButtonEventReceiver(ComponentName)
     * @see AudioManager#registerRemoteControlClient(RemoteControlClient)
     */
    public RemoteControlClient(PendingIntent mediaButtonIntent, Looper looper) {
        mRcMediaIntent = mediaButtonIntent;
    }

    /**
     * @hide
     */
    public void registerWithSession(MediaSessionLegacyHelper helper) {
        helper.addRccListener(mRcMediaIntent, mTransportListener);
        mSession = helper.getSession(mRcMediaIntent);
        setTransportControlFlags(mTransportControlFlags);
    }

    /**
     * @hide
     */
    public void unregisterWithSession(MediaSessionLegacyHelper helper) {
        helper.removeRccListener(mRcMediaIntent);
        mSession = null;
    }

    /**
     * Get a {@link MediaSession} associated with this RCC. It will only have a
     * session while it is registered with
     * {@link AudioManager#registerRemoteControlClient}. The session returned
     * should not be modified directly by the application but may be used with
     * other APIs that require a session.
     *
     * @return A media session object or null.
     */
    public MediaSession getMediaSession() {
        return mSession;
    }

    /**
     * Class used to modify metadata in a {@link RemoteControlClient} object.
     * Use {@link RemoteControlClient#editMetadata(boolean)} to create an instance of an editor,
     * on which you set the metadata for the RemoteControlClient instance. Once all the information
     * has been set, use {@link #apply()} to make it the new metadata that should be displayed
     * for the associated client. Once the metadata has been "applied", you cannot reuse this
     * instance of the MetadataEditor.
     *
     * @deprecated Use {@link MediaMetadata} and {@link MediaSession} instead.
     */
    @Deprecated public class MetadataEditor extends MediaMetadataEditor {

        // only use RemoteControlClient.editMetadata() to get a MetadataEditor instance
        private MetadataEditor() { }
        /**
         * @hide
         */
        public Object clone() throws CloneNotSupportedException {
            throw new CloneNotSupportedException();
        }

        /**
         * The metadata key for the content artwork / album art.
         */
        public final static int BITMAP_KEY_ARTWORK = 100;

        /**
         * @hide
         * TODO(jmtrivi) have lockscreen move to the new key name and remove
         */
        public final static int METADATA_KEY_ARTWORK = BITMAP_KEY_ARTWORK;

        /**
         * Adds textual information to be displayed.
         * Note that none of the information added after {@link #apply()} has been called,
         * will be displayed.
         * @param key The identifier of a the metadata field to set. Valid values are
         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_ALBUM},
         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_ALBUMARTIST},
         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_TITLE},
         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_ARTIST},
         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_AUTHOR},
         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_COMPILATION},
         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_COMPOSER},
         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_DATE},
         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_GENRE},
         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_TITLE},
         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_WRITER}.
         * @param value The text for the given key, or {@code null} to signify there is no valid
         *      information for the field.
         * @return Returns a reference to the same MetadataEditor object, so you can chain put
         *      calls together.
         */
        public synchronized MetadataEditor putString(int key, String value)
                throws IllegalArgumentException {
            super.putString(key, value);
            if (mMetadataBuilder != null) {
                // MediaMetadata supports all the same fields as MetadataEditor
                String metadataKey = MediaMetadata.getKeyFromMetadataEditorKey(key);
                // But just in case, don't add things we don't understand
                if (metadataKey != null) {
                    mMetadataBuilder.putText(metadataKey, value);
                }
            }

            return this;
        }

        /**
         * Adds numerical information to be displayed.
         * Note that none of the information added after {@link #apply()} has been called,
         * will be displayed.
         * @param key the identifier of a the metadata field to set. Valid values are
         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_CD_TRACK_NUMBER},
         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_DISC_NUMBER},
         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_DURATION} (with a value
         *      expressed in milliseconds),
         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_YEAR}.
         * @param value The long value for the given key
         * @return Returns a reference to the same MetadataEditor object, so you can chain put
         *      calls together.
         * @throws IllegalArgumentException
         */
        public synchronized MetadataEditor putLong(int key, long value)
                throws IllegalArgumentException {
            super.putLong(key, value);
            if (mMetadataBuilder != null) {
                // MediaMetadata supports all the same fields as MetadataEditor
                String metadataKey = MediaMetadata.getKeyFromMetadataEditorKey(key);
                // But just in case, don't add things we don't understand
                if (metadataKey != null) {
                    mMetadataBuilder.putLong(metadataKey, value);
                }
            }
            return this;
        }

        /**
         * Sets the album / artwork picture to be displayed on the remote control.
         * @param key the identifier of the bitmap to set. The only valid value is
         *      {@link #BITMAP_KEY_ARTWORK}
         * @param bitmap The bitmap for the artwork, or null if there isn't any.
         * @return Returns a reference to the same MetadataEditor object, so you can chain put
         *      calls together.
         * @throws IllegalArgumentException
         * @see android.graphics.Bitmap
         */
        @Override
        public synchronized MetadataEditor putBitmap(int key, Bitmap bitmap)
                throws IllegalArgumentException {
            super.putBitmap(key, bitmap);
            if (mMetadataBuilder != null) {
                // MediaMetadata supports all the same fields as MetadataEditor
                String metadataKey = MediaMetadata.getKeyFromMetadataEditorKey(key);
                // But just in case, don't add things we don't understand
                if (metadataKey != null) {
                    mMetadataBuilder.putBitmap(metadataKey, bitmap);
                }
            }
            return this;
        }

        @Override
        public synchronized MetadataEditor putObject(int key, Object object)
                throws IllegalArgumentException {
            super.putObject(key, object);
            if (mMetadataBuilder != null &&
                    (key == MediaMetadataEditor.RATING_KEY_BY_USER ||
                    key == MediaMetadataEditor.RATING_KEY_BY_OTHERS)) {
                String metadataKey = MediaMetadata.getKeyFromMetadataEditorKey(key);
                if (metadataKey != null) {
                    mMetadataBuilder.putRating(metadataKey, (Rating) object);
                }
            }
            return this;
        }

        /**
         * Clears all the metadata that has been set since the MetadataEditor instance was created
         * (with {@link RemoteControlClient#editMetadata(boolean)}).
         * Note that clearing the metadata doesn't reset the editable keys
         * (use {@link MediaMetadataEditor#removeEditableKeys()} instead).
         */
        @Override
        public synchronized void clear() {
            super.clear();
        }

        /**
         * Associates all the metadata that has been set since the MetadataEditor instance was
         *     created with {@link RemoteControlClient#editMetadata(boolean)}, or since
         *     {@link #clear()} was called, with the RemoteControlClient. Once "applied",
         *     this MetadataEditor cannot be reused to edit the RemoteControlClient's metadata.
         */
        public synchronized void apply() {
            if (mApplied) {
                Log.e(TAG, "Can't apply a previously applied MetadataEditor");
                return;
            }
            synchronized (mCacheLock) {
                // Still build the old metadata so when creating a new editor
                // you get the expected values.
                // assign the edited data
                mMetadata = new Bundle(mEditorMetadata);
                // add the information about editable keys
                mMetadata.putLong(String.valueOf(KEY_EDITABLE_MASK), mEditableKeys);
                if ((mOriginalArtwork != null) && (!mOriginalArtwork.equals(mEditorArtwork))) {
                    mOriginalArtwork.recycle();
                }
                mOriginalArtwork = mEditorArtwork;
                mEditorArtwork = null;

                // USE_SESSIONS
                if (mSession != null && mMetadataBuilder != null) {
                    mMediaMetadata = mMetadataBuilder.build();
                    mSession.setMetadata(mMediaMetadata);
                }
                mApplied = true;
            }
        }
    }

    /**
     * Creates a {@link MetadataEditor}.
     * @param startEmpty Set to false if you want the MetadataEditor to contain the metadata that
     *     was previously applied to the RemoteControlClient, or true if it is to be created empty.
     * @return a new MetadataEditor instance.
     */
    public MetadataEditor editMetadata(boolean startEmpty) {
        MetadataEditor editor = new MetadataEditor();
        if (startEmpty) {
            editor.mEditorMetadata = new Bundle();
            editor.mEditorArtwork = null;
            editor.mMetadataChanged = true;
            editor.mArtworkChanged = true;
            editor.mEditableKeys = 0;
        } else {
            editor.mEditorMetadata = new Bundle(mMetadata);
            editor.mEditorArtwork = mOriginalArtwork;
            editor.mMetadataChanged = false;
            editor.mArtworkChanged = false;
        }
        // USE_SESSIONS
        if (startEmpty || mMediaMetadata == null) {
            editor.mMetadataBuilder = new MediaMetadata.Builder();
        } else {
            editor.mMetadataBuilder = new MediaMetadata.Builder(mMediaMetadata);
        }
        return editor;
    }

    /**
     * Sets the current playback state.
     * @param state The current playback state, one of the following values:
     *       {@link #PLAYSTATE_STOPPED},
     *       {@link #PLAYSTATE_PAUSED},
     *       {@link #PLAYSTATE_PLAYING},
     *       {@link #PLAYSTATE_FAST_FORWARDING},
     *       {@link #PLAYSTATE_REWINDING},
     *       {@link #PLAYSTATE_SKIPPING_FORWARDS},
     *       {@link #PLAYSTATE_SKIPPING_BACKWARDS},
     *       {@link #PLAYSTATE_BUFFERING},
     *       {@link #PLAYSTATE_ERROR}.
     */
    public void setPlaybackState(int state) {
        setPlaybackStateInt(state, PLAYBACK_POSITION_ALWAYS_UNKNOWN, PLAYBACK_SPEED_1X,
                false /* legacy API, converting to method with position and speed */);
    }

    /**
     * Sets the current playback state and the matching media position for the current playback
     *   speed.
     * @param state The current playback state, one of the following values:
     *       {@link #PLAYSTATE_STOPPED},
     *       {@link #PLAYSTATE_PAUSED},
     *       {@link #PLAYSTATE_PLAYING},
     *       {@link #PLAYSTATE_FAST_FORWARDING},
     *       {@link #PLAYSTATE_REWINDING},
     *       {@link #PLAYSTATE_SKIPPING_FORWARDS},
     *       {@link #PLAYSTATE_SKIPPING_BACKWARDS},
     *       {@link #PLAYSTATE_BUFFERING},
     *       {@link #PLAYSTATE_ERROR}.
     * @param timeInMs a 0 or positive value for the current media position expressed in ms
     *    (same unit as for when sending the media duration, if applicable, with
     *    {@link android.media.MediaMetadataRetriever#METADATA_KEY_DURATION} in the
     *    {@link RemoteControlClient.MetadataEditor}). Negative values imply that position is not
     *    known (e.g. listening to a live stream of a radio) or not applicable (e.g. when state
     *    is {@link #PLAYSTATE_BUFFERING} and nothing had played yet).
     * @param playbackSpeed a value expressed as a ratio of 1x playback: 1.0f is normal playback,
     *    2.0f is 2x, 0.5f is half-speed, -2.0f is rewind at 2x speed. 0.0f means nothing is
     *    playing (e.g. when state is {@link #PLAYSTATE_ERROR}).
     */
    public void setPlaybackState(int state, long timeInMs, float playbackSpeed) {
        setPlaybackStateInt(state, timeInMs, playbackSpeed, true);
    }

    private void setPlaybackStateInt(int state, long timeInMs, float playbackSpeed,
            boolean hasPosition) {
        synchronized(mCacheLock) {
            if ((mPlaybackState != state) || (mPlaybackPositionMs != timeInMs)
                    || (mPlaybackSpeed != playbackSpeed)) {
                // store locally
                mPlaybackState = state;
                // distinguish between an application not knowing the current playback position
                // at the moment and an application using the API where only the playback state
                // is passed, not the playback position.
                if (hasPosition) {
                    if (timeInMs < 0) {
                        mPlaybackPositionMs = PLAYBACK_POSITION_INVALID;
                    } else {
                        mPlaybackPositionMs = timeInMs;
                    }
                } else {
                    mPlaybackPositionMs = PLAYBACK_POSITION_ALWAYS_UNKNOWN;
                }
                mPlaybackSpeed = playbackSpeed;
                // keep track of when the state change occurred
                mPlaybackStateChangeTimeMs = SystemClock.elapsedRealtime();

                // USE_SESSIONS
                if (mSession != null) {
                    int pbState = getStateFromRccState(state);
                    long position = hasPosition ? mPlaybackPositionMs
                            : PlaybackState.PLAYBACK_POSITION_UNKNOWN;

                    PlaybackState.Builder bob = new PlaybackState.Builder(mSessionPlaybackState);
                    bob.setState(pbState, position, playbackSpeed, SystemClock.elapsedRealtime());
                    bob.setErrorMessage(null);
                    mSessionPlaybackState = bob.build();
                    mSession.setPlaybackState(mSessionPlaybackState);
                }
            }
        }
    }

    /**
     * Sets the flags for the media transport control buttons that this client supports.
     * @param transportControlFlags A combination of the following flags:
     *      {@link #FLAG_KEY_MEDIA_PREVIOUS},
     *      {@link #FLAG_KEY_MEDIA_REWIND},
     *      {@link #FLAG_KEY_MEDIA_PLAY},
     *      {@link #FLAG_KEY_MEDIA_PLAY_PAUSE},
     *      {@link #FLAG_KEY_MEDIA_PAUSE},
     *      {@link #FLAG_KEY_MEDIA_STOP},
     *      {@link #FLAG_KEY_MEDIA_FAST_FORWARD},
     *      {@link #FLAG_KEY_MEDIA_NEXT},
     *      {@link #FLAG_KEY_MEDIA_POSITION_UPDATE},
     *      {@link #FLAG_KEY_MEDIA_RATING}.
     */
    public void setTransportControlFlags(int transportControlFlags) {
        synchronized(mCacheLock) {
            // store locally
            mTransportControlFlags = transportControlFlags;

            // USE_SESSIONS
            if (mSession != null) {
                PlaybackState.Builder bob = new PlaybackState.Builder(mSessionPlaybackState);
                bob.setActions(getActionsFromRccControlFlags(transportControlFlags));
                mSessionPlaybackState = bob.build();
                mSession.setPlaybackState(mSessionPlaybackState);
            }
        }
    }

    /**
     * Interface definition for a callback to be invoked when one of the metadata values has
     * been updated.
     * Implement this interface to receive metadata updates after registering your listener
     * through {@link RemoteControlClient#setMetadataUpdateListener(OnMetadataUpdateListener)}.
     */
    public interface OnMetadataUpdateListener {
        /**
         * Called on the implementer to notify that the metadata field for the given key has
         * been updated to the new value.
         * @param key the identifier of the updated metadata field.
         * @param newValue the Object storing the new value for the key.
         */
        public abstract void onMetadataUpdate(int key, Object newValue);
    }

    /**
     * Sets the listener to be called whenever the metadata is updated.
     * New metadata values will be received in the same thread as the one in which
     * RemoteControlClient was created.
     * @param l the metadata update listener
     */
    public void setMetadataUpdateListener(OnMetadataUpdateListener l) {
        synchronized(mCacheLock) {
            mMetadataUpdateListener = l;
        }
    }


    /**
     * Interface definition for a callback to be invoked when the media playback position is
     * requested to be updated.
     * @see RemoteControlClient#FLAG_KEY_MEDIA_POSITION_UPDATE
     */
    public interface OnPlaybackPositionUpdateListener {
        /**
         * Called on the implementer to notify it that the playback head should be set at the given
         * position. If the position can be changed from its current value, the implementor of
         * the interface must also update the playback position using
         * {@link #setPlaybackState(int, long, float)} to reflect the actual new
         * position being used, regardless of whether it differs from the requested position.
         * Failure to do so would cause the system to not know the new actual playback position,
         * and user interface components would fail to show the user where playback resumed after
         * the position was updated.
         * @param newPositionMs the new requested position in the current media, expressed in ms.
         */
        void onPlaybackPositionUpdate(long newPositionMs);
    }

    /**
     * Interface definition for a callback to be invoked when the media playback position is
     * queried.
     * @see RemoteControlClient#FLAG_KEY_MEDIA_POSITION_UPDATE
     */
    public interface OnGetPlaybackPositionListener {
        /**
         * Called on the implementer of the interface to query the current playback position.
         * @return a negative value if the current playback position (or the last valid playback
         *     position) is not known, or a zero or positive value expressed in ms indicating the
         *     current position, or the last valid known position.
         */
        long onGetPlaybackPosition();
    }

    /**
     * Sets the listener to be called whenever the media playback position is requested
     * to be updated.
     * Notifications will be received in the same thread as the one in which RemoteControlClient
     * was created.
     * @param l the position update listener to be called
     */
    public void setPlaybackPositionUpdateListener(OnPlaybackPositionUpdateListener l) {
        synchronized(mCacheLock) {
            mPositionUpdateListener = l;
        }
    }

    /**
     * Sets the listener to be called whenever the media current playback position is needed.
     * Queries will be received in the same thread as the one in which RemoteControlClient
     * was created.
     * @param l the listener to be called to retrieve the playback position
     */
    public void setOnGetPlaybackPositionListener(OnGetPlaybackPositionListener l) {
        synchronized(mCacheLock) {
            mPositionProvider = l;
        }
    }

    /**
     * @hide
     * Flag to reflect that the application controlling this RemoteControlClient sends playback
     * position updates. The playback position being "readable" is considered from the application's
     * point of view.
     */
    @UnsupportedAppUsage
    public static int MEDIA_POSITION_READABLE = 1 << 0;
    /**
     * @hide
     * Flag to reflect that the application controlling this RemoteControlClient can receive
     * playback position updates. The playback position being "writable"
     * is considered from the application's point of view.
     */
    @UnsupportedAppUsage
    public static int MEDIA_POSITION_WRITABLE = 1 << 1;

    /** @hide */
    public final static int DEFAULT_PLAYBACK_VOLUME_HANDLING = PLAYBACK_VOLUME_VARIABLE;
    /** @hide */
    // hard-coded to the same number of steps as AudioService.MAX_STREAM_VOLUME[STREAM_MUSIC]
    public final static int DEFAULT_PLAYBACK_VOLUME = 15;

    /**
     * Lock for all cached data
     */
    private final Object mCacheLock = new Object();
    /**
     * Cache for the playback state.
     * Access synchronized on mCacheLock
     */
    private int mPlaybackState = PLAYSTATE_NONE;
    /**
     * Time of last play state change
     * Access synchronized on mCacheLock
     */
    private long mPlaybackStateChangeTimeMs = 0;
    /**
     * Last playback position in ms reported by the user
     */
    private long mPlaybackPositionMs = PLAYBACK_POSITION_INVALID;
    /**
     * Last playback speed reported by the user
     */
    private float mPlaybackSpeed = PLAYBACK_SPEED_1X;
    /**
     * Cache for the artwork bitmap.
     * Access synchronized on mCacheLock
     * Artwork and metadata are not kept in one Bundle because the bitmap sometimes needs to be
     * accessed to be resized, in which case a copy will be made. This would add overhead in
     * Bundle operations.
     */
    private Bitmap mOriginalArtwork;
    /**
     * Cache for the transport control mask.
     * Access synchronized on mCacheLock
     */
    private int mTransportControlFlags = FLAGS_KEY_MEDIA_NONE;
    /**
     * Cache for the metadata strings.
     * Access synchronized on mCacheLock
     * This is re-initialized in apply() and so cannot be final.
     */
    private Bundle mMetadata = new Bundle();
    /**
     * Listener registered by user of RemoteControlClient to receive requests for playback position
     * update requests.
     */
    private OnPlaybackPositionUpdateListener mPositionUpdateListener;
    /**
     * Provider registered by user of RemoteControlClient to provide the current playback position.
     */
    private OnGetPlaybackPositionListener mPositionProvider;
    /**
     * Listener registered by user of RemoteControlClient to receive edit changes to metadata
     * it exposes.
     */
    private OnMetadataUpdateListener mMetadataUpdateListener;
    /**
     * The current remote control client generation ID across the system, as known by this object
     */
    private int mCurrentClientGenId = -1;

    /**
     * The media button intent description associated with this remote control client
     * (can / should include target component for intent handling, used when persisting media
     *    button event receiver across reboots).
     */
    private final PendingIntent mRcMediaIntent;

    /**
     * Reflects whether any "plugged in" IRemoteControlDisplay has mWantsPositonSync set to true.
     */
    // TODO consider using a ref count for IRemoteControlDisplay requiring sync instead
    private boolean mNeedsPositionSync = false;

    /**
     * Cache for the current playback state using Session APIs.
     */
    private PlaybackState mSessionPlaybackState = null;

    /**
     * Cache for metadata using Session APIs. This is re-initialized in apply().
     */
    private MediaMetadata mMediaMetadata;

    /**
     * @hide
     * Accessor to media button intent description (includes target component)
     */
    public PendingIntent getRcMediaIntent() {
        return mRcMediaIntent;
    }

    /**
     * @hide
     * Default value for the unique identifier
     */
    public final static int RCSE_ID_UNREGISTERED = -1;

    // USE_SESSIONS
    private MediaSession.Callback mTransportListener = new MediaSession.Callback() {

        @Override
        public void onSeekTo(long pos) {
            RemoteControlClient.this.onSeekTo(mCurrentClientGenId, pos);
        }

        @Override
        public void onSetRating(Rating rating) {
            if ((mTransportControlFlags & FLAG_KEY_MEDIA_RATING) != 0) {
                onUpdateMetadata(mCurrentClientGenId, MetadataEditor.RATING_KEY_BY_USER, rating);
            }
        }
    };

    //===========================================================
    // Message handlers

    private void onSeekTo(int generationId, long timeMs) {
        synchronized (mCacheLock) {
            if ((mCurrentClientGenId == generationId) && (mPositionUpdateListener != null)) {
                mPositionUpdateListener.onPlaybackPositionUpdate(timeMs);
            }
        }
    }

    private void onUpdateMetadata(int generationId, int key, Object value) {
        synchronized (mCacheLock) {
            if ((mCurrentClientGenId == generationId) && (mMetadataUpdateListener != null)) {
                mMetadataUpdateListener.onMetadataUpdate(key, value);
            }
        }
    }

    //===========================================================
    // Internal utilities

    /**
     * Returns whether, for the given playback state, the playback position is expected to
     * be changing.
     * @param playstate the playback state to evaluate
     * @return true during any form of playback, false if it's not playing anything while in this
     *     playback state
     */
    static boolean playbackPositionShouldMove(int playstate) {
        switch(playstate) {
            case PLAYSTATE_STOPPED:
            case PLAYSTATE_PAUSED:
            case PLAYSTATE_BUFFERING:
            case PLAYSTATE_ERROR:
            case PLAYSTATE_SKIPPING_FORWARDS:
            case PLAYSTATE_SKIPPING_BACKWARDS:
                return false;
            case PLAYSTATE_PLAYING:
            case PLAYSTATE_FAST_FORWARDING:
            case PLAYSTATE_REWINDING:
            default:
                return true;
        }
    }

    /**
     * Period for playback position drift checks, 15s when playing at 1x or slower.
     */
    private final static long POSITION_REFRESH_PERIOD_PLAYING_MS = 15000;

    /**
     * Minimum period for playback position drift checks, never more often when every 2s, when
     * fast forwarding or rewinding.
     */
    private final static long POSITION_REFRESH_PERIOD_MIN_MS = 2000;

    /**
     * The value above which the difference between client-reported playback position and
     * estimated position is considered a drift.
     */
    private final static long POSITION_DRIFT_MAX_MS = 500;

    /**
     * Compute the period at which the estimated playback position should be compared against the
     * actual playback position. Is a funciton of playback speed.
     * @param speed 1.0f is normal playback speed
     * @return the period in ms
     */
    private static long getCheckPeriodFromSpeed(float speed) {
        if (Math.abs(speed) <= 1.0f) {
            return POSITION_REFRESH_PERIOD_PLAYING_MS;
        } else {
            return Math.max((long)(POSITION_REFRESH_PERIOD_PLAYING_MS / Math.abs(speed)),
                    POSITION_REFRESH_PERIOD_MIN_MS);
        }
    }

    /**
     * Get the {@link PlaybackState} state for the given
     * {@link RemoteControlClient} state.
     *
     * @param rccState The state used by {@link RemoteControlClient}.
     * @return The equivalent state used by {@link PlaybackState}.
     */
    private static int getStateFromRccState(int rccState) {
        switch (rccState) {
            case PLAYSTATE_BUFFERING:
                return PlaybackState.STATE_BUFFERING;
            case PLAYSTATE_ERROR:
                return PlaybackState.STATE_ERROR;
            case PLAYSTATE_FAST_FORWARDING:
                return PlaybackState.STATE_FAST_FORWARDING;
            case PLAYSTATE_NONE:
                return PlaybackState.STATE_NONE;
            case PLAYSTATE_PAUSED:
                return PlaybackState.STATE_PAUSED;
            case PLAYSTATE_PLAYING:
                return PlaybackState.STATE_PLAYING;
            case PLAYSTATE_REWINDING:
                return PlaybackState.STATE_REWINDING;
            case PLAYSTATE_SKIPPING_BACKWARDS:
                return PlaybackState.STATE_SKIPPING_TO_PREVIOUS;
            case PLAYSTATE_SKIPPING_FORWARDS:
                return PlaybackState.STATE_SKIPPING_TO_NEXT;
            case PLAYSTATE_STOPPED:
                return PlaybackState.STATE_STOPPED;
            default:
                return -1;
        }
    }

    /**
     * Get the {@link RemoteControlClient} state for the given
     * {@link PlaybackState} state.
     *
     * @param state The state used by {@link PlaybackState}.
     * @return The equivalent state used by {@link RemoteControlClient}.
     */
    static int getRccStateFromState(int state) {
        switch (state) {
            case PlaybackState.STATE_BUFFERING:
                return PLAYSTATE_BUFFERING;
            case PlaybackState.STATE_ERROR:
                return PLAYSTATE_ERROR;
            case PlaybackState.STATE_FAST_FORWARDING:
                return PLAYSTATE_FAST_FORWARDING;
            case PlaybackState.STATE_NONE:
                return PLAYSTATE_NONE;
            case PlaybackState.STATE_PAUSED:
                return PLAYSTATE_PAUSED;
            case PlaybackState.STATE_PLAYING:
                return PLAYSTATE_PLAYING;
            case PlaybackState.STATE_REWINDING:
                return PLAYSTATE_REWINDING;
            case PlaybackState.STATE_SKIPPING_TO_PREVIOUS:
                return PLAYSTATE_SKIPPING_BACKWARDS;
            case PlaybackState.STATE_SKIPPING_TO_NEXT:
                return PLAYSTATE_SKIPPING_FORWARDS;
            case PlaybackState.STATE_STOPPED:
                return PLAYSTATE_STOPPED;
            default:
                return -1;
        }
    }

    private static long getActionsFromRccControlFlags(int rccFlags) {
        long actions = 0;
        long flag = 1;
        while (flag <= rccFlags) {
            if ((flag & rccFlags) != 0) {
                actions |= getActionForRccFlag((int) flag);
            }
            flag = flag << 1;
        }
        return actions;
    }

    static int getRccControlFlagsFromActions(long actions) {
        int rccFlags = 0;
        long action = 1;
        while (action <= actions && action < Integer.MAX_VALUE) {
            if ((action & actions) != 0) {
                rccFlags |= getRccFlagForAction(action);
            }
            action = action << 1;
        }
        return rccFlags;
    }

    private static long getActionForRccFlag(int flag) {
        switch (flag) {
            case FLAG_KEY_MEDIA_PREVIOUS:
                return PlaybackState.ACTION_SKIP_TO_PREVIOUS;
            case FLAG_KEY_MEDIA_REWIND:
                return PlaybackState.ACTION_REWIND;
            case FLAG_KEY_MEDIA_PLAY:
                return PlaybackState.ACTION_PLAY;
            case FLAG_KEY_MEDIA_PLAY_PAUSE:
                return PlaybackState.ACTION_PLAY_PAUSE;
            case FLAG_KEY_MEDIA_PAUSE:
                return PlaybackState.ACTION_PAUSE;
            case FLAG_KEY_MEDIA_STOP:
                return PlaybackState.ACTION_STOP;
            case FLAG_KEY_MEDIA_FAST_FORWARD:
                return PlaybackState.ACTION_FAST_FORWARD;
            case FLAG_KEY_MEDIA_NEXT:
                return PlaybackState.ACTION_SKIP_TO_NEXT;
            case FLAG_KEY_MEDIA_POSITION_UPDATE:
                return PlaybackState.ACTION_SEEK_TO;
            case FLAG_KEY_MEDIA_RATING:
                return PlaybackState.ACTION_SET_RATING;
        }
        return 0;
    }

    private static int getRccFlagForAction(long action) {
        // We only care about the lower set of actions that can map to rcc
        // flags.
        int testAction = action < Integer.MAX_VALUE ? (int) action : 0;
        switch (testAction) {
            case (int) PlaybackState.ACTION_SKIP_TO_PREVIOUS:
                return FLAG_KEY_MEDIA_PREVIOUS;
            case (int) PlaybackState.ACTION_REWIND:
                return FLAG_KEY_MEDIA_REWIND;
            case (int) PlaybackState.ACTION_PLAY:
                return FLAG_KEY_MEDIA_PLAY;
            case (int) PlaybackState.ACTION_PLAY_PAUSE:
                return FLAG_KEY_MEDIA_PLAY_PAUSE;
            case (int) PlaybackState.ACTION_PAUSE:
                return FLAG_KEY_MEDIA_PAUSE;
            case (int) PlaybackState.ACTION_STOP:
                return FLAG_KEY_MEDIA_STOP;
            case (int) PlaybackState.ACTION_FAST_FORWARD:
                return FLAG_KEY_MEDIA_FAST_FORWARD;
            case (int) PlaybackState.ACTION_SKIP_TO_NEXT:
                return FLAG_KEY_MEDIA_NEXT;
            case (int) PlaybackState.ACTION_SEEK_TO:
                return FLAG_KEY_MEDIA_POSITION_UPDATE;
            case (int) PlaybackState.ACTION_SET_RATING:
                return FLAG_KEY_MEDIA_RATING;
        }
        return 0;
    }
}
