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; 303114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Triviimport android.os.ServiceManager; 3168622396b62f9084781add1e12f4d513b633ab54Jean-Michel Triviimport android.os.SystemClock; 324426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Triviimport android.util.Log; 334426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi 345ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Triviimport java.lang.IllegalArgumentException; 35178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi 36178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi/** 374426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * RemoteControlClient enables exposing information meant to be consumed by remote controls 38466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * capable of displaying metadata, artwork and media transport control buttons. 39ad87f5b40f2a3fd2d506dc15e00b8af28a8fa2baJean-Michel Trivi * 40ad87f5b40f2a3fd2d506dc15e00b8af28a8fa2baJean-Michel Trivi * <p>A remote control client object is associated with a media button event receiver. This 41466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * event receiver must have been previously registered with 42466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * {@link AudioManager#registerMediaButtonEventReceiver(ComponentName)} before the 43466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * RemoteControlClient can be registered through 444426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * {@link AudioManager#registerRemoteControlClient(RemoteControlClient)}. 45ad87f5b40f2a3fd2d506dc15e00b8af28a8fa2baJean-Michel Trivi * 46ad87f5b40f2a3fd2d506dc15e00b8af28a8fa2baJean-Michel Trivi * <p>Here is an example of creating a RemoteControlClient instance after registering a media 47ad87f5b40f2a3fd2d506dc15e00b8af28a8fa2baJean-Michel Trivi * button event receiver: 48ad87f5b40f2a3fd2d506dc15e00b8af28a8fa2baJean-Michel Trivi * <pre>ComponentName myEventReceiver = new ComponentName(getPackageName(), MyRemoteControlEventReceiver.class.getName()); 49ad87f5b40f2a3fd2d506dc15e00b8af28a8fa2baJean-Michel Trivi * AudioManager myAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); 50ad87f5b40f2a3fd2d506dc15e00b8af28a8fa2baJean-Michel Trivi * myAudioManager.registerMediaButtonEventReceiver(myEventReceiver); 51ad87f5b40f2a3fd2d506dc15e00b8af28a8fa2baJean-Michel Trivi * // build the PendingIntent for the remote control client 52ad87f5b40f2a3fd2d506dc15e00b8af28a8fa2baJean-Michel Trivi * Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON); 53ad87f5b40f2a3fd2d506dc15e00b8af28a8fa2baJean-Michel Trivi * mediaButtonIntent.setComponent(myEventReceiver); 54ad87f5b40f2a3fd2d506dc15e00b8af28a8fa2baJean-Michel Trivi * PendingIntent mediaPendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, mediaButtonIntent, 0); 55ad87f5b40f2a3fd2d506dc15e00b8af28a8fa2baJean-Michel Trivi * // create and register the remote control client 56ad87f5b40f2a3fd2d506dc15e00b8af28a8fa2baJean-Michel Trivi * RemoteControlClient myRemoteControlClient = new RemoteControlClient(mediaPendingIntent); 57ad87f5b40f2a3fd2d506dc15e00b8af28a8fa2baJean-Michel Trivi * myAudioManager.registerRemoteControlClient(myRemoteControlClient);</pre> 58edb158f55f48a1f7b2cbf30ddec9b8917dc9a619RoboErik * 59edb158f55f48a1f7b2cbf30ddec9b8917dc9a619RoboErik * @deprecated Use {@link MediaSession} instead. 60178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi */ 61edb158f55f48a1f7b2cbf30ddec9b8917dc9a619RoboErik@Deprecated public class RemoteControlClient 62178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi{ 634426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi private final static String TAG = "RemoteControlClient"; 64521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi private final static boolean DEBUG = false; 654426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi 66178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi /** 67178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * Playback state of a RemoteControlClient which is stopped. 68178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * 694426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * @see #setPlaybackState(int) 70178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi */ 71178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi public final static int PLAYSTATE_STOPPED = 1; 72178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi /** 73178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * Playback state of a RemoteControlClient which is paused. 74178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * 754426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * @see #setPlaybackState(int) 76178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi */ 77178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi public final static int PLAYSTATE_PAUSED = 2; 78178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi /** 79178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * Playback state of a RemoteControlClient which is playing media. 80178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * 814426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * @see #setPlaybackState(int) 82178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi */ 83178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi public final static int PLAYSTATE_PLAYING = 3; 84178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi /** 85178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * Playback state of a RemoteControlClient which is fast forwarding in the media 86178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * it is currently playing. 87178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * 884426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * @see #setPlaybackState(int) 89178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi */ 90178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi public final static int PLAYSTATE_FAST_FORWARDING = 4; 91178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi /** 92178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * Playback state of a RemoteControlClient which is fast rewinding in the media 93178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * it is currently playing. 94178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * 954426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * @see #setPlaybackState(int) 96178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi */ 97178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi public final static int PLAYSTATE_REWINDING = 5; 98178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi /** 99178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * Playback state of a RemoteControlClient which is skipping to the next 100178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * logical chapter (such as a song in a playlist) in the media it is currently playing. 101178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * 1024426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * @see #setPlaybackState(int) 103178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi */ 104178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi public final static int PLAYSTATE_SKIPPING_FORWARDS = 6; 105178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi /** 106178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * Playback state of a RemoteControlClient which is skipping back to the previous 107178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * logical chapter (such as a song in a playlist) in the media it is currently playing. 108178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * 1094426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * @see #setPlaybackState(int) 110178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi */ 111178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi public final static int PLAYSTATE_SKIPPING_BACKWARDS = 7; 112178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi /** 113178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * Playback state of a RemoteControlClient which is buffering data to play before it can 114178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * start or resume playback. 115178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * 1164426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * @see #setPlaybackState(int) 117178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi */ 118178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi public final static int PLAYSTATE_BUFFERING = 8; 119178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi /** 120178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * Playback state of a RemoteControlClient which cannot perform any playback related 121178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * operation because of an internal error. Examples of such situations are no network 122178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * connectivity when attempting to stream data from a server, or expired user credentials 123178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * when trying to play subscription-based content. 124178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * 1254426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * @see #setPlaybackState(int) 126178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi */ 127178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi public final static int PLAYSTATE_ERROR = 9; 1284426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi /** 1294426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * @hide 130466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * The value of a playback state when none has been declared. 131466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * Intentionally hidden as an application shouldn't set such a playback state value. 1324426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi */ 1334426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi public final static int PLAYSTATE_NONE = 0; 134178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi 135178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi /** 1361357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @hide 1373114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * The default playback type, "local", indicating the presentation of the media is happening on 1383114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * the same device (e.g. a phone, a tablet) as where it is controlled from. 1393114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi */ 1403114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi public final static int PLAYBACK_TYPE_LOCAL = 0; 1413114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi /** 1421357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @hide 1433114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * A playback type indicating the presentation of the media is happening on 1443114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * a different device (i.e. the remote device) than where it is controlled from. 1453114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi */ 1463114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi public final static int PLAYBACK_TYPE_REMOTE = 1; 1473114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi private final static int PLAYBACK_TYPE_MIN = PLAYBACK_TYPE_LOCAL; 1483114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi private final static int PLAYBACK_TYPE_MAX = PLAYBACK_TYPE_REMOTE; 1493114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi /** 1501357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @hide 1513114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * Playback information indicating the playback volume is fixed, i.e. it cannot be controlled 1523114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * from this object. An example of fixed playback volume is a remote player, playing over HDMI 1533114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * where the user prefer to control the volume on the HDMI sink, rather than attenuate at the 1543114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * source. 1553114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * @see #PLAYBACKINFO_VOLUME_HANDLING. 1563114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi */ 1573114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi public final static int PLAYBACK_VOLUME_FIXED = 0; 1583114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi /** 1591357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @hide 1603114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * Playback information indicating the playback volume is variable and can be controlled from 1613114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * this object. 1623114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * @see #PLAYBACKINFO_VOLUME_HANDLING. 1633114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi */ 1643114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi public final static int PLAYBACK_VOLUME_VARIABLE = 1; 1653114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi /** 1663114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * @hide (to be un-hidden) 1673114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * The playback information value indicating the value of a given information type is invalid. 1683114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * @see #PLAYBACKINFO_VOLUME_HANDLING. 1693114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi */ 1703114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi public final static int PLAYBACKINFO_INVALID_VALUE = Integer.MIN_VALUE; 1713114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi 172bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi /** 173bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi * @hide 174bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi * An unknown or invalid playback position value. 175bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi */ 176bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi public final static long PLAYBACK_POSITION_INVALID = -1; 177bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi /** 178bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi * @hide 1791b16cc3de51d69c8027cefcc70a084a5b2d7a3d0Jean-Michel Trivi * An invalid playback position value associated with the use of {@link #setPlaybackState(int)} 1801b16cc3de51d69c8027cefcc70a084a5b2d7a3d0Jean-Michel Trivi * used to indicate that playback position will remain unknown. 1811b16cc3de51d69c8027cefcc70a084a5b2d7a3d0Jean-Michel Trivi */ 1821b16cc3de51d69c8027cefcc70a084a5b2d7a3d0Jean-Michel Trivi public final static long PLAYBACK_POSITION_ALWAYS_UNKNOWN = 0x8019771980198300L; 1831b16cc3de51d69c8027cefcc70a084a5b2d7a3d0Jean-Michel Trivi /** 1841b16cc3de51d69c8027cefcc70a084a5b2d7a3d0Jean-Michel Trivi * @hide 185bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi * The default playback speed, 1x. 186bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi */ 187bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi public final static float PLAYBACK_SPEED_1X = 1.0f; 188bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi 1893114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi //========================================== 1903114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi // Public keys for playback information 1913114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi /** 1921357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @hide 1933114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * Playback information that defines the type of playback associated with this 1943114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * RemoteControlClient. See {@link #PLAYBACK_TYPE_LOCAL} and {@link #PLAYBACK_TYPE_REMOTE}. 1953114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi */ 1963114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi public final static int PLAYBACKINFO_PLAYBACK_TYPE = 1; 1973114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi /** 1981357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @hide 1993114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * Playback information that defines at what volume the playback associated with this 2003114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * RemoteControlClient is performed. This information is only used when the playback type is not 2013114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * local (see {@link #PLAYBACKINFO_PLAYBACK_TYPE}). 2023114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi */ 2033114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi public final static int PLAYBACKINFO_VOLUME = 2; 2043114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi /** 2051357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @hide 2063114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * Playback information that defines the maximum volume volume value that is supported 2073114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * by the playback associated with this RemoteControlClient. This information is only used 2083114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * when the playback type is not local (see {@link #PLAYBACKINFO_PLAYBACK_TYPE}). 2093114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi */ 2103114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi public final static int PLAYBACKINFO_VOLUME_MAX = 3; 2113114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi /** 2121357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @hide 2133114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * Playback information that defines how volume is handled for the presentation of the media. 2143114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * @see #PLAYBACK_VOLUME_FIXED 2153114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * @see #PLAYBACK_VOLUME_VARIABLE 2163114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi */ 2173114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi public final static int PLAYBACKINFO_VOLUME_HANDLING = 4; 2183114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi /** 2191357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @hide 2203114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * Playback information that defines over what stream type the media is presented. 2213114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi */ 2223114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi public final static int PLAYBACKINFO_USES_STREAM = 5; 2233114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi 2243114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi //========================================== 225521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi // Public flags for the supported transport control capabilities 2263114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi /** 227178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * Flag indicating a RemoteControlClient makes use of the "previous" media key. 228178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * 2294426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * @see #setTransportControlFlags(int) 230178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * @see android.view.KeyEvent#KEYCODE_MEDIA_PREVIOUS 231178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi */ 232178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi public final static int FLAG_KEY_MEDIA_PREVIOUS = 1 << 0; 233178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi /** 234466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * Flag indicating a RemoteControlClient makes use of the "rewind" media key. 235178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * 2364426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * @see #setTransportControlFlags(int) 237178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * @see android.view.KeyEvent#KEYCODE_MEDIA_REWIND 238178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi */ 239178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi public final static int FLAG_KEY_MEDIA_REWIND = 1 << 1; 240178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi /** 241178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * Flag indicating a RemoteControlClient makes use of the "play" media key. 242178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * 2434426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * @see #setTransportControlFlags(int) 244178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * @see android.view.KeyEvent#KEYCODE_MEDIA_PLAY 245178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi */ 246178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi public final static int FLAG_KEY_MEDIA_PLAY = 1 << 2; 247178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi /** 248178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * Flag indicating a RemoteControlClient makes use of the "play/pause" media key. 249178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * 2504426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * @see #setTransportControlFlags(int) 251178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * @see android.view.KeyEvent#KEYCODE_MEDIA_PLAY_PAUSE 252178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi */ 253178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi public final static int FLAG_KEY_MEDIA_PLAY_PAUSE = 1 << 3; 254178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi /** 255178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * Flag indicating a RemoteControlClient makes use of the "pause" media key. 256178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * 2574426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * @see #setTransportControlFlags(int) 258178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * @see android.view.KeyEvent#KEYCODE_MEDIA_PAUSE 259178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi */ 260178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi public final static int FLAG_KEY_MEDIA_PAUSE = 1 << 4; 261178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi /** 262178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * Flag indicating a RemoteControlClient makes use of the "stop" media key. 263178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * 2644426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * @see #setTransportControlFlags(int) 265178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * @see android.view.KeyEvent#KEYCODE_MEDIA_STOP 266178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi */ 267178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi public final static int FLAG_KEY_MEDIA_STOP = 1 << 5; 268178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi /** 269178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * Flag indicating a RemoteControlClient makes use of the "fast forward" media key. 270178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * 2714426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * @see #setTransportControlFlags(int) 272178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * @see android.view.KeyEvent#KEYCODE_MEDIA_FAST_FORWARD 273178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi */ 274178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi public final static int FLAG_KEY_MEDIA_FAST_FORWARD = 1 << 6; 275178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi /** 276178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * Flag indicating a RemoteControlClient makes use of the "next" media key. 277178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * 2784426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * @see #setTransportControlFlags(int) 279178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * @see android.view.KeyEvent#KEYCODE_MEDIA_NEXT 280178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi */ 281178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi public final static int FLAG_KEY_MEDIA_NEXT = 1 << 7; 282bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi /** 283bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi * Flag indicating a RemoteControlClient can receive changes in the media playback position 284e63b0609c3b5f6c21d4e006ee9ddd3ba98a4e684Scott Main * through the {@link OnPlaybackPositionUpdateListener} interface. This flag must be set 2853261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi * in order for components that display the RemoteControlClient information, to display and 2863261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi * let the user control media playback position. 287bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi * @see #setTransportControlFlags(int) 288915747730060dff71b5b2ca7e4ee4073024fc24eJean-Michel Trivi * @see #setOnGetPlaybackPositionListener(OnGetPlaybackPositionListener) 2893261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi * @see #setPlaybackPositionUpdateListener(OnPlaybackPositionUpdateListener) 290bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi */ 291bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi public final static int FLAG_KEY_MEDIA_POSITION_UPDATE = 1 << 8; 292f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi /** 293f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi * Flag indicating a RemoteControlClient supports ratings. 294f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi * This flag must be set in order for components that display the RemoteControlClient 295f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi * information, to display ratings information, and, if ratings are declared editable 296f841d70155c991b6cf728dd41e6d37e051be453dJean-Michel Trivi * (by calling {@link MediaMetadataEditor#addEditableKey(int)} with the 297f841d70155c991b6cf728dd41e6d37e051be453dJean-Michel Trivi * {@link MediaMetadataEditor#RATING_KEY_BY_USER} key), it will enable the user to rate 298b23cd118ce3339589fffd40ecf1aa9c5816b3438Jean-Michel Trivi * the media, with values being received through the interface set with 299b23cd118ce3339589fffd40ecf1aa9c5816b3438Jean-Michel Trivi * {@link #setMetadataUpdateListener(OnMetadataUpdateListener)}. 300f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi * @see #setTransportControlFlags(int) 301f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi */ 302f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi public final static int FLAG_KEY_MEDIA_RATING = 1 << 9; 303178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi 304178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi /** 3054426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * @hide 306466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * The flags for when no media keys are declared supported. 307466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * Intentionally hidden as an application shouldn't set the transport control flags 308466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * to this value. 3094426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi */ 3104426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi public final static int FLAGS_KEY_MEDIA_NONE = 0; 3114426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi 3124426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi /** 3134426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * @hide 3144426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * Flag used to signal some type of metadata exposed by the RemoteControlClient is requested. 315178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi */ 3164426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi public final static int FLAG_INFORMATION_REQUEST_METADATA = 1 << 0; 317178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi /** 3184426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * @hide 319178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * Flag used to signal that the transport control buttons supported by the 320466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * RemoteControlClient are requested. 321178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * This can for instance happen when playback is at the end of a playlist, and the "next" 322178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * operation is not supported anymore. 323178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi */ 3244426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi public final static int FLAG_INFORMATION_REQUEST_KEY_MEDIA = 1 << 1; 325178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi /** 3264426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * @hide 327466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * Flag used to signal that the playback state of the RemoteControlClient is requested. 328178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi */ 3294426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi public final static int FLAG_INFORMATION_REQUEST_PLAYSTATE = 1 << 2; 330178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi /** 3314426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * @hide 332466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * Flag used to signal that the album art for the RemoteControlClient is requested. 333178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi */ 3344426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi public final static int FLAG_INFORMATION_REQUEST_ALBUM_ART = 1 << 3; 3354426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi 33642ea7eecd149161ed192d3029f0d77d1d08a4aa5RoboErik private MediaSession mSession; 337f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik 3384426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi /** 3396e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi * Class constructor. 3406e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi * @param mediaButtonIntent The intent that will be sent for the media button events sent 3416e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi * by remote controls. 3426e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi * This intent needs to have been constructed with the {@link Intent#ACTION_MEDIA_BUTTON} 3436e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi * action, and have a component that will handle the intent (set with 3446e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi * {@link Intent#setComponent(ComponentName)}) registered with 3456e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi * {@link AudioManager#registerMediaButtonEventReceiver(ComponentName)} 3466e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi * before this new RemoteControlClient can itself be registered with 3476e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi * {@link AudioManager#registerRemoteControlClient(RemoteControlClient)}. 3486e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi * @see AudioManager#registerMediaButtonEventReceiver(ComponentName) 3496e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi * @see AudioManager#registerRemoteControlClient(RemoteControlClient) 3506e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi */ 3516e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi public RemoteControlClient(PendingIntent mediaButtonIntent) { 352f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi mRcMediaIntent = mediaButtonIntent; 3536e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi 3546e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi Looper looper; 3556e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi if ((looper = Looper.myLooper()) != null) { 3566e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi mEventHandler = new EventHandler(this, looper); 3576e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi } else if ((looper = Looper.getMainLooper()) != null) { 3586e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi mEventHandler = new EventHandler(this, looper); 3596e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi } else { 3606e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi mEventHandler = null; 3616e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi Log.e(TAG, "RemoteControlClient() couldn't find main application thread"); 3626e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi } 3636e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi } 3646e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi 3656e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi /** 3666e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi * Class constructor for a remote control client whose internal event handling 3676e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi * happens on a user-provided Looper. 3686e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi * @param mediaButtonIntent The intent that will be sent for the media button events sent 3696e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi * by remote controls. 3706e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi * This intent needs to have been constructed with the {@link Intent#ACTION_MEDIA_BUTTON} 3716e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi * action, and have a component that will handle the intent (set with 3726e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi * {@link Intent#setComponent(ComponentName)}) registered with 3736e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi * {@link AudioManager#registerMediaButtonEventReceiver(ComponentName)} 3746e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi * before this new RemoteControlClient can itself be registered with 3756e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi * {@link AudioManager#registerRemoteControlClient(RemoteControlClient)}. 3766e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi * @param looper The Looper running the event loop. 3776e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi * @see AudioManager#registerMediaButtonEventReceiver(ComponentName) 3786e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi * @see AudioManager#registerRemoteControlClient(RemoteControlClient) 3796e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi */ 3806e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi public RemoteControlClient(PendingIntent mediaButtonIntent, Looper looper) { 381f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi mRcMediaIntent = mediaButtonIntent; 3826e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi 3836e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi mEventHandler = new EventHandler(this, looper); 3846e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi } 3856e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi 3864426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi /** 387f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik * @hide 388f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik */ 389f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik public void registerWithSession(MediaSessionLegacyHelper helper) { 390f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik helper.addRccListener(mRcMediaIntent, mTransportListener); 391f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik mSession = helper.getSession(mRcMediaIntent); 3926c30ff976dc6b49186c162ecbae08eb571a6b9f1RoboErik setTransportControlFlags(mTransportControlFlags); 393f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik } 394f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik 395f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik /** 396f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik * @hide 397f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik */ 398f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik public void unregisterWithSession(MediaSessionLegacyHelper helper) { 399f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik helper.removeRccListener(mRcMediaIntent); 400f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik mSession = null; 401f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik } 402f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik 403f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik /** 4045f31737c68f7709cb75a8fefb7536daa77812cc3RoboErik * Get a {@link MediaSession} associated with this RCC. It will only have a 4055f31737c68f7709cb75a8fefb7536daa77812cc3RoboErik * session while it is registered with 4065f31737c68f7709cb75a8fefb7536daa77812cc3RoboErik * {@link AudioManager#registerRemoteControlClient}. The session returned 4075f31737c68f7709cb75a8fefb7536daa77812cc3RoboErik * should not be modified directly by the application but may be used with 4085f31737c68f7709cb75a8fefb7536daa77812cc3RoboErik * other APIs that require a session. 4095f31737c68f7709cb75a8fefb7536daa77812cc3RoboErik * 4105f31737c68f7709cb75a8fefb7536daa77812cc3RoboErik * @return A media session object or null. 4115f31737c68f7709cb75a8fefb7536daa77812cc3RoboErik */ 4125f31737c68f7709cb75a8fefb7536daa77812cc3RoboErik public MediaSession getMediaSession() { 4135f31737c68f7709cb75a8fefb7536daa77812cc3RoboErik return mSession; 4145f31737c68f7709cb75a8fefb7536daa77812cc3RoboErik } 4155f31737c68f7709cb75a8fefb7536daa77812cc3RoboErik 4165f31737c68f7709cb75a8fefb7536daa77812cc3RoboErik /** 4174426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * Class used to modify metadata in a {@link RemoteControlClient} object. 418466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * Use {@link RemoteControlClient#editMetadata(boolean)} to create an instance of an editor, 419466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * on which you set the metadata for the RemoteControlClient instance. Once all the information 420466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * has been set, use {@link #apply()} to make it the new metadata that should be displayed 421466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * for the associated client. Once the metadata has been "applied", you cannot reuse this 422466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * instance of the MetadataEditor. 423edb158f55f48a1f7b2cbf30ddec9b8917dc9a619RoboErik * 424edb158f55f48a1f7b2cbf30ddec9b8917dc9a619RoboErik * @deprecated Use {@link MediaMetadata} and {@link MediaSession} instead. 4254426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi */ 426edb158f55f48a1f7b2cbf30ddec9b8917dc9a619RoboErik @Deprecated public class MetadataEditor extends MediaMetadataEditor { 4274da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi 4284da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi // only use RemoteControlClient.editMetadata() to get a MetadataEditor instance 4294da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi private MetadataEditor() { } 4304da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi /** 4314da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi * @hide 4324da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi */ 4334da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi public Object clone() throws CloneNotSupportedException { 4344da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi throw new CloneNotSupportedException(); 4354426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 4364426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi 4374da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi /** 4385ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi * The metadata key for the content artwork / album art. 4395ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi */ 440466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi public final static int BITMAP_KEY_ARTWORK = 100; 441f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi 442f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi /** 443f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi * @hide 44488183e67d4628e8c8a3310af0076b6f33f955cb2Jean-Michel Trivi * TODO(jmtrivi) have lockscreen move to the new key name and remove 445466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi */ 446466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi public final static int METADATA_KEY_ARTWORK = BITMAP_KEY_ARTWORK; 4475ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi 4485ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi /** 4494da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi * Adds textual information to be displayed. 4504da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi * Note that none of the information added after {@link #apply()} has been called, 4514da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi * will be displayed. 452466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * @param key The identifier of a the metadata field to set. Valid values are 4534da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi * {@link android.media.MediaMetadataRetriever#METADATA_KEY_ALBUM}, 4544da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi * {@link android.media.MediaMetadataRetriever#METADATA_KEY_ALBUMARTIST}, 4554da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi * {@link android.media.MediaMetadataRetriever#METADATA_KEY_TITLE}, 4564da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi * {@link android.media.MediaMetadataRetriever#METADATA_KEY_ARTIST}, 4574da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi * {@link android.media.MediaMetadataRetriever#METADATA_KEY_AUTHOR}, 4584da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi * {@link android.media.MediaMetadataRetriever#METADATA_KEY_COMPILATION}, 4594da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi * {@link android.media.MediaMetadataRetriever#METADATA_KEY_COMPOSER}, 4604da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi * {@link android.media.MediaMetadataRetriever#METADATA_KEY_DATE}, 4614da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi * {@link android.media.MediaMetadataRetriever#METADATA_KEY_GENRE}, 4624da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi * {@link android.media.MediaMetadataRetriever#METADATA_KEY_TITLE}, 463466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * {@link android.media.MediaMetadataRetriever#METADATA_KEY_WRITER}. 464466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * @param value The text for the given key, or {@code null} to signify there is no valid 4654da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi * information for the field. 466466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * @return Returns a reference to the same MetadataEditor object, so you can chain put 467466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * calls together. 4684da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi */ 4695ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi public synchronized MetadataEditor putString(int key, String value) 4705ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi throws IllegalArgumentException { 47188183e67d4628e8c8a3310af0076b6f33f955cb2Jean-Michel Trivi super.putString(key, value); 472f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik if (mMetadataBuilder != null) { 473f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik // MediaMetadata supports all the same fields as MetadataEditor 474f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik String metadataKey = MediaMetadata.getKeyFromMetadataEditorKey(key); 475f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik // But just in case, don't add things we don't understand 476f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik if (metadataKey != null) { 47775847b98f39e521a57042c50e69be9e142788d32RoboErik mMetadataBuilder.putText(metadataKey, value); 478f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik } 479f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik } 480f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik 4814426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi return this; 4824426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 4834426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi 4844da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi /** 485466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * Adds numerical information to be displayed. 486466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * Note that none of the information added after {@link #apply()} has been called, 487466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * will be displayed. 4885ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi * @param key the identifier of a the metadata field to set. Valid values are 4895ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi * {@link android.media.MediaMetadataRetriever#METADATA_KEY_CD_TRACK_NUMBER}, 4905ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi * {@link android.media.MediaMetadataRetriever#METADATA_KEY_DISC_NUMBER}, 4915ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi * {@link android.media.MediaMetadataRetriever#METADATA_KEY_DURATION} (with a value 4925ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi * expressed in milliseconds), 49388183e67d4628e8c8a3310af0076b6f33f955cb2Jean-Michel Trivi * {@link android.media.MediaMetadataRetriever#METADATA_KEY_YEAR}. 494466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * @param value The long value for the given key 495466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * @return Returns a reference to the same MetadataEditor object, so you can chain put 496466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * calls together. 4975ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi * @throws IllegalArgumentException 4984da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi */ 4995ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi public synchronized MetadataEditor putLong(int key, long value) 5005ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi throws IllegalArgumentException { 50188183e67d4628e8c8a3310af0076b6f33f955cb2Jean-Michel Trivi super.putLong(key, value); 502f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik if (mMetadataBuilder != null) { 503f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik // MediaMetadata supports all the same fields as MetadataEditor 504f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik String metadataKey = MediaMetadata.getKeyFromMetadataEditorKey(key); 505f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik // But just in case, don't add things we don't understand 506f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik if (metadataKey != null) { 507f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik mMetadataBuilder.putLong(metadataKey, value); 508f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik } 509f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik } 5105ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi return this; 5115ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi } 5124da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi 5134da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi /** 5144da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi * Sets the album / artwork picture to be displayed on the remote control. 515466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * @param key the identifier of the bitmap to set. The only valid value is 516466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * {@link #BITMAP_KEY_ARTWORK} 517466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * @param bitmap The bitmap for the artwork, or null if there isn't any. 518466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * @return Returns a reference to the same MetadataEditor object, so you can chain put 519466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * calls together. 5205ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi * @throws IllegalArgumentException 5214da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi * @see android.graphics.Bitmap 5224da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi */ 52388183e67d4628e8c8a3310af0076b6f33f955cb2Jean-Michel Trivi @Override 5245ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi public synchronized MetadataEditor putBitmap(int key, Bitmap bitmap) 5255ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi throws IllegalArgumentException { 52688183e67d4628e8c8a3310af0076b6f33f955cb2Jean-Michel Trivi super.putBitmap(key, bitmap); 527f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik if (mMetadataBuilder != null) { 528f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik // MediaMetadata supports all the same fields as MetadataEditor 529f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik String metadataKey = MediaMetadata.getKeyFromMetadataEditorKey(key); 530f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik // But just in case, don't add things we don't understand 531f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik if (metadataKey != null) { 532f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik mMetadataBuilder.putBitmap(metadataKey, bitmap); 533f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik } 534f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik } 5354da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi return this; 5364426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 537178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi 53838696ba77d7f614cb50672aaca99f7ba59b56126RoboErik @Override 53938696ba77d7f614cb50672aaca99f7ba59b56126RoboErik public synchronized MetadataEditor putObject(int key, Object object) 54038696ba77d7f614cb50672aaca99f7ba59b56126RoboErik throws IllegalArgumentException { 54138696ba77d7f614cb50672aaca99f7ba59b56126RoboErik super.putObject(key, object); 54238696ba77d7f614cb50672aaca99f7ba59b56126RoboErik if (mMetadataBuilder != null && 54338696ba77d7f614cb50672aaca99f7ba59b56126RoboErik (key == MediaMetadataEditor.RATING_KEY_BY_USER || 54438696ba77d7f614cb50672aaca99f7ba59b56126RoboErik key == MediaMetadataEditor.RATING_KEY_BY_OTHERS)) { 54538696ba77d7f614cb50672aaca99f7ba59b56126RoboErik String metadataKey = MediaMetadata.getKeyFromMetadataEditorKey(key); 54638696ba77d7f614cb50672aaca99f7ba59b56126RoboErik if (metadataKey != null) { 54738696ba77d7f614cb50672aaca99f7ba59b56126RoboErik mMetadataBuilder.putRating(metadataKey, (Rating) object); 54838696ba77d7f614cb50672aaca99f7ba59b56126RoboErik } 54938696ba77d7f614cb50672aaca99f7ba59b56126RoboErik } 55038696ba77d7f614cb50672aaca99f7ba59b56126RoboErik return this; 55138696ba77d7f614cb50672aaca99f7ba59b56126RoboErik } 55238696ba77d7f614cb50672aaca99f7ba59b56126RoboErik 5534da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi /** 55488183e67d4628e8c8a3310af0076b6f33f955cb2Jean-Michel Trivi * Clears all the metadata that has been set since the MetadataEditor instance was created 55588183e67d4628e8c8a3310af0076b6f33f955cb2Jean-Michel Trivi * (with {@link RemoteControlClient#editMetadata(boolean)}). 556b23cd118ce3339589fffd40ecf1aa9c5816b3438Jean-Michel Trivi * Note that clearing the metadata doesn't reset the editable keys 55788183e67d4628e8c8a3310af0076b6f33f955cb2Jean-Michel Trivi * (use {@link MediaMetadataEditor#removeEditableKeys()} instead). 5584da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi */ 55988183e67d4628e8c8a3310af0076b6f33f955cb2Jean-Michel Trivi @Override 5604da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi public synchronized void clear() { 56188183e67d4628e8c8a3310af0076b6f33f955cb2Jean-Michel Trivi super.clear(); 562f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi } 563f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi 564f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi /** 565466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * Associates all the metadata that has been set since the MetadataEditor instance was 566466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * created with {@link RemoteControlClient#editMetadata(boolean)}, or since 567466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * {@link #clear()} was called, with the RemoteControlClient. Once "applied", 568466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * this MetadataEditor cannot be reused to edit the RemoteControlClient's metadata. 5694da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi */ 5704da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi public synchronized void apply() { 5714da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi if (mApplied) { 5724da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi Log.e(TAG, "Can't apply a previously applied MetadataEditor"); 5734da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi return; 5744da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi } 575f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik synchronized (mCacheLock) { 576430fc48865e5a371b08f180390946b96d73848feRoboErik // Still build the old metadata so when creating a new editor 577430fc48865e5a371b08f180390946b96d73848feRoboErik // you get the expected values. 5784da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi // assign the edited data 5794da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi mMetadata = new Bundle(mEditorMetadata); 580f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi // add the information about editable keys 581f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi mMetadata.putLong(String.valueOf(KEY_EDITABLE_MASK), mEditableKeys); 5824a5700556191c835116ec2a6997a4f16f464ac9dJean-Michel Trivi if ((mOriginalArtwork != null) && (!mOriginalArtwork.equals(mEditorArtwork))) { 5834a5700556191c835116ec2a6997a4f16f464ac9dJean-Michel Trivi mOriginalArtwork.recycle(); 58434d0d300cac645b48cce5a1735f45e1102d4ef0eJean-Michel Trivi } 5854a5700556191c835116ec2a6997a4f16f464ac9dJean-Michel Trivi mOriginalArtwork = mEditorArtwork; 58634d0d300cac645b48cce5a1735f45e1102d4ef0eJean-Michel Trivi mEditorArtwork = null; 587f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik 588f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik // USE_SESSIONS 589f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik if (mSession != null && mMetadataBuilder != null) { 59051c07bc0bf338c9dd9d2345fe81d2cd964d680caRoboErik mMediaMetadata = mMetadataBuilder.build(); 59151c07bc0bf338c9dd9d2345fe81d2cd964d680caRoboErik mSession.setMetadata(mMediaMetadata); 592f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik } 5934da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi mApplied = true; 5944da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi } 5954426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 5964426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 5974426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi 5984426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi /** 599466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * Creates a {@link MetadataEditor}. 600466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * @param startEmpty Set to false if you want the MetadataEditor to contain the metadata that 601466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * was previously applied to the RemoteControlClient, or true if it is to be created empty. 602466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * @return a new MetadataEditor instance. 6034426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi */ 6044da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi public MetadataEditor editMetadata(boolean startEmpty) { 6054da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi MetadataEditor editor = new MetadataEditor(); 6064da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi if (startEmpty) { 6074da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi editor.mEditorMetadata = new Bundle(); 6084da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi editor.mEditorArtwork = null; 6094da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi editor.mMetadataChanged = true; 6104da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi editor.mArtworkChanged = true; 611f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi editor.mEditableKeys = 0; 6124da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi } else { 6134da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi editor.mEditorMetadata = new Bundle(mMetadata); 6144a5700556191c835116ec2a6997a4f16f464ac9dJean-Michel Trivi editor.mEditorArtwork = mOriginalArtwork; 6154da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi editor.mMetadataChanged = false; 6164da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi editor.mArtworkChanged = false; 6174426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 618f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik // USE_SESSIONS 619f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik if (startEmpty || mMediaMetadata == null) { 620f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik editor.mMetadataBuilder = new MediaMetadata.Builder(); 621f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik } else { 622f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik editor.mMetadataBuilder = new MediaMetadata.Builder(mMediaMetadata); 623f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik } 6244da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi return editor; 6254426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 6264426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi 6274426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi /** 6284426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * Sets the current playback state. 629466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * @param state The current playback state, one of the following values: 630178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * {@link #PLAYSTATE_STOPPED}, 631178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * {@link #PLAYSTATE_PAUSED}, 632178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * {@link #PLAYSTATE_PLAYING}, 633178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * {@link #PLAYSTATE_FAST_FORWARDING}, 634178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * {@link #PLAYSTATE_REWINDING}, 635178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * {@link #PLAYSTATE_SKIPPING_FORWARDS}, 636178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * {@link #PLAYSTATE_SKIPPING_BACKWARDS}, 637178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * {@link #PLAYSTATE_BUFFERING}, 638178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * {@link #PLAYSTATE_ERROR}. 639178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi */ 6404426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi public void setPlaybackState(int state) { 6411b16cc3de51d69c8027cefcc70a084a5b2d7a3d0Jean-Michel Trivi setPlaybackStateInt(state, PLAYBACK_POSITION_ALWAYS_UNKNOWN, PLAYBACK_SPEED_1X, 6421b16cc3de51d69c8027cefcc70a084a5b2d7a3d0Jean-Michel Trivi false /* legacy API, converting to method with position and speed */); 643bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi } 644bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi 645bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi /** 646bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi * Sets the current playback state and the matching media position for the current playback 647bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi * speed. 648bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi * @param state The current playback state, one of the following values: 649bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi * {@link #PLAYSTATE_STOPPED}, 650bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi * {@link #PLAYSTATE_PAUSED}, 651bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi * {@link #PLAYSTATE_PLAYING}, 652bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi * {@link #PLAYSTATE_FAST_FORWARDING}, 653bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi * {@link #PLAYSTATE_REWINDING}, 654bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi * {@link #PLAYSTATE_SKIPPING_FORWARDS}, 655bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi * {@link #PLAYSTATE_SKIPPING_BACKWARDS}, 656bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi * {@link #PLAYSTATE_BUFFERING}, 657bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi * {@link #PLAYSTATE_ERROR}. 658bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi * @param timeInMs a 0 or positive value for the current media position expressed in ms 659bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi * (same unit as for when sending the media duration, if applicable, with 660bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi * {@link android.media.MediaMetadataRetriever#METADATA_KEY_DURATION} in the 661bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi * {@link RemoteControlClient.MetadataEditor}). Negative values imply that position is not 662bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi * known (e.g. listening to a live stream of a radio) or not applicable (e.g. when state 663bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi * is {@link #PLAYSTATE_BUFFERING} and nothing had played yet). 664bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi * @param playbackSpeed a value expressed as a ratio of 1x playback: 1.0f is normal playback, 665bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi * 2.0f is 2x, 0.5f is half-speed, -2.0f is rewind at 2x speed. 0.0f means nothing is 666bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi * playing (e.g. when state is {@link #PLAYSTATE_ERROR}). 667bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi */ 668bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi public void setPlaybackState(int state, long timeInMs, float playbackSpeed) { 6691b16cc3de51d69c8027cefcc70a084a5b2d7a3d0Jean-Michel Trivi setPlaybackStateInt(state, timeInMs, playbackSpeed, true); 6701b16cc3de51d69c8027cefcc70a084a5b2d7a3d0Jean-Michel Trivi } 6711b16cc3de51d69c8027cefcc70a084a5b2d7a3d0Jean-Michel Trivi 6721b16cc3de51d69c8027cefcc70a084a5b2d7a3d0Jean-Michel Trivi private void setPlaybackStateInt(int state, long timeInMs, float playbackSpeed, 6731b16cc3de51d69c8027cefcc70a084a5b2d7a3d0Jean-Michel Trivi boolean hasPosition) { 6744426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi synchronized(mCacheLock) { 675bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi if ((mPlaybackState != state) || (mPlaybackPositionMs != timeInMs) 676bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi || (mPlaybackSpeed != playbackSpeed)) { 67768622396b62f9084781add1e12f4d513b633ab54Jean-Michel Trivi // store locally 67868622396b62f9084781add1e12f4d513b633ab54Jean-Michel Trivi mPlaybackState = state; 6791b16cc3de51d69c8027cefcc70a084a5b2d7a3d0Jean-Michel Trivi // distinguish between an application not knowing the current playback position 6801b16cc3de51d69c8027cefcc70a084a5b2d7a3d0Jean-Michel Trivi // at the moment and an application using the API where only the playback state 6811b16cc3de51d69c8027cefcc70a084a5b2d7a3d0Jean-Michel Trivi // is passed, not the playback position. 6821b16cc3de51d69c8027cefcc70a084a5b2d7a3d0Jean-Michel Trivi if (hasPosition) { 6831b16cc3de51d69c8027cefcc70a084a5b2d7a3d0Jean-Michel Trivi if (timeInMs < 0) { 6841b16cc3de51d69c8027cefcc70a084a5b2d7a3d0Jean-Michel Trivi mPlaybackPositionMs = PLAYBACK_POSITION_INVALID; 6851b16cc3de51d69c8027cefcc70a084a5b2d7a3d0Jean-Michel Trivi } else { 6861b16cc3de51d69c8027cefcc70a084a5b2d7a3d0Jean-Michel Trivi mPlaybackPositionMs = timeInMs; 6871b16cc3de51d69c8027cefcc70a084a5b2d7a3d0Jean-Michel Trivi } 6881b16cc3de51d69c8027cefcc70a084a5b2d7a3d0Jean-Michel Trivi } else { 6891b16cc3de51d69c8027cefcc70a084a5b2d7a3d0Jean-Michel Trivi mPlaybackPositionMs = PLAYBACK_POSITION_ALWAYS_UNKNOWN; 6901b16cc3de51d69c8027cefcc70a084a5b2d7a3d0Jean-Michel Trivi } 691bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi mPlaybackSpeed = playbackSpeed; 69268622396b62f9084781add1e12f4d513b633ab54Jean-Michel Trivi // keep track of when the state change occurred 69368622396b62f9084781add1e12f4d513b633ab54Jean-Michel Trivi mPlaybackStateChangeTimeMs = SystemClock.elapsedRealtime(); 69468622396b62f9084781add1e12f4d513b633ab54Jean-Michel Trivi 695f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik // USE_SESSIONS 696f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik if (mSession != null) { 697f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik int pbState = PlaybackState.getStateFromRccState(state); 698c785a78fb483fe54012175c53d3758b2412de7b9RoboErik long position = hasPosition ? mPlaybackPositionMs 699c785a78fb483fe54012175c53d3758b2412de7b9RoboErik : PlaybackState.PLAYBACK_POSITION_UNKNOWN; 700c785a78fb483fe54012175c53d3758b2412de7b9RoboErik 701c785a78fb483fe54012175c53d3758b2412de7b9RoboErik PlaybackState.Builder bob = new PlaybackState.Builder(mSessionPlaybackState); 702c785a78fb483fe54012175c53d3758b2412de7b9RoboErik bob.setState(pbState, position, playbackSpeed, SystemClock.elapsedRealtime()); 703c785a78fb483fe54012175c53d3758b2412de7b9RoboErik bob.setErrorMessage(null); 704c785a78fb483fe54012175c53d3758b2412de7b9RoboErik mSessionPlaybackState = bob.build(); 705c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik mSession.setPlaybackState(mSessionPlaybackState); 706f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik } 707521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi } 708521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi } 709521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi } 710521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi 711430fc48865e5a371b08f180390946b96d73848feRoboErik // TODO investigate if we still need position drift checking 712521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi private void onPositionDriftCheck() { 713521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi if (DEBUG) { Log.d(TAG, "onPositionDriftCheck()"); } 714521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi synchronized(mCacheLock) { 715c3c4babf8424f65b3d3d2700f60fae6e94e9cd00Jean-Michel Trivi if ((mEventHandler == null) || (mPositionProvider == null) || !mNeedsPositionSync) { 716521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi return; 717521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi } 718c3c4babf8424f65b3d3d2700f60fae6e94e9cd00Jean-Michel Trivi if ((mPlaybackPositionMs < 0) || (mPlaybackSpeed == 0.0f)) { 719c3c4babf8424f65b3d3d2700f60fae6e94e9cd00Jean-Michel Trivi if (DEBUG) { Log.d(TAG, " no valid position or 0 speed, no check needed"); } 720521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi return; 721521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi } 722521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi long estPos = mPlaybackPositionMs + (long) 723521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi ((SystemClock.elapsedRealtime() - mPlaybackStateChangeTimeMs) / mPlaybackSpeed); 724521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi long actPos = mPositionProvider.onGetPlaybackPosition(); 725521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi if (actPos >= 0) { 726521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi if (Math.abs(estPos - actPos) > POSITION_DRIFT_MAX_MS) { 727521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi // drift happened, report the new position 728521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi if (DEBUG) { Log.w(TAG, " drift detected: actual=" +actPos +" est=" +estPos); } 729521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi setPlaybackState(mPlaybackState, actPos, mPlaybackSpeed); 730521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi } else { 731521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi if (DEBUG) { Log.d(TAG, " no drift: actual=" + actPos +" est=" + estPos); } 732521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi // no drift, schedule the next drift check 733521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi mEventHandler.sendMessageDelayed( 734521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi mEventHandler.obtainMessage(MSG_POSITION_DRIFT_CHECK), 735521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi getCheckPeriodFromSpeed(mPlaybackSpeed)); 736521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi } 737521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi } else { 738521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi // invalid position (negative value), can't check for drift 739521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi mEventHandler.removeMessages(MSG_POSITION_DRIFT_CHECK); 74068622396b62f9084781add1e12f4d513b633ab54Jean-Michel Trivi } 7414426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 7424426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 743178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi 744178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi /** 7454426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * Sets the flags for the media transport control buttons that this client supports. 746466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * @param transportControlFlags A combination of the following flags: 7474426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * {@link #FLAG_KEY_MEDIA_PREVIOUS}, 748178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * {@link #FLAG_KEY_MEDIA_REWIND}, 749178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * {@link #FLAG_KEY_MEDIA_PLAY}, 750178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * {@link #FLAG_KEY_MEDIA_PLAY_PAUSE}, 751178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * {@link #FLAG_KEY_MEDIA_PAUSE}, 752178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * {@link #FLAG_KEY_MEDIA_STOP}, 753178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * {@link #FLAG_KEY_MEDIA_FAST_FORWARD}, 754915747730060dff71b5b2ca7e4ee4073024fc24eJean-Michel Trivi * {@link #FLAG_KEY_MEDIA_NEXT}, 755b23cd118ce3339589fffd40ecf1aa9c5816b3438Jean-Michel Trivi * {@link #FLAG_KEY_MEDIA_POSITION_UPDATE}, 756b23cd118ce3339589fffd40ecf1aa9c5816b3438Jean-Michel Trivi * {@link #FLAG_KEY_MEDIA_RATING}. 757178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi */ 7584426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi public void setTransportControlFlags(int transportControlFlags) { 7594426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi synchronized(mCacheLock) { 7604426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi // store locally 7614426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi mTransportControlFlags = transportControlFlags; 7624426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi 763f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik // USE_SESSIONS 764f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik if (mSession != null) { 765c785a78fb483fe54012175c53d3758b2412de7b9RoboErik PlaybackState.Builder bob = new PlaybackState.Builder(mSessionPlaybackState); 766f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal bob.setActions( 767f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal PlaybackState.getActionsFromRccControlFlags(transportControlFlags)); 768c785a78fb483fe54012175c53d3758b2412de7b9RoboErik mSessionPlaybackState = bob.build(); 769c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik mSession.setPlaybackState(mSessionPlaybackState); 770f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik } 7714426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 7724426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 773178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi 774bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi /** 775b23cd118ce3339589fffd40ecf1aa9c5816b3438Jean-Michel Trivi * Interface definition for a callback to be invoked when one of the metadata values has 776b23cd118ce3339589fffd40ecf1aa9c5816b3438Jean-Michel Trivi * been updated. 77788183e67d4628e8c8a3310af0076b6f33f955cb2Jean-Michel Trivi * Implement this interface to receive metadata updates after registering your listener 77888183e67d4628e8c8a3310af0076b6f33f955cb2Jean-Michel Trivi * through {@link RemoteControlClient#setMetadataUpdateListener(OnMetadataUpdateListener)}. 779f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi */ 7807ddd226e7c6e759feaf2747a90be1cc06acf37a3Jean-Michel Trivi public interface OnMetadataUpdateListener { 781f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi /** 782b23cd118ce3339589fffd40ecf1aa9c5816b3438Jean-Michel Trivi * Called on the implementer to notify that the metadata field for the given key has 78388183e67d4628e8c8a3310af0076b6f33f955cb2Jean-Michel Trivi * been updated to the new value. 78488183e67d4628e8c8a3310af0076b6f33f955cb2Jean-Michel Trivi * @param key the identifier of the updated metadata field. 78588183e67d4628e8c8a3310af0076b6f33f955cb2Jean-Michel Trivi * @param newValue the Object storing the new value for the key. 786f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi */ 78788183e67d4628e8c8a3310af0076b6f33f955cb2Jean-Michel Trivi public abstract void onMetadataUpdate(int key, Object newValue); 788f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi } 789f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi 790f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi /** 791b23cd118ce3339589fffd40ecf1aa9c5816b3438Jean-Michel Trivi * Sets the listener to be called whenever the metadata is updated. 792b23cd118ce3339589fffd40ecf1aa9c5816b3438Jean-Michel Trivi * New metadata values will be received in the same thread as the one in which 793b23cd118ce3339589fffd40ecf1aa9c5816b3438Jean-Michel Trivi * RemoteControlClient was created. 794b23cd118ce3339589fffd40ecf1aa9c5816b3438Jean-Michel Trivi * @param l the metadata update listener 795f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi */ 796f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi public void setMetadataUpdateListener(OnMetadataUpdateListener l) { 797f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi synchronized(mCacheLock) { 798f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi mMetadataUpdateListener = l; 799f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi } 800f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi } 801f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi 802f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi 803f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi /** 804bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi * Interface definition for a callback to be invoked when the media playback position is 805bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi * requested to be updated. 8063261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi * @see RemoteControlClient#FLAG_KEY_MEDIA_POSITION_UPDATE 807bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi */ 808bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi public interface OnPlaybackPositionUpdateListener { 809bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi /** 8103261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi * Called on the implementer to notify it that the playback head should be set at the given 811bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi * position. If the position can be changed from its current value, the implementor of 8123fbf67e217fb489fe7318a9e43d8ae86646eb4ccJean-Michel Trivi * the interface must also update the playback position using 813e63b0609c3b5f6c21d4e006ee9ddd3ba98a4e684Scott Main * {@link #setPlaybackState(int, long, float)} to reflect the actual new 814bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi * position being used, regardless of whether it differs from the requested position. 8153fbf67e217fb489fe7318a9e43d8ae86646eb4ccJean-Michel Trivi * Failure to do so would cause the system to not know the new actual playback position, 8163fbf67e217fb489fe7318a9e43d8ae86646eb4ccJean-Michel Trivi * and user interface components would fail to show the user where playback resumed after 8173fbf67e217fb489fe7318a9e43d8ae86646eb4ccJean-Michel Trivi * the position was updated. 818bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi * @param newPositionMs the new requested position in the current media, expressed in ms. 819bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi */ 820bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi void onPlaybackPositionUpdate(long newPositionMs); 821bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi } 822bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi 823bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi /** 8243261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi * Interface definition for a callback to be invoked when the media playback position is 8253261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi * queried. 8263261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi * @see RemoteControlClient#FLAG_KEY_MEDIA_POSITION_UPDATE 8273261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi */ 828915747730060dff71b5b2ca7e4ee4073024fc24eJean-Michel Trivi public interface OnGetPlaybackPositionListener { 8293261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi /** 8303261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi * Called on the implementer of the interface to query the current playback position. 8313261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi * @return a negative value if the current playback position (or the last valid playback 8323261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi * position) is not known, or a zero or positive value expressed in ms indicating the 8333261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi * current position, or the last valid known position. 8343261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi */ 835915747730060dff71b5b2ca7e4ee4073024fc24eJean-Michel Trivi long onGetPlaybackPosition(); 8363261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi } 8373261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi 8383261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi /** 8393261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi * Sets the listener to be called whenever the media playback position is requested 840bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi * to be updated. 841bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi * Notifications will be received in the same thread as the one in which RemoteControlClient 842bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi * was created. 843915747730060dff71b5b2ca7e4ee4073024fc24eJean-Michel Trivi * @param l the position update listener to be called 844bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi */ 845bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi public void setPlaybackPositionUpdateListener(OnPlaybackPositionUpdateListener l) { 846bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi synchronized(mCacheLock) { 847bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi mPositionUpdateListener = l; 8483261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi } 8493261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi } 8503261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi 8513261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi /** 8523261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi * Sets the listener to be called whenever the media current playback position is needed. 8533261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi * Queries will be received in the same thread as the one in which RemoteControlClient 8543261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi * was created. 855915747730060dff71b5b2ca7e4ee4073024fc24eJean-Michel Trivi * @param l the listener to be called to retrieve the playback position 8563261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi */ 857915747730060dff71b5b2ca7e4ee4073024fc24eJean-Michel Trivi public void setOnGetPlaybackPositionListener(OnGetPlaybackPositionListener l) { 8583261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi synchronized(mCacheLock) { 8593261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi mPositionProvider = l; 860521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi if ((mPositionProvider != null) && (mEventHandler != null) 861521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi && playbackPositionShouldMove(mPlaybackState)) { 862521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi // playback position is already moving, but now we have a position provider, 863521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi // so schedule a drift check right now 864521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi mEventHandler.sendMessageDelayed( 865521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi mEventHandler.obtainMessage(MSG_POSITION_DRIFT_CHECK), 866521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi 0 /*check now*/); 867521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi } 868bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi } 869bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi } 870bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi 871bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi /** 872bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi * @hide 873bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi * Flag to reflect that the application controlling this RemoteControlClient sends playback 874bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi * position updates. The playback position being "readable" is considered from the application's 875bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi * point of view. 876bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi */ 877bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi public static int MEDIA_POSITION_READABLE = 1 << 0; 878bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi /** 879bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi * @hide 880bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi * Flag to reflect that the application controlling this RemoteControlClient can receive 881bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi * playback position updates. The playback position being "writable" 882bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi * is considered from the application's point of view. 883bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi */ 884bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi public static int MEDIA_POSITION_WRITABLE = 1 << 1; 885bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi 8863114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi /** @hide */ 8873114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi public final static int DEFAULT_PLAYBACK_VOLUME_HANDLING = PLAYBACK_VOLUME_VARIABLE; 8883114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi /** @hide */ 8893114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi // hard-coded to the same number of steps as AudioService.MAX_STREAM_VOLUME[STREAM_MUSIC] 8903114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi public final static int DEFAULT_PLAYBACK_VOLUME = 15; 8913114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi 892178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi /** 8934426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * Lock for all cached data 8944426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi */ 8954426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi private final Object mCacheLock = new Object(); 8964426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi /** 8974426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * Cache for the playback state. 8984426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * Access synchronized on mCacheLock 899178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi */ 9004426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi private int mPlaybackState = PLAYSTATE_NONE; 9014426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi /** 90268622396b62f9084781add1e12f4d513b633ab54Jean-Michel Trivi * Time of last play state change 90368622396b62f9084781add1e12f4d513b633ab54Jean-Michel Trivi * Access synchronized on mCacheLock 90468622396b62f9084781add1e12f4d513b633ab54Jean-Michel Trivi */ 90568622396b62f9084781add1e12f4d513b633ab54Jean-Michel Trivi private long mPlaybackStateChangeTimeMs = 0; 90668622396b62f9084781add1e12f4d513b633ab54Jean-Michel Trivi /** 907bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi * Last playback position in ms reported by the user 908bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi */ 909bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi private long mPlaybackPositionMs = PLAYBACK_POSITION_INVALID; 910bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi /** 911bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi * Last playback speed reported by the user 912bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi */ 913bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi private float mPlaybackSpeed = PLAYBACK_SPEED_1X; 914bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi /** 9154426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * Cache for the artwork bitmap. 9164426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * Access synchronized on mCacheLock 9174da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi * Artwork and metadata are not kept in one Bundle because the bitmap sometimes needs to be 9184da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi * accessed to be resized, in which case a copy will be made. This would add overhead in 9194da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi * Bundle operations. 9204426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi */ 9214a5700556191c835116ec2a6997a4f16f464ac9dJean-Michel Trivi private Bitmap mOriginalArtwork; 9224426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi /** 9234426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * Cache for the transport control mask. 9244426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * Access synchronized on mCacheLock 9254426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi */ 9264426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi private int mTransportControlFlags = FLAGS_KEY_MEDIA_NONE; 9274426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi /** 9284426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * Cache for the metadata strings. 9294426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * Access synchronized on mCacheLock 93030c918ce7fbe171944b28fc91b3f22b3d631872dGlenn Kasten * This is re-initialized in apply() and so cannot be final. 9314426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi */ 9324426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi private Bundle mMetadata = new Bundle(); 9334426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi /** 934bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi * Listener registered by user of RemoteControlClient to receive requests for playback position 935bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi * update requests. 936bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi */ 937bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi private OnPlaybackPositionUpdateListener mPositionUpdateListener; 938bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi /** 9393261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi * Provider registered by user of RemoteControlClient to provide the current playback position. 9403261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi */ 941915747730060dff71b5b2ca7e4ee4073024fc24eJean-Michel Trivi private OnGetPlaybackPositionListener mPositionProvider; 9423261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi /** 943f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi * Listener registered by user of RemoteControlClient to receive edit changes to metadata 944f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi * it exposes. 945f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi */ 946f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi private OnMetadataUpdateListener mMetadataUpdateListener; 947f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi /** 948bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi * The current remote control client generation ID across the system, as known by this object 9494426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi */ 9504426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi private int mCurrentClientGenId = -1; 9514426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi 9524426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi /** 953f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi * The media button intent description associated with this remote control client 954bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi * (can / should include target component for intent handling, used when persisting media 955bc43b4c2f24fd03c0d0546895c97918c1736d9fbJean-Michel Trivi * button event receiver across reboots). 9564426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi */ 957f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi private final PendingIntent mRcMediaIntent; 9584426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi 9594426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi /** 960c3c4babf8424f65b3d3d2700f60fae6e94e9cd00Jean-Michel Trivi * Reflects whether any "plugged in" IRemoteControlDisplay has mWantsPositonSync set to true. 961c3c4babf8424f65b3d3d2700f60fae6e94e9cd00Jean-Michel Trivi */ 962c3c4babf8424f65b3d3d2700f60fae6e94e9cd00Jean-Michel Trivi // TODO consider using a ref count for IRemoteControlDisplay requiring sync instead 963c3c4babf8424f65b3d3d2700f60fae6e94e9cd00Jean-Michel Trivi private boolean mNeedsPositionSync = false; 964c3c4babf8424f65b3d3d2700f60fae6e94e9cd00Jean-Michel Trivi 965c3c4babf8424f65b3d3d2700f60fae6e94e9cd00Jean-Michel Trivi /** 966f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik * Cache for the current playback state using Session APIs. 967f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik */ 968c785a78fb483fe54012175c53d3758b2412de7b9RoboErik private PlaybackState mSessionPlaybackState = null; 969f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik 970f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik /** 971f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik * Cache for metadata using Session APIs. This is re-initialized in apply(). 972f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik */ 973f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik private MediaMetadata mMediaMetadata; 974f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik 975f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik /** 9764426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * @hide 977f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi * Accessor to media button intent description (includes target component) 9784426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi */ 979f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi public PendingIntent getRcMediaIntent() { 980f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi return mRcMediaIntent; 9814426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 9824426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi 9833114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi /** 9843114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * @hide 9853114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * Default value for the unique identifier 9863114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi */ 9873114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi public final static int RCSE_ID_UNREGISTERED = -1; 9881357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi 989f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik // USE_SESSIONS 990477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik private MediaSession.Callback mTransportListener = new MediaSession.Callback() { 991f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik 992f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik @Override 993f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik public void onSeekTo(long pos) { 994f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik RemoteControlClient.this.onSeekTo(mCurrentClientGenId, pos); 995f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik } 996f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik 997f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik @Override 99879fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik public void onSetRating(Rating rating) { 999f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik if ((mTransportControlFlags & FLAG_KEY_MEDIA_RATING) != 0) { 1000430fc48865e5a371b08f180390946b96d73848feRoboErik onUpdateMetadata(mCurrentClientGenId, MetadataEditor.RATING_KEY_BY_USER, rating); 1001f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik } 1002f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik } 1003f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik }; 1004f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik 10054426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi private EventHandler mEventHandler; 1006521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi private final static int MSG_POSITION_DRIFT_CHECK = 11; 10074426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi 10084426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi private class EventHandler extends Handler { 10094426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi public EventHandler(RemoteControlClient rcc, Looper looper) { 10104426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi super(looper); 10114426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 10124426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi 10134426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi @Override 10144426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi public void handleMessage(Message msg) { 10154426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi switch(msg.what) { 1016521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi case MSG_POSITION_DRIFT_CHECK: 1017521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi onPositionDriftCheck(); 1018521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi break; 10194426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi default: 10204426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi Log.e(TAG, "Unknown event " + msg.what + " in RemoteControlClient handler"); 10214426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 10224426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 10234426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 10244426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi 10253114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi //=========================================================== 10263114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi // Message handlers 10273114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi 10283261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi private void onSeekTo(int generationId, long timeMs) { 10293261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi synchronized (mCacheLock) { 10303261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi if ((mCurrentClientGenId == generationId) && (mPositionUpdateListener != null)) { 10313261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi mPositionUpdateListener.onPlaybackPositionUpdate(timeMs); 10323261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi } 10333261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi } 10343261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi } 10353261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi 103688183e67d4628e8c8a3310af0076b6f33f955cb2Jean-Michel Trivi private void onUpdateMetadata(int generationId, int key, Object value) { 1037f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi synchronized (mCacheLock) { 1038f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi if ((mCurrentClientGenId == generationId) && (mMetadataUpdateListener != null)) { 103988183e67d4628e8c8a3310af0076b6f33f955cb2Jean-Michel Trivi mMetadataUpdateListener.onMetadataUpdate(key, value); 1040f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi } 1041f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi } 1042f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi } 1043f823fc4dba2df5cf5f00e13361f2db93c81f6961Jean-Michel Trivi 10443114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi //=========================================================== 10453114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi // Internal utilities 10463114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi 10474426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi /** 1048521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi * Returns whether, for the given playback state, the playback position is expected to 1049521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi * be changing. 1050521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi * @param playstate the playback state to evaluate 1051521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi * @return true during any form of playback, false if it's not playing anything while in this 1052521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi * playback state 1053521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi */ 1054f8895248e2ac4dbb46622f3e04c7256f03175b4fAdam Powell static boolean playbackPositionShouldMove(int playstate) { 1055521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi switch(playstate) { 1056521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi case PLAYSTATE_STOPPED: 1057521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi case PLAYSTATE_PAUSED: 1058521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi case PLAYSTATE_BUFFERING: 1059521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi case PLAYSTATE_ERROR: 1060521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi case PLAYSTATE_SKIPPING_FORWARDS: 1061521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi case PLAYSTATE_SKIPPING_BACKWARDS: 1062521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi return false; 1063521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi case PLAYSTATE_PLAYING: 1064521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi case PLAYSTATE_FAST_FORWARDING: 1065521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi case PLAYSTATE_REWINDING: 1066521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi default: 1067521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi return true; 1068521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi } 1069521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi } 1070521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi 1071521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi /** 1072521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi * Period for playback position drift checks, 15s when playing at 1x or slower. 1073521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi */ 1074521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi private final static long POSITION_REFRESH_PERIOD_PLAYING_MS = 15000; 1075521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi /** 1076521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi * Minimum period for playback position drift checks, never more often when every 2s, when 1077521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi * fast forwarding or rewinding. 1078521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi */ 1079521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi private final static long POSITION_REFRESH_PERIOD_MIN_MS = 2000; 1080521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi /** 1081521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi * The value above which the difference between client-reported playback position and 1082521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi * estimated position is considered a drift. 1083521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi */ 1084521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi private final static long POSITION_DRIFT_MAX_MS = 500; 1085521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi /** 1086521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi * Compute the period at which the estimated playback position should be compared against the 1087521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi * actual playback position. Is a funciton of playback speed. 1088521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi * @param speed 1.0f is normal playback speed 1089521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi * @return the period in ms 1090521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi */ 1091521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi private static long getCheckPeriodFromSpeed(float speed) { 1092521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi if (Math.abs(speed) <= 1.0f) { 1093521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi return POSITION_REFRESH_PERIOD_PLAYING_MS; 1094521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi } else { 1095521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi return Math.max((long)(POSITION_REFRESH_PERIOD_PLAYING_MS / Math.abs(speed)), 1096521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi POSITION_REFRESH_PERIOD_MIN_MS); 1097521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi } 1098521e68e76cfdcf297d0de056032dc142d4939fa0Jean-Michel Trivi } 1099178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi} 1100