/*
 * Copyright (C) 2013 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.ActivityManager;
import android.app.PendingIntent;
import android.app.PendingIntent.CanceledException;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.media.session.MediaController;
import android.media.session.MediaSession;
import android.media.session.MediaSessionLegacyHelper;
import android.media.session.MediaSessionManager;
import android.media.session.PlaybackState;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.SystemClock;
import android.os.UserHandle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.KeyEvent;

import java.lang.ref.WeakReference;
import java.util.List;

/**
 * The RemoteController class is used to control media playback, display and update media metadata
 * and playback status, published by applications using the {@link RemoteControlClient} class.
 * <p>
 * A RemoteController shall be registered through
 * {@link AudioManager#registerRemoteController(RemoteController)} in order for the system to send
 * media event updates to the {@link OnClientUpdateListener} listener set in the class constructor.
 * Implement the methods of the interface to receive the information published by the active
 * {@link RemoteControlClient} instances.
 * <br>By default an {@link OnClientUpdateListener} implementation will not receive bitmaps for
 * album art. Use {@link #setArtworkConfiguration(int, int)} to receive images as well.
 * <p>
 * Registration requires the {@link OnClientUpdateListener} listener to be one of the enabled
 * notification listeners (see {@link android.service.notification.NotificationListenerService}).
 *
 * @deprecated Use {@link MediaController} instead.
 */
@Deprecated public final class RemoteController
{
    private final static int MAX_BITMAP_DIMENSION = 512;
    private final static int TRANSPORT_UNKNOWN = 0;
    private final static String TAG = "RemoteController";
    private final static boolean DEBUG = false;
    private final static boolean USE_SESSIONS = true;
    private final static Object mGenLock = new Object();
    private final static Object mInfoLock = new Object();
    private final RcDisplay mRcd;
    private final Context mContext;
    private final AudioManager mAudioManager;
    private final int mMaxBitmapDimension;
    private MetadataEditor mMetadataEditor;

    private MediaSessionManager mSessionManager;
    private MediaSessionManager.OnActiveSessionsChangedListener mSessionListener;
    private MediaController.Callback mSessionCb = new MediaControllerCallback();

    /**
     * Synchronized on mGenLock
     */
    private int mClientGenerationIdCurrent = 0;

    /**
     * Synchronized on mInfoLock
     */
    private boolean mIsRegistered = false;
    private PendingIntent mClientPendingIntentCurrent;
    private OnClientUpdateListener mOnClientUpdateListener;
    private PlaybackInfo mLastPlaybackInfo;
    private int mArtworkWidth = -1;
    private int mArtworkHeight = -1;
    private boolean mEnabled = true;
    // synchronized on mInfoLock, for USE_SESSION apis.
    private MediaController mCurrentSession;

    /**
     * Class constructor.
     * @param context the {@link Context}, must be non-null.
     * @param updateListener the listener to be called whenever new client information is available,
     *     must be non-null.
     * @throws IllegalArgumentException
     */
    public RemoteController(Context context, OnClientUpdateListener updateListener)
            throws IllegalArgumentException {
        this(context, updateListener, null);
    }

    /**
     * Class constructor.
     * @param context the {@link Context}, must be non-null.
     * @param updateListener the listener to be called whenever new client information is available,
     *     must be non-null.
     * @param looper the {@link Looper} on which to run the event loop,
     *     or null to use the current thread's looper.
     * @throws java.lang.IllegalArgumentException
     */
    public RemoteController(Context context, OnClientUpdateListener updateListener, Looper looper)
            throws IllegalArgumentException {
        if (context == null) {
            throw new IllegalArgumentException("Invalid null Context");
        }
        if (updateListener == null) {
            throw new IllegalArgumentException("Invalid null OnClientUpdateListener");
        }
        if (looper != null) {
            mEventHandler = new EventHandler(this, looper);
        } else {
            Looper l = Looper.myLooper();
            if (l != null) {
                mEventHandler = new EventHandler(this, l);
            } else {
                throw new IllegalArgumentException("Calling thread not associated with a looper");
            }
        }
        mOnClientUpdateListener = updateListener;
        mContext = context;
        mRcd = new RcDisplay(this);
        mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
        mSessionManager = (MediaSessionManager) context
                .getSystemService(Context.MEDIA_SESSION_SERVICE);
        mSessionListener = new TopTransportSessionListener();

        if (ActivityManager.isLowRamDeviceStatic()) {
            mMaxBitmapDimension = MAX_BITMAP_DIMENSION;
        } else {
            final DisplayMetrics dm = context.getResources().getDisplayMetrics();
            mMaxBitmapDimension = Math.max(dm.widthPixels, dm.heightPixels);
        }
    }


    /**
     * Interface definition for the callbacks to be invoked whenever media events, metadata
     * and playback status are available.
     */
    public interface OnClientUpdateListener {
        /**
         * Called whenever all information, previously received through the other
         * methods of the listener, is no longer valid and is about to be refreshed.
         * This is typically called whenever a new {@link RemoteControlClient} has been selected
         * by the system to have its media information published.
         * @param clearing true if there is no selected RemoteControlClient and no information
         *     is available.
         */
        public void onClientChange(boolean clearing);

