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

package com.android.keyguard;

import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.drawable.Drawable;
import android.media.AudioManager;
import android.media.MediaMetadataEditor;
import android.media.MediaMetadataRetriever;
import android.media.RemoteControlClient;
import android.media.RemoteController;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.SystemClock;
import android.text.TextUtils;
import android.text.format.DateFormat;
import android.transition.ChangeBounds;
import android.transition.ChangeText;
import android.transition.Fade;
import android.transition.TransitionManager;
import android.transition.TransitionSet;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.TextView;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;

/**
 * This is the widget responsible for showing music controls in keyguard.
 */
public class KeyguardTransportControlView extends FrameLayout {

    private static final int RESET_TO_METADATA_DELAY = 5000;
    protected static final boolean DEBUG = false;
    protected static final String TAG = "TransportControlView";

    private static final boolean ANIMATE_TRANSITIONS = true;
    protected static final long QUIESCENT_PLAYBACK_FACTOR = 1000;

    private ViewGroup mMetadataContainer;
    private ViewGroup mInfoContainer;
    private TextView mTrackTitle;
    private TextView mTrackArtistAlbum;

    private View mTransientSeek;
    private SeekBar mTransientSeekBar;
    private TextView mTransientSeekTimeElapsed;
    private TextView mTransientSeekTimeTotal;

    private ImageView mBtnPrev;
    private ImageView mBtnPlay;
    private ImageView mBtnNext;
    private Metadata mMetadata = new Metadata();
    private int mTransportControlFlags;
    private int mCurrentPlayState;
    private AudioManager mAudioManager;
    private RemoteController mRemoteController;

    private ImageView mBadge;

    private boolean mSeekEnabled;
    private java.text.DateFormat mFormat;

    private Date mTempDate = new Date();

    /**
     * The metadata which should be populated into the view once we've been attached
     */
    private RemoteController.MetadataEditor mPopulateMetadataWhenAttached = null;

    private RemoteController.OnClientUpdateListener mRCClientUpdateListener =
            new RemoteController.OnClientUpdateListener() {
        @Override
        public void onClientChange(boolean clearing) {
            if (clearing) {
                clearMetadata();
            }
        }

        @Override
        public void onClientPlaybackStateUpdate(int state) {
            updatePlayPauseState(state);
        }

        @Override
        public void onClientPlaybackStateUpdate(int state, long stateChangeTimeMs,
                long currentPosMs, float speed) {
            updatePlayPauseState(state);
            if (DEBUG) Log.d(TAG, "onClientPlaybackStateUpdate(state=" + state +
                    ", stateChangeTimeMs=" + stateChangeTimeMs + ", currentPosMs=" + currentPosMs +
                    ", speed=" + speed + ")");

            removeCallbacks(mUpdateSeekBars);
            // Since the music client may be responding to historical events that cause the
            // playback state to change dramatically, wait until things become quiescent before
            // resuming automatic scrub position update.
            if (mTransientSeek.getVisibility() == View.VISIBLE
                    && playbackPositionShouldMove(mCurrentPlayState)) {
                postDelayed(mUpdateSeekBars, QUIESCENT_PLAYBACK_FACTOR);
            }
        }

        @Override
        public void onClientTransportControlUpdate(int transportControlFlags) {
            updateTransportControls(transportControlFlags);
        }

        @Override
        public void onClientMetadataUpdate(RemoteController.MetadataEditor metadataEditor) {
            updateMetadata(metadataEditor);
        }
    };

    private class UpdateSeekBarRunnable implements  Runnable {
        public void run() {
            boolean seekAble = updateOnce();
            if (seekAble) {
                removeCallbacks(this);
                postDelayed(this, 1000);
            }
        }
        public boolean updateOnce() {
            return updateSeekBars();
        }
    };

    private final UpdateSeekBarRunnable mUpdateSeekBars = new UpdateSeekBarRunnable();

    private final Runnable mResetToMetadata = new Runnable() {
        public void run() {
            resetToMetadata();
        }
    };

