From 68622396b62f9084781add1e12f4d513b633ab54 Mon Sep 17 00:00:00 2001 From: Jean-Michel Trivi Date: Mon, 19 Sep 2011 14:53:14 -0700 Subject: [PATCH] Bug 5045498 Keep track of RemoteControlClient play state change time Store the time at which a RemoteControlClient changes it playback state, and send that time to the IRemoteControlDisplay. This change will enable displays to implement strategies such as timeouts (e.g. to not display transport controls for clients which have been paused or stopped for a certain amount of time). Change-Id: I902882500565743d455d56f6000efaf612cbe0a9 --- .../internal/widget/TransportControlView.java | 33 ++++++++++++++++++- .../android/media/IRemoteControlDisplay.aidl | 2 +- .../android/media/RemoteControlClient.java | 21 +++++++++--- 3 files changed, 49 insertions(+), 7 deletions(-) diff --git a/core/java/com/android/internal/widget/TransportControlView.java b/core/java/com/android/internal/widget/TransportControlView.java index 1c7ad617176be..1042a59d6d24a 100644 --- a/core/java/com/android/internal/widget/TransportControlView.java +++ b/core/java/com/android/internal/widget/TransportControlView.java @@ -35,6 +35,7 @@ import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.os.RemoteException; +import android.os.SystemClock; import android.text.Spannable; import android.text.TextUtils; import android.text.style.ForegroundColorSpan; @@ -59,6 +60,7 @@ public class TransportControlView extends FrameLayout implements OnClickListener private static final int MSG_SET_ARTWORK = 103; private static final int MSG_SET_GENERATION_ID = 104; private static final int MAXDIM = 512; + private static final int DISPLAY_TIMEOUT_MS = 5000; // 5s protected static final boolean DEBUG = true; protected static final String TAG = "TransportControlView"; @@ -142,7 +144,7 @@ public class TransportControlView extends FrameLayout implements OnClickListener mLocalHandler = new WeakReference(handler); } - public void setPlaybackState(int generationId, int state) { + public void setPlaybackState(int generationId, int state, long stateChangeTimeMs) { Handler handler = mLocalHandler.get(); if (handler != null) { handler.obtainMessage(MSG_UPDATE_STATE, generationId, state).sendToTarget(); @@ -401,4 +403,33 @@ public class TransportControlView extends FrameLayout implements OnClickListener return false; } + private boolean wasPlayingRecently(int state, long stateChangeTimeMs) { + switch (state) { + case RemoteControlClient.PLAYSTATE_PLAYING: + case RemoteControlClient.PLAYSTATE_FAST_FORWARDING: + case RemoteControlClient.PLAYSTATE_REWINDING: + case RemoteControlClient.PLAYSTATE_SKIPPING_FORWARDS: + case RemoteControlClient.PLAYSTATE_SKIPPING_BACKWARDS: + case RemoteControlClient.PLAYSTATE_BUFFERING: + // actively playing or about to play + return true; + case RemoteControlClient.PLAYSTATE_NONE: + return false; + case RemoteControlClient.PLAYSTATE_STOPPED: + case RemoteControlClient.PLAYSTATE_PAUSED: + case RemoteControlClient.PLAYSTATE_ERROR: + // we have stopped playing, check how long ago + if (DEBUG) { + if ((SystemClock.elapsedRealtime() - stateChangeTimeMs) < DISPLAY_TIMEOUT_MS) { + Log.v(TAG, "wasPlayingRecently: time < TIMEOUT was playing recently"); + } else { + Log.v(TAG, "wasPlayingRecently: time > TIMEOUT"); + } + } + return ((SystemClock.elapsedRealtime() - stateChangeTimeMs) < DISPLAY_TIMEOUT_MS); + default: + Log.e(TAG, "Unknown playback state " + state + " in wasPlayingRecently()"); + return false; + } + } } diff --git a/media/java/android/media/IRemoteControlDisplay.aidl b/media/java/android/media/IRemoteControlDisplay.aidl index e15b07c3c897d..204de3c28d7c7 100644 --- a/media/java/android/media/IRemoteControlDisplay.aidl +++ b/media/java/android/media/IRemoteControlDisplay.aidl @@ -40,7 +40,7 @@ oneway interface IRemoteControlDisplay void setCurrentClientId(int clientGeneration, in PendingIntent clientMediaIntent, boolean clearing); - void setPlaybackState(int generationId, int state); + void setPlaybackState(int generationId, int state, long stateChangeTimeMs); void setTransportControlFlags(int generationId, int transportControlFlags); diff --git a/media/java/android/media/RemoteControlClient.java b/media/java/android/media/RemoteControlClient.java index 5dea87f756fd5..198ae4c8f7f7a 100644 --- a/media/java/android/media/RemoteControlClient.java +++ b/media/java/android/media/RemoteControlClient.java @@ -29,6 +29,7 @@ import android.os.Handler; import android.os.Looper; import android.os.Message; import android.os.RemoteException; +import android.os.SystemClock; import android.util.Log; import java.lang.IllegalArgumentException; @@ -494,11 +495,15 @@ public class RemoteControlClient */ public void setPlaybackState(int state) { synchronized(mCacheLock) { - // store locally - mPlaybackState = state; + if (mPlaybackState != state) { + // store locally + mPlaybackState = state; + // keep track of when the state change occurred + mPlaybackStateChangeTimeMs = SystemClock.elapsedRealtime(); - // send to remote control display if conditions are met - sendPlaybackState_syncCacheLock(); + // send to remote control display if conditions are met + sendPlaybackState_syncCacheLock(); + } } } @@ -533,6 +538,11 @@ public class RemoteControlClient * Access synchronized on mCacheLock */ private int mPlaybackState = PLAYSTATE_NONE; + /** + * Time of last play state change + * Access synchronized on mCacheLock + */ + private long mPlaybackStateChangeTimeMs = 0; /** * Cache for the artwork bitmap. * Access synchronized on mCacheLock @@ -716,7 +726,8 @@ public class RemoteControlClient private void sendPlaybackState_syncCacheLock() { if ((mCurrentClientGenId == mInternalClientGenId) && (mRcDisplay != null)) { try { - mRcDisplay.setPlaybackState(mInternalClientGenId, mPlaybackState); + mRcDisplay.setPlaybackState(mInternalClientGenId, mPlaybackState, + mPlaybackStateChangeTimeMs); } catch (RemoteException e) { Log.e(TAG, "Error in setPlaybackState(), dead display "+e); detachFromDisplay_syncCacheLock();