        /**
         * Called whenever the playback state has changed.
         * It is called when no information is known about the playback progress in the media and
         * the playback speed.
         * @param state one of the playback states authorized
         *     in {@link RemoteControlClient#setPlaybackState(int)}.
         */
        public void onClientPlaybackStateUpdate(int state);
        /**
         * Called whenever the playback state has changed, and playback position
         * and speed are known.
         * @param state one of the playback states authorized
         *     in {@link RemoteControlClient#setPlaybackState(int)}.
         * @param stateChangeTimeMs the system time at which the state change was reported,
         *     expressed in ms. Based on {@link android.os.SystemClock#elapsedRealtime()}.
         * @param currentPosMs a positive value for the current media playback position expressed
         *     in ms, a negative value if the position is temporarily unknown.
         * @param speed  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 RemoteControlClient#PLAYSTATE_ERROR}).
         */
        public void onClientPlaybackStateUpdate(int state, long stateChangeTimeMs,
                long currentPosMs, float speed);
        /**
         * Called whenever the transport control flags have changed.
         * @param transportControlFlags one of the flags authorized
         *     in {@link RemoteControlClient#setTransportControlFlags(int)}.
         */
        public void onClientTransportControlUpdate(int transportControlFlags);
        /**
         * Called whenever new metadata is available.
         * See the {@link MediaMetadataEditor#putLong(int, long)},
         *  {@link MediaMetadataEditor#putString(int, String)},
         *  {@link MediaMetadataEditor#putBitmap(int, Bitmap)}, and
         *  {@link MediaMetadataEditor#putObject(int, Object)} methods for the various keys that
         *  can be queried.
         * @param metadataEditor the container of the new metadata.
         */
        public void onClientMetadataUpdate(MetadataEditor metadataEditor);
    };


    /**
     * @hide
     */
    public String getRemoteControlClientPackageName() {
        if (USE_SESSIONS) {
            synchronized (mInfoLock) {
                return mCurrentSession != null ? mCurrentSession.getPackageName()
                        : null;
            }
        } else {
            return mClientPendingIntentCurrent != null ?
                    mClientPendingIntentCurrent.getCreatorPackage() : null;
        }
    }

    /**
     * Return the estimated playback position of the current media track or a negative value
     * if not available.
     *
     * <p>The value returned is estimated by the current process and may not be perfect.
     * The time returned by this method is calculated from the last state change time based
     * on the current play position at that time and the last known playback speed.
     * An application may call {@link #setSynchronizationMode(int)} to apply
     * a synchronization policy that will periodically re-sync the estimated position
     * with the RemoteControlClient.</p>
     *
     * @return the current estimated playback position in milliseconds or a negative value
     *         if not available
     *
     * @see OnClientUpdateListener#onClientPlaybackStateUpdate(int, long, long, float)
     */
    public long getEstimatedMediaPosition() {
        if (USE_SESSIONS) {
            synchronized (mInfoLock) {
                if (mCurrentSession != null) {
                    PlaybackState state = mCurrentSession.getPlaybackState();
                    if (state != null) {
                        return state.getPosition();
                    }
                }
            }
        } else {
            final PlaybackInfo lastPlaybackInfo;
            synchronized (mInfoLock) {
                lastPlaybackInfo = mLastPlaybackInfo;
            }
            if (lastPlaybackInfo != null) {
                if (!RemoteControlClient.playbackPositionShouldMove(lastPlaybackInfo.mState)) {
                    return lastPlaybackInfo.mCurrentPosMs;
                }

                // Take the current position at the time of state change and
                // estimate.
                final long thenPos = lastPlaybackInfo.mCurrentPosMs;
                if (thenPos < 0) {
                    return -1;
                }

                final long now = SystemClock.elapsedRealtime();
                final long then = lastPlaybackInfo.mStateChangeTimeMs;
                final long sinceThen = now - then;
                final long scaledSinceThen = (long) (sinceThen * lastPlaybackInfo.mSpeed);
                return thenPos + scaledSinceThen;
            }
        }
        return -1;
    }