    private final OnClickListener mTransportCommandListener = new OnClickListener() {
        public void onClick(View v) {
            int keyCode = -1;
            if (v == mBtnPrev) {
                keyCode = KeyEvent.KEYCODE_MEDIA_PREVIOUS;
            } else if (v == mBtnNext) {
                keyCode = KeyEvent.KEYCODE_MEDIA_NEXT;
            } else if (v == mBtnPlay) {
                keyCode = KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE;
            }
            if (keyCode != -1) {
                sendMediaButtonClick(keyCode);
                delayResetToMetadata(); // if the scrub bar is showing, keep showing it.
            }
        }
    };

    private final OnLongClickListener mTransportShowSeekBarListener = new OnLongClickListener() {
        @Override
        public boolean onLongClick(View v) {
            if (mSeekEnabled) {
                return tryToggleSeekBar();
            }
            return false;
        }
    };

    // This class is here to throttle scrub position updates to the music client
    class FutureSeekRunnable implements Runnable {
        private int mProgress;
        private boolean mPending;

        public void run() {
            scrubTo(mProgress);
            mPending = false;
        }

        void setProgress(int progress) {
            mProgress = progress;
            if (!mPending) {
                mPending = true;
                postDelayed(this, 30);
            }
        }
    };

    // This is here because RemoteControlClient's method isn't visible :/
    private final static boolean playbackPositionShouldMove(int playstate) {
        switch(playstate) {
            case RemoteControlClient.PLAYSTATE_STOPPED:
            case RemoteControlClient.PLAYSTATE_PAUSED:
            case RemoteControlClient.PLAYSTATE_BUFFERING:
            case RemoteControlClient.PLAYSTATE_ERROR:
            case RemoteControlClient.PLAYSTATE_SKIPPING_FORWARDS:
            case RemoteControlClient.PLAYSTATE_SKIPPING_BACKWARDS:
                return false;
            case RemoteControlClient.PLAYSTATE_PLAYING:
            case RemoteControlClient.PLAYSTATE_FAST_FORWARDING:
            case RemoteControlClient.PLAYSTATE_REWINDING:
            default:
                return true;
        }
    }

    private final FutureSeekRunnable mFutureSeekRunnable = new FutureSeekRunnable();

    private final SeekBar.OnSeekBarChangeListener mOnSeekBarChangeListener =
            new SeekBar.OnSeekBarChangeListener() {
        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
            if (fromUser) {
                mFutureSeekRunnable.setProgress(progress);
                delayResetToMetadata();
                mTempDate.setTime(progress);
                mTransientSeekTimeElapsed.setText(mFormat.format(mTempDate));
            } else {
                updateSeekDisplay();
            }
        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {
            delayResetToMetadata();
            removeCallbacks(mUpdateSeekBars); // don't update during user interaction
        }

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {
        }
    };

    private static final int TRANSITION_DURATION = 200;
    private final TransitionSet mMetadataChangeTransition;

    KeyguardHostView.TransportControlCallback mTransportControlCallback;

    private final KeyguardUpdateMonitorCallback mUpdateMonitor
            = new KeyguardUpdateMonitorCallback() {
        public void onScreenTurnedOff(int why) {
            setEnableMarquee(false);
        }
        public void onScreenTurnedOn() {
            setEnableMarquee(true);
        }
    };

    public KeyguardTransportControlView(Context context, AttributeSet attrs) {
        super(context, attrs);
        if (DEBUG) Log.v(TAG, "Create TCV " + this);
        mAudioManager = new AudioManager(mContext);
        mCurrentPlayState = RemoteControlClient.PLAYSTATE_NONE; // until we get a callback
        mRemoteController = new RemoteController(context, mRCClientUpdateListener);

        final DisplayMetrics dm = context.getResources().getDisplayMetrics();
        final int dim = Math.max(dm.widthPixels, dm.heightPixels);
        mRemoteController.setArtworkConfiguration(true, dim, dim);

        final ChangeText tc = new ChangeText();
        tc.setChangeBehavior(ChangeText.CHANGE_BEHAVIOR_OUT_IN);
        final TransitionSet inner = new TransitionSet();
        inner.addTransition(tc).addTransition(new ChangeBounds());
        final TransitionSet tg = new TransitionSet();
        tg.addTransition(new Fade(Fade.OUT)).addTransition(inner).
                addTransition(new Fade(Fade.IN));
        tg.setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
        tg.setDuration(TRANSITION_DURATION);
        mMetadataChangeTransition = tg;
    }

