Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1b16cc3d authored by Jean-Michel Trivi's avatar Jean-Michel Trivi
Browse files

Let RemoteControlDisplay know more about playback position

The BT stack needs to differentiate between applications that use
 the new RemoteControlClient APIs to pass a playback position but
 don't have one yet, and applications that use the legacy API and
 will never pass a position.

Bug 9294855

Change-Id: I05cba82a073e6e0aaea1d8bbf9cc8c99da715f58
parent 865047f8
Loading
Loading
Loading
Loading
+27 −0
Original line number Diff line number Diff line
@@ -40,6 +40,33 @@ oneway interface IRemoteControlDisplay
    void setCurrentClientId(int clientGeneration, in PendingIntent clientMediaIntent,
            boolean clearing);

    /**
     * Sets the playback information (state, position and speed) of a client.
     * @param generationId the current generation ID as known by this client
     * @param state the current playback state, one of the following values:
     *       {@link RemoteControlClient#PLAYSTATE_STOPPED},
     *       {@link RemoteControlClient#PLAYSTATE_PAUSED},
     *       {@link RemoteControlClient#PLAYSTATE_PLAYING},
     *       {@link RemoteControlClient#PLAYSTATE_FAST_FORWARDING},
     *       {@link RemoteControlClient#PLAYSTATE_REWINDING},
     *       {@link RemoteControlClient#PLAYSTATE_SKIPPING_FORWARDS},
     *       {@link RemoteControlClient#PLAYSTATE_SKIPPING_BACKWARDS},
     *       {@link RemoteControlClient#PLAYSTATE_BUFFERING},
     *       {@link RemoteControlClient#PLAYSTATE_ERROR}.
     * @param stateChangeTimeMs the time at which the client reported the playback information
     * @param currentPosMs a 0 or positive value for the current media position expressed in ms
     *    Strictly negative values imply that position is not known:
     *    a value of {@link RemoteControlClient#PLAYBACK_POSITION_INVALID} is intended to express
     *    that an application doesn't know the position (e.g. listening to a live stream of a radio)
     *    or that the position information is not applicable (e.g. when state
     *    is {@link RemoteControlClient#PLAYSTATE_BUFFERING} and nothing had played yet);
     *    a value of {@link RemoteControlClient#PLAYBACK_POSITION_ALWAYS_UNKNOWN} implies that the
     *    application uses {@link RemoteControlClient#setPlaybackState(int)} (legacy API) and will
     *    never pass a playback position.
     * @param speed a value expressed as a ratio of 1x playback: 1.0f is normal playback,
     *    2.0f is 2x, 0.5f is half-speed, -2.0f is rewind at 2x speed. 0.0f means nothing is
     *    playing (e.g. when state is {@link RemoteControlClient#PLAYSTATE_ERROR}).
     */
    void setPlaybackState(int generationId, int state, long stateChangeTimeMs, long currentPosMs,
            float speed);

+25 −2
Original line number Diff line number Diff line
@@ -178,6 +178,12 @@ public class RemoteControlClient
     * An unknown or invalid playback position value.
     */
    public final static long PLAYBACK_POSITION_INVALID = -1;
    /**
     * @hide
     * An invalid playback position value associated with the use of {@link #setPlaybackState(int)}
     * used to indicate that playback position will remain unknown.
     */
    public final static long PLAYBACK_POSITION_ALWAYS_UNKNOWN = 0x8019771980198300L;
    /**
     * @hide
     * The default playback speed, 1x.
@@ -602,7 +608,8 @@ public class RemoteControlClient
     *       {@link #PLAYSTATE_ERROR}.
     */
    public void setPlaybackState(int state) {
        setPlaybackState(state, PLAYBACK_POSITION_INVALID, PLAYBACK_SPEED_1X);
        setPlaybackStateInt(state, PLAYBACK_POSITION_ALWAYS_UNKNOWN, PLAYBACK_SPEED_1X,
                false /* legacy API, converting to method with position and speed */);
    }

    /**
@@ -629,12 +636,28 @@ public class RemoteControlClient
     *    playing (e.g. when state is {@link #PLAYSTATE_ERROR}).
     */
    public void setPlaybackState(int state, long timeInMs, float playbackSpeed) {
        setPlaybackStateInt(state, timeInMs, playbackSpeed, true);
    }

    private void setPlaybackStateInt(int state, long timeInMs, float playbackSpeed,
            boolean hasPosition) {
        synchronized(mCacheLock) {
            if ((mPlaybackState != state) || (mPlaybackPositionMs != timeInMs)
                    || (mPlaybackSpeed != playbackSpeed)) {
                // store locally
                mPlaybackState = state;
                // distinguish between an application not knowing the current playback position
                // at the moment and an application using the API where only the playback state
                // is passed, not the playback position.
                if (hasPosition) {
                    if (timeInMs < 0) {
                        mPlaybackPositionMs = PLAYBACK_POSITION_INVALID;
                    } else {
                        mPlaybackPositionMs = timeInMs;
                    }
                } else {
                    mPlaybackPositionMs = PLAYBACK_POSITION_ALWAYS_UNKNOWN;
                }
                mPlaybackSpeed = playbackSpeed;
                // keep track of when the state change occurred
                mPlaybackStateChangeTimeMs = SystemClock.elapsedRealtime();