    /**
     * Send a simulated key event for a media button to be received by the current client.
     * To simulate a key press, you must first send a KeyEvent built with
     * a {@link KeyEvent#ACTION_DOWN} action, then another event with the {@link KeyEvent#ACTION_UP}
     * action.
     * <p>The key event will be sent to the registered receiver
     * (see {@link AudioManager#registerMediaButtonEventReceiver(PendingIntent)}) whose associated
     * {@link RemoteControlClient}'s metadata and playback state is published (there may be
     * none under some circumstances).
     * @param keyEvent a {@link KeyEvent} instance whose key code is one of
     *     {@link KeyEvent#KEYCODE_MUTE},
     *     {@link KeyEvent#KEYCODE_HEADSETHOOK},
     *     {@link KeyEvent#KEYCODE_MEDIA_PLAY},
     *     {@link KeyEvent#KEYCODE_MEDIA_PAUSE},
     *     {@link KeyEvent#KEYCODE_MEDIA_PLAY_PAUSE},
     *     {@link KeyEvent#KEYCODE_MEDIA_STOP},
     *     {@link KeyEvent#KEYCODE_MEDIA_NEXT},
     *     {@link KeyEvent#KEYCODE_MEDIA_PREVIOUS},
     *     {@link KeyEvent#KEYCODE_MEDIA_REWIND},
     *     {@link KeyEvent#KEYCODE_MEDIA_RECORD},
     *     {@link KeyEvent#KEYCODE_MEDIA_FAST_FORWARD},
     *     {@link KeyEvent#KEYCODE_MEDIA_CLOSE},
     *     {@link KeyEvent#KEYCODE_MEDIA_EJECT},
     *     or {@link KeyEvent#KEYCODE_MEDIA_AUDIO_TRACK}.
     * @return true if the event was successfully sent, false otherwise.
     * @throws IllegalArgumentException
     */
    public boolean sendMediaKeyEvent(KeyEvent keyEvent) throws IllegalArgumentException {
        if (!KeyEvent.isMediaKey(keyEvent.getKeyCode())) {
            throw new IllegalArgumentException("not a media key event");
        }
        if (USE_SESSIONS) {
            synchronized (mInfoLock) {
                if (mCurrentSession != null) {
                    return mCurrentSession.dispatchMediaButtonEvent(keyEvent);
                }
                return false;
            }
        } else {
            final PendingIntent pi;
            synchronized (mInfoLock) {
                if (!mIsRegistered) {
                    Log.e(TAG,
                            "Cannot use sendMediaKeyEvent() from an unregistered RemoteController");
                    return false;
                }
                if (!mEnabled) {
                    Log.e(TAG, "Cannot use sendMediaKeyEvent() from a disabled RemoteController");
                    return false;
                }
                pi = mClientPendingIntentCurrent;
            }
            if (pi != null) {
                Intent intent = new Intent(Intent.ACTION_MEDIA_BUTTON);
                intent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
                try {
                    pi.send(mContext, 0, intent);
                } catch (CanceledException e) {
                    Log.e(TAG, "Error sending intent for media button down: ", e);
                    return false;
                }
            } else {
                Log.i(TAG, "No-op when sending key click, no receiver right now");
                return false;
            }
        }
        return true;
    }


    /**
     * Sets the new playback position.
     * This method can only be called on a registered RemoteController.
     * @param timeMs a 0 or positive value for the new playback position, expressed in ms.
     * @return true if the command to set the playback position was successfully sent.
     * @throws IllegalArgumentException
     */
    public boolean seekTo(long timeMs) throws IllegalArgumentException {
        if (!mEnabled) {
            Log.e(TAG, "Cannot use seekTo() from a disabled RemoteController");
            return false;
        }
        if (timeMs < 0) {
            throw new IllegalArgumentException("illegal negative time value");
        }
        synchronized (mInfoLock) {
            if (mCurrentSession != null) {
                mCurrentSession.getTransportControls().seekTo(timeMs);
            }
        }
        return true;
    }


    /**
     * @hide
     * @param wantBitmap
     * @param width
     * @param height
     * @return true if successful
     * @throws IllegalArgumentException
     */
    public boolean setArtworkConfiguration(boolean wantBitmap, int width, int height)
            throws IllegalArgumentException {
        synchronized (mInfoLock) {
            if (wantBitmap) {
                if ((width > 0) && (height > 0)) {
                    if (width > mMaxBitmapDimension) { width = mMaxBitmapDimension; }
                    if (height > mMaxBitmapDimension) { height = mMaxBitmapDimension; }
                    mArtworkWidth = width;
                    mArtworkHeight = height;
                } else {
                    throw new IllegalArgumentException("Invalid dimensions");
                }
            } else {
                mArtworkWidth = -1;
                mArtworkHeight = -1;
            }
        }
        return true;
    }

    /**
     * Set the maximum artwork image dimensions to be received in the metadata.
     * No bitmaps will be received unless this has been specified.
     * @param width the maximum width in pixels
     * @param height  the maximum height in pixels
     * @return true if the artwork dimension was successfully set.
     * @throws IllegalArgumentException
     */
    public boolean setArtworkConfiguration(int width, int height) throws IllegalArgumentException {
        return setArtworkConfiguration(true, width, height);
    }

    /**
     * Prevents this RemoteController from receiving artwork images.
     * @return true if receiving artwork images was successfully disabled.
     */
    public boolean clearArtworkConfiguration() {
        return setArtworkConfiguration(false, -1, -1);
    }


    /**
     * Default playback position synchronization mode where the RemoteControlClient is not
     * asked regularly for its playback position to see if it has drifted from the estimated
     * position.
     */
    public static final int POSITION_SYNCHRONIZATION_NONE = 0;