    private void updateTransportControls(int transportControlFlags) {
        mTransportControlFlags = transportControlFlags;
        setSeekBarsEnabled(
                (transportControlFlags & RemoteControlClient.FLAG_KEY_MEDIA_POSITION_UPDATE) != 0);
    }

    void setSeekBarsEnabled(boolean enabled) {
        if (enabled == mSeekEnabled) return;

        mSeekEnabled = enabled;
        if (mTransientSeek.getVisibility() == VISIBLE && !enabled) {
            mTransientSeek.setVisibility(INVISIBLE);
            mMetadataContainer.setVisibility(VISIBLE);
            cancelResetToMetadata();
        }
    }

    public void setTransportControlCallback(KeyguardHostView.TransportControlCallback
            transportControlCallback) {
        mTransportControlCallback = transportControlCallback;
    }

    private void setEnableMarquee(boolean enabled) {
        if (DEBUG) Log.v(TAG, (enabled ? "Enable" : "Disable") + " transport text marquee");
        if (mTrackTitle != null) mTrackTitle.setSelected(enabled);
        if (mTrackArtistAlbum != null) mTrackTitle.setSelected(enabled);
    }

    @Override
    public void onFinishInflate() {
        super.onFinishInflate();
        mInfoContainer = (ViewGroup) findViewById(R.id.info_container);
        mMetadataContainer = (ViewGroup) findViewById(R.id.metadata_container);
        mBadge = (ImageView) findViewById(R.id.badge);
        mTrackTitle = (TextView) findViewById(R.id.title);
        mTrackArtistAlbum = (TextView) findViewById(R.id.artist_album);
        mTransientSeek = findViewById(R.id.transient_seek);
        mTransientSeekBar = (SeekBar) findViewById(R.id.transient_seek_bar);
        mTransientSeekBar.setOnSeekBarChangeListener(mOnSeekBarChangeListener);
        mTransientSeekTimeElapsed = (TextView) findViewById(R.id.transient_seek_time_elapsed);
        mTransientSeekTimeTotal = (TextView) findViewById(R.id.transient_seek_time_remaining);
        mBtnPrev = (ImageView) findViewById(R.id.btn_prev);
        mBtnPlay = (ImageView) findViewById(R.id.btn_play);
        mBtnNext = (ImageView) findViewById(R.id.btn_next);
        final View buttons[] = { mBtnPrev, mBtnPlay, mBtnNext };
        for (View view : buttons) {
            view.setOnClickListener(mTransportCommandListener);
            view.setOnLongClickListener(mTransportShowSeekBarListener);
        }
        final boolean screenOn = KeyguardUpdateMonitor.getInstance(mContext).isScreenOn();
        setEnableMarquee(screenOn);
        // Allow long-press anywhere else in this view to show the seek bar
        setOnLongClickListener(mTransportShowSeekBarListener);
    }

