[go: nahoru, domu]

1178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi/*
2178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * Copyright (C) 2011 The Android Open Source Project
3178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi *
4178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * Licensed under the Apache License, Version 2.0 (the "License");
5178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * you may not use this file except in compliance with the License.
6178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * You may obtain a copy of the License at
7178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi *
8178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi *      http://www.apache.org/licenses/LICENSE-2.0
9178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi *
10178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * Unless required by applicable law or agreed to in writing, software
11178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * distributed under the License is distributed on an "AS IS" BASIS,
12178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * See the License for the specific language governing permissions and
14178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * limitations under the License.
15178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi */
16178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi
17178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivipackage android.media;
18178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi
196e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Triviimport android.app.PendingIntent;
20178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Triviimport android.content.ComponentName;
216e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Triviimport android.content.Intent;
22178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Triviimport android.graphics.Bitmap;
23f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErikimport android.media.session.MediaSessionLegacyHelper;
24f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErikimport android.media.session.PlaybackState;
2542ea7eecd149161ed192d3029f0d77d1d08a4aa5RoboErikimport android.media.session.MediaSession;
264426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Triviimport android.os.Bundle;
274426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Triviimport android.os.Handler;
284426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Triviimport android.os.Looper;
294426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Triviimport android.os.Message;
3068622396b62f9084781add1e12f4d513b633ab54Jean-Michel Triviimport android.os.SystemClock;
314426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Triviimport android.util.Log;
324426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi
335ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Triviimport java.lang.IllegalArgumentException;
34178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi
35178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi/**
364426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * RemoteControlClient enables exposing information meant to be consumed by remote controls
37466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * capable of displaying metadata, artwork and media transport control buttons.
38ad87f5b40f2a3fd2d506dc15e00b8af28a8fa2baJean-Michel Trivi *
39ad87f5b40f2a3fd2d506dc15e00b8af28a8fa2baJean-Michel Trivi * <p>A remote control client object is associated with a media button event receiver. This
40466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * event receiver must have been previously registered with
41466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * {@link AudioManager#registerMediaButtonEventReceiver(ComponentName)} before the
42466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * RemoteControlClient can be registered through
434426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * {@link AudioManager#registerRemoteControlClient(RemoteControlClient)}.
44ad87f5b40f2a3fd2d506dc15e00b8af28a8fa2baJean-Michel Trivi *
45ad87f5b40f2a3fd2d506dc15e00b8af28a8fa2baJean-Michel Trivi * <p>Here is an example of creating a RemoteControlClient instance after registering a media
46ad87f5b40f2a3fd2d506dc15e00b8af28a8fa2baJean-Michel Trivi * button event receiver:
47ad87f5b40f2a3fd2d506dc15e00b8af28a8fa2baJean-Michel Trivi * <pre>ComponentName myEventReceiver = new ComponentName(getPackageName(), MyRemoteControlEventReceiver.class.getName());
48ad87f5b40f2a3fd2d506dc15e00b8af28a8fa2baJean-Michel Trivi * AudioManager myAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
49ad87f5b40f2a3fd2d506dc15e00b8af28a8fa2baJean-Michel Trivi * myAudioManager.registerMediaButtonEventReceiver(myEventReceiver);
50ad87f5b40f2a3fd2d506dc15e00b8af28a8fa2baJean-Michel Trivi * // build the PendingIntent for the remote control client
51ad87f5b40f2a3fd2d506dc15e00b8af28a8fa2baJean-Michel Trivi * Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
52ad87f5b40f2a3fd2d506dc15e00b8af28a8fa2baJean-Michel Trivi * mediaButtonIntent.setComponent(myEventReceiver);
53ad87f5b40f2a3fd2d506dc15e00b8af28a8fa2baJean-Michel Trivi * PendingIntent mediaPendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, mediaButtonIntent, 0);
54ad87f5b40f2a3fd2d506dc15e00b8af28a8fa2baJean-Michel Trivi * // create and register the remote control client
55ad87f5b40f2a3fd2d506dc15e00b8af28a8fa2baJean-Michel Trivi * RemoteControlClient myRemoteControlClient = new RemoteControlClient(mediaPendingIntent);
56ad87f5b40f2a3fd2d506dc15e00b8af28a8fa2baJean-Michel Trivi * myAudioManager.registerRemoteControlClient(myRemoteControlClient);</pre>
57edb158f55f48a1f7b2cbf30ddec9b8917dc9a619RoboErik *
58edb158f55f48a1f7b2cbf30ddec9b8917dc9a619RoboErik * @deprecated Use {@link MediaSession} instead.
59178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi */
60edb158f55f48a1f7b2cbf30ddec9b8917dc9a619RoboErik@Deprecated public class RemoteControlClient
61178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi{
624426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi    private final static String TAG = "RemoteControlClient";
63521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi    private final static boolean DEBUG = false;
644426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi
65178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi    /**
66178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     * Playback state of a RemoteControlClient which is stopped.
67178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     *
684426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi     * @see #setPlaybackState(int)
69178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     */
70178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi    public final static int PLAYSTATE_STOPPED            = 1;
71178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi    /**
72178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     * Playback state of a RemoteControlClient which is paused.
73178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     *
744426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi     * @see #setPlaybackState(int)
75178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     */
76178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi    public final static int PLAYSTATE_PAUSED             = 2;
77178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi    /**
78178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     * Playback state of a RemoteControlClient which is playing media.
79178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     *
804426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi     * @see #setPlaybackState(int)
81178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     */
82178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi    public final static int PLAYSTATE_PLAYING            = 3;
83178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi    /**
84178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     * Playback state of a RemoteControlClient which is fast forwarding in the media
85178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     *    it is currently playing.
86178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     *
874426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi     * @see #setPlaybackState(int)
88178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     */
89178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi    public final static int PLAYSTATE_FAST_FORWARDING    = 4;
90178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi    /**
91178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     * Playback state of a RemoteControlClient which is fast rewinding in the media
92178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     *    it is currently playing.
93178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     *
944426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi     * @see #setPlaybackState(int)
95178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     */
96178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi    public final static int PLAYSTATE_REWINDING          = 5;
97178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi    /**
98178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     * Playback state of a RemoteControlClient which is skipping to the next
99178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     *    logical chapter (such as a song in a playlist) in the media it is currently playing.
100178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     *
1014426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi     * @see #setPlaybackState(int)
102178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     */
103178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi    public final static int PLAYSTATE_SKIPPING_FORWARDS  = 6;
104178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi    /**
105178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     * Playback state of a RemoteControlClient which is skipping back to the previous
106178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     *    logical chapter (such as a song in a playlist) in the media it is currently playing.
107178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     *
1084426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi     * @see #setPlaybackState(int)
109178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     */
110178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi    public final static int PLAYSTATE_SKIPPING_BACKWARDS = 7;
111178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi    /**
112178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     * Playback state of a RemoteControlClient which is buffering data to play before it can
113178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     *    start or resume playback.
114178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     *
1154426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi     * @see #setPlaybackState(int)
116178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     */
117178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi    public final static int PLAYSTATE_BUFFERING          = 8;
118178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi    /**
119178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     * Playback state of a RemoteControlClient which cannot perform any playback related
120178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     *    operation because of an internal error. Examples of such situations are no network
121178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     *    connectivity when attempting to stream data from a server, or expired user credentials
122178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     *    when trying to play subscription-based content.
123178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     *
1244426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi     * @see #setPlaybackState(int)
125178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     */
126178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi    public final static int PLAYSTATE_ERROR              = 9;
1274426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi    /**
1284426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi     * @hide
129466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi     * The value of a playback state when none has been declared.
130466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi     * Intentionally hidden as an application shouldn't set such a playback state value.
1314426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi     */
1324426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi    public final static int PLAYSTATE_NONE               = 0;
133178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi
134178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi    /**
1351357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi     * @hide
1363114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi     * The default playback type, "local", indicating the presentation of the media is happening on
1373114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi     * the same device (e.g. a phone, a tablet) as where it is controlled from.
1383114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi     */
1393114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi    public final static int PLAYBACK_TYPE_LOCAL = 0;
1403114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi    /**
1411357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi     * @hide
1423114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi     * A playback type indicating the presentation of the media is happening on
1433114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi     * a different device (i.e. the remote device) than where it is controlled from.
1443114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi     */
1453114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi    public final static int PLAYBACK_TYPE_REMOTE = 1;
1463114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi    private final static int PLAYBACK_TYPE_MIN = PLAYBACK_TYPE_LOCAL;
1473114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi    private final static int PLAYBACK_TYPE_MAX = PLAYBACK_TYPE_REMOTE;
1483114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi    /**
1491357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi     * @hide
1503114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi     * Playback information indicating the playback volume is fixed, i.e. it cannot be controlled
1513114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi     * from this object. An example of fixed playback volume is a remote player, playing over HDMI
1523114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi     * where the user prefer to control the volume on the HDMI sink, rather than attenuate at the
1533114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi     * source.
1543114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi     * @see #PLAYBACKINFO_VOLUME_HANDLING.
1553114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi     */
1563114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi    public final static int PLAYBACK_VOLUME_FIXED = 0;
1573114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi    /**
1581357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi     * @hide
1593114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi     * Playback information indicating the playback volume is variable and can be controlled from
1603114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi     * this object.
1613114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi     * @see #PLAYBACKINFO_VOLUME_HANDLING.
1623114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi     */
1633114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi    public final static int PLAYBACK_VOLUME_VARIABLE = 1;
1643114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi    /**
1653114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi     * @hide (to be un-hidden)
1663114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi     * The playback information value indicating the value of a given information type is invalid.
1673114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi     * @see #PLAYBACKINFO_VOLUME_HANDLING.
1683114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi     */
1693114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi    public final static int PLAYBACKINFO_INVALID_VALUE = Integer.MIN_VALUE;
1703114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi
171bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi    /**
172bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     * @hide
173bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     * An unknown or invalid playback position value.
174bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     */
175bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi    public final static long PLAYBACK_POSITION_INVALID = -1;
176bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi    /**
177bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     * @hide
1781b16cc3de51d69c8027cefcc70a084a5b2d7a3d0Jean-Michel Trivi     * An invalid playback position value associated with the use of {@link #setPlaybackState(int)}
1791b16cc3de51d69c8027cefcc70a084a5b2d7a3d0Jean-Michel Trivi     * used to indicate that playback position will remain unknown.
1801b16cc3de51d69c8027cefcc70a084a5b2d7a3d0Jean-Michel Trivi     */
1811b16cc3de51d69c8027cefcc70a084a5b2d7a3d0Jean-Michel Trivi    public final static long PLAYBACK_POSITION_ALWAYS_UNKNOWN = 0x8019771980198300L;
1821b16cc3de51d69c8027cefcc70a084a5b2d7a3d0Jean-Michel Trivi    /**
1831b16cc3de51d69c8027cefcc70a084a5b2d7a3d0Jean-Michel Trivi     * @hide
184bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     * The default playback speed, 1x.
185bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     */
186bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi    public final static float PLAYBACK_SPEED_1X = 1.0f;
187bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi
1883114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi    //==========================================
1893114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi    // Public keys for playback information
1903114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi    /**
1911357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi     * @hide
1923114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi     * Playback information that defines the type of playback associated with this
1933114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi     * RemoteControlClient. See {@link #PLAYBACK_TYPE_LOCAL} and {@link #PLAYBACK_TYPE_REMOTE}.
1943114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi     */
1953114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi    public final static int PLAYBACKINFO_PLAYBACK_TYPE = 1;
1963114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi    /**
1971357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi     * @hide
1983114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi     * Playback information that defines at what volume the playback associated with this
1993114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi     * RemoteControlClient is performed. This information is only used when the playback type is not
2003114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi     * local (see {@link #PLAYBACKINFO_PLAYBACK_TYPE}).
2013114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi     */
2023114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi    public final static int PLAYBACKINFO_VOLUME = 2;
2033114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi    /**
2041357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi     * @hide
2053114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi     * Playback information that defines the maximum volume volume value that is supported
2063114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi     * by the playback associated with this RemoteControlClient. This information is only used
2073114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi     * when the playback type is not local (see {@link #PLAYBACKINFO_PLAYBACK_TYPE}).
2083114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi     */
2093114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi    public final static int PLAYBACKINFO_VOLUME_MAX = 3;
2103114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi    /**
2111357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi     * @hide
2123114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi     * Playback information that defines how volume is handled for the presentation of the media.
2133114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi     * @see #PLAYBACK_VOLUME_FIXED
2143114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi     * @see #PLAYBACK_VOLUME_VARIABLE
2153114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi     */
2163114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi    public final static int PLAYBACKINFO_VOLUME_HANDLING = 4;
2173114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi    /**
2181357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi     * @hide
2193114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi     * Playback information that defines over what stream type the media is presented.
2203114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi     */
2213114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi    public final static int PLAYBACKINFO_USES_STREAM = 5;
2223114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi
2233114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi    //==========================================
224521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi    // Public flags for the supported transport control capabilities
2253114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi    /**
226178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     * Flag indicating a RemoteControlClient makes use of the "previous" media key.
227178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     *
2284426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi     * @see #setTransportControlFlags(int)
229178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     * @see android.view.KeyEvent#KEYCODE_MEDIA_PREVIOUS
230178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     */
231178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi    public final static int FLAG_KEY_MEDIA_PREVIOUS = 1 << 0;
232178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi    /**
233466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi     * Flag indicating a RemoteControlClient makes use of the "rewind" media key.
234178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     *
2354426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi     * @see #setTransportControlFlags(int)
236178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     * @see android.view.KeyEvent#KEYCODE_MEDIA_REWIND
237178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     */
238178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi    public final static int FLAG_KEY_MEDIA_REWIND = 1 << 1;
239178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi    /**
240178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     * Flag indicating a RemoteControlClient makes use of the "play" media key.
241178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     *
2424426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi     * @see #setTransportControlFlags(int)
243178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     * @see android.view.KeyEvent#KEYCODE_MEDIA_PLAY
244178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     */
245178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi    public final static int FLAG_KEY_MEDIA_PLAY = 1 << 2;
246178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi    /**
247178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     * Flag indicating a RemoteControlClient makes use of the "play/pause" media key.
248178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     *
2494426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi     * @see #setTransportControlFlags(int)
250178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     * @see android.view.KeyEvent#KEYCODE_MEDIA_PLAY_PAUSE
251178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     */
252178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi    public final static int FLAG_KEY_MEDIA_PLAY_PAUSE = 1 << 3;
253178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi    /**
254178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     * Flag indicating a RemoteControlClient makes use of the "pause" media key.
255178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     *
2564426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi     * @see #setTransportControlFlags(int)
257178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     * @see android.view.KeyEvent#KEYCODE_MEDIA_PAUSE
258178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     */
259178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi    public final static int FLAG_KEY_MEDIA_PAUSE = 1 << 4;
260178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi    /**
261178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     * Flag indicating a RemoteControlClient makes use of the "stop" media key.
262178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     *
2634426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi     * @see #setTransportControlFlags(int)
264178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     * @see android.view.KeyEvent#KEYCODE_MEDIA_STOP
265178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     */
266178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi    public final static int FLAG_KEY_MEDIA_STOP = 1 << 5;
267178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi    /**
268178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     * Flag indicating a RemoteControlClient makes use of the "fast forward" media key.
269178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     *
2704426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi     * @see #setTransportControlFlags(int)
271178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     * @see android.view.KeyEvent#KEYCODE_MEDIA_FAST_FORWARD
272178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     */
273178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi    public final static int FLAG_KEY_MEDIA_FAST_FORWARD = 1 << 6;
274178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi    /**
275178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     * Flag indicating a RemoteControlClient makes use of the "next" media key.
276178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     *
2774426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi     * @see #setTransportControlFlags(int)
278178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     * @see android.view.KeyEvent#KEYCODE_MEDIA_NEXT
279178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     */
280178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi    public final static int FLAG_KEY_MEDIA_NEXT = 1 << 7;
281bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi    /**
282bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     * Flag indicating a RemoteControlClient can receive changes in the media playback position
283e63b0609c3b5f6c21d4e006ee9ddd3ba98a4e684Scott Main     * through the {@link OnPlaybackPositionUpdateListener} interface. This flag must be set
2843261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi     * in order for components that display the RemoteControlClient information, to display and
2853261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi     * let the user control media playback position.
286bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     * @see #setTransportControlFlags(int)
287915747730060dff71b5b2ca7e4ee4073024fc24eJean-Michel Trivi     * @see #setOnGetPlaybackPositionListener(OnGetPlaybackPositionListener)
2883261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi     * @see #setPlaybackPositionUpdateListener(OnPlaybackPositionUpdateListener)
289bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     */
290bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi    public final static int FLAG_KEY_MEDIA_POSITION_UPDATE = 1 << 8;
291f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi    /**
292f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi     * Flag indicating a RemoteControlClient supports ratings.
293f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi     * This flag must be set in order for components that display the RemoteControlClient
294f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi     * information, to display ratings information, and, if ratings are declared editable
295f841d70155c991b6cf728dd41e6d37e051be453dJean-Michel Trivi     * (by calling {@link MediaMetadataEditor#addEditableKey(int)} with the
296f841d70155c991b6cf728dd41e6d37e051be453dJean-Michel Trivi     * {@link MediaMetadataEditor#RATING_KEY_BY_USER} key), it will enable the user to rate
297b23cd118ce3339589fffd40ecf1aa9c5816b3438Jean-Michel Trivi     * the media, with values being received through the interface set with
298b23cd118ce3339589fffd40ecf1aa9c5816b3438Jean-Michel Trivi     * {@link #setMetadataUpdateListener(OnMetadataUpdateListener)}.
299f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi     * @see #setTransportControlFlags(int)
300f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi     */
301f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi    public final static int FLAG_KEY_MEDIA_RATING = 1 << 9;
302178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi
303178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi    /**
3044426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi     * @hide
305466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi     * The flags for when no media keys are declared supported.
306466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi     * Intentionally hidden as an application shouldn't set the transport control flags
307466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi     *     to this value.
3084426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi     */
3094426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi    public final static int FLAGS_KEY_MEDIA_NONE = 0;
3104426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi
3114426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi    /**
3124426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi     * @hide
3134426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi     * Flag used to signal some type of metadata exposed by the RemoteControlClient is requested.
314178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     */
3154426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi    public final static int FLAG_INFORMATION_REQUEST_METADATA = 1 << 0;
316178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi    /**
3174426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi     * @hide
318178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     * Flag used to signal that the transport control buttons supported by the
319466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi     *     RemoteControlClient are requested.
320178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     * This can for instance happen when playback is at the end of a playlist, and the "next"
321178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     * operation is not supported anymore.
322178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     */
3234426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi    public final static int FLAG_INFORMATION_REQUEST_KEY_MEDIA = 1 << 1;
324178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi    /**
3254426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi     * @hide
326466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi     * Flag used to signal that the playback state of the RemoteControlClient is requested.
327178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     */
3284426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi    public final static int FLAG_INFORMATION_REQUEST_PLAYSTATE = 1 << 2;
329178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi    /**
3304426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi     * @hide
331466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi     * Flag used to signal that the album art for the RemoteControlClient is requested.
332178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     */
3334426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi    public final static int FLAG_INFORMATION_REQUEST_ALBUM_ART = 1 << 3;
3344426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi
33542ea7eecd149161ed192d3029f0d77d1d08a4aa5RoboErik    private MediaSession mSession;
336f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik
3374426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi    /**
3386e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi     * Class constructor.
3396e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi     * @param mediaButtonIntent The intent that will be sent for the media button events sent
3406e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi     *     by remote controls.
3416e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi     *     This intent needs to have been constructed with the {@link Intent#ACTION_MEDIA_BUTTON}
3426e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi     *     action, and have a component that will handle the intent (set with
3436e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi     *     {@link Intent#setComponent(ComponentName)}) registered with
3446e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi     *     {@link AudioManager#registerMediaButtonEventReceiver(ComponentName)}
3456e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi     *     before this new RemoteControlClient can itself be registered with
3466e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi     *     {@link AudioManager#registerRemoteControlClient(RemoteControlClient)}.
3476e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi     * @see AudioManager#registerMediaButtonEventReceiver(ComponentName)
3486e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi     * @see AudioManager#registerRemoteControlClient(RemoteControlClient)
3496e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi     */
3506e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi    public RemoteControlClient(PendingIntent mediaButtonIntent) {
351f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi        mRcMediaIntent = mediaButtonIntent;
3526e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi    }
3536e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi
3546e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi    /**
3556e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi     * Class constructor for a remote control client whose internal event handling
3566e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi     * happens on a user-provided Looper.
3576e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi     * @param mediaButtonIntent The intent that will be sent for the media button events sent
3586e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi     *     by remote controls.
3596e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi     *     This intent needs to have been constructed with the {@link Intent#ACTION_MEDIA_BUTTON}
3606e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi     *     action, and have a component that will handle the intent (set with
3616e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi     *     {@link Intent#setComponent(ComponentName)}) registered with
3626e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi     *     {@link AudioManager#registerMediaButtonEventReceiver(ComponentName)}
3636e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi     *     before this new RemoteControlClient can itself be registered with
3646e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi     *     {@link AudioManager#registerRemoteControlClient(RemoteControlClient)}.
3656e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi     * @param looper The Looper running the event loop.
3666e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi     * @see AudioManager#registerMediaButtonEventReceiver(ComponentName)
3676e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi     * @see AudioManager#registerRemoteControlClient(RemoteControlClient)
3686e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi     */
3696e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi    public RemoteControlClient(PendingIntent mediaButtonIntent, Looper looper) {
370f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi        mRcMediaIntent = mediaButtonIntent;
3716e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi    }
3726e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi
3734426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi    /**
374f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik     * @hide
375f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik     */
376f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik    public void registerWithSession(MediaSessionLegacyHelper helper) {
377f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik        helper.addRccListener(mRcMediaIntent, mTransportListener);
378f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik        mSession = helper.getSession(mRcMediaIntent);
3796c30ff976dc6b49186c162ecbae08eb571a6b9f1RoboErik        setTransportControlFlags(mTransportControlFlags);
380f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik    }
381f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik
382f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik    /**
383f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik     * @hide
384f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik     */
385f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik    public void unregisterWithSession(MediaSessionLegacyHelper helper) {
386f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik        helper.removeRccListener(mRcMediaIntent);
387f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik        mSession = null;
388f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik    }
389f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik
390f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik    /**
3915f31737c68f7709cb75a8fefb7536daa77812cc3RoboErik     * Get a {@link MediaSession} associated with this RCC. It will only have a
3925f31737c68f7709cb75a8fefb7536daa77812cc3RoboErik     * session while it is registered with
3935f31737c68f7709cb75a8fefb7536daa77812cc3RoboErik     * {@link AudioManager#registerRemoteControlClient}. The session returned
3945f31737c68f7709cb75a8fefb7536daa77812cc3RoboErik     * should not be modified directly by the application but may be used with
3955f31737c68f7709cb75a8fefb7536daa77812cc3RoboErik     * other APIs that require a session.
3965f31737c68f7709cb75a8fefb7536daa77812cc3RoboErik     *
3975f31737c68f7709cb75a8fefb7536daa77812cc3RoboErik     * @return A media session object or null.
3985f31737c68f7709cb75a8fefb7536daa77812cc3RoboErik     */
3995f31737c68f7709cb75a8fefb7536daa77812cc3RoboErik    public MediaSession getMediaSession() {
4005f31737c68f7709cb75a8fefb7536daa77812cc3RoboErik        return mSession;
4015f31737c68f7709cb75a8fefb7536daa77812cc3RoboErik    }
4025f31737c68f7709cb75a8fefb7536daa77812cc3RoboErik
4035f31737c68f7709cb75a8fefb7536daa77812cc3RoboErik    /**
4044426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi     * Class used to modify metadata in a {@link RemoteControlClient} object.
405466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi     * Use {@link RemoteControlClient#editMetadata(boolean)} to create an instance of an editor,
406466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi     * on which you set the metadata for the RemoteControlClient instance. Once all the information
407466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi     * has been set, use {@link #apply()} to make it the new metadata that should be displayed
408466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi     * for the associated client. Once the metadata has been "applied", you cannot reuse this
409466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi     * instance of the MetadataEditor.
410edb158f55f48a1f7b2cbf30ddec9b8917dc9a619RoboErik     *
411edb158f55f48a1f7b2cbf30ddec9b8917dc9a619RoboErik     * @deprecated Use {@link MediaMetadata} and {@link MediaSession} instead.
4124426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi     */
413edb158f55f48a1f7b2cbf30ddec9b8917dc9a619RoboErik    @Deprecated public class MetadataEditor extends MediaMetadataEditor {
4144da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi
4154da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi        // only use RemoteControlClient.editMetadata() to get a MetadataEditor instance
4164da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi        private MetadataEditor() { }
4174da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi        /**
4184da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi         * @hide
4194da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi         */
4204da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi        public Object clone() throws CloneNotSupportedException {
4214da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi            throw new CloneNotSupportedException();
4224426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi        }
4234426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi
4244da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi        /**
4255ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi         * The metadata key for the content artwork / album art.
4265ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi         */
427466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi        public final static int BITMAP_KEY_ARTWORK = 100;
428f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi
429f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi        /**
430f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi         * @hide
43188183e67d4628e8c8a3310af0076b6f33f955cb2Jean-Michel Trivi         * TODO(jmtrivi) have lockscreen move to the new key name and remove
432466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi         */
433466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi        public final static int METADATA_KEY_ARTWORK = BITMAP_KEY_ARTWORK;
4345ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi
4355ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi        /**
4364da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi         * Adds textual information to be displayed.
4374da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi         * Note that none of the information added after {@link #apply()} has been called,
4384da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi         * will be displayed.
439466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi         * @param key The identifier of a the metadata field to set. Valid values are
4404da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_ALBUM},
4414da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_ALBUMARTIST},
4424da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_TITLE},
4434da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_ARTIST},
4444da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_AUTHOR},
4454da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_COMPILATION},
4464da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_COMPOSER},
4474da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_DATE},
4484da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_GENRE},
4494da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_TITLE},
450466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_WRITER}.
451466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi         * @param value The text for the given key, or {@code null} to signify there is no valid
4524da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi         *      information for the field.
453466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi         * @return Returns a reference to the same MetadataEditor object, so you can chain put
454466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi         *      calls together.
4554da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi         */
4565ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi        public synchronized MetadataEditor putString(int key, String value)
4575ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi                throws IllegalArgumentException {
45888183e67d4628e8c8a3310af0076b6f33f955cb2Jean-Michel Trivi            super.putString(key, value);
459f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik            if (mMetadataBuilder != null) {
460f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik                // MediaMetadata supports all the same fields as MetadataEditor
461f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik                String metadataKey = MediaMetadata.getKeyFromMetadataEditorKey(key);
462f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik                // But just in case, don't add things we don't understand
463f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik                if (metadataKey != null) {
46475847b98f39e521a57042c50e69be9e142788d32RoboErik                    mMetadataBuilder.putText(metadataKey, value);
465f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik                }
466f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik            }
467f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik
4684426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi            return this;
4694426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi        }
4704426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi
4714da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi        /**
472466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi         * Adds numerical information to be displayed.
473466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi         * Note that none of the information added after {@link #apply()} has been called,
474466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi         * will be displayed.
4755ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi         * @param key the identifier of a the metadata field to set. Valid values are
4765ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_CD_TRACK_NUMBER},
4775ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_DISC_NUMBER},
4785ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_DURATION} (with a value
4795ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi         *      expressed in milliseconds),
48088183e67d4628e8c8a3310af0076b6f33f955cb2Jean-Michel Trivi         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_YEAR}.
481466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi         * @param value The long value for the given key
482466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi         * @return Returns a reference to the same MetadataEditor object, so you can chain put
483466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi         *      calls together.
4845ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi         * @throws IllegalArgumentException
4854da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi         */
4865ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi        public synchronized MetadataEditor putLong(int key, long value)
4875ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi                throws IllegalArgumentException {
48888183e67d4628e8c8a3310af0076b6f33f955cb2Jean-Michel Trivi            super.putLong(key, value);
489f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik            if (mMetadataBuilder != null) {
490f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik                // MediaMetadata supports all the same fields as MetadataEditor
491f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik                String metadataKey = MediaMetadata.getKeyFromMetadataEditorKey(key);
492f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik                // But just in case, don't add things we don't understand
493f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik                if (metadataKey != null) {
494f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik                    mMetadataBuilder.putLong(metadataKey, value);
495f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik                }
496f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik            }
4975ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi            return this;
4985ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi        }
4994da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi
5004da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi        /**
5014da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi         * Sets the album / artwork picture to be displayed on the remote control.
502466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi         * @param key the identifier of the bitmap to set. The only valid value is
503466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi         *      {@link #BITMAP_KEY_ARTWORK}
504466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi         * @param bitmap The bitmap for the artwork, or null if there isn't any.
505466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi         * @return Returns a reference to the same MetadataEditor object, so you can chain put
506466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi         *      calls together.
5075ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi         * @throws IllegalArgumentException
5084da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi         * @see android.graphics.Bitmap
5094da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi         */
51088183e67d4628e8c8a3310af0076b6f33f955cb2Jean-Michel Trivi        @Override
5115ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi        public synchronized MetadataEditor putBitmap(int key, Bitmap bitmap)
5125ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi                throws IllegalArgumentException {
51388183e67d4628e8c8a3310af0076b6f33f955cb2Jean-Michel Trivi            super.putBitmap(key, bitmap);
514f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik            if (mMetadataBuilder != null) {
515f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik                // MediaMetadata supports all the same fields as MetadataEditor
516f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik                String metadataKey = MediaMetadata.getKeyFromMetadataEditorKey(key);
517f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik                // But just in case, don't add things we don't understand
518f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik                if (metadataKey != null) {
519f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik                    mMetadataBuilder.putBitmap(metadataKey, bitmap);
520f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik                }
521f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik            }
5224da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi            return this;
5234426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi        }
524178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi
52538696ba77d7f614cb50672aaca99f7ba59b56126RoboErik        @Override
52638696ba77d7f614cb50672aaca99f7ba59b56126RoboErik        public synchronized MetadataEditor putObject(int key, Object object)
52738696ba77d7f614cb50672aaca99f7ba59b56126RoboErik                throws IllegalArgumentException {
52838696ba77d7f614cb50672aaca99f7ba59b56126RoboErik            super.putObject(key, object);
52938696ba77d7f614cb50672aaca99f7ba59b56126RoboErik            if (mMetadataBuilder != null &&
53038696ba77d7f614cb50672aaca99f7ba59b56126RoboErik                    (key == MediaMetadataEditor.RATING_KEY_BY_USER ||
53138696ba77d7f614cb50672aaca99f7ba59b56126RoboErik                    key == MediaMetadataEditor.RATING_KEY_BY_OTHERS)) {
53238696ba77d7f614cb50672aaca99f7ba59b56126RoboErik                String metadataKey = MediaMetadata.getKeyFromMetadataEditorKey(key);
53338696ba77d7f614cb50672aaca99f7ba59b56126RoboErik                if (metadataKey != null) {
53438696ba77d7f614cb50672aaca99f7ba59b56126RoboErik                    mMetadataBuilder.putRating(metadataKey, (Rating) object);
53538696ba77d7f614cb50672aaca99f7ba59b56126RoboErik                }
53638696ba77d7f614cb50672aaca99f7ba59b56126RoboErik            }
53738696ba77d7f614cb50672aaca99f7ba59b56126RoboErik            return this;
53838696ba77d7f614cb50672aaca99f7ba59b56126RoboErik        }
53938696ba77d7f614cb50672aaca99f7ba59b56126RoboErik
5404da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi        /**
54188183e67d4628e8c8a3310af0076b6f33f955cb2Jean-Michel Trivi         * Clears all the metadata that has been set since the MetadataEditor instance was created
54288183e67d4628e8c8a3310af0076b6f33f955cb2Jean-Michel Trivi         * (with {@link RemoteControlClient#editMetadata(boolean)}).
543b23cd118ce3339589fffd40ecf1aa9c5816b3438Jean-Michel Trivi         * Note that clearing the metadata doesn't reset the editable keys
54488183e67d4628e8c8a3310af0076b6f33f955cb2Jean-Michel Trivi         * (use {@link MediaMetadataEditor#removeEditableKeys()} instead).
5454da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi         */
54688183e67d4628e8c8a3310af0076b6f33f955cb2Jean-Michel Trivi        @Override
5474da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi        public synchronized void clear() {
54888183e67d4628e8c8a3310af0076b6f33f955cb2Jean-Michel Trivi            super.clear();
549f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi        }
550f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi
551f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi        /**
552466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi         * Associates all the metadata that has been set since the MetadataEditor instance was
553466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi         *     created with {@link RemoteControlClient#editMetadata(boolean)}, or since
554466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi         *     {@link #clear()} was called, with the RemoteControlClient. Once "applied",
555466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi         *     this MetadataEditor cannot be reused to edit the RemoteControlClient's metadata.
5564da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi         */
5574da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi        public synchronized void apply() {
5584da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi            if (mApplied) {
5594da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi                Log.e(TAG, "Can't apply a previously applied MetadataEditor");
5604da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi                return;
5614da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi            }
562f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik            synchronized (mCacheLock) {
563430fc48865e5a371b08f180390946b96d73848feRoboErik                // Still build the old metadata so when creating a new editor
564430fc48865e5a371b08f180390946b96d73848feRoboErik                // you get the expected values.
5654da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi                // assign the edited data
5664da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi                mMetadata = new Bundle(mEditorMetadata);
567f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi                // add the information about editable keys
568f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi                mMetadata.putLong(String.valueOf(KEY_EDITABLE_MASK), mEditableKeys);
5694a5700556191c835116ec2a6997a4f16f464ac9dJean-Michel Trivi                if ((mOriginalArtwork != null) && (!mOriginalArtwork.equals(mEditorArtwork))) {
5704a5700556191c835116ec2a6997a4f16f464ac9dJean-Michel Trivi                    mOriginalArtwork.recycle();
57134d0d300cac645b48cce5a1735f45e1102d4ef0eJean-Michel Trivi                }
5724a5700556191c835116ec2a6997a4f16f464ac9dJean-Michel Trivi                mOriginalArtwork = mEditorArtwork;
57334d0d300cac645b48cce5a1735f45e1102d4ef0eJean-Michel Trivi                mEditorArtwork = null;
574f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik
575f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik                // USE_SESSIONS
576f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik                if (mSession != null && mMetadataBuilder != null) {
57751c07bc0bf338c9dd9d2345fe81d2cd964d680caRoboErik                    mMediaMetadata = mMetadataBuilder.build();
57851c07bc0bf338c9dd9d2345fe81d2cd964d680caRoboErik                    mSession.setMetadata(mMediaMetadata);
579f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik                }
5804da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi                mApplied = true;
5814da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi            }
5824426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi        }
5834426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi    }
5844426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi
5854426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi    /**
586466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi     * Creates a {@link MetadataEditor}.
587466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi     * @param startEmpty Set to false if you want the MetadataEditor to contain the metadata that
588466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi     *     was previously applied to the RemoteControlClient, or true if it is to be created empty.
589466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi     * @return a new MetadataEditor instance.
5904426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi     */
5914da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi    public MetadataEditor editMetadata(boolean startEmpty) {
5924da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi        MetadataEditor editor = new MetadataEditor();
5934da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi        if (startEmpty) {
5944da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi            editor.mEditorMetadata = new Bundle();
5954da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi            editor.mEditorArtwork = null;
5964da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi            editor.mMetadataChanged = true;
5974da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi            editor.mArtworkChanged = true;
598f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi            editor.mEditableKeys = 0;
5994da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi        } else {
6004da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi            editor.mEditorMetadata = new Bundle(mMetadata);
6014a5700556191c835116ec2a6997a4f16f464ac9dJean-Michel Trivi            editor.mEditorArtwork = mOriginalArtwork;
6024da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi            editor.mMetadataChanged = false;
6034da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi            editor.mArtworkChanged = false;
6044426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi        }
605f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik        // USE_SESSIONS
606f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik        if (startEmpty || mMediaMetadata == null) {
607f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik            editor.mMetadataBuilder = new MediaMetadata.Builder();
608f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik        } else {
609f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik            editor.mMetadataBuilder = new MediaMetadata.Builder(mMediaMetadata);
610f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik        }
6114da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi        return editor;
6124426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi    }
6134426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi
6144426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi    /**
6154426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi     * Sets the current playback state.
616466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi     * @param state The current playback state, one of the following values:
617178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     *       {@link #PLAYSTATE_STOPPED},
618178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     *       {@link #PLAYSTATE_PAUSED},
619178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     *       {@link #PLAYSTATE_PLAYING},
620178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     *       {@link #PLAYSTATE_FAST_FORWARDING},
621178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     *       {@link #PLAYSTATE_REWINDING},
622178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     *       {@link #PLAYSTATE_SKIPPING_FORWARDS},
623178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     *       {@link #PLAYSTATE_SKIPPING_BACKWARDS},
624178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     *       {@link #PLAYSTATE_BUFFERING},
625178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     *       {@link #PLAYSTATE_ERROR}.
626178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     */
6274426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi    public void setPlaybackState(int state) {
6281b16cc3de51d69c8027cefcc70a084a5b2d7a3d0Jean-Michel Trivi        setPlaybackStateInt(state, PLAYBACK_POSITION_ALWAYS_UNKNOWN, PLAYBACK_SPEED_1X,
6291b16cc3de51d69c8027cefcc70a084a5b2d7a3d0Jean-Michel Trivi                false /* legacy API, converting to method with position and speed */);
630bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi    }
631bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi
632bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi    /**
633bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     * Sets the current playback state and the matching media position for the current playback
634bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     *   speed.
635bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     * @param state The current playback state, one of the following values:
636bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     *       {@link #PLAYSTATE_STOPPED},
637bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     *       {@link #PLAYSTATE_PAUSED},
638bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     *       {@link #PLAYSTATE_PLAYING},
639bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     *       {@link #PLAYSTATE_FAST_FORWARDING},
640bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     *       {@link #PLAYSTATE_REWINDING},
641bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     *       {@link #PLAYSTATE_SKIPPING_FORWARDS},
642bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     *       {@link #PLAYSTATE_SKIPPING_BACKWARDS},
643bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     *       {@link #PLAYSTATE_BUFFERING},
644bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     *       {@link #PLAYSTATE_ERROR}.
645bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     * @param timeInMs a 0 or positive value for the current media position expressed in ms
646bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     *    (same unit as for when sending the media duration, if applicable, with
647bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     *    {@link android.media.MediaMetadataRetriever#METADATA_KEY_DURATION} in the
648bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     *    {@link RemoteControlClient.MetadataEditor}). Negative values imply that position is not
649bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     *    known (e.g. listening to a live stream of a radio) or not applicable (e.g. when state
650bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     *    is {@link #PLAYSTATE_BUFFERING} and nothing had played yet).
651bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     * @param playbackSpeed a value expressed as a ratio of 1x playback: 1.0f is normal playback,
652bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     *    2.0f is 2x, 0.5f is half-speed, -2.0f is rewind at 2x speed. 0.0f means nothing is
653bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     *    playing (e.g. when state is {@link #PLAYSTATE_ERROR}).
654bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     */
655bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi    public void setPlaybackState(int state, long timeInMs, float playbackSpeed) {
6561b16cc3de51d69c8027cefcc70a084a5b2d7a3d0Jean-Michel Trivi        setPlaybackStateInt(state, timeInMs, playbackSpeed, true);
6571b16cc3de51d69c8027cefcc70a084a5b2d7a3d0Jean-Michel Trivi    }
6581b16cc3de51d69c8027cefcc70a084a5b2d7a3d0Jean-Michel Trivi
6591b16cc3de51d69c8027cefcc70a084a5b2d7a3d0Jean-Michel Trivi    private void setPlaybackStateInt(int state, long timeInMs, float playbackSpeed,
6601b16cc3de51d69c8027cefcc70a084a5b2d7a3d0Jean-Michel Trivi            boolean hasPosition) {
6614426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi        synchronized(mCacheLock) {
662bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi            if ((mPlaybackState != state) || (mPlaybackPositionMs != timeInMs)
663bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi                    || (mPlaybackSpeed != playbackSpeed)) {
66468622396b62f9084781add1e12f4d513b633ab54Jean-Michel Trivi                // store locally
66568622396b62f9084781add1e12f4d513b633ab54Jean-Michel Trivi                mPlaybackState = state;
6661b16cc3de51d69c8027cefcc70a084a5b2d7a3d0Jean-Michel Trivi                // distinguish between an application not knowing the current playback position
6671b16cc3de51d69c8027cefcc70a084a5b2d7a3d0Jean-Michel Trivi                // at the moment and an application using the API where only the playback state
6681b16cc3de51d69c8027cefcc70a084a5b2d7a3d0Jean-Michel Trivi                // is passed, not the playback position.
6691b16cc3de51d69c8027cefcc70a084a5b2d7a3d0Jean-Michel Trivi                if (hasPosition) {
6701b16cc3de51d69c8027cefcc70a084a5b2d7a3d0Jean-Michel Trivi                    if (timeInMs < 0) {
6711b16cc3de51d69c8027cefcc70a084a5b2d7a3d0Jean-Michel Trivi                        mPlaybackPositionMs = PLAYBACK_POSITION_INVALID;
6721b16cc3de51d69c8027cefcc70a084a5b2d7a3d0Jean-Michel Trivi                    } else {
6731b16cc3de51d69c8027cefcc70a084a5b2d7a3d0Jean-Michel Trivi                        mPlaybackPositionMs = timeInMs;
6741b16cc3de51d69c8027cefcc70a084a5b2d7a3d0Jean-Michel Trivi                    }
6751b16cc3de51d69c8027cefcc70a084a5b2d7a3d0Jean-Michel Trivi                } else {
6761b16cc3de51d69c8027cefcc70a084a5b2d7a3d0Jean-Michel Trivi                    mPlaybackPositionMs = PLAYBACK_POSITION_ALWAYS_UNKNOWN;
6771b16cc3de51d69c8027cefcc70a084a5b2d7a3d0Jean-Michel Trivi                }
678bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi                mPlaybackSpeed = playbackSpeed;
67968622396b62f9084781add1e12f4d513b633ab54Jean-Michel Trivi                // keep track of when the state change occurred
68068622396b62f9084781add1e12f4d513b633ab54Jean-Michel Trivi                mPlaybackStateChangeTimeMs = SystemClock.elapsedRealtime();
68168622396b62f9084781add1e12f4d513b633ab54Jean-Michel Trivi
682f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik                // USE_SESSIONS
683f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik                if (mSession != null) {
684f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik                    int pbState = PlaybackState.getStateFromRccState(state);
685c785a78fb483fe54012175c53d3758b2412de7b9RoboErik                    long position = hasPosition ? mPlaybackPositionMs
686c785a78fb483fe54012175c53d3758b2412de7b9RoboErik                            : PlaybackState.PLAYBACK_POSITION_UNKNOWN;
687c785a78fb483fe54012175c53d3758b2412de7b9RoboErik
688c785a78fb483fe54012175c53d3758b2412de7b9RoboErik                    PlaybackState.Builder bob = new PlaybackState.Builder(mSessionPlaybackState);
689c785a78fb483fe54012175c53d3758b2412de7b9RoboErik                    bob.setState(pbState, position, playbackSpeed, SystemClock.elapsedRealtime());
690c785a78fb483fe54012175c53d3758b2412de7b9RoboErik                    bob.setErrorMessage(null);
691c785a78fb483fe54012175c53d3758b2412de7b9RoboErik                    mSessionPlaybackState = bob.build();
692c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik                    mSession.setPlaybackState(mSessionPlaybackState);
693f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik                }
694521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi            }
695521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi        }
696521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi    }
697521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi
698178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi    /**
6994426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi     * Sets the flags for the media transport control buttons that this client supports.
700466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi     * @param transportControlFlags A combination of the following flags:
7014426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi     *      {@link #FLAG_KEY_MEDIA_PREVIOUS},
702178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     *      {@link #FLAG_KEY_MEDIA_REWIND},
703178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     *      {@link #FLAG_KEY_MEDIA_PLAY},
704178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     *      {@link #FLAG_KEY_MEDIA_PLAY_PAUSE},
705178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     *      {@link #FLAG_KEY_MEDIA_PAUSE},
706178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     *      {@link #FLAG_KEY_MEDIA_STOP},
707178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     *      {@link #FLAG_KEY_MEDIA_FAST_FORWARD},
708915747730060dff71b5b2ca7e4ee4073024fc24eJean-Michel Trivi     *      {@link #FLAG_KEY_MEDIA_NEXT},
709b23cd118ce3339589fffd40ecf1aa9c5816b3438Jean-Michel Trivi     *      {@link #FLAG_KEY_MEDIA_POSITION_UPDATE},
710b23cd118ce3339589fffd40ecf1aa9c5816b3438Jean-Michel Trivi     *      {@link #FLAG_KEY_MEDIA_RATING}.
711178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     */
7124426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi    public void setTransportControlFlags(int transportControlFlags) {
7134426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi        synchronized(mCacheLock) {
7144426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi            // store locally
7154426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi            mTransportControlFlags = transportControlFlags;
7164426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi
717f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik            // USE_SESSIONS
718f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik            if (mSession != null) {
719c785a78fb483fe54012175c53d3758b2412de7b9RoboErik                PlaybackState.Builder bob = new PlaybackState.Builder(mSessionPlaybackState);
720f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal                bob.setActions(
721f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal                        PlaybackState.getActionsFromRccControlFlags(transportControlFlags));
722c785a78fb483fe54012175c53d3758b2412de7b9RoboErik                mSessionPlaybackState = bob.build();
723c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik                mSession.setPlaybackState(mSessionPlaybackState);
724f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik            }
7254426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi        }
7264426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi    }
727178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi
728bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi    /**
729b23cd118ce3339589fffd40ecf1aa9c5816b3438Jean-Michel Trivi     * Interface definition for a callback to be invoked when one of the metadata values has
730b23cd118ce3339589fffd40ecf1aa9c5816b3438Jean-Michel Trivi     * been updated.
73188183e67d4628e8c8a3310af0076b6f33f955cb2Jean-Michel Trivi     * Implement this interface to receive metadata updates after registering your listener
73288183e67d4628e8c8a3310af0076b6f33f955cb2Jean-Michel Trivi     * through {@link RemoteControlClient#setMetadataUpdateListener(OnMetadataUpdateListener)}.
733f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi     */
7347ddd226e7c6e759feaf2747a90be1cc06acf37a3Jean-Michel Trivi    public interface OnMetadataUpdateListener {
735f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi        /**
736b23cd118ce3339589fffd40ecf1aa9c5816b3438Jean-Michel Trivi         * Called on the implementer to notify that the metadata field for the given key has
73788183e67d4628e8c8a3310af0076b6f33f955cb2Jean-Michel Trivi         * been updated to the new value.
73888183e67d4628e8c8a3310af0076b6f33f955cb2Jean-Michel Trivi         * @param key the identifier of the updated metadata field.
73988183e67d4628e8c8a3310af0076b6f33f955cb2Jean-Michel Trivi         * @param newValue the Object storing the new value for the key.
740f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi         */
74188183e67d4628e8c8a3310af0076b6f33f955cb2Jean-Michel Trivi        public abstract void onMetadataUpdate(int key, Object newValue);
742f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi    }
743f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi
744f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi    /**
745b23cd118ce3339589fffd40ecf1aa9c5816b3438Jean-Michel Trivi     * Sets the listener to be called whenever the metadata is updated.
746b23cd118ce3339589fffd40ecf1aa9c5816b3438Jean-Michel Trivi     * New metadata values will be received in the same thread as the one in which
747b23cd118ce3339589fffd40ecf1aa9c5816b3438Jean-Michel Trivi     * RemoteControlClient was created.
748b23cd118ce3339589fffd40ecf1aa9c5816b3438Jean-Michel Trivi     * @param l the metadata update listener
749f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi     */
750f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi    public void setMetadataUpdateListener(OnMetadataUpdateListener l) {
751f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi        synchronized(mCacheLock) {
752f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi            mMetadataUpdateListener = l;
753f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi        }
754f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi    }
755f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi
756f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi
757f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi    /**
758bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     * Interface definition for a callback to be invoked when the media playback position is
759bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     * requested to be updated.
7603261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi     * @see RemoteControlClient#FLAG_KEY_MEDIA_POSITION_UPDATE
761bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     */
762bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi    public interface OnPlaybackPositionUpdateListener {
763bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi        /**
7643261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi         * Called on the implementer to notify it that the playback head should be set at the given
765bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi         * position. If the position can be changed from its current value, the implementor of
7663fbf67e217fb489fe7318a9e43d8ae86646eb4ccJean-Michel Trivi         * the interface must also update the playback position using
767e63b0609c3b5f6c21d4e006ee9ddd3ba98a4e684Scott Main         * {@link #setPlaybackState(int, long, float)} to reflect the actual new
768bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi         * position being used, regardless of whether it differs from the requested position.
7693fbf67e217fb489fe7318a9e43d8ae86646eb4ccJean-Michel Trivi         * Failure to do so would cause the system to not know the new actual playback position,
7703fbf67e217fb489fe7318a9e43d8ae86646eb4ccJean-Michel Trivi         * and user interface components would fail to show the user where playback resumed after
7713fbf67e217fb489fe7318a9e43d8ae86646eb4ccJean-Michel Trivi         * the position was updated.
772bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi         * @param newPositionMs the new requested position in the current media, expressed in ms.
773bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi         */
774bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi        void onPlaybackPositionUpdate(long newPositionMs);
775bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi    }
776bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi
777bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi    /**
7783261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi     * Interface definition for a callback to be invoked when the media playback position is
7793261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi     * queried.
7803261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi     * @see RemoteControlClient#FLAG_KEY_MEDIA_POSITION_UPDATE
7813261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi     */
782915747730060dff71b5b2ca7e4ee4073024fc24eJean-Michel Trivi    public interface OnGetPlaybackPositionListener {
7833261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi        /**
7843261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi         * Called on the implementer of the interface to query the current playback position.
7853261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi         * @return a negative value if the current playback position (or the last valid playback
7863261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi         *     position) is not known, or a zero or positive value expressed in ms indicating the
7873261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi         *     current position, or the last valid known position.
7883261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi         */
789915747730060dff71b5b2ca7e4ee4073024fc24eJean-Michel Trivi        long onGetPlaybackPosition();
7903261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi    }
7913261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi
7923261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi    /**
7933261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi     * Sets the listener to be called whenever the media playback position is requested
794bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     * to be updated.
795bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     * Notifications will be received in the same thread as the one in which RemoteControlClient
796bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     * was created.
797915747730060dff71b5b2ca7e4ee4073024fc24eJean-Michel Trivi     * @param l the position update listener to be called
798bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     */
799bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi    public void setPlaybackPositionUpdateListener(OnPlaybackPositionUpdateListener l) {
800bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi        synchronized(mCacheLock) {
801bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi            mPositionUpdateListener = l;
8023261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi        }
8033261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi    }
8043261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi
8053261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi    /**
8063261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi     * Sets the listener to be called whenever the media current playback position is needed.
8073261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi     * Queries will be received in the same thread as the one in which RemoteControlClient
8083261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi     * was created.
809915747730060dff71b5b2ca7e4ee4073024fc24eJean-Michel Trivi     * @param l the listener to be called to retrieve the playback position
8103261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi     */
811915747730060dff71b5b2ca7e4ee4073024fc24eJean-Michel Trivi    public void setOnGetPlaybackPositionListener(OnGetPlaybackPositionListener l) {
8123261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi        synchronized(mCacheLock) {
8133261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi            mPositionProvider = l;
814bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi        }
815bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi    }
816bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi
817bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi    /**
818bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     * @hide
819bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     * Flag to reflect that the application controlling this RemoteControlClient sends playback
820bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     * position updates. The playback position being "readable" is considered from the application's
821bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     * point of view.
822bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     */
823bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi    public static int MEDIA_POSITION_READABLE = 1 << 0;
824bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi    /**
825bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     * @hide
826bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     * Flag to reflect that the application controlling this RemoteControlClient can receive
827bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     * playback position updates. The playback position being "writable"
828bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     * is considered from the application's point of view.
829bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     */
830bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi    public static int MEDIA_POSITION_WRITABLE = 1 << 1;
831bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi
8323114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi    /** @hide */
8333114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi    public final static int DEFAULT_PLAYBACK_VOLUME_HANDLING = PLAYBACK_VOLUME_VARIABLE;
8343114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi    /** @hide */
8353114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi    // hard-coded to the same number of steps as AudioService.MAX_STREAM_VOLUME[STREAM_MUSIC]
8363114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi    public final static int DEFAULT_PLAYBACK_VOLUME = 15;
8373114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi
838178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi    /**
8394426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi     * Lock for all cached data
8404426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi     */
8414426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi    private final Object mCacheLock = new Object();
8424426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi    /**
8434426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi     * Cache for the playback state.
8444426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi     * Access synchronized on mCacheLock
845178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     */
8464426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi    private int mPlaybackState = PLAYSTATE_NONE;
8474426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi    /**
84868622396b62f9084781add1e12f4d513b633ab54Jean-Michel Trivi     * Time of last play state change
84968622396b62f9084781add1e12f4d513b633ab54Jean-Michel Trivi     * Access synchronized on mCacheLock
85068622396b62f9084781add1e12f4d513b633ab54Jean-Michel Trivi     */
85168622396b62f9084781add1e12f4d513b633ab54Jean-Michel Trivi    private long mPlaybackStateChangeTimeMs = 0;
85268622396b62f9084781add1e12f4d513b633ab54Jean-Michel Trivi    /**
853bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     * Last playback position in ms reported by the user
854bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     */
855bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi    private long mPlaybackPositionMs = PLAYBACK_POSITION_INVALID;
856bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi    /**
857bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     * Last playback speed reported by the user
858bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     */
859bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi    private float mPlaybackSpeed = PLAYBACK_SPEED_1X;
860bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi    /**
8614426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi     * Cache for the artwork bitmap.
8624426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi     * Access synchronized on mCacheLock
8634da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi     * Artwork and metadata are not kept in one Bundle because the bitmap sometimes needs to be
8644da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi     * accessed to be resized, in which case a copy will be made. This would add overhead in
8654da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi     * Bundle operations.
8664426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi     */
8674a5700556191c835116ec2a6997a4f16f464ac9dJean-Michel Trivi    private Bitmap mOriginalArtwork;
8684426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi    /**
8694426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi     * Cache for the transport control mask.
8704426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi     * Access synchronized on mCacheLock
8714426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi     */
8724426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi    private int mTransportControlFlags = FLAGS_KEY_MEDIA_NONE;
8734426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi    /**
8744426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi     * Cache for the metadata strings.
8754426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi     * Access synchronized on mCacheLock
87630c918ce7fbe171944b28fc91b3f22b3d631872dGlenn Kasten     * This is re-initialized in apply() and so cannot be final.
8774426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi     */
8784426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi    private Bundle mMetadata = new Bundle();
8794426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi    /**
880bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     * Listener registered by user of RemoteControlClient to receive requests for playback position
881bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     * update requests.
882bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     */
883bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi    private OnPlaybackPositionUpdateListener mPositionUpdateListener;
884bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi    /**
8853261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi     * Provider registered by user of RemoteControlClient to provide the current playback position.
8863261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi     */
887915747730060dff71b5b2ca7e4ee4073024fc24eJean-Michel Trivi    private OnGetPlaybackPositionListener mPositionProvider;
8883261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi    /**
889f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi     * Listener registered by user of RemoteControlClient to receive edit changes to metadata
890f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi     * it exposes.
891f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi     */
892f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi    private OnMetadataUpdateListener mMetadataUpdateListener;
893f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi    /**
894bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     * The current remote control client generation ID across the system, as known by this object
8954426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi     */
8964426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi    private int mCurrentClientGenId = -1;
8974426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi
8984426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi    /**
899f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi     * The media button intent description associated with this remote control client
900bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     * (can / should include target component for intent handling, used when persisting media
901bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi     *    button event receiver across reboots).
9024426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi     */
903f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi    private final PendingIntent mRcMediaIntent;
9044426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi
9054426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi    /**
906c3c4babf8424f65b3d3d2700f60fae6e94e9cd00Jean-Michel Trivi     * Reflects whether any "plugged in" IRemoteControlDisplay has mWantsPositonSync set to true.
907c3c4babf8424f65b3d3d2700f60fae6e94e9cd00Jean-Michel Trivi     */
908c3c4babf8424f65b3d3d2700f60fae6e94e9cd00Jean-Michel Trivi    // TODO consider using a ref count for IRemoteControlDisplay requiring sync instead
909c3c4babf8424f65b3d3d2700f60fae6e94e9cd00Jean-Michel Trivi    private boolean mNeedsPositionSync = false;
910c3c4babf8424f65b3d3d2700f60fae6e94e9cd00Jean-Michel Trivi
911c3c4babf8424f65b3d3d2700f60fae6e94e9cd00Jean-Michel Trivi    /**
912f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik     * Cache for the current playback state using Session APIs.
913f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik     */
914c785a78fb483fe54012175c53d3758b2412de7b9RoboErik    private PlaybackState mSessionPlaybackState = null;
915f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik
916f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik    /**
917f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik     * Cache for metadata using Session APIs. This is re-initialized in apply().
918f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik     */
919f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik    private MediaMetadata mMediaMetadata;
920f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik
921f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik    /**
9224426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi     * @hide
923f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi     * Accessor to media button intent description (includes target component)
9244426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi     */
925f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi    public PendingIntent getRcMediaIntent() {
926f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi        return mRcMediaIntent;
9274426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi    }
9284426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi
9293114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi    /**
9303114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi     * @hide
9313114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi     * Default value for the unique identifier
9323114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi     */
9333114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi    public final static int RCSE_ID_UNREGISTERED = -1;
9341357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi
935f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik    // USE_SESSIONS
936477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik    private MediaSession.Callback mTransportListener = new MediaSession.Callback() {
937f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik
938f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik        @Override
939f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik        public void onSeekTo(long pos) {
940f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik            RemoteControlClient.this.onSeekTo(mCurrentClientGenId, pos);
941f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik        }
942f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik
943f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik        @Override
94479fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik        public void onSetRating(Rating rating) {
945f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik            if ((mTransportControlFlags & FLAG_KEY_MEDIA_RATING) != 0) {
946430fc48865e5a371b08f180390946b96d73848feRoboErik                onUpdateMetadata(mCurrentClientGenId, MetadataEditor.RATING_KEY_BY_USER, rating);
947f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik            }
948f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik        }
949f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik    };
950f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik
9513114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi    //===========================================================
9523114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi    // Message handlers
9533114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi
9543261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi    private void onSeekTo(int generationId, long timeMs) {
9553261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi        synchronized (mCacheLock) {
9563261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi            if ((mCurrentClientGenId == generationId) && (mPositionUpdateListener != null)) {
9573261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi                mPositionUpdateListener.onPlaybackPositionUpdate(timeMs);
9583261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi            }
9593261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi        }
9603261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi    }
9613261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi
96288183e67d4628e8c8a3310af0076b6f33f955cb2Jean-Michel Trivi    private void onUpdateMetadata(int generationId, int key, Object value) {
963f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi        synchronized (mCacheLock) {
964f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi            if ((mCurrentClientGenId == generationId) && (mMetadataUpdateListener != null)) {
96588183e67d4628e8c8a3310af0076b6f33f955cb2Jean-Michel Trivi                mMetadataUpdateListener.onMetadataUpdate(key, value);
966f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi            }
967f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi        }
968f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi    }
969f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi
9703114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi    //===========================================================
9713114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi    // Internal utilities
9723114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi
9734426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi    /**
974521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi     * Returns whether, for the given playback state, the playback position is expected to
975521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi     * be changing.
976521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi     * @param playstate the playback state to evaluate
977521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi     * @return true during any form of playback, false if it's not playing anything while in this
978521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi     *     playback state
979521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi     */
980f8895248e2ac4dbb46622f3e04c7256f03175b4fAdam Powell    static boolean playbackPositionShouldMove(int playstate) {
981521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi        switch(playstate) {
982521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi            case PLAYSTATE_STOPPED:
983521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi            case PLAYSTATE_PAUSED:
984521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi            case PLAYSTATE_BUFFERING:
985521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi            case PLAYSTATE_ERROR:
986521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi            case PLAYSTATE_SKIPPING_FORWARDS:
987521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi            case PLAYSTATE_SKIPPING_BACKWARDS:
988521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi                return false;
989521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi            case PLAYSTATE_PLAYING:
990521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi            case PLAYSTATE_FAST_FORWARDING:
991521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi            case PLAYSTATE_REWINDING:
992521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi            default:
993521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi                return true;
994521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi        }
995521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi    }
996521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi
997521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi    /**
998521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi     * Period for playback position drift checks, 15s when playing at 1x or slower.
999521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi     */
1000521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi    private final static long POSITION_REFRESH_PERIOD_PLAYING_MS = 15000;
1001521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi    /**
1002521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi     * Minimum period for playback position drift checks, never more often when every 2s, when
1003521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi     * fast forwarding or rewinding.
1004521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi     */
1005521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi    private final static long POSITION_REFRESH_PERIOD_MIN_MS = 2000;
1006521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi    /**
1007521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi     * The value above which the difference between client-reported playback position and
1008521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi     * estimated position is considered a drift.
1009521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi     */
1010521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi    private final static long POSITION_DRIFT_MAX_MS = 500;
1011521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi    /**
1012521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi     * Compute the period at which the estimated playback position should be compared against the
1013521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi     * actual playback position. Is a funciton of playback speed.
1014521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi     * @param speed 1.0f is normal playback speed
1015521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi     * @return the period in ms
1016521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi     */
1017521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi    private static long getCheckPeriodFromSpeed(float speed) {
1018521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi        if (Math.abs(speed) <= 1.0f) {
1019521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi            return POSITION_REFRESH_PERIOD_PLAYING_MS;
1020521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi        } else {
1021521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi            return Math.max((long)(POSITION_REFRESH_PERIOD_PLAYING_MS / Math.abs(speed)),
1022521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi                    POSITION_REFRESH_PERIOD_MIN_MS);
1023521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi        }
1024521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi    }
1025178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi}
1026