    /**
     * The playback position synchronization mode where the RemoteControlClient instances which
     * expose their playback position to the framework, will be regularly polled to check
     * whether any drift has been noticed between their estimated position and the one they report.
     * Note that this mode should only ever be used when needing to display very accurate playback
     * position, as regularly polling a RemoteControlClient for its position may have an impact
     * on battery life (if applicable) when this query will trigger network transactions in the
     * case of remote playback.
     */
    public static final int POSITION_SYNCHRONIZATION_CHECK = 1;

    /**
     * Set the playback position synchronization mode.
     * Must be called on a registered RemoteController.
     * @param sync {@link #POSITION_SYNCHRONIZATION_NONE} or {@link #POSITION_SYNCHRONIZATION_CHECK}
     * @return true if the synchronization mode was successfully set.
     * @throws IllegalArgumentException
     */
    public boolean setSynchronizationMode(int sync) throws IllegalArgumentException {
        if ((sync != POSITION_SYNCHRONIZATION_NONE) && (sync != POSITION_SYNCHRONIZATION_CHECK)) {
            throw new IllegalArgumentException("Unknown synchronization mode " + sync);
        }
        if (!mIsRegistered) {
            Log.e(TAG, "Cannot set synchronization mode on an unregistered RemoteController");
            return false;
        }
        mAudioManager.remoteControlDisplayWantsPlaybackPositionSync(mRcd,
                POSITION_SYNCHRONIZATION_CHECK == sync);
        return true;
    }


    /**
     * Creates a {@link MetadataEditor} for updating metadata values of the editable keys of
     * the current {@link RemoteControlClient}.
     * This method can only be called on a registered RemoteController.
     * @return a new MetadataEditor instance.
     */
    public MetadataEditor editMetadata() {
        MetadataEditor editor = new MetadataEditor();
        editor.mEditorMetadata = new Bundle();
        editor.mEditorArtwork = null;
        editor.mMetadataChanged = true;
        editor.mArtworkChanged = true;
        editor.mEditableKeys = 0;
        return editor;
    }

    /**
     * A class to read the metadata published by a {@link RemoteControlClient}, or send a
     * {@link RemoteControlClient} new values for keys that can be edited.
     */
    public class MetadataEditor extends MediaMetadataEditor {
        /**
         * @hide
         */
        protected MetadataEditor() { }

        /**
         * @hide
         */
        protected MetadataEditor(Bundle metadata, long editableKeys) {
            mEditorMetadata = metadata;
            mEditableKeys = editableKeys;

            mEditorArtwork = (Bitmap) metadata.getParcelable(
                    String.valueOf(MediaMetadataEditor.BITMAP_KEY_ARTWORK));
            if (mEditorArtwork != null) {
                cleanupBitmapFromBundle(MediaMetadataEditor.BITMAP_KEY_ARTWORK);
            }

            mMetadataChanged = true;
            mArtworkChanged = true;
            mApplied = false;
        }

        private void cleanupBitmapFromBundle(int key) {
            if (METADATA_KEYS_TYPE.get(key, METADATA_TYPE_INVALID) == METADATA_TYPE_BITMAP) {
                mEditorMetadata.remove(String.valueOf(key));
            }
        }

        /**
         * Applies all of the metadata changes that have been set since the MediaMetadataEditor
         * instance was created with {@link RemoteController#editMetadata()}
         * or since {@link #clear()} was called.
         */
        public synchronized void apply() {
            // "applying" a metadata bundle in RemoteController is only for sending edited
            // key values back to the RemoteControlClient, so here we only care about the only
            // editable key we support: RATING_KEY_BY_USER
            if (!mMetadataChanged) {
                return;
            }
            synchronized (mInfoLock) {
                if (mCurrentSession != null) {
                    if (mEditorMetadata.containsKey(
                            String.valueOf(MediaMetadataEditor.RATING_KEY_BY_USER))) {
                        Rating rating = (Rating) getObject(
                                MediaMetadataEditor.RATING_KEY_BY_USER, null);
                        if (rating != null) {
                            mCurrentSession.getTransportControls().setRating(rating);
                        }
                    }
                }
            }
            // NOT setting mApplied to true as this type of MetadataEditor will be applied
            // multiple times, whenever the user of a RemoteController needs to change the
            // metadata (e.g. user changes the rating of a song more than once during playback)
            mApplied = false;
        }

    }


    //==================================================
    // Implementation of IRemoteControlDisplay interface
    private static class RcDisplay extends IRemoteControlDisplay.Stub {
        private final WeakReference<RemoteController> mController;

        RcDisplay(RemoteController rc) {
            mController = new WeakReference<RemoteController>(rc);
        }

        public void setCurrentClientId(int genId, PendingIntent clientMediaIntent,
                boolean clearing) {
            final RemoteController rc = mController.get();
            if (rc == null) {
                return;
            }
            boolean isNew = false;
            synchronized(mGenLock) {
                if (rc.mClientGenerationIdCurrent != genId) {
                    rc.mClientGenerationIdCurrent = genId;
                    isNew = true;
                }
            }
            if (clientMediaIntent != null) {
                sendMsg(rc.mEventHandler, MSG_NEW_PENDING_INTENT, SENDMSG_REPLACE,
                        genId /*arg1*/, 0, clientMediaIntent /*obj*/, 0 /*delay*/);
            }
            if (isNew || clearing) {
                sendMsg(rc.mEventHandler, MSG_CLIENT_CHANGE, SENDMSG_REPLACE,
                        genId /*arg1*/, clearing ? 1 : 0, null /*obj*/, 0 /*delay*/);
            }
        }

