OSDN Git Service

Bug 5045498 Keep track of RemoteControlClient play state change time
authorJean-Michel Trivi <jmtrivi@google.com>
Mon, 19 Sep 2011 21:53:14 +0000 (14:53 -0700)
committerJean-Michel Trivi <jmtrivi@google.com>
Tue, 20 Sep 2011 18:59:51 +0000 (11:59 -0700)
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

core/java/com/android/internal/widget/TransportControlView.java
media/java/android/media/IRemoteControlDisplay.aidl
media/java/android/media/RemoteControlClient.java

index 1c7ad61..1042a59 100644 (file)
@@ -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>(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;
+        }
+    }
 }
index e15b07c..204de3c 100644 (file)
@@ -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);
 
index 5dea87f..198ae4c 100644 (file)
@@ -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;
-
-            // send to remote control display if conditions are met
-            sendPlaybackState_syncCacheLock();
+            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();
+            }
         }
     }
 
@@ -534,6 +539,11 @@ public class RemoteControlClient
      */
     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
      * Artwork and metadata are not kept in one Bundle because the bitmap sometimes needs to be
@@ -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();