Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2011 The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | |
Jim Miller | 5ecd811 | 2013-01-09 18:50:26 -0800 | [diff] [blame] | 17 | package com.android.keyguard; |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 18 | |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 19 | import android.content.Context; |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 20 | import android.content.pm.PackageManager; |
| 21 | import android.content.res.Configuration; |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 22 | import android.graphics.Bitmap; |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 23 | import android.graphics.ColorMatrix; |
| 24 | import android.graphics.ColorMatrixColorFilter; |
Adam Powell | 31049d7 | 2013-10-07 12:58:42 -0700 | [diff] [blame] | 25 | import android.graphics.PorterDuff; |
| 26 | import android.graphics.PorterDuffXfermode; |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 27 | import android.graphics.drawable.Drawable; |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 28 | import android.media.AudioManager; |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 29 | import android.media.MediaMetadataEditor; |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 30 | import android.media.MediaMetadataRetriever; |
| 31 | import android.media.RemoteControlClient; |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 32 | import android.media.RemoteController; |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 33 | import android.os.Parcel; |
| 34 | import android.os.Parcelable; |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 35 | import android.os.SystemClock; |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 36 | import android.text.TextUtils; |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 37 | import android.text.format.DateFormat; |
| 38 | import android.transition.ChangeBounds; |
| 39 | import android.transition.ChangeText; |
| 40 | import android.transition.Fade; |
| 41 | import android.transition.TransitionManager; |
| 42 | import android.transition.TransitionSet; |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 43 | import android.util.AttributeSet; |
Adam Powell | 43a372f | 2013-09-27 17:43:53 -0700 | [diff] [blame] | 44 | import android.util.DisplayMetrics; |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 45 | import android.util.Log; |
| 46 | import android.view.KeyEvent; |
| 47 | import android.view.View; |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 48 | import android.view.ViewGroup; |
Jim Miller | bdca3c0 | 2012-10-29 19:11:50 -0700 | [diff] [blame] | 49 | import android.widget.FrameLayout; |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 50 | import android.widget.ImageView; |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 51 | import android.widget.SeekBar; |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 52 | import android.widget.TextView; |
| 53 | |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 54 | import java.text.SimpleDateFormat; |
| 55 | import java.util.Date; |
| 56 | import java.util.TimeZone; |
| 57 | |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 58 | /** |
| 59 | * This is the widget responsible for showing music controls in keyguard. |
| 60 | */ |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 61 | public class KeyguardTransportControlView extends FrameLayout { |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 62 | |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 63 | private static final int RESET_TO_METADATA_DELAY = 5000; |
Jim Miller | 71b3cd5 | 2012-10-10 19:02:40 -0700 | [diff] [blame] | 64 | protected static final boolean DEBUG = false; |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 65 | protected static final String TAG = "TransportControlView"; |
| 66 | |
Chet Haase | df32aa8 | 2013-10-21 17:19:37 -0700 | [diff] [blame] | 67 | private static final boolean ANIMATE_TRANSITIONS = true; |
Jim Miller | cc747ad | 2013-10-24 19:53:09 -0700 | [diff] [blame] | 68 | protected static final long QUIESCENT_PLAYBACK_FACTOR = 1000; |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 69 | |
| 70 | private ViewGroup mMetadataContainer; |
| 71 | private ViewGroup mInfoContainer; |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 72 | private TextView mTrackTitle; |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 73 | private TextView mTrackArtistAlbum; |
| 74 | |
| 75 | private View mTransientSeek; |
| 76 | private SeekBar mTransientSeekBar; |
| 77 | private TextView mTransientSeekTimeElapsed; |
Chris Wren | 6af85cc | 2013-10-29 13:19:54 -0400 | [diff] [blame] | 78 | private TextView mTransientSeekTimeTotal; |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 79 | |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 80 | private ImageView mBtnPrev; |
| 81 | private ImageView mBtnPlay; |
| 82 | private ImageView mBtnNext; |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 83 | private Metadata mMetadata = new Metadata(); |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 84 | private int mTransportControlFlags; |
| 85 | private int mCurrentPlayState; |
| 86 | private AudioManager mAudioManager; |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 87 | private RemoteController mRemoteController; |
| 88 | |
| 89 | private ImageView mBadge; |
| 90 | |
| 91 | private boolean mSeekEnabled; |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 92 | private java.text.DateFormat mFormat; |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 93 | |
Jim Miller | cc747ad | 2013-10-24 19:53:09 -0700 | [diff] [blame] | 94 | private Date mTempDate = new Date(); |
Chris Wren | cab6965 | 2013-10-29 13:04:00 -0400 | [diff] [blame] | 95 | |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 96 | /** |
| 97 | * The metadata which should be populated into the view once we've been attached |
| 98 | */ |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 99 | private RemoteController.MetadataEditor mPopulateMetadataWhenAttached = null; |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 100 | |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 101 | private RemoteController.OnClientUpdateListener mRCClientUpdateListener = |
| 102 | new RemoteController.OnClientUpdateListener() { |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 103 | @Override |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 104 | public void onClientChange(boolean clearing) { |
Craig Mautner | 8334192 | 2013-10-30 10:29:38 -0700 | [diff] [blame] | 105 | if (clearing) { |
| 106 | clearMetadata(); |
| 107 | } |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 108 | } |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 109 | |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 110 | @Override |
| 111 | public void onClientPlaybackStateUpdate(int state) { |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 112 | updatePlayPauseState(state); |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 113 | } |
| 114 | |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 115 | @Override |
| 116 | public void onClientPlaybackStateUpdate(int state, long stateChangeTimeMs, |
Jean-Michel Trivi | bc43b4c | 2013-03-22 09:30:50 -0700 | [diff] [blame] | 117 | long currentPosMs, float speed) { |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 118 | updatePlayPauseState(state); |
| 119 | if (DEBUG) Log.d(TAG, "onClientPlaybackStateUpdate(state=" + state + |
| 120 | ", stateChangeTimeMs=" + stateChangeTimeMs + ", currentPosMs=" + currentPosMs + |
| 121 | ", speed=" + speed + ")"); |
Jim Miller | cc747ad | 2013-10-24 19:53:09 -0700 | [diff] [blame] | 122 | |
| 123 | removeCallbacks(mUpdateSeekBars); |
| 124 | // Since the music client may be responding to historical events that cause the |
| 125 | // playback state to change dramatically, wait until things become quiescent before |
| 126 | // resuming automatic scrub position update. |
| 127 | if (mTransientSeek.getVisibility() == View.VISIBLE |
| 128 | && playbackPositionShouldMove(mCurrentPlayState)) { |
| 129 | postDelayed(mUpdateSeekBars, QUIESCENT_PLAYBACK_FACTOR); |
| 130 | } |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 131 | } |
| 132 | |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 133 | @Override |
| 134 | public void onClientTransportControlUpdate(int transportControlFlags) { |
| 135 | updateTransportControls(transportControlFlags); |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 136 | } |
| 137 | |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 138 | @Override |
| 139 | public void onClientMetadataUpdate(RemoteController.MetadataEditor metadataEditor) { |
| 140 | updateMetadata(metadataEditor); |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 141 | } |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 142 | }; |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 143 | |
Jim Miller | cc747ad | 2013-10-24 19:53:09 -0700 | [diff] [blame] | 144 | private class UpdateSeekBarRunnable implements Runnable { |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 145 | public void run() { |
Jim Miller | cc747ad | 2013-10-24 19:53:09 -0700 | [diff] [blame] | 146 | boolean seekAble = updateOnce(); |
| 147 | if (seekAble) { |
Jim Miller | 1693f6a | 2013-10-20 17:21:57 -0700 | [diff] [blame] | 148 | removeCallbacks(this); |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 149 | postDelayed(this, 1000); |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 150 | } |
| 151 | } |
Jim Miller | cc747ad | 2013-10-24 19:53:09 -0700 | [diff] [blame] | 152 | public boolean updateOnce() { |
| 153 | return updateSeekBars(); |
| 154 | } |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 155 | }; |
| 156 | |
Jim Miller | cc747ad | 2013-10-24 19:53:09 -0700 | [diff] [blame] | 157 | private final UpdateSeekBarRunnable mUpdateSeekBars = new UpdateSeekBarRunnable(); |
| 158 | |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 159 | private final Runnable mResetToMetadata = new Runnable() { |
| 160 | public void run() { |
| 161 | resetToMetadata(); |
| 162 | } |
| 163 | }; |
| 164 | |
| 165 | private final OnClickListener mTransportCommandListener = new OnClickListener() { |
| 166 | public void onClick(View v) { |
| 167 | int keyCode = -1; |
| 168 | if (v == mBtnPrev) { |
| 169 | keyCode = KeyEvent.KEYCODE_MEDIA_PREVIOUS; |
| 170 | } else if (v == mBtnNext) { |
| 171 | keyCode = KeyEvent.KEYCODE_MEDIA_NEXT; |
| 172 | } else if (v == mBtnPlay) { |
| 173 | keyCode = KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE; |
| 174 | } |
| 175 | if (keyCode != -1) { |
| 176 | sendMediaButtonClick(keyCode); |
Jim Miller | cc747ad | 2013-10-24 19:53:09 -0700 | [diff] [blame] | 177 | delayResetToMetadata(); // if the scrub bar is showing, keep showing it. |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 178 | } |
| 179 | } |
| 180 | }; |
| 181 | |
| 182 | private final OnLongClickListener mTransportShowSeekBarListener = new OnLongClickListener() { |
| 183 | @Override |
| 184 | public boolean onLongClick(View v) { |
| 185 | if (mSeekEnabled) { |
| 186 | return tryToggleSeekBar(); |
| 187 | } |
| 188 | return false; |
| 189 | } |
| 190 | }; |
| 191 | |
Jim Miller | cc747ad | 2013-10-24 19:53:09 -0700 | [diff] [blame] | 192 | // This class is here to throttle scrub position updates to the music client |
| 193 | class FutureSeekRunnable implements Runnable { |
| 194 | private int mProgress; |
| 195 | private boolean mPending; |
| 196 | |
| 197 | public void run() { |
| 198 | scrubTo(mProgress); |
| 199 | mPending = false; |
| 200 | } |
| 201 | |
| 202 | void setProgress(int progress) { |
| 203 | mProgress = progress; |
| 204 | if (!mPending) { |
| 205 | mPending = true; |
| 206 | postDelayed(this, 30); |
| 207 | } |
| 208 | } |
| 209 | }; |
| 210 | |
| 211 | // This is here because RemoteControlClient's method isn't visible :/ |
| 212 | private final static boolean playbackPositionShouldMove(int playstate) { |
| 213 | switch(playstate) { |
| 214 | case RemoteControlClient.PLAYSTATE_STOPPED: |
| 215 | case RemoteControlClient.PLAYSTATE_PAUSED: |
| 216 | case RemoteControlClient.PLAYSTATE_BUFFERING: |
| 217 | case RemoteControlClient.PLAYSTATE_ERROR: |
| 218 | case RemoteControlClient.PLAYSTATE_SKIPPING_FORWARDS: |
| 219 | case RemoteControlClient.PLAYSTATE_SKIPPING_BACKWARDS: |
| 220 | return false; |
| 221 | case RemoteControlClient.PLAYSTATE_PLAYING: |
| 222 | case RemoteControlClient.PLAYSTATE_FAST_FORWARDING: |
| 223 | case RemoteControlClient.PLAYSTATE_REWINDING: |
| 224 | default: |
| 225 | return true; |
| 226 | } |
| 227 | } |
| 228 | |
| 229 | private final FutureSeekRunnable mFutureSeekRunnable = new FutureSeekRunnable(); |
| 230 | |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 231 | private final SeekBar.OnSeekBarChangeListener mOnSeekBarChangeListener = |
| 232 | new SeekBar.OnSeekBarChangeListener() { |
| 233 | @Override |
| 234 | public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { |
| 235 | if (fromUser) { |
Jim Miller | cc747ad | 2013-10-24 19:53:09 -0700 | [diff] [blame] | 236 | mFutureSeekRunnable.setProgress(progress); |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 237 | delayResetToMetadata(); |
Jim Miller | cc747ad | 2013-10-24 19:53:09 -0700 | [diff] [blame] | 238 | mTempDate.setTime(progress); |
| 239 | mTransientSeekTimeElapsed.setText(mFormat.format(mTempDate)); |
| 240 | } else { |
| 241 | updateSeekDisplay(); |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 242 | } |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 243 | } |
| 244 | |
| 245 | @Override |
| 246 | public void onStartTrackingTouch(SeekBar seekBar) { |
Jim Miller | cc747ad | 2013-10-24 19:53:09 -0700 | [diff] [blame] | 247 | delayResetToMetadata(); |
| 248 | removeCallbacks(mUpdateSeekBars); // don't update during user interaction |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 249 | } |
| 250 | |
| 251 | @Override |
| 252 | public void onStopTrackingTouch(SeekBar seekBar) { |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 253 | } |
| 254 | }; |
| 255 | |
| 256 | private static final int TRANSITION_DURATION = 200; |
| 257 | private final TransitionSet mMetadataChangeTransition; |
| 258 | |
| 259 | KeyguardHostView.TransportControlCallback mTransportControlCallback; |
| 260 | |
Jim Miller | 20daffd | 2013-10-07 14:59:53 -0700 | [diff] [blame] | 261 | private final KeyguardUpdateMonitorCallback mUpdateMonitor |
| 262 | = new KeyguardUpdateMonitorCallback() { |
| 263 | public void onScreenTurnedOff(int why) { |
| 264 | setEnableMarquee(false); |
Craig Mautner | 8334192 | 2013-10-30 10:29:38 -0700 | [diff] [blame] | 265 | } |
Jim Miller | 20daffd | 2013-10-07 14:59:53 -0700 | [diff] [blame] | 266 | public void onScreenTurnedOn() { |
| 267 | setEnableMarquee(true); |
Craig Mautner | 8334192 | 2013-10-30 10:29:38 -0700 | [diff] [blame] | 268 | } |
Jim Miller | 20daffd | 2013-10-07 14:59:53 -0700 | [diff] [blame] | 269 | }; |
| 270 | |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 271 | public KeyguardTransportControlView(Context context, AttributeSet attrs) { |
| 272 | super(context, attrs); |
Dianne Hackborn | 40e9f29 | 2012-11-27 19:12:23 -0800 | [diff] [blame] | 273 | if (DEBUG) Log.v(TAG, "Create TCV " + this); |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 274 | mAudioManager = new AudioManager(mContext); |
| 275 | mCurrentPlayState = RemoteControlClient.PLAYSTATE_NONE; // until we get a callback |
Jean-Michel Trivi | f108cdd9 | 2013-09-27 18:37:36 -0700 | [diff] [blame] | 276 | mRemoteController = new RemoteController(context, mRCClientUpdateListener); |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 277 | |
| 278 | final DisplayMetrics dm = context.getResources().getDisplayMetrics(); |
| 279 | final int dim = Math.max(dm.widthPixels, dm.heightPixels); |
| 280 | mRemoteController.setArtworkConfiguration(true, dim, dim); |
| 281 | |
| 282 | final ChangeText tc = new ChangeText(); |
| 283 | tc.setChangeBehavior(ChangeText.CHANGE_BEHAVIOR_OUT_IN); |
| 284 | final TransitionSet inner = new TransitionSet(); |
| 285 | inner.addTransition(tc).addTransition(new ChangeBounds()); |
| 286 | final TransitionSet tg = new TransitionSet(); |
| 287 | tg.addTransition(new Fade(Fade.OUT)).addTransition(inner). |
| 288 | addTransition(new Fade(Fade.IN)); |
| 289 | tg.setOrdering(TransitionSet.ORDERING_SEQUENTIAL); |
| 290 | tg.setDuration(TRANSITION_DURATION); |
| 291 | mMetadataChangeTransition = tg; |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 292 | } |
| 293 | |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 294 | private void updateTransportControls(int transportControlFlags) { |
| 295 | mTransportControlFlags = transportControlFlags; |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 296 | setSeekBarsEnabled( |
| 297 | (transportControlFlags & RemoteControlClient.FLAG_KEY_MEDIA_POSITION_UPDATE) != 0); |
| 298 | } |
| 299 | |
| 300 | void setSeekBarsEnabled(boolean enabled) { |
| 301 | if (enabled == mSeekEnabled) return; |
| 302 | |
| 303 | mSeekEnabled = enabled; |
Jim Miller | cc747ad | 2013-10-24 19:53:09 -0700 | [diff] [blame] | 304 | if (mTransientSeek.getVisibility() == VISIBLE && !enabled) { |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 305 | mTransientSeek.setVisibility(INVISIBLE); |
| 306 | mMetadataContainer.setVisibility(VISIBLE); |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 307 | cancelResetToMetadata(); |
| 308 | } |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 309 | } |
| 310 | |
| 311 | public void setTransportControlCallback(KeyguardHostView.TransportControlCallback |
| 312 | transportControlCallback) { |
| 313 | mTransportControlCallback = transportControlCallback; |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 314 | } |
| 315 | |
Jim Miller | 20daffd | 2013-10-07 14:59:53 -0700 | [diff] [blame] | 316 | private void setEnableMarquee(boolean enabled) { |
| 317 | if (DEBUG) Log.v(TAG, (enabled ? "Enable" : "Disable") + " transport text marquee"); |
Adam Powell | 31049d7 | 2013-10-07 12:58:42 -0700 | [diff] [blame] | 318 | if (mTrackTitle != null) mTrackTitle.setSelected(enabled); |
| 319 | if (mTrackArtistAlbum != null) mTrackTitle.setSelected(enabled); |
Jim Miller | 20daffd | 2013-10-07 14:59:53 -0700 | [diff] [blame] | 320 | } |
| 321 | |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 322 | @Override |
| 323 | public void onFinishInflate() { |
| 324 | super.onFinishInflate(); |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 325 | mInfoContainer = (ViewGroup) findViewById(R.id.info_container); |
| 326 | mMetadataContainer = (ViewGroup) findViewById(R.id.metadata_container); |
| 327 | mBadge = (ImageView) findViewById(R.id.badge); |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 328 | mTrackTitle = (TextView) findViewById(R.id.title); |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 329 | mTrackArtistAlbum = (TextView) findViewById(R.id.artist_album); |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 330 | mTransientSeek = findViewById(R.id.transient_seek); |
| 331 | mTransientSeekBar = (SeekBar) findViewById(R.id.transient_seek_bar); |
| 332 | mTransientSeekBar.setOnSeekBarChangeListener(mOnSeekBarChangeListener); |
| 333 | mTransientSeekTimeElapsed = (TextView) findViewById(R.id.transient_seek_time_elapsed); |
Chris Wren | 6af85cc | 2013-10-29 13:19:54 -0400 | [diff] [blame] | 334 | mTransientSeekTimeTotal = (TextView) findViewById(R.id.transient_seek_time_remaining); |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 335 | mBtnPrev = (ImageView) findViewById(R.id.btn_prev); |
| 336 | mBtnPlay = (ImageView) findViewById(R.id.btn_play); |
| 337 | mBtnNext = (ImageView) findViewById(R.id.btn_next); |
| 338 | final View buttons[] = { mBtnPrev, mBtnPlay, mBtnNext }; |
| 339 | for (View view : buttons) { |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 340 | view.setOnClickListener(mTransportCommandListener); |
| 341 | view.setOnLongClickListener(mTransportShowSeekBarListener); |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 342 | } |
Jim Miller | 20daffd | 2013-10-07 14:59:53 -0700 | [diff] [blame] | 343 | final boolean screenOn = KeyguardUpdateMonitor.getInstance(mContext).isScreenOn(); |
| 344 | setEnableMarquee(screenOn); |
Jim Miller | cc747ad | 2013-10-24 19:53:09 -0700 | [diff] [blame] | 345 | // Allow long-press anywhere else in this view to show the seek bar |
| 346 | setOnLongClickListener(mTransportShowSeekBarListener); |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 347 | } |
| 348 | |
| 349 | @Override |
| 350 | public void onAttachedToWindow() { |
| 351 | super.onAttachedToWindow(); |
| 352 | if (DEBUG) Log.v(TAG, "onAttachToWindow()"); |
| 353 | if (mPopulateMetadataWhenAttached != null) { |
| 354 | updateMetadata(mPopulateMetadataWhenAttached); |
| 355 | mPopulateMetadataWhenAttached = null; |
| 356 | } |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 357 | if (DEBUG) Log.v(TAG, "Registering TCV " + this); |
Adam Powell | 3b435fb | 2013-10-15 19:15:39 -0700 | [diff] [blame] | 358 | mMetadata.clear(); |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 359 | mAudioManager.registerRemoteController(mRemoteController); |
Jim Miller | 20daffd | 2013-10-07 14:59:53 -0700 | [diff] [blame] | 360 | KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mUpdateMonitor); |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 361 | } |
| 362 | |
| 363 | @Override |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 364 | protected void onConfigurationChanged(Configuration newConfig) { |
| 365 | super.onConfigurationChanged(newConfig); |
| 366 | final DisplayMetrics dm = getContext().getResources().getDisplayMetrics(); |
| 367 | final int dim = Math.max(dm.widthPixels, dm.heightPixels); |
| 368 | mRemoteController.setArtworkConfiguration(true, dim, dim); |
Jean-Michel Trivi | 9e589b9 | 2013-03-08 14:30:10 -0800 | [diff] [blame] | 369 | } |
| 370 | |
| 371 | @Override |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 372 | public void onDetachedFromWindow() { |
| 373 | if (DEBUG) Log.v(TAG, "onDetachFromWindow()"); |
| 374 | super.onDetachedFromWindow(); |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 375 | if (DEBUG) Log.v(TAG, "Unregistering TCV " + this); |
| 376 | mAudioManager.unregisterRemoteController(mRemoteController); |
Jim Miller | 20daffd | 2013-10-07 14:59:53 -0700 | [diff] [blame] | 377 | KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mUpdateMonitor); |
Adam Powell | 3b435fb | 2013-10-15 19:15:39 -0700 | [diff] [blame] | 378 | mMetadata.clear(); |
Jim Miller | b2c6469 | 2013-10-15 20:09:07 -0700 | [diff] [blame] | 379 | removeCallbacks(mUpdateSeekBars); |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 380 | } |
| 381 | |
Craig Mautner | 8334192 | 2013-10-30 10:29:38 -0700 | [diff] [blame] | 382 | @Override |
| 383 | protected Parcelable onSaveInstanceState() { |
| 384 | SavedState ss = new SavedState(super.onSaveInstanceState()); |
| 385 | ss.artist = mMetadata.artist; |
| 386 | ss.trackTitle = mMetadata.trackTitle; |
| 387 | ss.albumTitle = mMetadata.albumTitle; |
| 388 | ss.duration = mMetadata.duration; |
| 389 | ss.bitmap = mMetadata.bitmap; |
| 390 | return ss; |
| 391 | } |
| 392 | |
| 393 | @Override |
| 394 | protected void onRestoreInstanceState(Parcelable state) { |
| 395 | if (!(state instanceof SavedState)) { |
| 396 | super.onRestoreInstanceState(state); |
| 397 | return; |
| 398 | } |
| 399 | SavedState ss = (SavedState) state; |
| 400 | super.onRestoreInstanceState(ss.getSuperState()); |
| 401 | mMetadata.artist = ss.artist; |
| 402 | mMetadata.trackTitle = ss.trackTitle; |
| 403 | mMetadata.albumTitle = ss.albumTitle; |
| 404 | mMetadata.duration = ss.duration; |
| 405 | mMetadata.bitmap = ss.bitmap; |
| 406 | populateMetadata(); |
| 407 | } |
| 408 | |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 409 | void setBadgeIcon(Drawable bmp) { |
| 410 | mBadge.setImageDrawable(bmp); |
| 411 | |
| 412 | final ColorMatrix cm = new ColorMatrix(); |
| 413 | cm.setSaturation(0); |
| 414 | mBadge.setColorFilter(new ColorMatrixColorFilter(cm)); |
Adam Powell | 31049d7 | 2013-10-07 12:58:42 -0700 | [diff] [blame] | 415 | mBadge.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SCREEN)); |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 416 | mBadge.setImageAlpha(0xef); |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 417 | } |
| 418 | |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 419 | class Metadata { |
| 420 | private String artist; |
| 421 | private String trackTitle; |
| 422 | private String albumTitle; |
| 423 | private Bitmap bitmap; |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 424 | private long duration; |
| 425 | |
| 426 | public void clear() { |
| 427 | artist = null; |
| 428 | trackTitle = null; |
| 429 | albumTitle = null; |
| 430 | bitmap = null; |
| 431 | duration = -1; |
| 432 | } |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 433 | |
| 434 | public String toString() { |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 435 | return "Metadata[artist=" + artist + " trackTitle=" + trackTitle + |
| 436 | " albumTitle=" + albumTitle + " duration=" + duration + "]"; |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 437 | } |
| 438 | } |
| 439 | |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 440 | void clearMetadata() { |
| 441 | mPopulateMetadataWhenAttached = null; |
| 442 | mMetadata.clear(); |
| 443 | populateMetadata(); |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 444 | } |
| 445 | |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 446 | void updateMetadata(RemoteController.MetadataEditor data) { |
| 447 | if (isAttachedToWindow()) { |
| 448 | mMetadata.artist = data.getString(MediaMetadataRetriever.METADATA_KEY_ALBUMARTIST, |
| 449 | mMetadata.artist); |
| 450 | mMetadata.trackTitle = data.getString(MediaMetadataRetriever.METADATA_KEY_TITLE, |
| 451 | mMetadata.trackTitle); |
| 452 | mMetadata.albumTitle = data.getString(MediaMetadataRetriever.METADATA_KEY_ALBUM, |
| 453 | mMetadata.albumTitle); |
| 454 | mMetadata.duration = data.getLong(MediaMetadataRetriever.METADATA_KEY_DURATION, -1); |
| 455 | mMetadata.bitmap = data.getBitmap(MediaMetadataEditor.BITMAP_KEY_ARTWORK, |
| 456 | mMetadata.bitmap); |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 457 | populateMetadata(); |
| 458 | } else { |
| 459 | mPopulateMetadataWhenAttached = data; |
| 460 | } |
| 461 | } |
| 462 | |
| 463 | /** |
| 464 | * Populates the given metadata into the view |
| 465 | */ |
| 466 | private void populateMetadata() { |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 467 | if (ANIMATE_TRANSITIONS && isLaidOut() && mMetadataContainer.getVisibility() == VISIBLE) { |
| 468 | TransitionManager.beginDelayedTransition(mMetadataContainer, mMetadataChangeTransition); |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 469 | } |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 470 | |
| 471 | final String remoteClientPackage = mRemoteController.getRemoteControlClientPackageName(); |
| 472 | Drawable badgeIcon = null; |
| 473 | try { |
| 474 | badgeIcon = getContext().getPackageManager().getApplicationIcon(remoteClientPackage); |
| 475 | } catch (PackageManager.NameNotFoundException e) { |
| 476 | Log.e(TAG, "Couldn't get remote control client package icon", e); |
| 477 | } |
| 478 | setBadgeIcon(badgeIcon); |
Adam Powell | 3b435fb | 2013-10-15 19:15:39 -0700 | [diff] [blame] | 479 | mTrackTitle.setText(!TextUtils.isEmpty(mMetadata.trackTitle) |
| 480 | ? mMetadata.trackTitle : null); |
| 481 | |
| 482 | final StringBuilder sb = new StringBuilder(); |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 483 | if (!TextUtils.isEmpty(mMetadata.artist)) { |
| 484 | if (sb.length() != 0) { |
| 485 | sb.append(" - "); |
| 486 | } |
| 487 | sb.append(mMetadata.artist); |
| 488 | } |
| 489 | if (!TextUtils.isEmpty(mMetadata.albumTitle)) { |
| 490 | if (sb.length() != 0) { |
| 491 | sb.append(" - "); |
| 492 | } |
| 493 | sb.append(mMetadata.albumTitle); |
| 494 | } |
Adam Powell | 3b435fb | 2013-10-15 19:15:39 -0700 | [diff] [blame] | 495 | |
| 496 | final String trackArtistAlbum = sb.toString(); |
| 497 | mTrackArtistAlbum.setText(!TextUtils.isEmpty(trackArtistAlbum) ? |
| 498 | trackArtistAlbum : null); |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 499 | |
| 500 | if (mMetadata.duration >= 0) { |
| 501 | setSeekBarsEnabled(true); |
| 502 | setSeekBarDuration(mMetadata.duration); |
| 503 | |
| 504 | final String skeleton; |
| 505 | |
| 506 | if (mMetadata.duration >= 86400000) { |
| 507 | skeleton = "DDD kk mm ss"; |
| 508 | } else if (mMetadata.duration >= 3600000) { |
| 509 | skeleton = "kk mm ss"; |
| 510 | } else { |
| 511 | skeleton = "mm ss"; |
| 512 | } |
| 513 | mFormat = new SimpleDateFormat(DateFormat.getBestDateTimePattern( |
| 514 | getContext().getResources().getConfiguration().locale, |
| 515 | skeleton)); |
| 516 | mFormat.setTimeZone(TimeZone.getTimeZone("GMT+0")); |
| 517 | } else { |
| 518 | setSeekBarsEnabled(false); |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 519 | } |
| 520 | |
Jim Miller | 1693f6a | 2013-10-20 17:21:57 -0700 | [diff] [blame] | 521 | KeyguardUpdateMonitor.getInstance(getContext()).dispatchSetBackground(mMetadata.bitmap); |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 522 | final int flags = mTransportControlFlags; |
| 523 | setVisibilityBasedOnFlag(mBtnPrev, flags, RemoteControlClient.FLAG_KEY_MEDIA_PREVIOUS); |
| 524 | setVisibilityBasedOnFlag(mBtnNext, flags, RemoteControlClient.FLAG_KEY_MEDIA_NEXT); |
| 525 | setVisibilityBasedOnFlag(mBtnPlay, flags, |
| 526 | RemoteControlClient.FLAG_KEY_MEDIA_PLAY |
| 527 | | RemoteControlClient.FLAG_KEY_MEDIA_PAUSE |
| 528 | | RemoteControlClient.FLAG_KEY_MEDIA_PLAY_PAUSE |
| 529 | | RemoteControlClient.FLAG_KEY_MEDIA_STOP); |
| 530 | |
| 531 | updatePlayPauseState(mCurrentPlayState); |
| 532 | } |
| 533 | |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 534 | void updateSeekDisplay() { |
| 535 | if (mMetadata != null && mRemoteController != null && mFormat != null) { |
Jim Miller | cc747ad | 2013-10-24 19:53:09 -0700 | [diff] [blame] | 536 | mTempDate.setTime(mRemoteController.getEstimatedMediaPosition()); |
| 537 | mTransientSeekTimeElapsed.setText(mFormat.format(mTempDate)); |
| 538 | mTempDate.setTime(mMetadata.duration); |
| 539 | mTransientSeekTimeTotal.setText(mFormat.format(mTempDate)); |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 540 | |
Jim Miller | cc747ad | 2013-10-24 19:53:09 -0700 | [diff] [blame] | 541 | if (DEBUG) Log.d(TAG, "updateSeekDisplay timeElapsed=" + mTempDate + |
Chris Wren | 6af85cc | 2013-10-29 13:19:54 -0400 | [diff] [blame] | 542 | " duration=" + mMetadata.duration); |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 543 | } |
| 544 | } |
| 545 | |
| 546 | boolean tryToggleSeekBar() { |
| 547 | if (ANIMATE_TRANSITIONS) { |
| 548 | TransitionManager.beginDelayedTransition(mInfoContainer); |
| 549 | } |
| 550 | if (mTransientSeek.getVisibility() == VISIBLE) { |
| 551 | mTransientSeek.setVisibility(INVISIBLE); |
| 552 | mMetadataContainer.setVisibility(VISIBLE); |
| 553 | cancelResetToMetadata(); |
Jim Miller | cc747ad | 2013-10-24 19:53:09 -0700 | [diff] [blame] | 554 | removeCallbacks(mUpdateSeekBars); // don't update if scrubber isn't visible |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 555 | } else { |
| 556 | mTransientSeek.setVisibility(VISIBLE); |
| 557 | mMetadataContainer.setVisibility(INVISIBLE); |
| 558 | delayResetToMetadata(); |
Jim Miller | cc747ad | 2013-10-24 19:53:09 -0700 | [diff] [blame] | 559 | if (playbackPositionShouldMove(mCurrentPlayState)) { |
| 560 | mUpdateSeekBars.run(); |
| 561 | } else { |
| 562 | mUpdateSeekBars.updateOnce(); |
| 563 | } |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 564 | } |
| 565 | mTransportControlCallback.userActivity(); |
| 566 | return true; |
| 567 | } |
| 568 | |
| 569 | void resetToMetadata() { |
| 570 | if (ANIMATE_TRANSITIONS) { |
| 571 | TransitionManager.beginDelayedTransition(mInfoContainer); |
| 572 | } |
| 573 | if (mTransientSeek.getVisibility() == VISIBLE) { |
| 574 | mTransientSeek.setVisibility(INVISIBLE); |
| 575 | mMetadataContainer.setVisibility(VISIBLE); |
| 576 | } |
| 577 | // TODO Also hide ratings, if applicable |
| 578 | } |
| 579 | |
| 580 | void delayResetToMetadata() { |
| 581 | removeCallbacks(mResetToMetadata); |
| 582 | postDelayed(mResetToMetadata, RESET_TO_METADATA_DELAY); |
| 583 | } |
| 584 | |
| 585 | void cancelResetToMetadata() { |
| 586 | removeCallbacks(mResetToMetadata); |
| 587 | } |
| 588 | |
| 589 | void setSeekBarDuration(long duration) { |
| 590 | mTransientSeekBar.setMax((int) duration); |
| 591 | } |
| 592 | |
| 593 | void scrubTo(int progress) { |
| 594 | mRemoteController.seekTo(progress); |
| 595 | mTransportControlCallback.userActivity(); |
| 596 | } |
| 597 | |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 598 | private static void setVisibilityBasedOnFlag(View view, int flags, int flag) { |
| 599 | if ((flags & flag) != 0) { |
| 600 | view.setVisibility(View.VISIBLE); |
| 601 | } else { |
Adam Powell | f517692 | 2013-10-13 10:39:04 -0700 | [diff] [blame] | 602 | view.setVisibility(View.INVISIBLE); |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 603 | } |
| 604 | } |
| 605 | |
| 606 | private void updatePlayPauseState(int state) { |
| 607 | if (DEBUG) Log.v(TAG, |
| 608 | "updatePlayPauseState(), old=" + mCurrentPlayState + ", state=" + state); |
| 609 | if (state == mCurrentPlayState) { |
| 610 | return; |
| 611 | } |
| 612 | final int imageResId; |
| 613 | final int imageDescId; |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 614 | switch (state) { |
| 615 | case RemoteControlClient.PLAYSTATE_ERROR: |
Jim Miller | 5ecd811 | 2013-01-09 18:50:26 -0800 | [diff] [blame] | 616 | imageResId = R.drawable.stat_sys_warning; |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 617 | // TODO use more specific image description string for warning, but here the "play" |
| 618 | // message is still valid because this button triggers a play command. |
Jim Miller | 5ecd811 | 2013-01-09 18:50:26 -0800 | [diff] [blame] | 619 | imageDescId = R.string.keyguard_transport_play_description; |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 620 | break; |
| 621 | |
| 622 | case RemoteControlClient.PLAYSTATE_PLAYING: |
Jim Miller | 5ecd811 | 2013-01-09 18:50:26 -0800 | [diff] [blame] | 623 | imageResId = R.drawable.ic_media_pause; |
| 624 | imageDescId = R.string.keyguard_transport_pause_description; |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 625 | break; |
| 626 | |
| 627 | case RemoteControlClient.PLAYSTATE_BUFFERING: |
Jim Miller | 5ecd811 | 2013-01-09 18:50:26 -0800 | [diff] [blame] | 628 | imageResId = R.drawable.ic_media_stop; |
| 629 | imageDescId = R.string.keyguard_transport_stop_description; |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 630 | break; |
| 631 | |
| 632 | case RemoteControlClient.PLAYSTATE_PAUSED: |
| 633 | default: |
Jim Miller | 5ecd811 | 2013-01-09 18:50:26 -0800 | [diff] [blame] | 634 | imageResId = R.drawable.ic_media_play; |
| 635 | imageDescId = R.string.keyguard_transport_play_description; |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 636 | break; |
| 637 | } |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 638 | |
Jim Miller | cc747ad | 2013-10-24 19:53:09 -0700 | [diff] [blame] | 639 | boolean clientSupportsSeek = mMetadata != null && mMetadata.duration > 0; |
| 640 | setSeekBarsEnabled(clientSupportsSeek); |
| 641 | |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 642 | mBtnPlay.setImageResource(imageResId); |
| 643 | mBtnPlay.setContentDescription(getResources().getString(imageDescId)); |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 644 | mCurrentPlayState = state; |
| 645 | } |
| 646 | |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 647 | boolean updateSeekBars() { |
| 648 | final int position = (int) mRemoteController.getEstimatedMediaPosition(); |
Jim Miller | cc747ad | 2013-10-24 19:53:09 -0700 | [diff] [blame] | 649 | if (DEBUG) Log.v(TAG, "Estimated time:" + position); |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 650 | if (position >= 0) { |
Jim Miller | cc747ad | 2013-10-24 19:53:09 -0700 | [diff] [blame] | 651 | mTransientSeekBar.setProgress(position); |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 652 | return true; |
| 653 | } |
| 654 | Log.w(TAG, "Updating seek bars; received invalid estimated media position (" + |
| 655 | position + "). Disabling seek."); |
| 656 | setSeekBarsEnabled(false); |
| 657 | return false; |
| 658 | } |
| 659 | |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 660 | static class SavedState extends BaseSavedState { |
Jim Miller | 223ce5c | 2012-10-05 19:13:23 -0700 | [diff] [blame] | 661 | boolean clientPresent; |
Craig Mautner | 8334192 | 2013-10-30 10:29:38 -0700 | [diff] [blame] | 662 | String artist; |
| 663 | String trackTitle; |
| 664 | String albumTitle; |
| 665 | long duration; |
| 666 | Bitmap bitmap; |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 667 | |
| 668 | SavedState(Parcelable superState) { |
| 669 | super(superState); |
| 670 | } |
| 671 | |
| 672 | private SavedState(Parcel in) { |
| 673 | super(in); |
Craig Mautner | 8334192 | 2013-10-30 10:29:38 -0700 | [diff] [blame] | 674 | clientPresent = in.readInt() != 0; |
| 675 | artist = in.readString(); |
| 676 | trackTitle = in.readString(); |
| 677 | albumTitle = in.readString(); |
| 678 | duration = in.readLong(); |
| 679 | bitmap = Bitmap.CREATOR.createFromParcel(in); |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 680 | } |
| 681 | |
| 682 | @Override |
| 683 | public void writeToParcel(Parcel out, int flags) { |
| 684 | super.writeToParcel(out, flags); |
Craig Mautner | 8334192 | 2013-10-30 10:29:38 -0700 | [diff] [blame] | 685 | out.writeInt(clientPresent ? 1 : 0); |
| 686 | out.writeString(artist); |
| 687 | out.writeString(trackTitle); |
| 688 | out.writeString(albumTitle); |
| 689 | out.writeLong(duration); |
| 690 | bitmap.writeToParcel(out, flags); |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 691 | } |
| 692 | |
| 693 | public static final Parcelable.Creator<SavedState> CREATOR |
| 694 | = new Parcelable.Creator<SavedState>() { |
| 695 | public SavedState createFromParcel(Parcel in) { |
| 696 | return new SavedState(in); |
| 697 | } |
| 698 | |
| 699 | public SavedState[] newArray(int size) { |
| 700 | return new SavedState[size]; |
| 701 | } |
| 702 | }; |
| 703 | } |
| 704 | |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 705 | private void sendMediaButtonClick(int keyCode) { |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 706 | // TODO We should think about sending these up/down events accurately with touch up/down |
| 707 | // on the buttons, but in the near term this will interfere with the long press behavior. |
| 708 | mRemoteController.sendMediaKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, keyCode)); |
| 709 | mRemoteController.sendMediaKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, keyCode)); |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 710 | |
Adam Powell | f889524 | 2013-09-30 16:16:24 -0700 | [diff] [blame] | 711 | mTransportControlCallback.userActivity(); |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 712 | } |
| 713 | |
| 714 | public boolean providesClock() { |
| 715 | return false; |
| 716 | } |
Jim Miller | ff2aa0b | 2012-09-06 19:03:52 -0700 | [diff] [blame] | 717 | } |