        public void setEnabled(boolean enabled) {
            final RemoteController rc = mController.get();
            if (rc == null) {
                return;
            }
            sendMsg(rc.mEventHandler, MSG_DISPLAY_ENABLE, SENDMSG_REPLACE,
                    enabled ? 1 : 0 /*arg1*/, 0, null /*obj*/, 0 /*delay*/);
        }

        public void setPlaybackState(int genId, int state,
                long stateChangeTimeMs, long currentPosMs, float speed) {
            final RemoteController rc = mController.get();
            if (rc == null) {
                return;
            }
            if (DEBUG) {
                Log.d(TAG, "> new playback state: genId="+genId
                        + " state="+ state
                        + " changeTime="+ stateChangeTimeMs
                        + " pos=" + currentPosMs
                        + "ms speed=" + speed);
            }

            synchronized(mGenLock) {
                if (rc.mClientGenerationIdCurrent != genId) {
                    return;
                }
            }
            final PlaybackInfo playbackInfo =
                    new PlaybackInfo(state, stateChangeTimeMs, currentPosMs, speed);
            sendMsg(rc.mEventHandler, MSG_NEW_PLAYBACK_INFO, SENDMSG_REPLACE,
                    genId /*arg1*/, 0, playbackInfo /*obj*/, 0 /*delay*/);

        }

        public void setTransportControlInfo(int genId, int transportControlFlags,
                int posCapabilities) {
            final RemoteController rc = mController.get();
            if (rc == null) {
                return;
            }
            synchronized(mGenLock) {
                if (rc.mClientGenerationIdCurrent != genId) {
                    return;
                }
            }
            sendMsg(rc.mEventHandler, MSG_NEW_TRANSPORT_INFO, SENDMSG_REPLACE,
                    genId /*arg1*/, transportControlFlags /*arg2*/,
                    null /*obj*/, 0 /*delay*/);
        }

        public void setMetadata(int genId, Bundle metadata) {
            final RemoteController rc = mController.get();
            if (rc == null) {
                return;
            }
            if (DEBUG) { Log.e(TAG, "setMetadata("+genId+")"); }
            if (metadata == null) {
                return;
            }
            synchronized(mGenLock) {
                if (rc.mClientGenerationIdCurrent != genId) {
                    return;
                }
            }
            sendMsg(rc.mEventHandler, MSG_NEW_METADATA, SENDMSG_QUEUE,
                    genId /*arg1*/, 0 /*arg2*/,
                    metadata /*obj*/, 0 /*delay*/);
        }

        public void setArtwork(int genId, Bitmap artwork) {
            final RemoteController rc = mController.get();
            if (rc == null) {
                return;
            }
            if (DEBUG) { Log.v(TAG, "setArtwork("+genId+")"); }
            synchronized(mGenLock) {
                if (rc.mClientGenerationIdCurrent != genId) {
                    return;
                }
            }
            Bundle metadata = new Bundle(1);
            metadata.putParcelable(String.valueOf(MediaMetadataEditor.BITMAP_KEY_ARTWORK), artwork);
            sendMsg(rc.mEventHandler, MSG_NEW_METADATA, SENDMSG_QUEUE,
                    genId /*arg1*/, 0 /*arg2*/,
                    metadata /*obj*/, 0 /*delay*/);
        }

        public void setAllMetadata(int genId, Bundle metadata, Bitmap artwork) {
            final RemoteController rc = mController.get();
            if (rc == null) {
                return;
            }
            if (DEBUG) { Log.e(TAG, "setAllMetadata("+genId+")"); }
            if ((metadata == null) && (artwork == null)) {
                return;
            }
            synchronized(mGenLock) {
                if (rc.mClientGenerationIdCurrent != genId) {
                    return;
                }
            }
            if (metadata == null) {
                metadata = new Bundle(1);
            }
            if (artwork != null) {
                metadata.putParcelable(String.valueOf(MediaMetadataEditor.BITMAP_KEY_ARTWORK),
                        artwork);
            }
            sendMsg(rc.mEventHandler, MSG_NEW_METADATA, SENDMSG_QUEUE,
                    genId /*arg1*/, 0 /*arg2*/,
                    metadata /*obj*/, 0 /*delay*/);
        }
    }

    /**
     * This receives updates when the current session changes. This is
     * registered to receive the updates on the handler thread so it can call
     * directly into the appropriate methods.
     */
    private class MediaControllerCallback extends MediaController.Callback {
        @Override
        public void onPlaybackStateChanged(PlaybackState state) {
            onNewPlaybackState(state);
        }