    @Override
    public void onAttachedToWindow() {
        super.onAttachedToWindow();
        if (DEBUG) Log.v(TAG, "onAttachToWindow()");
        if (mPopulateMetadataWhenAttached != null) {
            updateMetadata(mPopulateMetadataWhenAttached);
            mPopulateMetadataWhenAttached = null;
        }
        if (DEBUG) Log.v(TAG, "Registering TCV " + this);
        mMetadata.clear();
        mAudioManager.registerRemoteController(mRemoteController);
        KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mUpdateMonitor);
    }

    @Override
    protected void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        final DisplayMetrics dm = getContext().getResources().getDisplayMetrics();
        final int dim = Math.max(dm.widthPixels, dm.heightPixels);
        mRemoteController.setArtworkConfiguration(true, dim, dim);
    }

    @Override
    public void onDetachedFromWindow() {
        if (DEBUG) Log.v(TAG, "onDetachFromWindow()");
        super.onDetachedFromWindow();
        if (DEBUG) Log.v(TAG, "Unregistering TCV " + this);
        mAudioManager.unregisterRemoteController(mRemoteController);
        KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mUpdateMonitor);
        mMetadata.clear();
        removeCallbacks(mUpdateSeekBars);
    }

    @Override
    protected Parcelable onSaveInstanceState() {
        SavedState ss = new SavedState(super.onSaveInstanceState());
        ss.artist = mMetadata.artist;
        ss.trackTitle = mMetadata.trackTitle;
        ss.albumTitle = mMetadata.albumTitle;
        ss.duration = mMetadata.duration;
        ss.bitmap = mMetadata.bitmap;
        return ss;
    }

    @Override
    protected void onRestoreInstanceState(Parcelable state) {
        if (!(state instanceof SavedState)) {
            super.onRestoreInstanceState(state);
            return;
        }
        SavedState ss = (SavedState) state;
        super.onRestoreInstanceState(ss.getSuperState());
        mMetadata.artist = ss.artist;
        mMetadata.trackTitle = ss.trackTitle;
        mMetadata.albumTitle = ss.albumTitle;
        mMetadata.duration = ss.duration;
        mMetadata.bitmap = ss.bitmap;
        populateMetadata();
    }

    void setBadgeIcon(Drawable bmp) {
        mBadge.setImageDrawable(bmp);

        final ColorMatrix cm = new ColorMatrix();
        cm.setSaturation(0);
        mBadge.setColorFilter(new ColorMatrixColorFilter(cm));
        mBadge.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SCREEN));
        mBadge.setImageAlpha(0xef);
    }

    class Metadata {
        private String artist;
        private String trackTitle;
        private String albumTitle;
        private Bitmap bitmap;
        private long duration;

        public void clear() {
            artist = null;
            trackTitle = null;
            albumTitle = null;
            bitmap = null;
            duration = -1;
        }

        public String toString() {
            return "Metadata[artist=" + artist + " trackTitle=" + trackTitle +
                    " albumTitle=" + albumTitle + " duration=" + duration + "]";
        }
    }

    void clearMetadata() {
        mPopulateMetadataWhenAttached = null;
        mMetadata.clear();
        populateMetadata();
    }

    void updateMetadata(RemoteController.MetadataEditor data) {
        if (isAttachedToWindow()) {
            mMetadata.artist = data.getString(MediaMetadataRetriever.METADATA_KEY_ALBUMARTIST,
                    mMetadata.artist);
            mMetadata.trackTitle = data.getString(MediaMetadataRetriever.METADATA_KEY_TITLE,
                    mMetadata.trackTitle);
            mMetadata.albumTitle = data.getString(MediaMetadataRetriever.METADATA_KEY_ALBUM,
                    mMetadata.albumTitle);
            mMetadata.duration = data.getLong(MediaMetadataRetriever.METADATA_KEY_DURATION, -1);
            mMetadata.bitmap = data.getBitmap(MediaMetadataEditor.BITMAP_KEY_ARTWORK,
                    mMetadata.bitmap);
            populateMetadata();
        } else {
            mPopulateMetadataWhenAttached = data;
        }
    }

    /**
     * Populates the given metadata into the view
     */
    private void populateMetadata() {
        if (ANIMATE_TRANSITIONS && isLaidOut() && mMetadataContainer.getVisibility() == VISIBLE) {
            TransitionManager.beginDelayedTransition(mMetadataContainer, mMetadataChangeTransition);
        }

        final String remoteClientPackage = mRemoteController.getRemoteControlClientPackageName();
        Drawable badgeIcon = null;
        try {
            badgeIcon = getContext().getPackageManager().getApplicationIcon(remoteClientPackage);
        } catch (PackageManager.NameNotFoundException e) {
            Log.e(TAG, "Couldn't get remote control client package icon", e);
        }
        setBadgeIcon(badgeIcon);
        mTrackTitle.setText(!TextUtils.isEmpty(mMetadata.trackTitle)
                ? mMetadata.trackTitle : null);

        final StringBuilder sb = new StringBuilder();
        if (!TextUtils.isEmpty(mMetadata.artist)) {
            if (sb.length() != 0) {
                sb.append(" - ");
            }
            sb.append(mMetadata.artist);
        }
        if (!TextUtils.isEmpty(mMetadata.albumTitle)) {
            if (sb.length() != 0) {
                sb.append(" - ");
            }
            sb.append(mMetadata.albumTitle);
        }

        final String trackArtistAlbum = sb.toString();
        mTrackArtistAlbum.setText(!TextUtils.isEmpty(trackArtistAlbum) ?
                trackArtistAlbum : null);

        if (mMetadata.duration >= 0) {
            setSeekBarsEnabled(true);
            setSeekBarDuration(mMetadata.duration);

            final String skeleton;

            if (mMetadata.duration >= 86400000) {
                skeleton = "DDD kk mm ss";
            } else if (mMetadata.duration >= 3600000) {
                skeleton = "kk mm ss";
            } else {
                skeleton = "mm ss";
            }
            mFormat = new SimpleDateFormat(DateFormat.getBestDateTimePattern(
                    getContext().getResources().getConfiguration().locale,
                    skeleton));
            mFormat.setTimeZone(TimeZone.getTimeZone("GMT+0"));
        } else {
            setSeekBarsEnabled(false);
        }

        KeyguardUpdateMonitor.getInstance(getContext()).dispatchSetBackground(mMetadata.bitmap);
        final int flags = mTransportControlFlags;
        setVisibilityBasedOnFlag(mBtnPrev, flags, RemoteControlClient.FLAG_KEY_MEDIA_PREVIOUS);
        setVisibilityBasedOnFlag(mBtnNext, flags, RemoteControlClient.FLAG_KEY_MEDIA_NEXT);
        setVisibilityBasedOnFlag(mBtnPlay, flags,
                RemoteControlClient.FLAG_KEY_MEDIA_PLAY
                | RemoteControlClient.FLAG_KEY_MEDIA_PAUSE
                | RemoteControlClient.FLAG_KEY_MEDIA_PLAY_PAUSE
                | RemoteControlClient.FLAG_KEY_MEDIA_STOP);

        updatePlayPauseState(mCurrentPlayState);
    }

    void updateSeekDisplay() {
        if (mMetadata != null && mRemoteController != null && mFormat != null) {
            mTempDate.setTime(mRemoteController.getEstimatedMediaPosition());
            mTransientSeekTimeElapsed.setText(mFormat.format(mTempDate));
            mTempDate.setTime(mMetadata.duration);
            mTransientSeekTimeTotal.setText(mFormat.format(mTempDate));

            if (DEBUG) Log.d(TAG, "updateSeekDisplay timeElapsed=" + mTempDate +
                    " duration=" + mMetadata.duration);
        }
    }

    boolean tryToggleSeekBar() {
        if (ANIMATE_TRANSITIONS) {
            TransitionManager.beginDelayedTransition(mInfoContainer);
        }
        if (mTransientSeek.getVisibility() == VISIBLE) {
            mTransientSeek.setVisibility(INVISIBLE);
            mMetadataContainer.setVisibility(VISIBLE);
            cancelResetToMetadata();
            removeCallbacks(mUpdateSeekBars); // don't update if scrubber isn't visible
        } else {
            mTransientSeek.setVisibility(VISIBLE);
            mMetadataContainer.setVisibility(INVISIBLE);
            delayResetToMetadata();
            if (playbackPositionShouldMove(mCurrentPlayState)) {
                mUpdateSeekBars.run();
            } else {
                mUpdateSeekBars.updateOnce();
            }
        }
        mTransportControlCallback.userActivity();
        return true;
    }

    void resetToMetadata() {
        if (ANIMATE_TRANSITIONS) {
            TransitionManager.beginDelayedTransition(mInfoContainer);
        }
        if (mTransientSeek.getVisibility() == VISIBLE) {
            mTransientSeek.setVisibility(INVISIBLE);
            mMetadataContainer.setVisibility(VISIBLE);
        }
        // TODO Also hide ratings, if applicable
    }

    void delayResetToMetadata() {
        removeCallbacks(mResetToMetadata);
        postDelayed(mResetToMetadata, RESET_TO_METADATA_DELAY);
    }

    void cancelResetToMetadata() {
        removeCallbacks(mResetToMetadata);
    }

    void setSeekBarDuration(long duration) {
        mTransientSeekBar.setMax((int) duration);
    }

    void scrubTo(int progress) {
        mRemoteController.seekTo(progress);
        mTransportControlCallback.userActivity();
    }

    private static void setVisibilityBasedOnFlag(View view, int flags, int flag) {
        if ((flags & flag) != 0) {
            view.setVisibility(View.VISIBLE);
        } else {
            view.setVisibility(View.INVISIBLE);
        }
    }

    private void updatePlayPauseState(int state) {
        if (DEBUG) Log.v(TAG,
                "updatePlayPauseState(), old=" + mCurrentPlayState + ", state=" + state);
        if (state == mCurrentPlayState) {
            return;
        }
        final int imageResId;
        final int imageDescId;
        switch (state) {
            case RemoteControlClient.PLAYSTATE_ERROR:
                imageResId = R.drawable.stat_sys_warning;
                // TODO use more specific image description string for warning, but here the "play"
                //      message is still valid because this button triggers a play command.
                imageDescId = R.string.keyguard_transport_play_description;
                break;

            case RemoteControlClient.PLAYSTATE_PLAYING:
                imageResId = R.drawable.ic_media_pause;
                imageDescId = R.string.keyguard_transport_pause_description;
                break;

            case RemoteControlClient.PLAYSTATE_BUFFERING:
                imageResId = R.drawable.ic_media_stop;
                imageDescId = R.string.keyguard_transport_stop_description;
                break;

            case RemoteControlClient.PLAYSTATE_PAUSED:
            default:
                imageResId = R.drawable.ic_media_play;
                imageDescId = R.string.keyguard_transport_play_description;
                break;
        }

        boolean clientSupportsSeek = mMetadata != null && mMetadata.duration > 0;
        setSeekBarsEnabled(clientSupportsSeek);

        mBtnPlay.setImageResource(imageResId);
        mBtnPlay.setContentDescription(getResources().getString(imageDescId));
        mCurrentPlayState = state;
    }

    boolean updateSeekBars() {
        final int position = (int) mRemoteController.getEstimatedMediaPosition();
        if (DEBUG) Log.v(TAG, "Estimated time:" + position);
        if (position >= 0) {
            mTransientSeekBar.setProgress(position);
            return true;
        }
        Log.w(TAG, "Updating seek bars; received invalid estimated media position (" +
                position + "). Disabling seek.");
        setSeekBarsEnabled(false);
        return false;
    }

    static class SavedState extends BaseSavedState {
        boolean clientPresent;
        String artist;
        String trackTitle;
        String albumTitle;
        long duration;
        Bitmap bitmap;

        SavedState(Parcelable superState) {
            super(superState);
        }

        private SavedState(Parcel in) {
            super(in);
            clientPresent = in.readInt() != 0;
            artist = in.readString();
            trackTitle = in.readString();
            albumTitle = in.readString();
            duration = in.readLong();
            bitmap = Bitmap.CREATOR.createFromParcel(in);
        }

        @Override
        public void writeToParcel(Parcel out, int flags) {
            super.writeToParcel(out, flags);
            out.writeInt(clientPresent ? 1 : 0);
            out.writeString(artist);
            out.writeString(trackTitle);
            out.writeString(albumTitle);
            out.writeLong(duration);
            bitmap.writeToParcel(out, flags);
        }

        public static final Parcelable.Creator<SavedState> CREATOR
                = new Parcelable.Creator<SavedState>() {
            public SavedState createFromParcel(Parcel in) {
                return new SavedState(in);
            }

            public SavedState[] newArray(int size) {
                return new SavedState[size];
            }
        };
    }

    private void sendMediaButtonClick(int keyCode) {
        // TODO We should think about sending these up/down events accurately with touch up/down
        // on the buttons, but in the near term this will interfere with the long press behavior.
        mRemoteController.sendMediaKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, keyCode));
        mRemoteController.sendMediaKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, keyCode));

        mTransportControlCallback.userActivity();
    }

    public boolean providesClock() {
        return false;
    }
}
