/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.media;

import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.media.AudioAttributes;
import android.media.AudioManager;
import android.media.AudioManagerInternal;
import android.media.AudioSystem;
import android.media.MediaMetadata;
import android.media.MediaParceledListSlice;
import android.media.Rating;
import android.media.VolumeProvider;
import android.media.session.ControllerCallbackLink;
import android.media.session.ISession;
import android.media.session.ISessionController;
import android.media.session.MediaController;
import android.media.session.MediaController.PlaybackInfo;
import android.media.session.MediaSession;
import android.media.session.MediaSession.QueueItem;
import android.media.session.PlaybackState;
import android.media.session.SessionCallbackLink;
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
import android.os.DeadObjectException;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.Process;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.SystemClock;
import android.util.Log;
import android.util.Slog;
import android.view.KeyEvent;

import com.android.server.LocalServices;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

/**
 * This is the system implementation of a Session. Apps will interact with the
 * MediaSession wrapper class instead.
 */
public class MediaSessionRecord implements IBinder.DeathRecipient {
    private static final String TAG = "MediaSessionRecord";
    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);

    /**
     * The amount of time we'll send an assumed volume after the last volume
     * command before reverting to the last reported volume.
     */
    private static final int OPTIMISTIC_VOLUME_TIMEOUT = 1000;

    private final MessageHandler mHandler;

    private final int mOwnerPid;
    private final int mOwnerUid;
    private final int mUserId;
    private final String mPackageName;
    private final String mTag;
    private final Bundle mSessionInfo;
    private final ControllerStub mController;
    private final MediaSession.Token mSessionToken;
    private final SessionStub mSession;
    private final SessionCb mSessionCb;
    private final MediaSessionService.ServiceImpl mService;
    private final Context mContext;

    private final Object mLock = new Object();
    private final ArrayList<ControllerCallbackLinkHolder> mControllerCallbackHolders =
            new ArrayList<>();

    private long mFlags;
    private PendingIntent mMediaButtonReceiver;
    private PendingIntent mLaunchIntent;

    // TransportPerformer fields
    private Bundle mExtras;
    // Note: Avoid unparceling the bundle inside MediaMetadata since unparceling in system process
    // may result in throwing an exception.
    private MediaMetadata mMetadata;
    private PlaybackState mPlaybackState;
    private List<QueueItem> mQueue;
    private CharSequence mQueueTitle;
    private int mRatingType;
    // End TransportPerformer fields

    // Volume handling fields
    private AudioAttributes mAudioAttrs;
    private AudioManager mAudioManager;
    private AudioManagerInternal mAudioManagerInternal;
    private int mVolumeType = PlaybackInfo.PLAYBACK_TYPE_LOCAL;
    private int mVolumeControlType = VolumeProvider.VOLUME_CONTROL_ABSOLUTE;
    private int mMaxVolume = 0;
    private int mCurrentVolume = 0;
    private int mOptimisticVolume = -1;
    // End volume handling fields

    private boolean mIsActive = false;
    private boolean mDestroyed = false;

    private long mDuration = -1;
    private String mMetadataDescription;

    public MediaSessionRecord(int ownerPid, int ownerUid, int userId, String ownerPackageName,
            SessionCallbackLink cb, String tag, Bundle sessionInfo,
            MediaSessionService.ServiceImpl service, Looper handlerLooper) {
        mOwnerPid = ownerPid;
        mOwnerUid = ownerUid;
        mUserId = userId;
        mPackageName = ownerPackageName;
        mTag = tag;
        mSessionInfo = sessionInfo;
        mController = new ControllerStub();
        mSessionToken = new MediaSession.Token(mController);
        mSession = new SessionStub();
        mSessionCb = new SessionCb(cb);
        mService = service;
        mContext = mService.getContext();
        mHandler = new MessageHandler(handlerLooper);
        mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
        mAudioManagerInternal = LocalServices.getService(AudioManagerInternal.class);
        mAudioAttrs = new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_MEDIA).build();
    }

    /**
     * Get the session binder for the {@link MediaSession}.
     *
     * @return The session binder apps talk to.
     */
    public ISession getSessionBinder() {
        return mSession;
    }

    /**
     * Get the controller binder for the {@link MediaController}.
     *
     * @return The controller binder apps talk to.
     */
    public ISessionController getControllerBinder() {
        return mController;
    }

    /**
     * Get the session token for creating {@link MediaController}.
     *
     * @return The session token.
     */
    public MediaSession.Token getSessionToken() {
        return mSessionToken;
    }

    /**
     * Get the info for this session.
     *
     * @return Info that identifies this session.
     */
    public String getPackageName() {
        return mPackageName;
    }

    /**
     * Get the tag for the session.
     *
     * @return The session's tag.
     */
    public String getTag() {
        return mTag;
    }

    /**
     * Get the intent the app set for their media button receiver.
     *
     * @return The pending intent set by the app or null.
     */
    public PendingIntent getMediaButtonReceiver() {
        return mMediaButtonReceiver;
    }

    /**
     * Get this session's flags.
     *
     * @return The flags for this session.
     */
    public long getFlags() {
        return mFlags;
    }

    /**
     * Check if this session has the specified flag.
     *
     * @param flag The flag to check.
     * @return True if this session has that flag set, false otherwise.
     */
    public boolean hasFlag(int flag) {
        return (mFlags & flag) != 0;
    }

    /**
     * Get the UID this session was created for.
     *
     * @return The UID for this session.
     */
    public int getUid() {
        return mOwnerUid;
    }

    /**
     * Get the user id this session was created for.
     *
     * @return The user id for this session.
     */
    public int getUserId() {
        return mUserId;
    }

    /**
     * Check if this session has system priorty and should receive media buttons
     * before any other sessions.
     *
     * @return True if this is a system priority session, false otherwise
     */
    public boolean isSystemPriority() {
        return (mFlags & MediaSession.FLAG_EXCLUSIVE_GLOBAL_PRIORITY) != 0;
    }

    /**
     * Send a volume adjustment to the session owner. Direction must be one of
     * {@link AudioManager#ADJUST_LOWER}, {@link AudioManager#ADJUST_RAISE},
     * {@link AudioManager#ADJUST_SAME}.
     *
     * @param packageName The package that made the original volume request.
     * @param opPackageName The op package that made the original volume request.
     * @param pid The pid that made the original volume request.
     * @param uid The uid that made the original volume request.
     * @param caller caller binder. can be {@code null} if it's from the volume key.
     * @param asSystemService {@code true} if the event sent to the session as if it was come from
     *          the system service instead of the app process. This helps sessions to distinguish
     *          between the key injection by the app and key events from the hardware devices.
     *          Should be used only when the volume key events aren't handled by foreground
     *          activity. {@code false} otherwise to tell session about the real caller.
     * @param direction The direction to adjust volume in.
     * @param flags Any of the flags from {@link AudioManager}.
     * @param useSuggested True to use adjustSuggestedStreamVolume instead of
     */
    public void adjustVolume(String packageName, String opPackageName, int pid, int uid,
            ControllerCallbackLink caller, boolean asSystemService, int direction, int flags,
            boolean useSuggested) {
        int previousFlagPlaySound = flags & AudioManager.FLAG_PLAY_SOUND;
        if (isPlaybackActive() || hasFlag(MediaSession.FLAG_EXCLUSIVE_GLOBAL_PRIORITY)) {
            flags &= ~AudioManager.FLAG_PLAY_SOUND;
        }
        if (mVolumeType == PlaybackInfo.PLAYBACK_TYPE_LOCAL) {
            // Adjust the volume with a handler not to be blocked by other system service.
            int stream = AudioAttributes.toLegacyStreamType(mAudioAttrs);
            postAdjustLocalVolume(stream, direction, flags, opPackageName, pid, uid,
                    asSystemService, useSuggested, previousFlagPlaySound);
        } else {
            if (mVolumeControlType == VolumeProvider.VOLUME_CONTROL_FIXED) {
                // Nothing to do, the volume cannot be changed
                return;
            }
            if (direction == AudioManager.ADJUST_TOGGLE_MUTE
                    || direction == AudioManager.ADJUST_MUTE
                    || direction == AudioManager.ADJUST_UNMUTE) {
                Log.w(TAG, "Muting remote playback is not supported");
                return;
            }
            if (DEBUG) {
                Log.w(TAG, "adjusting volume, pkg=" + packageName + ", asSystemService="
                        + asSystemService + ", dir=" + direction);
            }
            mSessionCb.adjustVolume(packageName, pid, uid, caller, asSystemService, direction);

            int volumeBefore = (mOptimisticVolume < 0 ? mCurrentVolume : mOptimisticVolume);
            mOptimisticVolume = volumeBefore + direction;
            mOptimisticVolume = Math.max(0, Math.min(mOptimisticVolume, mMaxVolume));
            mHandler.removeCallbacks(mClearOptimisticVolumeRunnable);
            mHandler.postDelayed(mClearOptimisticVolumeRunnable, OPTIMISTIC_VOLUME_TIMEOUT);
            if (volumeBefore != mOptimisticVolume) {
                pushVolumeUpdate();
            }
            mService.notifyRemoteVolumeChanged(flags, this);

            if (DEBUG) {
                Log.d(TAG, "Adjusted optimistic volume to " + mOptimisticVolume + " max is "
                        + mMaxVolume);
            }
        }
    }

    private void setVolumeTo(String packageName, String opPackageName, int pid, int uid,
            ControllerCallbackLink caller, int value, int flags) {
        if (mVolumeType == PlaybackInfo.PLAYBACK_TYPE_LOCAL) {
            int stream = AudioAttributes.toLegacyStreamType(mAudioAttrs);
            final int volumeValue = value;
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    try {
                        mAudioManagerInternal.setStreamVolumeForUid(stream, volumeValue, flags,
                                opPackageName, uid);
                    } catch (IllegalArgumentException | SecurityException e) {
                        Log.e(TAG, "Cannot set volume: stream=" + stream + ", value=" + volumeValue
                                + ", flags=" + flags, e);
                    }
                }
            });
        } else {
            if (mVolumeControlType != VolumeProvider.VOLUME_CONTROL_ABSOLUTE) {
                // Nothing to do. The volume can't be set directly.
                return;
            }
            value = Math.max(0, Math.min(value, mMaxVolume));
            mSessionCb.setVolumeTo(packageName, pid, uid, caller, value);

            int volumeBefore = (mOptimisticVolume < 0 ? mCurrentVolume : mOptimisticVolume);
            mOptimisticVolume = Math.max(0, Math.min(value, mMaxVolume));
            mHandler.removeCallbacks(mClearOptimisticVolumeRunnable);
            mHandler.postDelayed(mClearOptimisticVolumeRunnable, OPTIMISTIC_VOLUME_TIMEOUT);
            if (volumeBefore != mOptimisticVolume) {
                pushVolumeUpdate();
            }
            mService.notifyRemoteVolumeChanged(flags, this);

            if (DEBUG) {
                Log.d(TAG, "Set optimistic volume to " + mOptimisticVolume + " max is "
                        + mMaxVolume);
            }
        }
    }

    /**
     * Check if this session has been set to active by the app.
     *
     * @return True if the session is active, false otherwise.
     */
    public boolean isActive() {
        return mIsActive && !mDestroyed;
    }

    /**
     * Get the playback state.
     *
     * @return The current playback state.
     */
    public PlaybackState getPlaybackState() {
        return mPlaybackState;
    }

    /**
     * Check if the session is currently performing playback.
     *
     * @return True if the session is performing playback, false otherwise.
     */
    public boolean isPlaybackActive() {
        int state = mPlaybackState == null ? PlaybackState.STATE_NONE : mPlaybackState.getState();
        return MediaSession.isActiveState(state);
    }

    /**
     * Get the type of playback, either local or remote.
     *
     * @return The current type of playback.
     */
    public int getPlaybackType() {
        return mVolumeType;
    }

    /**
     * Get the local audio stream being used. Only valid if playback type is
     * local.
     *
     * @return The audio stream the session is using.
     */
    public AudioAttributes getAudioAttributes() {
        return mAudioAttrs;
    }

    /**
     * Get the type of volume control. Only valid if playback type is remote.
     *
     * @return The volume control type being used.
     */
    public int getVolumeControl() {
        return mVolumeControlType;
    }

    /**
     * Get the max volume that can be set. Only valid if playback type is
     * remote.
     *
     * @return The max volume that can be set.
     */
    public int getMaxVolume() {
        return mMaxVolume;
    }

    /**
     * Get the current volume for this session. Only valid if playback type is
     * remote.
     *
     * @return The current volume of the remote playback.
     */
    public int getCurrentVolume() {
        return mCurrentVolume;
    }

    /**
     * Get the volume we'd like it to be set to. This is only valid for a short
     * while after a call to adjust or set volume.
     *
     * @return The current optimistic volume or -1.
     */
    public int getOptimisticVolume() {
        return mOptimisticVolume;
    }

    public boolean isTransportControlEnabled() {
        return hasFlag(MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS);
    }

    @Override
    public void binderDied() {
        mService.sessionDied(this);
    }

    /**
     * Finish cleaning up this session, including disconnecting if connected and
     * removing the death observer from the callback binder.
     */
    public void onDestroy() {
        synchronized (mLock) {
            if (mDestroyed) {
                return;
            }
            mDestroyed = true;
            mHandler.post(MessageHandler.MSG_DESTROYED);
        }
    }

    public SessionCallbackLink getCallback() {
        return mSessionCb.mCb;
    }

    /**
     * Sends media button.
     *
     * @param packageName caller package name
     * @param pid caller pid
     * @param uid caller uid
     * @param asSystemService {@code true} if the event sent to the session as if it was come from
     *          the system service instead of the app process.
     * @param ke key events
     * @param sequenceId (optional) sequence id. Use this only when a wake lock is needed.
     * @param cb (optional) result receiver to receive callback. Use this only when a wake lock is
     *           needed.
     * @return {@code true} if the attempt to send media button was successfuly.
     *         {@code false} otherwise.
     */
    public boolean sendMediaButton(String packageName, int pid, int uid, boolean asSystemService,
            KeyEvent ke, int sequenceId, ResultReceiver cb) {
        return mSessionCb.sendMediaButton(packageName, pid, uid, asSystemService, ke, sequenceId,
                cb);
    }

    public void dump(PrintWriter pw, String prefix) {
        pw.println(prefix + mTag + " " + this);

        final String indent = prefix + "  ";
        pw.println(indent + "ownerPid=" + mOwnerPid + ", ownerUid=" + mOwnerUid
                + ", userId=" + mUserId);
        pw.println(indent + "package=" + mPackageName);
        pw.println(indent + "launchIntent=" + mLaunchIntent);
        pw.println(indent + "mediaButtonReceiver=" + mMediaButtonReceiver);
        pw.println(indent + "active=" + mIsActive);
        pw.println(indent + "flags=" + mFlags);
        pw.println(indent + "rating type=" + mRatingType);
        pw.println(indent + "controllers: " + mControllerCallbackHolders.size());
        pw.println(indent + "state=" + (mPlaybackState == null ? null : mPlaybackState.toString()));
        pw.println(indent + "audioAttrs=" + mAudioAttrs);
        pw.println(indent + "volumeType=" + mVolumeType + ", controlType=" + mVolumeControlType
                + ", max=" + mMaxVolume + ", current=" + mCurrentVolume);
        pw.println(indent + "metadata: " + mMetadataDescription);
        pw.println(indent + "queueTitle=" + mQueueTitle + ", size="
                + (mQueue == null ? 0 : mQueue.size()));
    }

    @Override
    public String toString() {
        return mPackageName + "/" + mTag + " (userId=" + mUserId + ")";
    }

    private void postAdjustLocalVolume(final int stream, final int direction, final int flags,
            final String callingOpPackageName, final int callingPid, final int callingUid,
            final boolean asSystemService, final boolean useSuggested,
            final int previousFlagPlaySound) {
        if (DEBUG) {
            Log.w(TAG, "adjusting local volume, stream=" + stream + ", dir=" + direction
                    + ", asSystemService=" + asSystemService + ", useSuggested=" + useSuggested);
        }
        // Must use opPackageName for adjusting volumes with UID.
        final String opPackageName;
        final int uid;
        if (asSystemService) {
            opPackageName = mContext.getOpPackageName();
            uid = Process.SYSTEM_UID;
        } else {
            opPackageName = callingOpPackageName;
            uid = callingUid;
        }
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                try {
                    if (useSuggested) {
                        if (AudioSystem.isStreamActive(stream, 0)) {
                            mAudioManagerInternal.adjustSuggestedStreamVolumeForUid(stream,
                                    direction, flags, opPackageName, uid);
                        } else {
                            mAudioManagerInternal.adjustSuggestedStreamVolumeForUid(
                                    AudioManager.USE_DEFAULT_STREAM_TYPE, direction,
                                    flags | previousFlagPlaySound, opPackageName, uid);
                        }
                    } else {
                        mAudioManagerInternal.adjustStreamVolumeForUid(stream, direction, flags,
                                opPackageName, uid);
                    }
                } catch (IllegalArgumentException | SecurityException e) {
                    Log.e(TAG, "Cannot adjust volume: direction=" + direction + ", stream="
                            + stream + ", flags=" + flags + ", opPackageName=" + opPackageName
                            + ", uid=" + uid + ", useSuggested=" + useSuggested
                            + ", previousFlagPlaySound=" + previousFlagPlaySound, e);
                }
            }
        });
    }

    private void logCallbackException(
            String msg, ControllerCallbackLinkHolder holder, Exception e) {
        Log.v(TAG, msg + ", this=" + this + ", callback package=" + holder.mPackageName
                + ", exception=" + e);
    }

    private void pushPlaybackStateUpdate() {
        synchronized (mLock) {
            if (mDestroyed) {
                return;
            }
            for (int i = mControllerCallbackHolders.size() - 1; i >= 0; i--) {
                ControllerCallbackLinkHolder holder = mControllerCallbackHolders.get(i);
                try {
                    holder.mCallback.notifyPlaybackStateChanged(mPlaybackState);
                } catch (RuntimeException e) {
                    if (e.getCause() instanceof DeadObjectException) {
                        mControllerCallbackHolders.remove(i);
                        logCallbackException("Removing dead callback in pushPlaybackStateUpdate",
                                holder, e);
                    } else {
                        logCallbackException("unexpected exception in pushPlaybackStateUpdate",
                                holder, e);
                    }
                }
            }
        }
    }

    private void pushMetadataUpdate() {
        synchronized (mLock) {
            if (mDestroyed) {
                return;
            }
            for (int i = mControllerCallbackHolders.size() - 1; i >= 0; i--) {
                ControllerCallbackLinkHolder holder = mControllerCallbackHolders.get(i);
                try {
                    holder.mCallback.notifyMetadataChanged(mMetadata);
                } catch (RuntimeException e) {
                    if (e.getCause() instanceof DeadObjectException) {
                        mControllerCallbackHolders.remove(i);
                        logCallbackException("Removing dead callback in pushMetadataUpdate",
                                holder, e);
                    } else {
                        logCallbackException("unexpected exception in pushMetadataUpdate",
                                holder, e);
                    }
                }
            }
        }
    }

    private void pushQueueUpdate() {
        synchronized (mLock) {
            if (mDestroyed) {
                return;
            }
            for (int i = mControllerCallbackHolders.size() - 1; i >= 0; i--) {
                ControllerCallbackLinkHolder holder = mControllerCallbackHolders.get(i);
                try {
                    holder.mCallback.notifyQueueChanged(mQueue);
                } catch (RuntimeException e) {
                    if (e.getCause() instanceof DeadObjectException) {
                        mControllerCallbackHolders.remove(i);
                        logCallbackException("Removing dead callback in pushQueueUpdate",
                                holder, e);
                    } else {
                        logCallbackException("unexpected exception in pushQueueUpdate", holder, e);
                    }
                }
            }
        }
    }

    private void pushQueueTitleUpdate() {
        synchronized (mLock) {
            if (mDestroyed) {
                return;
            }
            for (int i = mControllerCallbackHolders.size() - 1; i >= 0; i--) {
                ControllerCallbackLinkHolder holder = mControllerCallbackHolders.get(i);
                try {
                    holder.mCallback.notifyQueueTitleChanged(mQueueTitle);
                } catch (RuntimeException e) {
                    if (e.getCause() instanceof DeadObjectException) {
                        mControllerCallbackHolders.remove(i);
                        logCallbackException("Removing dead callback in pushQueueTitleUpdate",
                                holder, e);
                    } else {
                        logCallbackException("unexpected exception in pushQueueTitleUpdate",
                                holder, e);
                    }
                }
            }
        }
    }

    private void pushExtrasUpdate() {
        synchronized (mLock) {
            if (mDestroyed) {
                return;
            }
            for (int i = mControllerCallbackHolders.size() - 1; i >= 0; i--) {
                ControllerCallbackLinkHolder holder = mControllerCallbackHolders.get(i);
                try {
                    holder.mCallback.notifyExtrasChanged(mExtras);
                } catch (RuntimeException e) {
                    if (e.getCause() instanceof DeadObjectException) {
                        mControllerCallbackHolders.remove(i);
                        logCallbackException("Removing dead callback in pushExtrasUpdate",
                                holder, e);
                    } else {
                        logCallbackException("unexpected exception in pushExtrasUpdate", holder, e);
                    }
                }
            }
        }
    }

    private void pushVolumeUpdate() {
        synchronized (mLock) {
            if (mDestroyed) {
                return;
            }
            PlaybackInfo info = getVolumeAttributes();
            for (int i = mControllerCallbackHolders.size() - 1; i >= 0; i--) {
                ControllerCallbackLinkHolder holder = mControllerCallbackHolders.get(i);
                try {
                    holder.mCallback.notifyVolumeInfoChanged(info);
                } catch (RuntimeException e) {
                    if (e.getCause() instanceof DeadObjectException) {
                        mControllerCallbackHolders.remove(i);
                        logCallbackException("Removing dead callback in pushVolumeUpdate",
                                holder, e);
                    } else {
                        logCallbackException("unexpected exception in pushVolumeUpdate", holder, e);
                    }
                }
            }
        }
    }

    private void pushEvent(String event, Bundle data) {
        synchronized (mLock) {
            if (mDestroyed) {
                return;
            }
            for (int i = mControllerCallbackHolders.size() - 1; i >= 0; i--) {
                ControllerCallbackLinkHolder holder = mControllerCallbackHolders.get(i);
                try {
                    holder.mCallback.notifyEvent(event, data);
                } catch (RuntimeException e) {
                    if (e.getCause() instanceof DeadObjectException) {
                        mControllerCallbackHolders.remove(i);
                        logCallbackException("Removing dead callback in pushEvent", holder, e);
                    } else {
                        logCallbackException("unexpected exception in pushEvent", holder, e);
                    }
                }
            }
        }
    }

    private void pushSessionDestroyed() {
        synchronized (mLock) {
            // This is the only method that may be (and can only be) called
            // after the session is destroyed.
            if (!mDestroyed) {
                return;
            }
            for (int i = mControllerCallbackHolders.size() - 1; i >= 0; i--) {
                ControllerCallbackLinkHolder holder = mControllerCallbackHolders.get(i);
                try {
                    holder.mCallback.notifySessionDestroyed();
                } catch (RuntimeException e) {
                    if (e.getCause() instanceof DeadObjectException) {
                        mControllerCallbackHolders.remove(i);
                        logCallbackException("Removing dead callback in pushSessionDestroyed",
                                holder, e);
                    } else {
                        logCallbackException("unexpected exception in pushSessionDestroyed",
                                holder, e);
                    }
                }
            }
            // After notifying clear all listeners
            mControllerCallbackHolders.clear();
        }
    }

    private PlaybackState getStateWithUpdatedPosition() {
        PlaybackState state;
        long duration;
        synchronized (mLock) {
            state = mPlaybackState;
            duration = mDuration;
        }
        PlaybackState result = null;
        if (state != null) {
            if (state.getState() == PlaybackState.STATE_PLAYING
                    || state.getState() == PlaybackState.STATE_FAST_FORWARDING
                    || state.getState() == PlaybackState.STATE_REWINDING) {
                long updateTime = state.getLastPositionUpdateTime();
                long currentTime = SystemClock.elapsedRealtime();
                if (updateTime > 0) {
                    long position = (long) (state.getPlaybackSpeed()
                            * (currentTime - updateTime)) + state.getPosition();
                    if (duration >= 0 && position > duration) {
                        position = duration;
                    } else if (position < 0) {
                        position = 0;
                    }
                    PlaybackState.Builder builder = new PlaybackState.Builder(state);
                    builder.setState(state.getState(), position, state.getPlaybackSpeed(),
                            currentTime);
                    result = builder.build();
                }
            }
        }
        return result == null ? state : result;
    }

    private int getControllerHolderIndexForCb(ControllerCallbackLink cb) {
        IBinder binder = cb.getBinder();
        for (int i = mControllerCallbackHolders.size() - 1; i >= 0; i--) {
            if (binder.equals(mControllerCallbackHolders.get(i).mCallback.getBinder())) {
                return i;
            }
        }
        return -1;
    }

    private PlaybackInfo getVolumeAttributes() {
        int volumeType;
        AudioAttributes attributes;
        synchronized (mLock) {
            if (mVolumeType == PlaybackInfo.PLAYBACK_TYPE_REMOTE) {
                int current = mOptimisticVolume != -1 ? mOptimisticVolume : mCurrentVolume;
                return new PlaybackInfo(mVolumeType, mVolumeControlType, mMaxVolume, current,
                        mAudioAttrs);
            }
            volumeType = mVolumeType;
            attributes = mAudioAttrs;
        }
        int stream = AudioAttributes.toLegacyStreamType(attributes);
        int max = mAudioManager.getStreamMaxVolume(stream);
        int current = mAudioManager.getStreamVolume(stream);
        return new PlaybackInfo(volumeType, VolumeProvider.VOLUME_CONTROL_ABSOLUTE, max,
                current, attributes);
    }

    private final Runnable mClearOptimisticVolumeRunnable = new Runnable() {
        @Override
        public void run() {
            boolean needUpdate = (mOptimisticVolume != mCurrentVolume);
            mOptimisticVolume = -1;
            if (needUpdate) {
                pushVolumeUpdate();
            }
        }
    };

    private final class SessionStub extends ISession.Stub {
        @Override
        public void destroySession() throws RemoteException {
            final long token = Binder.clearCallingIdentity();
            try {
                mService.destroySession(MediaSessionRecord.this);
            } finally {
                Binder.restoreCallingIdentity(token);
            }
        }

        @Override
        public void sendEvent(String event, Bundle data) throws RemoteException {
            mHandler.post(MessageHandler.MSG_SEND_EVENT, event,
                    data == null ? null : new Bundle(data));
        }

        @Override
        public ISessionController getController() throws RemoteException {
            return mController;
        }

        @Override
        public void setActive(boolean active) throws RemoteException {
            mIsActive = active;
            final long token = Binder.clearCallingIdentity();
            try {
                mService.updateSession(MediaSessionRecord.this);
            } finally {
                Binder.restoreCallingIdentity(token);
            }
            mHandler.post(MessageHandler.MSG_UPDATE_SESSION_STATE);
        }

        @Override
        public void setFlags(int flags) throws RemoteException {
            if ((flags & MediaSession.FLAG_EXCLUSIVE_GLOBAL_PRIORITY) != 0) {
                int pid = Binder.getCallingPid();
                int uid = Binder.getCallingUid();
                mService.enforcePhoneStatePermission(pid, uid);
            }
            mFlags = flags;
            if ((flags & MediaSession.FLAG_EXCLUSIVE_GLOBAL_PRIORITY) != 0) {
                final long token = Binder.clearCallingIdentity();
                try {
                    mService.setGlobalPrioritySession(MediaSessionRecord.this);
                } finally {
                    Binder.restoreCallingIdentity(token);
                }
            }
            mHandler.post(MessageHandler.MSG_UPDATE_SESSION_STATE);
        }

        @Override
        public void setMediaButtonReceiver(PendingIntent pi) throws RemoteException {
            mMediaButtonReceiver = pi;
            final long token = Binder.clearCallingIdentity();
            try {
                mService.onMediaButtonReceiverChanged(MediaSessionRecord.this);
            } finally {
                Binder.restoreCallingIdentity(token);
            }
        }

        @Override
        public void setLaunchPendingIntent(PendingIntent pi) throws RemoteException {
            mLaunchIntent = pi;
        }

        @Override
        public void setMetadata(MediaMetadata metadata, long duration, String metadataDescription)
                throws RemoteException {
            synchronized (mLock) {
                MediaMetadata temp = metadata == null ? null : new MediaMetadata.Builder(metadata)
                        .build();
                // This is to guarantee that the underlying bundle is unparceled
                // before we set it to prevent concurrent reads from throwing an
                // exception
                if (temp != null) {
                    temp.size();
                }
                mMetadata = temp;
                mDuration = duration;
                mMetadataDescription = metadataDescription;
            }
            mHandler.post(MessageHandler.MSG_UPDATE_METADATA);
        }

        @Override
        public void setPlaybackState(PlaybackState state) throws RemoteException {
            int oldState = mPlaybackState == null
                    ? PlaybackState.STATE_NONE : mPlaybackState.getState();
            int newState = state == null
                    ? PlaybackState.STATE_NONE : state.getState();
            synchronized (mLock) {
                mPlaybackState = state;
            }
            final long token = Binder.clearCallingIdentity();
            try {
                mService.onSessionPlaystateChanged(MediaSessionRecord.this, oldState, newState);
            } finally {
                Binder.restoreCallingIdentity(token);
            }
            mHandler.post(MessageHandler.MSG_UPDATE_PLAYBACK_STATE);
        }

        @Override
        public void setQueue(MediaParceledListSlice queue) throws RemoteException {
            synchronized (mLock) {
                mQueue = queue == null ? null : (List<QueueItem>) queue.getList();
            }
            mHandler.post(MessageHandler.MSG_UPDATE_QUEUE);
        }

        @Override
        public void setQueueTitle(CharSequence title) throws RemoteException {
            mQueueTitle = title;
            mHandler.post(MessageHandler.MSG_UPDATE_QUEUE_TITLE);
        }

        @Override
        public void setExtras(Bundle extras) throws RemoteException {
            synchronized (mLock) {
                mExtras = extras == null ? null : new Bundle(extras);
            }
            mHandler.post(MessageHandler.MSG_UPDATE_EXTRAS);
        }

        @Override
        public void setRatingType(int type) throws RemoteException {
            mRatingType = type;
        }

        @Override
        public void setCurrentVolume(int volume) throws RemoteException {
            mCurrentVolume = volume;
            mHandler.post(MessageHandler.MSG_UPDATE_VOLUME);
        }

        @Override
        public void setPlaybackToLocal(AudioAttributes attributes) throws RemoteException {
            boolean typeChanged;
            synchronized (mLock) {
                typeChanged = mVolumeType == PlaybackInfo.PLAYBACK_TYPE_REMOTE;
                mVolumeType = PlaybackInfo.PLAYBACK_TYPE_LOCAL;
                if (attributes != null) {
                    mAudioAttrs = attributes;
                } else {
                    Log.e(TAG, "Received null audio attributes, using existing attributes");
                }
            }
            if (typeChanged) {
                final long token = Binder.clearCallingIdentity();
                try {
                    mService.onSessionPlaybackTypeChanged(MediaSessionRecord.this);
                } finally {
                    Binder.restoreCallingIdentity(token);
                }
                mHandler.post(MessageHandler.MSG_UPDATE_VOLUME);
            }
        }

        @Override
        public void setPlaybackToRemote(int control, int max) throws RemoteException {
            boolean typeChanged;
            synchronized (mLock) {
                typeChanged = mVolumeType == PlaybackInfo.PLAYBACK_TYPE_LOCAL;
                mVolumeType = PlaybackInfo.PLAYBACK_TYPE_REMOTE;
                mVolumeControlType = control;
                mMaxVolume = max;
            }
            if (typeChanged) {
                final long token = Binder.clearCallingIdentity();
                try {
                    mService.onSessionPlaybackTypeChanged(MediaSessionRecord.this);
                } finally {
                    Binder.restoreCallingIdentity(token);
                }
                mHandler.post(MessageHandler.MSG_UPDATE_VOLUME);
            }
        }
    }

    class SessionCb {
        private final SessionCallbackLink mCb;

        SessionCb(SessionCallbackLink cb) {
            mCb = cb;
        }

        public boolean sendMediaButton(String packageName, int pid, int uid,
                boolean asSystemService, KeyEvent keyEvent, int sequenceId, ResultReceiver cb) {
            try {
                if (asSystemService) {
                    mCb.notifyMediaButton(mContext.getPackageName(), Process.myPid(),
                            Process.SYSTEM_UID, createMediaButtonIntent(keyEvent), sequenceId, cb);
                } else {
                    mCb.notifyMediaButton(packageName, pid, uid,
                            createMediaButtonIntent(keyEvent), sequenceId, cb);
                }
                return true;
            } catch (RuntimeException e) {
                Slog.e(TAG, "Remote failure in sendMediaRequest.", e);
            }
            return false;
        }

        public boolean sendMediaButton(String packageName, int pid, int uid,
                ControllerCallbackLink caller, boolean asSystemService,
                KeyEvent keyEvent) {
            try {
                if (asSystemService) {
                    mCb.notifyMediaButton(mContext.getPackageName(), Process.myPid(),
                            Process.SYSTEM_UID, createMediaButtonIntent(keyEvent), 0, null);
                } else {
                    mCb.notifyMediaButtonFromController(packageName, pid, uid, caller,
                            createMediaButtonIntent(keyEvent));
                }
                return true;
            } catch (RuntimeException e) {
                Slog.e(TAG, "Remote failure in sendMediaRequest.", e);
            }
            return false;
        }

        public void sendCommand(String packageName, int pid, int uid,
                ControllerCallbackLink caller, String command, Bundle args, ResultReceiver cb) {
            try {
                mCb.notifyCommand(packageName, pid, uid, caller, command, args, cb);
            } catch (RuntimeException e) {
                Slog.e(TAG, "Remote failure in sendCommand.", e);
            }
        }

        public void sendCustomAction(String packageName, int pid, int uid,
                ControllerCallbackLink caller, String action,
                Bundle args) {
            try {
                mCb.notifyCustomAction(packageName, pid, uid, caller, action, args);
            } catch (RuntimeException e) {
                Slog.e(TAG, "Remote failure in sendCustomAction.", e);
            }
        }

        public void prepare(String packageName, int pid, int uid,
                ControllerCallbackLink caller) {
            try {
                mCb.notifyPrepare(packageName, pid, uid, caller);
            } catch (RuntimeException e) {
                Slog.e(TAG, "Remote failure in prepare.", e);
            }
        }

        public void prepareFromMediaId(String packageName, int pid, int uid,
                ControllerCallbackLink caller, String mediaId, Bundle extras) {
            try {
                mCb.notifyPrepareFromMediaId(packageName, pid, uid, caller, mediaId, extras);
            } catch (RuntimeException e) {
                Slog.e(TAG, "Remote failure in prepareFromMediaId.", e);
            }
        }

        public void prepareFromSearch(String packageName, int pid, int uid,
                ControllerCallbackLink caller, String query, Bundle extras) {
            try {
                mCb.notifyPrepareFromSearch(packageName, pid, uid, caller, query, extras);
            } catch (RuntimeException e) {
                Slog.e(TAG, "Remote failure in prepareFromSearch.", e);
            }
        }

        public void prepareFromUri(String packageName, int pid, int uid,
                ControllerCallbackLink caller, Uri uri, Bundle extras) {
            try {
                mCb.notifyPrepareFromUri(packageName, pid, uid, caller, uri, extras);
            } catch (RuntimeException e) {
                Slog.e(TAG, "Remote failure in prepareFromUri.", e);
            }
        }

        public void play(String packageName, int pid, int uid, ControllerCallbackLink caller) {
            try {
                mCb.notifyPlay(packageName, pid, uid, caller);
            } catch (RuntimeException e) {
                Slog.e(TAG, "Remote failure in play.", e);
            }
        }

        public void playFromMediaId(String packageName, int pid, int uid,
                ControllerCallbackLink caller, String mediaId, Bundle extras) {
            try {
                mCb.notifyPlayFromMediaId(packageName, pid, uid, caller, mediaId, extras);
            } catch (RuntimeException e) {
                Slog.e(TAG, "Remote failure in playFromMediaId.", e);
            }
        }

        public void playFromSearch(String packageName, int pid, int uid,
                ControllerCallbackLink caller, String query, Bundle extras) {
            try {
                mCb.notifyPlayFromSearch(packageName, pid, uid, caller, query, extras);
            } catch (RuntimeException e) {
                Slog.e(TAG, "Remote failure in playFromSearch.", e);
            }
        }

        public void playFromUri(String packageName, int pid, int uid,
                ControllerCallbackLink caller, Uri uri, Bundle extras) {
            try {
                mCb.notifyPlayFromUri(packageName, pid, uid, caller, uri, extras);
            } catch (RuntimeException e) {
                Slog.e(TAG, "Remote failure in playFromUri.", e);
            }
        }

        public void skipToTrack(String packageName, int pid, int uid,
                ControllerCallbackLink caller, long id) {
            try {
                mCb.notifySkipToTrack(packageName, pid, uid, caller, id);
            } catch (RuntimeException e) {
                Slog.e(TAG, "Remote failure in skipToTrack", e);
            }
        }

        public void pause(String packageName, int pid, int uid, ControllerCallbackLink caller) {
            try {
                mCb.notifyPause(packageName, pid, uid, caller);
            } catch (RuntimeException e) {
                Slog.e(TAG, "Remote failure in pause.", e);
            }
        }

        public void stop(String packageName, int pid, int uid, ControllerCallbackLink caller) {
            try {
                mCb.notifyStop(packageName, pid, uid, caller);
            } catch (RuntimeException e) {
                Slog.e(TAG, "Remote failure in stop.", e);
            }
        }

        public void next(String packageName, int pid, int uid, ControllerCallbackLink caller) {
            try {
                mCb.notifyNext(packageName, pid, uid, caller);
            } catch (RuntimeException e) {
                Slog.e(TAG, "Remote failure in next.", e);
            }
        }

        public void previous(String packageName, int pid, int uid,
                ControllerCallbackLink caller) {
            try {
                mCb.notifyPrevious(packageName, pid, uid, caller);
            } catch (RuntimeException e) {
                Slog.e(TAG, "Remote failure in previous.", e);
            }
        }

        public void fastForward(String packageName, int pid, int uid,
                ControllerCallbackLink caller) {
            try {
                mCb.notifyFastForward(packageName, pid, uid, caller);
            } catch (RuntimeException e) {
                Slog.e(TAG, "Remote failure in fastForward.", e);
            }
        }

        public void rewind(String packageName, int pid, int uid,
                ControllerCallbackLink caller) {
            try {
                mCb.notifyRewind(packageName, pid, uid, caller);
            } catch (RuntimeException e) {
                Slog.e(TAG, "Remote failure in rewind.", e);
            }
        }

        public void seekTo(String packageName, int pid, int uid, ControllerCallbackLink caller,
                long pos) {
            try {
                mCb.notifySeekTo(packageName, pid, uid, caller, pos);
            } catch (RuntimeException e) {
                Slog.e(TAG, "Remote failure in seekTo.", e);
            }
        }

        public void rate(String packageName, int pid, int uid, ControllerCallbackLink caller,
                Rating rating) {
            try {
                mCb.notifyRate(packageName, pid, uid, caller, rating);
            } catch (RuntimeException e) {
                Slog.e(TAG, "Remote failure in rate.", e);
            }
        }

        public void setPlaybackSpeed(String packageName, int pid, int uid,
                ControllerCallbackLink caller, float speed) {
            try {
                mCb.notifySetPlaybackSpeed(packageName, pid, uid, caller, speed);
            } catch (RuntimeException e) {
                Slog.e(TAG, "Remote failure in setPlaybackSpeed.", e);
            }
        }

        public void adjustVolume(String packageName, int pid, int uid,
                ControllerCallbackLink caller, boolean asSystemService, int direction) {
            try {
                if (asSystemService) {
                    mCb.notifyAdjustVolume(mContext.getPackageName(), Process.myPid(),
                            Process.SYSTEM_UID, null, direction);
                } else {
                    mCb.notifyAdjustVolume(packageName, pid, uid, caller, direction);
                }
            } catch (RuntimeException e) {
                Slog.e(TAG, "Remote failure in adjustVolume.", e);
            }
        }

        public void setVolumeTo(String packageName, int pid, int uid,
                ControllerCallbackLink caller, int value) {
            try {
                mCb.notifySetVolumeTo(packageName, pid, uid, caller, value);
            } catch (RuntimeException e) {
                Slog.e(TAG, "Remote failure in setVolumeTo.", e);
            }
        }

        private Intent createMediaButtonIntent(KeyEvent keyEvent) {
            Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
            mediaButtonIntent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
            return mediaButtonIntent;
        }
    }

    class ControllerStub extends ISessionController.Stub {
        @Override
        public void sendCommand(String packageName, ControllerCallbackLink caller,
                String command, Bundle args, ResultReceiver cb) {
            mSessionCb.sendCommand(packageName, Binder.getCallingPid(), Binder.getCallingUid(),
                    caller, command, args, cb);
        }

        @Override
        public boolean sendMediaButton(String packageName, ControllerCallbackLink cb,
                KeyEvent keyEvent) {
            return mSessionCb.sendMediaButton(packageName, Binder.getCallingPid(),
                    Binder.getCallingUid(), cb, false, keyEvent);
        }

        @Override
        public void registerCallback(String packageName, ControllerCallbackLink cb) {
            synchronized (mLock) {
                // If this session is already destroyed tell the caller and
                // don't add them.
                if (mDestroyed) {
                    try {
                        cb.notifySessionDestroyed();
                    } catch (Exception e) {
                        // ignored
                    }
                    return;
                }
                if (getControllerHolderIndexForCb(cb) < 0) {
                    mControllerCallbackHolders.add(new ControllerCallbackLinkHolder(cb,
                            packageName, Binder.getCallingUid()));
                    if (DEBUG) {
                        Log.d(TAG, "registering controller callback " + cb + " from controller"
                                + packageName);
                    }
                }
            }
        }

        @Override
        public void unregisterCallback(ControllerCallbackLink cb) {
            synchronized (mLock) {
                int index = getControllerHolderIndexForCb(cb);
                if (index != -1) {
                    mControllerCallbackHolders.remove(index);
                }
                if (DEBUG) {
                    Log.d(TAG, "unregistering callback " + cb.getBinder());
                }
            }
        }

        @Override
        public String getPackageName() {
            return mPackageName;
        }

        @Override
        public String getTag() {
            return mTag;
        }

        @Override
        public Bundle getSessionInfo() {
            return mSessionInfo;
        }

        @Override
        public PendingIntent getLaunchPendingIntent() {
            return mLaunchIntent;
        }

        @Override
        public long getFlags() {
            return mFlags;
        }

        @Override
        public PlaybackInfo getVolumeAttributes() {
            return MediaSessionRecord.this.getVolumeAttributes();
        }

        @Override
        public void adjustVolume(String packageName, String opPackageName,
                ControllerCallbackLink caller, int direction, int flags) {
            int pid = Binder.getCallingPid();
            int uid = Binder.getCallingUid();
            final long token = Binder.clearCallingIdentity();
            try {
                MediaSessionRecord.this.adjustVolume(packageName, opPackageName, pid, uid, caller,
                        false, direction, flags, false /* useSuggested */);
            } finally {
                Binder.restoreCallingIdentity(token);
            }
        }

        @Override
        public void setVolumeTo(String packageName, String opPackageName,
                ControllerCallbackLink caller, int value, int flags) {
            int pid = Binder.getCallingPid();
            int uid = Binder.getCallingUid();
            final long token = Binder.clearCallingIdentity();
            try {
                MediaSessionRecord.this.setVolumeTo(packageName, opPackageName, pid, uid, caller,
                        value, flags);
            } finally {
                Binder.restoreCallingIdentity(token);
            }
        }

        @Override
        public void prepare(String packageName, ControllerCallbackLink caller) {
            mSessionCb.prepare(packageName, Binder.getCallingPid(), Binder.getCallingUid(), caller);
        }

        @Override
        public void prepareFromMediaId(String packageName, ControllerCallbackLink caller,
                String mediaId, Bundle extras) {
            mSessionCb.prepareFromMediaId(packageName, Binder.getCallingPid(),
                    Binder.getCallingUid(), caller, mediaId, extras);
        }

        @Override
        public void prepareFromSearch(String packageName, ControllerCallbackLink caller,
                String query, Bundle extras) {
            mSessionCb.prepareFromSearch(packageName, Binder.getCallingPid(),
                    Binder.getCallingUid(), caller, query, extras);
        }

        @Override
        public void prepareFromUri(String packageName, ControllerCallbackLink caller,
                Uri uri, Bundle extras) {
            mSessionCb.prepareFromUri(packageName, Binder.getCallingPid(), Binder.getCallingUid(),
                    caller, uri, extras);
        }

        @Override
        public void play(String packageName, ControllerCallbackLink caller) {
            mSessionCb.play(packageName, Binder.getCallingPid(), Binder.getCallingUid(), caller);
        }

        @Override
        public void playFromMediaId(String packageName, ControllerCallbackLink caller,
                String mediaId, Bundle extras) {
            mSessionCb.playFromMediaId(packageName, Binder.getCallingPid(), Binder.getCallingUid(),
                    caller, mediaId, extras);
        }

        @Override
        public void playFromSearch(String packageName, ControllerCallbackLink caller,
                String query, Bundle extras) {
            mSessionCb.playFromSearch(packageName, Binder.getCallingPid(), Binder.getCallingUid(),
                    caller, query, extras);
        }

        @Override
        public void playFromUri(String packageName, ControllerCallbackLink caller,
                Uri uri, Bundle extras) {
            mSessionCb.playFromUri(packageName, Binder.getCallingPid(), Binder.getCallingUid(),
                    caller, uri, extras);
        }

        @Override
        public void skipToQueueItem(String packageName, ControllerCallbackLink caller,
                long id) {
            mSessionCb.skipToTrack(packageName, Binder.getCallingPid(), Binder.getCallingUid(),
                    caller, id);
        }

        @Override
        public void pause(String packageName, ControllerCallbackLink caller) {
            mSessionCb.pause(packageName, Binder.getCallingPid(), Binder.getCallingUid(), caller);
        }

        @Override
        public void stop(String packageName, ControllerCallbackLink caller) {
            mSessionCb.stop(packageName, Binder.getCallingPid(), Binder.getCallingUid(), caller);
        }

        @Override
        public void next(String packageName, ControllerCallbackLink caller) {
            mSessionCb.next(packageName, Binder.getCallingPid(), Binder.getCallingUid(), caller);
        }

        @Override
        public void previous(String packageName, ControllerCallbackLink caller) {
            mSessionCb.previous(packageName, Binder.getCallingPid(), Binder.getCallingUid(),
                    caller);
        }

        @Override
        public void fastForward(String packageName, ControllerCallbackLink caller) {
            mSessionCb.fastForward(packageName, Binder.getCallingPid(), Binder.getCallingUid(),
                    caller);
        }

        @Override
        public void rewind(String packageName, ControllerCallbackLink caller) {
            mSessionCb.rewind(packageName, Binder.getCallingPid(), Binder.getCallingUid(), caller);
        }

        @Override
        public void seekTo(String packageName, ControllerCallbackLink caller, long pos) {
            mSessionCb.seekTo(packageName, Binder.getCallingPid(), Binder.getCallingUid(), caller,
                    pos);
        }

        @Override
        public void rate(String packageName, ControllerCallbackLink caller, Rating rating) {
            mSessionCb.rate(packageName, Binder.getCallingPid(), Binder.getCallingUid(), caller,
                    rating);
        }

        @Override
        public void setPlaybackSpeed(String packageName, ControllerCallbackLink caller,
                float speed) {
            mSessionCb.setPlaybackSpeed(packageName, Binder.getCallingPid(), Binder.getCallingUid(),
                    caller, speed);
        }

        @Override
        public void sendCustomAction(String packageName, ControllerCallbackLink caller,
                String action, Bundle args) {
            mSessionCb.sendCustomAction(packageName, Binder.getCallingPid(), Binder.getCallingUid(),
                    caller, action, args);
        }

        @Override
        public MediaMetadata getMetadata() {
            synchronized (mLock) {
                return mMetadata;
            }
        }

        @Override
        public PlaybackState getPlaybackState() {
            return getStateWithUpdatedPosition();
        }

        @Override
        public MediaParceledListSlice getQueue() {
            synchronized (mLock) {
                return mQueue == null ? null : new MediaParceledListSlice<>(mQueue);
            }
        }

        @Override
        public CharSequence getQueueTitle() {
            return mQueueTitle;
        }

        @Override
        public Bundle getExtras() {
            synchronized (mLock) {
                return mExtras;
            }
        }

        @Override
        public int getRatingType() {
            return mRatingType;
        }
    }

    private class ControllerCallbackLinkHolder {
        private final ControllerCallbackLink mCallback;
        private final String mPackageName;
        private final int mUid;

        ControllerCallbackLinkHolder(ControllerCallbackLink callback, String packageName,
                int uid) {
            mCallback = callback;
            mPackageName = packageName;
            mUid = uid;
        }
    }

    private class MessageHandler extends Handler {
        private static final int MSG_UPDATE_METADATA = 1;
        private static final int MSG_UPDATE_PLAYBACK_STATE = 2;
        private static final int MSG_UPDATE_QUEUE = 3;
        private static final int MSG_UPDATE_QUEUE_TITLE = 4;
        private static final int MSG_UPDATE_EXTRAS = 5;
        private static final int MSG_SEND_EVENT = 6;
        private static final int MSG_UPDATE_SESSION_STATE = 7;
        private static final int MSG_UPDATE_VOLUME = 8;
        private static final int MSG_DESTROYED = 9;

        public MessageHandler(Looper looper) {
            super(looper);
        }
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_UPDATE_METADATA:
                    pushMetadataUpdate();
                    break;
                case MSG_UPDATE_PLAYBACK_STATE:
                    pushPlaybackStateUpdate();
                    break;
                case MSG_UPDATE_QUEUE:
                    pushQueueUpdate();
                    break;
                case MSG_UPDATE_QUEUE_TITLE:
                    pushQueueTitleUpdate();
                    break;
                case MSG_UPDATE_EXTRAS:
                    pushExtrasUpdate();
                    break;
                case MSG_SEND_EVENT:
                    pushEvent((String) msg.obj, msg.getData());
                    break;
                case MSG_UPDATE_SESSION_STATE:
                    // TODO add session state
                    break;
                case MSG_UPDATE_VOLUME:
                    pushVolumeUpdate();
                    break;
                case MSG_DESTROYED:
                    pushSessionDestroyed();
            }
        }

        public void post(int what) {
            post(what, null);
        }

        public void post(int what, Object obj) {
            obtainMessage(what, obj).sendToTarget();
        }

        public void post(int what, Object obj, Bundle data) {
            Message msg = obtainMessage(what, obj);
            msg.setData(data);
            msg.sendToTarget();
        }
    }

}