        @Override
        public void onMetadataChanged(MediaMetadata metadata) {
            onNewMediaMetadata(metadata);
        }
    }

    /**
     * Listens for changes to the active session stack and replaces the
     * currently tracked session if it has changed.
     */
    private class TopTransportSessionListener implements
            MediaSessionManager.OnActiveSessionsChangedListener {

        @Override
        public void onActiveSessionsChanged(List<MediaController> controllers) {
            int size = controllers.size();
            for (int i = 0; i < size; i++) {
                MediaController controller = controllers.get(i);
                long flags = controller.getFlags();
                // We only care about sessions that handle transport controls,
                // which will be true for apps using RCC
                if ((flags & MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS) != 0) {
                    updateController(controller);
                    return;
                }
            }
            updateController(null);
        }

    }

    //==================================================
    // Event handling
    private final EventHandler mEventHandler;
    private final static int MSG_NEW_PENDING_INTENT = 0;
    private final static int MSG_NEW_PLAYBACK_INFO =  1;
    private final static int MSG_NEW_TRANSPORT_INFO = 2;
    private final static int MSG_NEW_METADATA       = 3; // msg always has non-null obj parameter
    private final static int MSG_CLIENT_CHANGE      = 4;
    private final static int MSG_DISPLAY_ENABLE     = 5;
    private final static int MSG_NEW_PLAYBACK_STATE = 6;
    private final static int MSG_NEW_MEDIA_METADATA = 7;

    private class EventHandler extends Handler {

        public EventHandler(RemoteController rc, Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            switch(msg.what) {
                case MSG_NEW_PENDING_INTENT:
                    onNewPendingIntent(msg.arg1, (PendingIntent) msg.obj);
                    break;
                case MSG_NEW_PLAYBACK_INFO:
                    onNewPlaybackInfo(msg.arg1, (PlaybackInfo) msg.obj);
                    break;
                case MSG_NEW_TRANSPORT_INFO:
                    onNewTransportInfo(msg.arg1, msg.arg2);
                    break;
                case MSG_NEW_METADATA:
                    onNewMetadata(msg.arg1, (Bundle)msg.obj);
                    break;
                case MSG_CLIENT_CHANGE:
                    onClientChange(msg.arg1, msg.arg2 == 1);
                    break;
                case MSG_DISPLAY_ENABLE:
                    onDisplayEnable(msg.arg1 == 1);
                    break;
                case MSG_NEW_PLAYBACK_STATE:
                    // same as new playback info but using new apis
                    onNewPlaybackState((PlaybackState) msg.obj);
                    break;
                case MSG_NEW_MEDIA_METADATA:
                    onNewMediaMetadata((MediaMetadata) msg.obj);
                    break;
                default:
                    Log.e(TAG, "unknown event " + msg.what);
            }
        }
    }

    /**
     * @hide
     */
    void startListeningToSessions() {
        final ComponentName listenerComponent = new ComponentName(mContext,
                mOnClientUpdateListener.getClass());
        mSessionManager.addOnActiveSessionsChangedListener(mSessionListener, listenerComponent,
                UserHandle.myUserId(), null);
        mSessionListener.onActiveSessionsChanged(mSessionManager
                .getActiveSessions(listenerComponent));
        if (DEBUG) {
            Log.d(TAG, "Registered session listener with component " + listenerComponent
                    + " for user " + UserHandle.myUserId());
        }
    }

    /**
     * @hide
     */
    void stopListeningToSessions() {
        mSessionManager.removeOnActiveSessionsChangedListener(mSessionListener);
        if (DEBUG) {
            Log.d(TAG, "Unregistered session listener for user "
                    + UserHandle.myUserId());
        }
    }

    /** If the msg is already queued, replace it with this one. */
    private static final int SENDMSG_REPLACE = 0;
    /** If the msg is already queued, ignore this one and leave the old. */
    private static final int SENDMSG_NOOP = 1;
    /** If the msg is already queued, queue this one and leave the old. */
    private static final int SENDMSG_QUEUE = 2;

    private static void sendMsg(Handler handler, int msg, int existingMsgPolicy,
            int arg1, int arg2, Object obj, int delayMs) {
        if (handler == null) {
            Log.e(TAG, "null event handler, will not deliver message " + msg);
            return;
        }
        if (existingMsgPolicy == SENDMSG_REPLACE) {
            handler.removeMessages(msg);
        } else if (existingMsgPolicy == SENDMSG_NOOP && handler.hasMessages(msg)) {
            return;
        }
        handler.sendMessageDelayed(handler.obtainMessage(msg, arg1, arg2, obj), delayMs);
    }

    ///////////// These calls are used by the old APIs with RCC and RCD //////////////////////
    private void onNewPendingIntent(int genId, PendingIntent pi) {
        synchronized(mGenLock) {
            if (mClientGenerationIdCurrent != genId) {
                return;
            }
        }
        synchronized(mInfoLock) {
            mClientPendingIntentCurrent = pi;
        }
    }

    private void onNewPlaybackInfo(int genId, PlaybackInfo pi) {
        synchronized(mGenLock) {
            if (mClientGenerationIdCurrent != genId) {
                return;
            }
        }
        final OnClientUpdateListener l;
        synchronized(mInfoLock) {
            l = this.mOnClientUpdateListener;
            mLastPlaybackInfo = pi;
        }
        if (l != null) {
            if (pi.mCurrentPosMs == RemoteControlClient.PLAYBACK_POSITION_ALWAYS_UNKNOWN) {
                l.onClientPlaybackStateUpdate(pi.mState);
            } else {
                l.onClientPlaybackStateUpdate(pi.mState, pi.mStateChangeTimeMs, pi.mCurrentPosMs,
                        pi.mSpeed);
            }
        }
    }

    private void onNewTransportInfo(int genId, int transportControlFlags) {
        synchronized(mGenLock) {
            if (mClientGenerationIdCurrent != genId) {
                return;
            }
        }
        final OnClientUpdateListener l;
        synchronized(mInfoLock) {
            l = mOnClientUpdateListener;
        }
        if (l != null) {
            l.onClientTransportControlUpdate(transportControlFlags);
        }
    }

    /**
     * @param genId
     * @param metadata guaranteed to be always non-null
     */
    private void onNewMetadata(int genId, Bundle metadata) {
        synchronized(mGenLock) {
            if (mClientGenerationIdCurrent != genId) {
                return;
            }
        }
        final OnClientUpdateListener l;
        final MetadataEditor metadataEditor;
        // prepare the received Bundle to be used inside a MetadataEditor
        final long editableKeys = metadata.getLong(
                String.valueOf(MediaMetadataEditor.KEY_EDITABLE_MASK), 0);
        if (editableKeys != 0) {
            metadata.remove(String.valueOf(MediaMetadataEditor.KEY_EDITABLE_MASK));
        }
        synchronized(mInfoLock) {
            l = mOnClientUpdateListener;
            if ((mMetadataEditor != null) && (mMetadataEditor.mEditorMetadata != null)) {
                if (mMetadataEditor.mEditorMetadata != metadata) {
                    // existing metadata, merge existing and new
                    mMetadataEditor.mEditorMetadata.putAll(metadata);
                }

                mMetadataEditor.putBitmap(MediaMetadataEditor.BITMAP_KEY_ARTWORK,
                        (Bitmap)metadata.getParcelable(
                                String.valueOf(MediaMetadataEditor.BITMAP_KEY_ARTWORK)));
                mMetadataEditor.cleanupBitmapFromBundle(MediaMetadataEditor.BITMAP_KEY_ARTWORK);
            } else {
                mMetadataEditor = new MetadataEditor(metadata, editableKeys);
            }
            metadataEditor = mMetadataEditor;
        }
        if (l != null) {
            l.onClientMetadataUpdate(metadataEditor);
        }
    }

    private void onClientChange(int genId, boolean clearing) {
        synchronized(mGenLock) {
            if (mClientGenerationIdCurrent != genId) {
                return;
            }
        }
        final OnClientUpdateListener l;
        synchronized(mInfoLock) {
            l = mOnClientUpdateListener;
            mMetadataEditor = null;
        }
        if (l != null) {
            l.onClientChange(clearing);
        }
    }

    private void onDisplayEnable(boolean enabled) {
        final OnClientUpdateListener l;
        synchronized(mInfoLock) {
            mEnabled = enabled;
            l = this.mOnClientUpdateListener;
        }
        if (!enabled) {
            // when disabling, reset all info sent to the user
            final int genId;
            synchronized (mGenLock) {
                genId = mClientGenerationIdCurrent;
            }
            // send "stopped" state, happened "now", playback position is 0, speed 0.0f
            final PlaybackInfo pi = new PlaybackInfo(RemoteControlClient.PLAYSTATE_STOPPED,
                    SystemClock.elapsedRealtime() /*stateChangeTimeMs*/,
                    0 /*currentPosMs*/, 0.0f /*speed*/);
            sendMsg(mEventHandler, MSG_NEW_PLAYBACK_INFO, SENDMSG_REPLACE,
                    genId /*arg1*/, 0 /*arg2, ignored*/, pi /*obj*/, 0 /*delay*/);
            // send "blank" transport control info: no controls are supported
            sendMsg(mEventHandler, MSG_NEW_TRANSPORT_INFO, SENDMSG_REPLACE,
                    genId /*arg1*/, 0 /*arg2, no flags*/,
                    null /*obj, ignored*/, 0 /*delay*/);
            // send dummy metadata with empty string for title and artist, duration of 0
            Bundle metadata = new Bundle(3);
            metadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_TITLE), "");
            metadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_ARTIST), "");
            metadata.putLong(String.valueOf(MediaMetadataRetriever.METADATA_KEY_DURATION), 0);
            sendMsg(mEventHandler, MSG_NEW_METADATA, SENDMSG_QUEUE,
                    genId /*arg1*/, 0 /*arg2, ignored*/, metadata /*obj*/, 0 /*delay*/);
        }
    }

    ///////////// These calls are used by the new APIs with Sessions //////////////////////
    private void updateController(MediaController controller) {
        if (DEBUG) {
            Log.d(TAG, "Updating controller to " + controller + " previous controller is "
                    + mCurrentSession);
        }
        synchronized (mInfoLock) {
            if (controller == null) {
                if (mCurrentSession != null) {
                    mCurrentSession.removeCallback(mSessionCb);
                    mCurrentSession = null;
                    sendMsg(mEventHandler, MSG_CLIENT_CHANGE, SENDMSG_REPLACE,
                            0 /* genId */, 1 /* clearing */, null /* obj */, 0 /* delay */);
                }
            } else if (mCurrentSession == null
                    || !controller.getSessionToken()
                            .equals(mCurrentSession.getSessionToken())) {
                if (mCurrentSession != null) {
                    mCurrentSession.removeCallback(mSessionCb);
                }
                sendMsg(mEventHandler, MSG_CLIENT_CHANGE, SENDMSG_REPLACE,
                        0 /* genId */, 0 /* clearing */, null /* obj */, 0 /* delay */);
                mCurrentSession = controller;
                mCurrentSession.addCallback(mSessionCb, mEventHandler);

                PlaybackState state = controller.getPlaybackState();
                sendMsg(mEventHandler, MSG_NEW_PLAYBACK_STATE, SENDMSG_REPLACE,
                        0 /* genId */, 0, state /* obj */, 0 /* delay */);

                MediaMetadata metadata = controller.getMetadata();
                sendMsg(mEventHandler, MSG_NEW_MEDIA_METADATA, SENDMSG_REPLACE,
                        0 /* arg1 */, 0 /* arg2 */, metadata /* obj */, 0 /* delay */);
            }
            // else same controller, no need to update
        }
    }

    private void onNewPlaybackState(PlaybackState state) {
        final OnClientUpdateListener l;
        synchronized (mInfoLock) {
            l = this.mOnClientUpdateListener;
        }
        if (l != null) {
            int playstate = state == null ? RemoteControlClient.PLAYSTATE_NONE : PlaybackState
                    .getRccStateFromState(state.getState());
            if (state == null || state.getPosition() == PlaybackState.PLAYBACK_POSITION_UNKNOWN) {
                l.onClientPlaybackStateUpdate(playstate);
            } else {
                l.onClientPlaybackStateUpdate(playstate, state.getLastPositionUpdateTime(),
                        state.getPosition(), state.getPlaybackSpeed());
            }
            if (state != null) {
                l.onClientTransportControlUpdate(
                        PlaybackState.getRccControlFlagsFromActions(state.getActions()));
            }
        }
    }

    private void onNewMediaMetadata(MediaMetadata metadata) {
        if (metadata == null) {
            // RemoteController only handles non-null metadata
            return;
        }
        final OnClientUpdateListener l;
        final MetadataEditor metadataEditor;
        // prepare the received Bundle to be used inside a MetadataEditor
        synchronized(mInfoLock) {
            l = mOnClientUpdateListener;
            boolean canRate = mCurrentSession != null
                    && mCurrentSession.getRatingType() != Rating.RATING_NONE;
            long editableKeys = canRate ? MediaMetadataEditor.RATING_KEY_BY_USER : 0;
            Bundle legacyMetadata = MediaSessionLegacyHelper.getOldMetadata(metadata,
                    mArtworkWidth, mArtworkHeight);
            mMetadataEditor = new MetadataEditor(legacyMetadata, editableKeys);
            metadataEditor = mMetadataEditor;
        }
        if (l != null) {
            l.onClientMetadataUpdate(metadataEditor);
        }
    }

    //==================================================
    private static class PlaybackInfo {
        int mState;
        long mStateChangeTimeMs;
        long mCurrentPosMs;
        float mSpeed;

        PlaybackInfo(int state, long stateChangeTimeMs, long currentPosMs, float speed) {
            mState = state;
            mStateChangeTimeMs = stateChangeTimeMs;
            mCurrentPosMs = currentPosMs;
            mSpeed = speed;
        }
    }

    /**
     * @hide
     * Used by AudioManager to mark this instance as registered.
     * @param registered
     */
    void setIsRegistered(boolean registered) {
        synchronized (mInfoLock) {
            mIsRegistered = registered;
        }
    }

    /**
     * @hide
     * Used by AudioManager to access binder to be registered/unregistered inside MediaFocusControl
     * @return
     */
    RcDisplay getRcDisplay() {
        return mRcd;
    }

    /**
     * @hide
     * Used by AudioManager to read the current artwork dimension
     * @return array containing width (index 0) and height (index 1) of currently set artwork size
     */
    int[] getArtworkSize() {
        synchronized (mInfoLock) {
            int[] size = { mArtworkWidth, mArtworkHeight };
            return size;
        }
    }

    /**
     * @hide
     * Used by AudioManager to access user listener receiving the client update notifications
     * @return
     */
    OnClientUpdateListener getUpdateListener() {
        return mOnClientUpdateListener;
    }
}
