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; 213114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Triviimport android.content.Context; 226e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Triviimport android.content.Intent; 23178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Triviimport android.graphics.Bitmap; 244426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Triviimport android.graphics.Canvas; 254426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Triviimport android.graphics.Paint; 264426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Triviimport android.graphics.RectF; 275ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Triviimport android.media.MediaMetadataRetriever; 284426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Triviimport android.os.Bundle; 294426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Triviimport android.os.Handler; 303114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Triviimport android.os.IBinder; 314426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Triviimport android.os.Looper; 324426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Triviimport android.os.Message; 334426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Triviimport android.os.RemoteException; 343114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Triviimport android.os.ServiceManager; 3568622396b62f9084781add1e12f4d513b633ab54Jean-Michel Triviimport android.os.SystemClock; 364426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Triviimport android.util.Log; 374426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi 385ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Triviimport java.lang.IllegalArgumentException; 39178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi 40178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi/** 414426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * RemoteControlClient enables exposing information meant to be consumed by remote controls 42466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * capable of displaying metadata, artwork and media transport control buttons. 43ad87f5b40f2a3fd2d506dc15e00b8af28a8fa2baJean-Michel Trivi * 44ad87f5b40f2a3fd2d506dc15e00b8af28a8fa2baJean-Michel Trivi * <p>A remote control client object is associated with a media button event receiver. This 45466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * event receiver must have been previously registered with 46466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * {@link AudioManager#registerMediaButtonEventReceiver(ComponentName)} before the 47466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * RemoteControlClient can be registered through 484426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * {@link AudioManager#registerRemoteControlClient(RemoteControlClient)}. 49ad87f5b40f2a3fd2d506dc15e00b8af28a8fa2baJean-Michel Trivi * 50ad87f5b40f2a3fd2d506dc15e00b8af28a8fa2baJean-Michel Trivi * <p>Here is an example of creating a RemoteControlClient instance after registering a media 51ad87f5b40f2a3fd2d506dc15e00b8af28a8fa2baJean-Michel Trivi * button event receiver: 52ad87f5b40f2a3fd2d506dc15e00b8af28a8fa2baJean-Michel Trivi * <pre>ComponentName myEventReceiver = new ComponentName(getPackageName(), MyRemoteControlEventReceiver.class.getName()); 53ad87f5b40f2a3fd2d506dc15e00b8af28a8fa2baJean-Michel Trivi * AudioManager myAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); 54ad87f5b40f2a3fd2d506dc15e00b8af28a8fa2baJean-Michel Trivi * myAudioManager.registerMediaButtonEventReceiver(myEventReceiver); 55ad87f5b40f2a3fd2d506dc15e00b8af28a8fa2baJean-Michel Trivi * // build the PendingIntent for the remote control client 56ad87f5b40f2a3fd2d506dc15e00b8af28a8fa2baJean-Michel Trivi * Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON); 57ad87f5b40f2a3fd2d506dc15e00b8af28a8fa2baJean-Michel Trivi * mediaButtonIntent.setComponent(myEventReceiver); 58ad87f5b40f2a3fd2d506dc15e00b8af28a8fa2baJean-Michel Trivi * PendingIntent mediaPendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, mediaButtonIntent, 0); 59ad87f5b40f2a3fd2d506dc15e00b8af28a8fa2baJean-Michel Trivi * // create and register the remote control client 60ad87f5b40f2a3fd2d506dc15e00b8af28a8fa2baJean-Michel Trivi * RemoteControlClient myRemoteControlClient = new RemoteControlClient(mediaPendingIntent); 61ad87f5b40f2a3fd2d506dc15e00b8af28a8fa2baJean-Michel Trivi * myAudioManager.registerRemoteControlClient(myRemoteControlClient);</pre> 62178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi */ 634426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivipublic class RemoteControlClient 64178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi{ 654426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi private final static String TAG = "RemoteControlClient"; 664426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi 67178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi /** 68178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * Playback state of a RemoteControlClient which is stopped. 69178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * 704426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * @see #setPlaybackState(int) 71178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi */ 72178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi public final static int PLAYSTATE_STOPPED = 1; 73178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi /** 74178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * Playback state of a RemoteControlClient which is paused. 75178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * 764426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * @see #setPlaybackState(int) 77178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi */ 78178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi public final static int PLAYSTATE_PAUSED = 2; 79178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi /** 80178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * Playback state of a RemoteControlClient which is playing media. 81178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * 824426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * @see #setPlaybackState(int) 83178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi */ 84178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi public final static int PLAYSTATE_PLAYING = 3; 85178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi /** 86178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * Playback state of a RemoteControlClient which is fast forwarding in the media 87178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * it is currently playing. 88178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * 894426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * @see #setPlaybackState(int) 90178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi */ 91178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi public final static int PLAYSTATE_FAST_FORWARDING = 4; 92178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi /** 93178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * Playback state of a RemoteControlClient which is fast rewinding in the media 94178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * it is currently playing. 95178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * 964426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * @see #setPlaybackState(int) 97178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi */ 98178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi public final static int PLAYSTATE_REWINDING = 5; 99178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi /** 100178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * Playback state of a RemoteControlClient which is skipping to the next 101178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * logical chapter (such as a song in a playlist) in the media it is currently playing. 102178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * 1034426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * @see #setPlaybackState(int) 104178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi */ 105178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi public final static int PLAYSTATE_SKIPPING_FORWARDS = 6; 106178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi /** 107178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * Playback state of a RemoteControlClient which is skipping back to the previous 108178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * logical chapter (such as a song in a playlist) in the media it is currently playing. 109178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * 1104426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * @see #setPlaybackState(int) 111178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi */ 112178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi public final static int PLAYSTATE_SKIPPING_BACKWARDS = 7; 113178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi /** 114178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * Playback state of a RemoteControlClient which is buffering data to play before it can 115178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * start or resume playback. 116178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * 1174426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * @see #setPlaybackState(int) 118178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi */ 119178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi public final static int PLAYSTATE_BUFFERING = 8; 120178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi /** 121178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * Playback state of a RemoteControlClient which cannot perform any playback related 122178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * operation because of an internal error. Examples of such situations are no network 123178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * connectivity when attempting to stream data from a server, or expired user credentials 124178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * when trying to play subscription-based content. 125178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * 1264426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * @see #setPlaybackState(int) 127178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi */ 128178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi public final static int PLAYSTATE_ERROR = 9; 1294426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi /** 1304426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * @hide 131466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * The value of a playback state when none has been declared. 132466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * Intentionally hidden as an application shouldn't set such a playback state value. 1334426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi */ 1344426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi public final static int PLAYSTATE_NONE = 0; 135178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi 136178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi /** 1371357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @hide 1383114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * The default playback type, "local", indicating the presentation of the media is happening on 1393114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * the same device (e.g. a phone, a tablet) as where it is controlled from. 1403114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi */ 1413114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi public final static int PLAYBACK_TYPE_LOCAL = 0; 1423114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi /** 1431357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @hide 1443114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * A playback type indicating the presentation of the media is happening on 1453114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * a different device (i.e. the remote device) than where it is controlled from. 1463114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi */ 1473114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi public final static int PLAYBACK_TYPE_REMOTE = 1; 1483114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi private final static int PLAYBACK_TYPE_MIN = PLAYBACK_TYPE_LOCAL; 1493114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi private final static int PLAYBACK_TYPE_MAX = PLAYBACK_TYPE_REMOTE; 1503114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi /** 1511357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @hide 1523114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * Playback information indicating the playback volume is fixed, i.e. it cannot be controlled 1533114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * from this object. An example of fixed playback volume is a remote player, playing over HDMI 1543114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * where the user prefer to control the volume on the HDMI sink, rather than attenuate at the 1553114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * source. 1563114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * @see #PLAYBACKINFO_VOLUME_HANDLING. 1573114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi */ 1583114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi public final static int PLAYBACK_VOLUME_FIXED = 0; 1593114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi /** 1601357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @hide 1613114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * Playback information indicating the playback volume is variable and can be controlled from 1623114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * this object. 1633114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * @see #PLAYBACKINFO_VOLUME_HANDLING. 1643114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi */ 1653114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi public final static int PLAYBACK_VOLUME_VARIABLE = 1; 1663114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi /** 1673114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * @hide (to be un-hidden) 1683114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * The playback information value indicating the value of a given information type is invalid. 1693114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * @see #PLAYBACKINFO_VOLUME_HANDLING. 1703114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi */ 1713114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi public final static int PLAYBACKINFO_INVALID_VALUE = Integer.MIN_VALUE; 1723114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi 1733114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi //========================================== 1743114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi // Public keys for playback information 1753114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi /** 1761357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @hide 1773114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * Playback information that defines the type of playback associated with this 1783114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * RemoteControlClient. See {@link #PLAYBACK_TYPE_LOCAL} and {@link #PLAYBACK_TYPE_REMOTE}. 1793114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi */ 1803114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi public final static int PLAYBACKINFO_PLAYBACK_TYPE = 1; 1813114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi /** 1821357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @hide 1833114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * Playback information that defines at what volume the playback associated with this 1843114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * RemoteControlClient is performed. This information is only used when the playback type is not 1853114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * local (see {@link #PLAYBACKINFO_PLAYBACK_TYPE}). 1863114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi */ 1873114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi public final static int PLAYBACKINFO_VOLUME = 2; 1883114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi /** 1891357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @hide 1903114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * Playback information that defines the maximum volume volume value that is supported 1913114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * by the playback associated with this RemoteControlClient. This information is only used 1923114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * when the playback type is not local (see {@link #PLAYBACKINFO_PLAYBACK_TYPE}). 1933114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi */ 1943114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi public final static int PLAYBACKINFO_VOLUME_MAX = 3; 1953114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi /** 1961357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @hide 1973114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * Playback information that defines how volume is handled for the presentation of the media. 1983114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * @see #PLAYBACK_VOLUME_FIXED 1993114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * @see #PLAYBACK_VOLUME_VARIABLE 2003114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi */ 2013114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi public final static int PLAYBACKINFO_VOLUME_HANDLING = 4; 2023114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi /** 2031357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @hide 2043114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * Playback information that defines over what stream type the media is presented. 2053114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi */ 2063114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi public final static int PLAYBACKINFO_USES_STREAM = 5; 2073114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi 2083114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi //========================================== 2093114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi // Private keys for playback information 2103114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi /** 2113114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * @hide 2123114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * Used internally to relay playback state (set by the application with 2133114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * {@link #setPlaybackState(int)}) to AudioService 2143114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi */ 2153114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi public final static int PLAYBACKINFO_PLAYSTATE = 255; 2163114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi 2173114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi 2183114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi /** 219178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * Flag indicating a RemoteControlClient makes use of the "previous" media key. 220178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * 2214426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * @see #setTransportControlFlags(int) 222178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * @see android.view.KeyEvent#KEYCODE_MEDIA_PREVIOUS 223178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi */ 224178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi public final static int FLAG_KEY_MEDIA_PREVIOUS = 1 << 0; 225178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi /** 226466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * Flag indicating a RemoteControlClient makes use of the "rewind" media key. 227178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * 2284426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * @see #setTransportControlFlags(int) 229178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * @see android.view.KeyEvent#KEYCODE_MEDIA_REWIND 230178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi */ 231178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi public final static int FLAG_KEY_MEDIA_REWIND = 1 << 1; 232178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi /** 233178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * Flag indicating a RemoteControlClient makes use of the "play" media key. 234178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * 2354426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * @see #setTransportControlFlags(int) 236178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * @see android.view.KeyEvent#KEYCODE_MEDIA_PLAY 237178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi */ 238178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi public final static int FLAG_KEY_MEDIA_PLAY = 1 << 2; 239178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi /** 240178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * Flag indicating a RemoteControlClient makes use of the "play/pause" media key. 241178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * 2424426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * @see #setTransportControlFlags(int) 243178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * @see android.view.KeyEvent#KEYCODE_MEDIA_PLAY_PAUSE 244178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi */ 245178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi public final static int FLAG_KEY_MEDIA_PLAY_PAUSE = 1 << 3; 246178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi /** 247178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * Flag indicating a RemoteControlClient makes use of the "pause" media key. 248178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * 2494426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * @see #setTransportControlFlags(int) 250178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * @see android.view.KeyEvent#KEYCODE_MEDIA_PAUSE 251178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi */ 252178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi public final static int FLAG_KEY_MEDIA_PAUSE = 1 << 4; 253178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi /** 254178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * Flag indicating a RemoteControlClient makes use of the "stop" media key. 255178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * 2564426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * @see #setTransportControlFlags(int) 257178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * @see android.view.KeyEvent#KEYCODE_MEDIA_STOP 258178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi */ 259178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi public final static int FLAG_KEY_MEDIA_STOP = 1 << 5; 260178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi /** 261178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * Flag indicating a RemoteControlClient makes use of the "fast forward" media key. 262178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * 2634426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * @see #setTransportControlFlags(int) 264178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * @see android.view.KeyEvent#KEYCODE_MEDIA_FAST_FORWARD 265178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi */ 266178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi public final static int FLAG_KEY_MEDIA_FAST_FORWARD = 1 << 6; 267178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi /** 268178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * Flag indicating a RemoteControlClient makes use of the "next" media key. 269178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * 2704426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * @see #setTransportControlFlags(int) 271178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * @see android.view.KeyEvent#KEYCODE_MEDIA_NEXT 272178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi */ 273178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi public final static int FLAG_KEY_MEDIA_NEXT = 1 << 7; 274178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi 275178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi /** 2764426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * @hide 277466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * The flags for when no media keys are declared supported. 278466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * Intentionally hidden as an application shouldn't set the transport control flags 279466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * to this value. 2804426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi */ 2814426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi public final static int FLAGS_KEY_MEDIA_NONE = 0; 2824426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi 2834426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi /** 2844426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * @hide 2854426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * Flag used to signal some type of metadata exposed by the RemoteControlClient is requested. 286178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi */ 2874426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi public final static int FLAG_INFORMATION_REQUEST_METADATA = 1 << 0; 288178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi /** 2894426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * @hide 290178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * Flag used to signal that the transport control buttons supported by the 291466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * RemoteControlClient are requested. 292178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * This can for instance happen when playback is at the end of a playlist, and the "next" 293178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * operation is not supported anymore. 294178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi */ 2954426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi public final static int FLAG_INFORMATION_REQUEST_KEY_MEDIA = 1 << 1; 296178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi /** 2974426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * @hide 298466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * Flag used to signal that the playback state of the RemoteControlClient is requested. 299178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi */ 3004426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi public final static int FLAG_INFORMATION_REQUEST_PLAYSTATE = 1 << 2; 301178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi /** 3024426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * @hide 303466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * Flag used to signal that the album art for the RemoteControlClient is requested. 304178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi */ 3054426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi public final static int FLAG_INFORMATION_REQUEST_ALBUM_ART = 1 << 3; 3064426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi 3074426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi /** 3086e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi * Class constructor. 3096e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi * @param mediaButtonIntent The intent that will be sent for the media button events sent 3106e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi * by remote controls. 3116e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi * This intent needs to have been constructed with the {@link Intent#ACTION_MEDIA_BUTTON} 3126e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi * action, and have a component that will handle the intent (set with 3136e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi * {@link Intent#setComponent(ComponentName)}) registered with 3146e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi * {@link AudioManager#registerMediaButtonEventReceiver(ComponentName)} 3156e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi * before this new RemoteControlClient can itself be registered with 3166e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi * {@link AudioManager#registerRemoteControlClient(RemoteControlClient)}. 3176e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi * @see AudioManager#registerMediaButtonEventReceiver(ComponentName) 3186e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi * @see AudioManager#registerRemoteControlClient(RemoteControlClient) 3196e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi */ 3206e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi public RemoteControlClient(PendingIntent mediaButtonIntent) { 321f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi mRcMediaIntent = mediaButtonIntent; 3226e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi 3236e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi Looper looper; 3246e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi if ((looper = Looper.myLooper()) != null) { 3256e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi mEventHandler = new EventHandler(this, looper); 3266e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi } else if ((looper = Looper.getMainLooper()) != null) { 3276e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi mEventHandler = new EventHandler(this, looper); 3286e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi } else { 3296e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi mEventHandler = null; 3306e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi Log.e(TAG, "RemoteControlClient() couldn't find main application thread"); 3316e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi } 3326e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi } 3336e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi 3346e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi /** 3356e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi * Class constructor for a remote control client whose internal event handling 3366e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi * happens on a user-provided Looper. 3376e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi * @param mediaButtonIntent The intent that will be sent for the media button events sent 3386e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi * by remote controls. 3396e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi * This intent needs to have been constructed with the {@link Intent#ACTION_MEDIA_BUTTON} 3406e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi * action, and have a component that will handle the intent (set with 3416e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi * {@link Intent#setComponent(ComponentName)}) registered with 3426e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi * {@link AudioManager#registerMediaButtonEventReceiver(ComponentName)} 3436e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi * before this new RemoteControlClient can itself be registered with 3446e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi * {@link AudioManager#registerRemoteControlClient(RemoteControlClient)}. 3456e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi * @param looper The Looper running the event loop. 3466e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi * @see AudioManager#registerMediaButtonEventReceiver(ComponentName) 3476e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi * @see AudioManager#registerRemoteControlClient(RemoteControlClient) 3486e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi */ 3496e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi public RemoteControlClient(PendingIntent mediaButtonIntent, Looper looper) { 350f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi mRcMediaIntent = mediaButtonIntent; 3516e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi 3526e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi mEventHandler = new EventHandler(this, looper); 3536e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi } 3546e920e6dac11c3ebf6c0c19402934834e9e491bfJean-Michel Trivi 3555ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi private static final int[] METADATA_KEYS_TYPE_STRING = { 3565ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi MediaMetadataRetriever.METADATA_KEY_ALBUM, 3575ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi MediaMetadataRetriever.METADATA_KEY_ALBUMARTIST, 3585ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi MediaMetadataRetriever.METADATA_KEY_TITLE, 3595ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi MediaMetadataRetriever.METADATA_KEY_ARTIST, 3605ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi MediaMetadataRetriever.METADATA_KEY_AUTHOR, 3615ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi MediaMetadataRetriever.METADATA_KEY_COMPILATION, 3625ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi MediaMetadataRetriever.METADATA_KEY_COMPOSER, 3635ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi MediaMetadataRetriever.METADATA_KEY_DATE, 3645ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi MediaMetadataRetriever.METADATA_KEY_GENRE, 3655ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi MediaMetadataRetriever.METADATA_KEY_TITLE, 3665ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi MediaMetadataRetriever.METADATA_KEY_WRITER }; 3675ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi private static final int[] METADATA_KEYS_TYPE_LONG = { 3685ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi MediaMetadataRetriever.METADATA_KEY_CD_TRACK_NUMBER, 3695ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi MediaMetadataRetriever.METADATA_KEY_DISC_NUMBER, 3705ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi MediaMetadataRetriever.METADATA_KEY_DURATION }; 3715ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi 3724426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi /** 3734426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * Class used to modify metadata in a {@link RemoteControlClient} object. 374466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * Use {@link RemoteControlClient#editMetadata(boolean)} to create an instance of an editor, 375466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * on which you set the metadata for the RemoteControlClient instance. Once all the information 376466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * has been set, use {@link #apply()} to make it the new metadata that should be displayed 377466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * for the associated client. Once the metadata has been "applied", you cannot reuse this 378466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * instance of the MetadataEditor. 3794426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi */ 3804426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi public class MetadataEditor { 381466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi /** 382466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * @hide 383466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi */ 3844da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi protected boolean mMetadataChanged; 385466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi /** 386466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * @hide 387466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi */ 3884da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi protected boolean mArtworkChanged; 389466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi /** 390466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * @hide 391466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi */ 3924da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi protected Bitmap mEditorArtwork; 393466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi /** 394466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * @hide 395466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi */ 3964da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi protected Bundle mEditorMetadata; 3974da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi private boolean mApplied = false; 3984da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi 3994da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi // only use RemoteControlClient.editMetadata() to get a MetadataEditor instance 4004da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi private MetadataEditor() { } 4014da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi /** 4024da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi * @hide 4034da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi */ 4044da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi public Object clone() throws CloneNotSupportedException { 4054da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi throw new CloneNotSupportedException(); 4064426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 4074426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi 4084da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi /** 4095ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi * The metadata key for the content artwork / album art. 4105ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi */ 411466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi public final static int BITMAP_KEY_ARTWORK = 100; 412466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi /** 413466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * @hide 414466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * TODO(jmtrivi) have lockscreen and music move to the new key name 415466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi */ 416466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi public final static int METADATA_KEY_ARTWORK = BITMAP_KEY_ARTWORK; 4175ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi 4185ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi /** 4194da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi * Adds textual information to be displayed. 4204da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi * Note that none of the information added after {@link #apply()} has been called, 4214da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi * will be displayed. 422466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * @param key The identifier of a the metadata field to set. Valid values are 4234da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi * {@link android.media.MediaMetadataRetriever#METADATA_KEY_ALBUM}, 4244da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi * {@link android.media.MediaMetadataRetriever#METADATA_KEY_ALBUMARTIST}, 4254da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi * {@link android.media.MediaMetadataRetriever#METADATA_KEY_TITLE}, 4264da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi * {@link android.media.MediaMetadataRetriever#METADATA_KEY_ARTIST}, 4274da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi * {@link android.media.MediaMetadataRetriever#METADATA_KEY_AUTHOR}, 4284da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi * {@link android.media.MediaMetadataRetriever#METADATA_KEY_COMPILATION}, 4294da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi * {@link android.media.MediaMetadataRetriever#METADATA_KEY_COMPOSER}, 4304da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi * {@link android.media.MediaMetadataRetriever#METADATA_KEY_DATE}, 4314da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi * {@link android.media.MediaMetadataRetriever#METADATA_KEY_GENRE}, 4324da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi * {@link android.media.MediaMetadataRetriever#METADATA_KEY_TITLE}, 433466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * {@link android.media.MediaMetadataRetriever#METADATA_KEY_WRITER}. 434466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * @param value The text for the given key, or {@code null} to signify there is no valid 4354da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi * information for the field. 436466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * @return Returns a reference to the same MetadataEditor object, so you can chain put 437466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * calls together. 4384da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi */ 4395ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi public synchronized MetadataEditor putString(int key, String value) 4405ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi throws IllegalArgumentException { 4414da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi if (mApplied) { 4424da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi Log.e(TAG, "Can't edit a previously applied MetadataEditor"); 4434da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi return this; 4444da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi } 4455ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi if (!validTypeForKey(key, METADATA_KEYS_TYPE_STRING)) { 4465ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi throw(new IllegalArgumentException("Invalid type 'String' for key "+ key)); 4475ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi } 4484da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi mEditorMetadata.putString(String.valueOf(key), value); 4494da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi mMetadataChanged = true; 4504426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi return this; 4514426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 4524426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi 4534da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi /** 454466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * Adds numerical information to be displayed. 455466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * Note that none of the information added after {@link #apply()} has been called, 456466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * will be displayed. 4575ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi * @param key the identifier of a the metadata field to set. Valid values are 4585ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi * {@link android.media.MediaMetadataRetriever#METADATA_KEY_CD_TRACK_NUMBER}, 4595ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi * {@link android.media.MediaMetadataRetriever#METADATA_KEY_DISC_NUMBER}, 4605ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi * {@link android.media.MediaMetadataRetriever#METADATA_KEY_DURATION} (with a value 4615ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi * expressed in milliseconds), 4625ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi * {@link android.media.MediaMetadataRetriever#METADATA_KEY_YEAR}. 463466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * @param value The long value for the given key 464466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * @return Returns a reference to the same MetadataEditor object, so you can chain put 465466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * calls together. 4665ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi * @throws IllegalArgumentException 4674da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi */ 4685ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi public synchronized MetadataEditor putLong(int key, long value) 4695ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi throws IllegalArgumentException { 4705ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi if (mApplied) { 4715ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi Log.e(TAG, "Can't edit a previously applied MetadataEditor"); 4725ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi return this; 4735ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi } 4745ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi if (!validTypeForKey(key, METADATA_KEYS_TYPE_LONG)) { 4755ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi throw(new IllegalArgumentException("Invalid type 'long' for key "+ key)); 4765ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi } 4775ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi mEditorMetadata.putLong(String.valueOf(key), value); 4785ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi mMetadataChanged = true; 4795ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi return this; 4805ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi } 4814da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi 4824da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi /** 4834da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi * Sets the album / artwork picture to be displayed on the remote control. 484466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * @param key the identifier of the bitmap to set. The only valid value is 485466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * {@link #BITMAP_KEY_ARTWORK} 486466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * @param bitmap The bitmap for the artwork, or null if there isn't any. 487466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * @return Returns a reference to the same MetadataEditor object, so you can chain put 488466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * calls together. 4895ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi * @throws IllegalArgumentException 4904da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi * @see android.graphics.Bitmap 4914da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi */ 4925ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi public synchronized MetadataEditor putBitmap(int key, Bitmap bitmap) 4935ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi throws IllegalArgumentException { 4944da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi if (mApplied) { 4954da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi Log.e(TAG, "Can't edit a previously applied MetadataEditor"); 4964da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi return this; 4974da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi } 498466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi if (key != BITMAP_KEY_ARTWORK) { 4995ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi throw(new IllegalArgumentException("Invalid type 'Bitmap' for key "+ key)); 5004da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi } 5014da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi if ((mArtworkExpectedWidth > 0) && (mArtworkExpectedHeight > 0)) { 5024da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi mEditorArtwork = scaleBitmapIfTooBig(bitmap, 5034da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi mArtworkExpectedWidth, mArtworkExpectedHeight); 5044da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi } else { 5054da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi // no valid resize dimensions, store as is 5064da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi mEditorArtwork = bitmap; 5074da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi } 5084da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi mArtworkChanged = true; 5094da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi return this; 5104426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 511178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi 5124da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi /** 513466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * Clears all the metadata that has been set since the MetadataEditor instance was 514466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * created with {@link RemoteControlClient#editMetadata(boolean)}. 5154da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi */ 5164da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi public synchronized void clear() { 5174da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi if (mApplied) { 5184da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi Log.e(TAG, "Can't clear a previously applied MetadataEditor"); 5194da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi return; 5204da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi } 5214da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi mEditorMetadata.clear(); 5224da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi mEditorArtwork = null; 5234426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 524178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi 5254da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi /** 526466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * Associates all the metadata that has been set since the MetadataEditor instance was 527466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * created with {@link RemoteControlClient#editMetadata(boolean)}, or since 528466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * {@link #clear()} was called, with the RemoteControlClient. Once "applied", 529466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * this MetadataEditor cannot be reused to edit the RemoteControlClient's metadata. 5304da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi */ 5314da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi public synchronized void apply() { 5324da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi if (mApplied) { 5334da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi Log.e(TAG, "Can't apply a previously applied MetadataEditor"); 5344da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi return; 5354da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi } 5364da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi synchronized(mCacheLock) { 5374da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi // assign the edited data 5384da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi mMetadata = new Bundle(mEditorMetadata); 53934d0d300cac645b48cce5a1735f45e1102d4ef0eJean-Michel Trivi if ((mArtwork != null) && (!mArtwork.equals(mEditorArtwork))) { 54034d0d300cac645b48cce5a1735f45e1102d4ef0eJean-Michel Trivi mArtwork.recycle(); 54134d0d300cac645b48cce5a1735f45e1102d4ef0eJean-Michel Trivi } 5424da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi mArtwork = mEditorArtwork; 54334d0d300cac645b48cce5a1735f45e1102d4ef0eJean-Michel Trivi mEditorArtwork = null; 5444da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi if (mMetadataChanged & mArtworkChanged) { 5454da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi // send to remote control display if conditions are met 54644413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi sendMetadataWithArtwork_syncCacheLock(); 5474da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi } else if (mMetadataChanged) { 5484da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi // send to remote control display if conditions are met 5494da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi sendMetadata_syncCacheLock(); 5504da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi } else if (mArtworkChanged) { 5514da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi // send to remote control display if conditions are met 5524da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi sendArtwork_syncCacheLock(); 5534da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi } 5544da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi mApplied = true; 5554da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi } 5564426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 5574426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 5584426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi 5594426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi /** 560466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * Creates a {@link MetadataEditor}. 561466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * @param startEmpty Set to false if you want the MetadataEditor to contain the metadata that 562466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * was previously applied to the RemoteControlClient, or true if it is to be created empty. 563466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * @return a new MetadataEditor instance. 5644426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi */ 5654da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi public MetadataEditor editMetadata(boolean startEmpty) { 5664da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi MetadataEditor editor = new MetadataEditor(); 5674da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi if (startEmpty) { 5684da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi editor.mEditorMetadata = new Bundle(); 5694da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi editor.mEditorArtwork = null; 5704da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi editor.mMetadataChanged = true; 5714da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi editor.mArtworkChanged = true; 5724da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi } else { 5734da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi editor.mEditorMetadata = new Bundle(mMetadata); 5744da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi editor.mEditorArtwork = mArtwork; 5754da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi editor.mMetadataChanged = false; 5764da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi editor.mArtworkChanged = false; 5774426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 5784da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi return editor; 5794426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 5804426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi 5814426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi /** 5824426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * Sets the current playback state. 583466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * @param state The current playback state, one of the following values: 584178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * {@link #PLAYSTATE_STOPPED}, 585178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * {@link #PLAYSTATE_PAUSED}, 586178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * {@link #PLAYSTATE_PLAYING}, 587178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * {@link #PLAYSTATE_FAST_FORWARDING}, 588178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * {@link #PLAYSTATE_REWINDING}, 589178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * {@link #PLAYSTATE_SKIPPING_FORWARDS}, 590178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * {@link #PLAYSTATE_SKIPPING_BACKWARDS}, 591178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * {@link #PLAYSTATE_BUFFERING}, 592178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * {@link #PLAYSTATE_ERROR}. 593178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi */ 5944426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi public void setPlaybackState(int state) { 5954426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi synchronized(mCacheLock) { 59668622396b62f9084781add1e12f4d513b633ab54Jean-Michel Trivi if (mPlaybackState != state) { 59768622396b62f9084781add1e12f4d513b633ab54Jean-Michel Trivi // store locally 59868622396b62f9084781add1e12f4d513b633ab54Jean-Michel Trivi mPlaybackState = state; 59968622396b62f9084781add1e12f4d513b633ab54Jean-Michel Trivi // keep track of when the state change occurred 60068622396b62f9084781add1e12f4d513b633ab54Jean-Michel Trivi mPlaybackStateChangeTimeMs = SystemClock.elapsedRealtime(); 60168622396b62f9084781add1e12f4d513b633ab54Jean-Michel Trivi 60268622396b62f9084781add1e12f4d513b633ab54Jean-Michel Trivi // send to remote control display if conditions are met 60368622396b62f9084781add1e12f4d513b633ab54Jean-Michel Trivi sendPlaybackState_syncCacheLock(); 6043114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi // update AudioService 6053114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi sendAudioServiceNewPlaybackInfo_syncCacheLock(PLAYBACKINFO_PLAYSTATE, state); 60668622396b62f9084781add1e12f4d513b633ab54Jean-Michel Trivi } 6074426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 6084426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 609178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi 610178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi /** 6114426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * Sets the flags for the media transport control buttons that this client supports. 612466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi * @param transportControlFlags A combination of the following flags: 6134426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * {@link #FLAG_KEY_MEDIA_PREVIOUS}, 614178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * {@link #FLAG_KEY_MEDIA_REWIND}, 615178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * {@link #FLAG_KEY_MEDIA_PLAY}, 616178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * {@link #FLAG_KEY_MEDIA_PLAY_PAUSE}, 617178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * {@link #FLAG_KEY_MEDIA_PAUSE}, 618178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * {@link #FLAG_KEY_MEDIA_STOP}, 619178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * {@link #FLAG_KEY_MEDIA_FAST_FORWARD}, 620178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi * {@link #FLAG_KEY_MEDIA_NEXT} 621178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi */ 6224426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi public void setTransportControlFlags(int transportControlFlags) { 6234426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi synchronized(mCacheLock) { 6244426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi // store locally 6254426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi mTransportControlFlags = transportControlFlags; 6264426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi 6274426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi // send to remote control display if conditions are met 6284426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi sendTransportControlFlags_syncCacheLock(); 6294426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 6304426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 631178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi 6323114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi /** @hide */ 6333114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi public final static int DEFAULT_PLAYBACK_VOLUME_HANDLING = PLAYBACK_VOLUME_VARIABLE; 6343114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi /** @hide */ 6353114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi // hard-coded to the same number of steps as AudioService.MAX_STREAM_VOLUME[STREAM_MUSIC] 6363114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi public final static int DEFAULT_PLAYBACK_VOLUME = 15; 6373114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi 6383114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi private int mPlaybackType = PLAYBACK_TYPE_LOCAL; 6393114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi private int mPlaybackVolumeMax = DEFAULT_PLAYBACK_VOLUME; 6403114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi private int mPlaybackVolume = DEFAULT_PLAYBACK_VOLUME; 6413114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi private int mPlaybackVolumeHandling = DEFAULT_PLAYBACK_VOLUME_HANDLING; 6423114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi private int mPlaybackStream = AudioManager.STREAM_MUSIC; 6433114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi 6443114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi /** 6451357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @hide 6463114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * Set information describing information related to the playback of media so the system 6473114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * can implement additional behavior to handle non-local playback usecases. 6483114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * @param what a key to specify the type of information to set. Valid keys are 6493114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * {@link #PLAYBACKINFO_PLAYBACK_TYPE}, 6503114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * {@link #PLAYBACKINFO_USES_STREAM}, 6513114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * {@link #PLAYBACKINFO_VOLUME}, 6523114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * {@link #PLAYBACKINFO_VOLUME_MAX}, 6533114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * and {@link #PLAYBACKINFO_VOLUME_HANDLING}. 6543114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * @param value the value for the supplied information to set. 6553114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi */ 6563114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi public void setPlaybackInformation(int what, int value) { 6573114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi synchronized(mCacheLock) { 6583114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi switch (what) { 6593114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi case PLAYBACKINFO_PLAYBACK_TYPE: 6603114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi if ((value >= PLAYBACK_TYPE_MIN) && (value <= PLAYBACK_TYPE_MAX)) { 6613114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi if (mPlaybackType != value) { 6623114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi mPlaybackType = value; 6633114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi sendAudioServiceNewPlaybackInfo_syncCacheLock(what, value); 6643114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi } 6653114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi } else { 6663114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi Log.w(TAG, "using invalid value for PLAYBACKINFO_PLAYBACK_TYPE"); 6673114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi } 6683114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi break; 6693114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi case PLAYBACKINFO_VOLUME: 6703114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi if ((value > -1) && (value <= mPlaybackVolumeMax)) { 6713114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi if (mPlaybackVolume != value) { 6723114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi mPlaybackVolume = value; 6733114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi sendAudioServiceNewPlaybackInfo_syncCacheLock(what, value); 6743114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi } 6753114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi } else { 6763114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi Log.w(TAG, "using invalid value for PLAYBACKINFO_VOLUME"); 6773114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi } 6783114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi break; 6793114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi case PLAYBACKINFO_VOLUME_MAX: 6803114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi if (value > 0) { 6813114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi if (mPlaybackVolumeMax != value) { 6823114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi mPlaybackVolumeMax = value; 6833114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi sendAudioServiceNewPlaybackInfo_syncCacheLock(what, value); 6843114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi } 6853114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi } else { 6863114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi Log.w(TAG, "using invalid value for PLAYBACKINFO_VOLUME_MAX"); 6873114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi } 6883114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi break; 6893114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi case PLAYBACKINFO_USES_STREAM: 6903114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi if ((value >= 0) && (value < AudioSystem.getNumStreamTypes())) { 6913114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi mPlaybackStream = value; 6923114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi } else { 6933114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi Log.w(TAG, "using invalid value for PLAYBACKINFO_USES_STREAM"); 6943114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi } 6953114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi break; 6963114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi case PLAYBACKINFO_VOLUME_HANDLING: 6973114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi if ((value >= PLAYBACK_VOLUME_FIXED) && (value <= PLAYBACK_VOLUME_VARIABLE)) { 6983114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi if (mPlaybackVolumeHandling != value) { 6993114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi mPlaybackVolumeHandling = value; 7003114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi sendAudioServiceNewPlaybackInfo_syncCacheLock(what, value); 7013114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi } 7023114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi } else { 7033114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi Log.w(TAG, "using invalid value for PLAYBACKINFO_VOLUME_HANDLING"); 7043114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi } 7053114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi break; 7063114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi default: 7073114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi // not throwing an exception or returning an error if more keys are to be 7083114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi // supported in the future 7093114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi Log.w(TAG, "setPlaybackInformation() ignoring unknown key " + what); 7103114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi break; 7113114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi } 7123114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi } 7133114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi } 7143114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi 7153114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi /** 7161357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @hide 7173114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * Return playback information represented as an integer value. 7183114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * @param what a key to specify the type of information to retrieve. Valid keys are 7193114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * {@link #PLAYBACKINFO_PLAYBACK_TYPE}, 7203114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * {@link #PLAYBACKINFO_USES_STREAM}, 7213114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * {@link #PLAYBACKINFO_VOLUME}, 7223114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * {@link #PLAYBACKINFO_VOLUME_MAX}, 7233114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * and {@link #PLAYBACKINFO_VOLUME_HANDLING}. 7243114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * @return the current value for the given information type, or 7253114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * {@link #PLAYBACKINFO_INVALID_VALUE} if an error occurred or the request is invalid, or 7263114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * the value is unknown. 7273114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi */ 7283114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi public int getIntPlaybackInformation(int what) { 7293114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi synchronized(mCacheLock) { 7303114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi switch (what) { 7313114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi case PLAYBACKINFO_PLAYBACK_TYPE: 7323114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi return mPlaybackType; 7333114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi case PLAYBACKINFO_VOLUME: 7343114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi return mPlaybackVolume; 7353114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi case PLAYBACKINFO_VOLUME_MAX: 7363114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi return mPlaybackVolumeMax; 7373114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi case PLAYBACKINFO_USES_STREAM: 7383114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi return mPlaybackStream; 7393114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi case PLAYBACKINFO_VOLUME_HANDLING: 7403114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi return mPlaybackVolumeHandling; 7413114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi default: 7423114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi Log.e(TAG, "getIntPlaybackInformation() unknown key " + what); 7433114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi return PLAYBACKINFO_INVALID_VALUE; 7443114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi } 7453114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi } 7463114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi } 7473114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi 748178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi /** 7494426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * Lock for all cached data 7504426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi */ 7514426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi private final Object mCacheLock = new Object(); 7524426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi /** 7534426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * Cache for the playback state. 7544426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * Access synchronized on mCacheLock 755178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi */ 7564426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi private int mPlaybackState = PLAYSTATE_NONE; 7574426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi /** 75868622396b62f9084781add1e12f4d513b633ab54Jean-Michel Trivi * Time of last play state change 75968622396b62f9084781add1e12f4d513b633ab54Jean-Michel Trivi * Access synchronized on mCacheLock 76068622396b62f9084781add1e12f4d513b633ab54Jean-Michel Trivi */ 76168622396b62f9084781add1e12f4d513b633ab54Jean-Michel Trivi private long mPlaybackStateChangeTimeMs = 0; 76268622396b62f9084781add1e12f4d513b633ab54Jean-Michel Trivi /** 7634426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * Cache for the artwork bitmap. 7644426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * Access synchronized on mCacheLock 7654da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi * Artwork and metadata are not kept in one Bundle because the bitmap sometimes needs to be 7664da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi * accessed to be resized, in which case a copy will be made. This would add overhead in 7674da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi * Bundle operations. 7684426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi */ 7694426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi private Bitmap mArtwork; 7704426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi private final int ARTWORK_DEFAULT_SIZE = 256; 77144413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi private final int ARTWORK_INVALID_SIZE = -1; 7724426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi private int mArtworkExpectedWidth = ARTWORK_DEFAULT_SIZE; 7734426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi private int mArtworkExpectedHeight = ARTWORK_DEFAULT_SIZE; 7744426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi /** 7754426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * Cache for the transport control mask. 7764426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * Access synchronized on mCacheLock 7774426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi */ 7784426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi private int mTransportControlFlags = FLAGS_KEY_MEDIA_NONE; 7794426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi /** 7804426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * Cache for the metadata strings. 7814426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * Access synchronized on mCacheLock 78230c918ce7fbe171944b28fc91b3f22b3d631872dGlenn Kasten * This is re-initialized in apply() and so cannot be final. 7834426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi */ 7844426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi private Bundle mMetadata = new Bundle(); 7854da5eeffc92331b958eeb111aa2f3d938083954eJean-Michel Trivi 7864426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi /** 7874426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * The current remote control client generation ID across the system 7884426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi */ 7894426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi private int mCurrentClientGenId = -1; 7904426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi /** 7914426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * The remote control client generation ID, the last time it was told it was the current RC. 7924426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * If (mCurrentClientGenId == mInternalClientGenId) is true, it means that this remote control 7934426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * client is the "focused" one, and that whenever this client's info is updated, it needs to 7944426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * send it to the known IRemoteControlDisplay interfaces. 7954426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi */ 7964426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi private int mInternalClientGenId = -2; 7974426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi 7984426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi /** 799f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi * The media button intent description associated with this remote control client 800f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi * (can / should include target component for intent handling) 8014426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi */ 802f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi private final PendingIntent mRcMediaIntent; 8034426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi 8044426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi /** 8054426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * The remote control display to which this client will send information. 8064426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * NOTE: Only one IRemoteControlDisplay supported in this implementation 8074426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi */ 8084426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi private IRemoteControlDisplay mRcDisplay; 8094426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi 8104426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi /** 8114426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * @hide 812f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi * Accessor to media button intent description (includes target component) 8134426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi */ 814f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi public PendingIntent getRcMediaIntent() { 815f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi return mRcMediaIntent; 8164426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 8174426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi /** 8184426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * @hide 8194426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * Accessor to IRemoteControlClient 8204426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi */ 8214426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi public IRemoteControlClient getIRemoteControlClient() { 8224426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi return mIRCC; 8234426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 8244426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi 8254426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi /** 8264426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * The IRemoteControlClient implementation 8274426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi */ 82830c918ce7fbe171944b28fc91b3f22b3d631872dGlenn Kasten private final IRemoteControlClient mIRCC = new IRemoteControlClient.Stub() { 8294426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi 8304426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi public void onInformationRequested(int clientGeneration, int infoFlags, 8314426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi int artWidth, int artHeight) { 8324426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi // only post messages, we can't block here 8334426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi if (mEventHandler != null) { 8344426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi // signal new client 8354426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi mEventHandler.removeMessages(MSG_NEW_INTERNAL_CLIENT_GEN); 8364426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi mEventHandler.dispatchMessage( 8374426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi mEventHandler.obtainMessage( 8384426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi MSG_NEW_INTERNAL_CLIENT_GEN, 8394426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi artWidth, artHeight, 8404426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi new Integer(clientGeneration))); 8414426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi // send the information 8424426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi mEventHandler.removeMessages(MSG_REQUEST_PLAYBACK_STATE); 8434426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi mEventHandler.removeMessages(MSG_REQUEST_METADATA); 8444426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi mEventHandler.removeMessages(MSG_REQUEST_TRANSPORTCONTROL); 8454426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi mEventHandler.removeMessages(MSG_REQUEST_ARTWORK); 8464426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi mEventHandler.dispatchMessage( 8474426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi mEventHandler.obtainMessage(MSG_REQUEST_PLAYBACK_STATE)); 8484426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi mEventHandler.dispatchMessage( 8494426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi mEventHandler.obtainMessage(MSG_REQUEST_TRANSPORTCONTROL)); 8504426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi mEventHandler.dispatchMessage(mEventHandler.obtainMessage(MSG_REQUEST_METADATA)); 8514426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi mEventHandler.dispatchMessage(mEventHandler.obtainMessage(MSG_REQUEST_ARTWORK)); 8524426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 8534426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 8544426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi 8554426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi public void setCurrentClientGenerationId(int clientGeneration) { 8564426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi // only post messages, we can't block here 8574426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi if (mEventHandler != null) { 8584426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi mEventHandler.removeMessages(MSG_NEW_CURRENT_CLIENT_GEN); 8594426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi mEventHandler.dispatchMessage(mEventHandler.obtainMessage( 8604426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi MSG_NEW_CURRENT_CLIENT_GEN, clientGeneration, 0/*ignored*/)); 8614426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 8624426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 8634426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi 8644426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi public void plugRemoteControlDisplay(IRemoteControlDisplay rcd) { 8654426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi // only post messages, we can't block here 8664426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi if (mEventHandler != null) { 8674426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi mEventHandler.dispatchMessage(mEventHandler.obtainMessage( 8684426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi MSG_PLUG_DISPLAY, rcd)); 8694426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 8704426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 8714426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi 8724426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi public void unplugRemoteControlDisplay(IRemoteControlDisplay rcd) { 8734426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi // only post messages, we can't block here 8744426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi if (mEventHandler != null) { 8754426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi mEventHandler.dispatchMessage(mEventHandler.obtainMessage( 8764426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi MSG_UNPLUG_DISPLAY, rcd)); 8774426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 8784426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 8794426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi }; 8804426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi 8813114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi /** 8823114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * @hide 8833114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * Default value for the unique identifier 8843114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi */ 8853114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi public final static int RCSE_ID_UNREGISTERED = -1; 8863114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi /** 8873114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * Unique identifier of the RemoteControlStackEntry in AudioService with which 8883114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * this RemoteControlClient is associated. 8893114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi */ 8903114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi private int mRcseId = RCSE_ID_UNREGISTERED; 8913114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi /** 8923114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * @hide 8933114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * To be only used by AudioManager after it has received the unique id from 8943114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * IAudioService.registerRemoteControlClient() 8953114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * @param id the unique identifier of the RemoteControlStackEntry in AudioService with which 8963114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi * this RemoteControlClient is associated. 8973114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi */ 8983114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi public void setRcseId(int id) { 8993114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi mRcseId = id; 9003114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi } 9013114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi 9021357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi /** 9031357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @hide 9041357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi */ 9051357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi public int getRcseId() { 9061357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi return mRcseId; 9071357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi } 9081357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi 9094426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi private EventHandler mEventHandler; 9104426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi private final static int MSG_REQUEST_PLAYBACK_STATE = 1; 9114426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi private final static int MSG_REQUEST_METADATA = 2; 9124426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi private final static int MSG_REQUEST_TRANSPORTCONTROL = 3; 9134426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi private final static int MSG_REQUEST_ARTWORK = 4; 9144426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi private final static int MSG_NEW_INTERNAL_CLIENT_GEN = 5; 9154426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi private final static int MSG_NEW_CURRENT_CLIENT_GEN = 6; 9164426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi private final static int MSG_PLUG_DISPLAY = 7; 9174426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi private final static int MSG_UNPLUG_DISPLAY = 8; 9184426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi 9194426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi private class EventHandler extends Handler { 9204426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi public EventHandler(RemoteControlClient rcc, Looper looper) { 9214426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi super(looper); 9224426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 9234426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi 9244426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi @Override 9254426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi public void handleMessage(Message msg) { 9264426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi switch(msg.what) { 9274426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi case MSG_REQUEST_PLAYBACK_STATE: 9284426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi synchronized (mCacheLock) { 9294426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi sendPlaybackState_syncCacheLock(); 9304426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 9314426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi break; 9324426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi case MSG_REQUEST_METADATA: 9334426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi synchronized (mCacheLock) { 9344426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi sendMetadata_syncCacheLock(); 9354426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 9364426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi break; 9374426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi case MSG_REQUEST_TRANSPORTCONTROL: 9384426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi synchronized (mCacheLock) { 9394426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi sendTransportControlFlags_syncCacheLock(); 9404426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 9414426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi break; 9424426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi case MSG_REQUEST_ARTWORK: 9434426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi synchronized (mCacheLock) { 9444426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi sendArtwork_syncCacheLock(); 9454426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 9464426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi break; 9474426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi case MSG_NEW_INTERNAL_CLIENT_GEN: 9484426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi onNewInternalClientGen((Integer)msg.obj, msg.arg1, msg.arg2); 9494426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi break; 9504426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi case MSG_NEW_CURRENT_CLIENT_GEN: 9514426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi onNewCurrentClientGen(msg.arg1); 9524426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi break; 9534426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi case MSG_PLUG_DISPLAY: 9544426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi onPlugDisplay((IRemoteControlDisplay)msg.obj); 9554426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi break; 9564426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi case MSG_UNPLUG_DISPLAY: 9574426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi onUnplugDisplay((IRemoteControlDisplay)msg.obj); 9584426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi break; 9594426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi default: 9604426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi Log.e(TAG, "Unknown event " + msg.what + " in RemoteControlClient handler"); 9614426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 9624426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 9634426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 9644426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi 9653114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi //=========================================================== 9663114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi // Communication with IRemoteControlDisplay 9673114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi 96844413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi private void detachFromDisplay_syncCacheLock() { 96944413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi mRcDisplay = null; 97044413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi mArtworkExpectedWidth = ARTWORK_INVALID_SIZE; 97144413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi mArtworkExpectedHeight = ARTWORK_INVALID_SIZE; 97244413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi } 97344413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi 9744426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi private void sendPlaybackState_syncCacheLock() { 9754426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi if ((mCurrentClientGenId == mInternalClientGenId) && (mRcDisplay != null)) { 9764426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi try { 97768622396b62f9084781add1e12f4d513b633ab54Jean-Michel Trivi mRcDisplay.setPlaybackState(mInternalClientGenId, mPlaybackState, 97868622396b62f9084781add1e12f4d513b633ab54Jean-Michel Trivi mPlaybackStateChangeTimeMs); 9794426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } catch (RemoteException e) { 9804426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi Log.e(TAG, "Error in setPlaybackState(), dead display "+e); 98144413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi detachFromDisplay_syncCacheLock(); 9824426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 9834426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 9844426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 9854426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi 9864426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi private void sendMetadata_syncCacheLock() { 9874426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi if ((mCurrentClientGenId == mInternalClientGenId) && (mRcDisplay != null)) { 9884426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi try { 9894426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi mRcDisplay.setMetadata(mInternalClientGenId, mMetadata); 9904426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } catch (RemoteException e) { 9914426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi Log.e(TAG, "Error in sendPlaybackState(), dead display "+e); 99244413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi detachFromDisplay_syncCacheLock(); 9934426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 9944426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 9954426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 9964426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi 9974426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi private void sendTransportControlFlags_syncCacheLock() { 9984426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi if ((mCurrentClientGenId == mInternalClientGenId) && (mRcDisplay != null)) { 9994426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi try { 10004426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi mRcDisplay.setTransportControlFlags(mInternalClientGenId, 10014426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi mTransportControlFlags); 10024426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } catch (RemoteException e) { 10034426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi Log.e(TAG, "Error in sendTransportControlFlags(), dead display "+e); 100444413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi detachFromDisplay_syncCacheLock(); 10054426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 10064426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 10074426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 10084426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi 10094426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi private void sendArtwork_syncCacheLock() { 10104426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi if ((mCurrentClientGenId == mInternalClientGenId) && (mRcDisplay != null)) { 10114426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi // even though we have already scaled in setArtwork(), when this client needs to 10124426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi // send the bitmap, there might be newer and smaller expected dimensions, so we have 10134426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi // to check again. 10144426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi mArtwork = scaleBitmapIfTooBig(mArtwork, mArtworkExpectedWidth, mArtworkExpectedHeight); 10154426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi try { 10164426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi mRcDisplay.setArtwork(mInternalClientGenId, mArtwork); 10174426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } catch (RemoteException e) { 10184426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi Log.e(TAG, "Error in sendArtwork(), dead display "+e); 101944413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi detachFromDisplay_syncCacheLock(); 102044413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi } 102144413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi } 102244413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi } 102344413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi 102444413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi private void sendMetadataWithArtwork_syncCacheLock() { 102544413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi if ((mCurrentClientGenId == mInternalClientGenId) && (mRcDisplay != null)) { 102644413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi // even though we have already scaled in setArtwork(), when this client needs to 102744413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi // send the bitmap, there might be newer and smaller expected dimensions, so we have 102844413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi // to check again. 102944413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi mArtwork = scaleBitmapIfTooBig(mArtwork, mArtworkExpectedWidth, mArtworkExpectedHeight); 103044413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi try { 103144413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi mRcDisplay.setAllMetadata(mInternalClientGenId, mMetadata, mArtwork); 103244413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi } catch (RemoteException e) { 103344413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi Log.e(TAG, "Error in setAllMetadata(), dead display "+e); 103444413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi detachFromDisplay_syncCacheLock(); 10354426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 10364426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 10374426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 10384426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi 10393114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi //=========================================================== 10403114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi // Communication with AudioService 10413114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi 10423114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi private static IAudioService sService; 10433114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi 10443114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi private static IAudioService getService() 10453114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi { 10463114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi if (sService != null) { 10473114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi return sService; 10483114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi } 10493114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi IBinder b = ServiceManager.getService(Context.AUDIO_SERVICE); 10503114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi sService = IAudioService.Stub.asInterface(b); 10513114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi return sService; 10523114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi } 10533114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi 10543114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi private void sendAudioServiceNewPlaybackInfo_syncCacheLock(int what, int value) { 10553114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi if (mRcseId == RCSE_ID_UNREGISTERED) { 10563114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi return; 10573114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi } 1058f98de1e8dd6dcbd191921b4aa07a1d41b0b9db91Jean-Michel Trivi //Log.d(TAG, "sending to AudioService key=" + what + ", value=" + value); 10593114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi IAudioService service = getService(); 10603114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi try { 10613114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi service.setPlaybackInfoForRcc(mRcseId, what, value); 10623114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi } catch (RemoteException e) { 10633114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi Log.e(TAG, "Dead object in sendAudioServiceNewPlaybackInfo_syncCacheLock", e); 10643114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi } 10653114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi } 10663114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi 10673114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi //=========================================================== 10683114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi // Message handlers 10693114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi 10704426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi private void onNewInternalClientGen(Integer clientGeneration, int artWidth, int artHeight) { 10714426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi synchronized (mCacheLock) { 10724426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi // this remote control client is told it is the "focused" one: 10734426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi // it implies that now (mCurrentClientGenId == mInternalClientGenId) is true 10744426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi mInternalClientGenId = clientGeneration.intValue(); 10754426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi if (artWidth > 0) { 10764426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi mArtworkExpectedWidth = artWidth; 10774426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi mArtworkExpectedHeight = artHeight; 10784426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 10794426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 10804426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 10814426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi 10824426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi private void onNewCurrentClientGen(int clientGeneration) { 10834426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi synchronized (mCacheLock) { 10844426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi mCurrentClientGenId = clientGeneration; 10854426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 10864426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 10874426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi 10884426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi private void onPlugDisplay(IRemoteControlDisplay rcd) { 10894426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi synchronized(mCacheLock) { 10904426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi mRcDisplay = rcd; 10914426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 10924426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 10934426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi 10944426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi private void onUnplugDisplay(IRemoteControlDisplay rcd) { 10954426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi synchronized(mCacheLock) { 10967309c83b95b36eac141680158df70ac1ce02a160Jean-Michel Trivi if ((mRcDisplay != null) && (mRcDisplay.asBinder().equals(rcd.asBinder()))) { 10974426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi mRcDisplay = null; 10984426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi mArtworkExpectedWidth = ARTWORK_DEFAULT_SIZE; 10994426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi mArtworkExpectedHeight = ARTWORK_DEFAULT_SIZE; 11004426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 11014426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 11024426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 11034426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi 11043114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi //=========================================================== 11053114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi // Internal utilities 11063114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi 11074426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi /** 11084426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * Scale a bitmap to fit the smallest dimension by uniformly scaling the incoming bitmap. 11094426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * If the bitmap fits, then do nothing and return the original. 11104426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * 11114426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * @param bitmap 11124426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * @param maxWidth 11134426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * @param maxHeight 11144426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi * @return 11154426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi */ 11164426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi 11174426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi private Bitmap scaleBitmapIfTooBig(Bitmap bitmap, int maxWidth, int maxHeight) { 11186e679d5a53091b348a2cdc0c76f4e8fa4ac52d4bJean-Michel Trivi if (bitmap != null) { 11196e679d5a53091b348a2cdc0c76f4e8fa4ac52d4bJean-Michel Trivi final int width = bitmap.getWidth(); 11206e679d5a53091b348a2cdc0c76f4e8fa4ac52d4bJean-Michel Trivi final int height = bitmap.getHeight(); 11216e679d5a53091b348a2cdc0c76f4e8fa4ac52d4bJean-Michel Trivi if (width > maxWidth || height > maxHeight) { 11226e679d5a53091b348a2cdc0c76f4e8fa4ac52d4bJean-Michel Trivi float scale = Math.min((float) maxWidth / width, (float) maxHeight / height); 11236e679d5a53091b348a2cdc0c76f4e8fa4ac52d4bJean-Michel Trivi int newWidth = Math.round(scale * width); 11246e679d5a53091b348a2cdc0c76f4e8fa4ac52d4bJean-Michel Trivi int newHeight = Math.round(scale * height); 112505c66cc5cc6357be19fdef0fc131731368c38646Jack Palevich Bitmap.Config newConfig = bitmap.getConfig(); 112605c66cc5cc6357be19fdef0fc131731368c38646Jack Palevich if (newConfig == null) { 112705c66cc5cc6357be19fdef0fc131731368c38646Jack Palevich newConfig = Bitmap.Config.ARGB_8888; 112805c66cc5cc6357be19fdef0fc131731368c38646Jack Palevich } 112905c66cc5cc6357be19fdef0fc131731368c38646Jack Palevich Bitmap outBitmap = Bitmap.createBitmap(newWidth, newHeight, newConfig); 11306e679d5a53091b348a2cdc0c76f4e8fa4ac52d4bJean-Michel Trivi Canvas canvas = new Canvas(outBitmap); 11316e679d5a53091b348a2cdc0c76f4e8fa4ac52d4bJean-Michel Trivi Paint paint = new Paint(); 11326e679d5a53091b348a2cdc0c76f4e8fa4ac52d4bJean-Michel Trivi paint.setAntiAlias(true); 11336e679d5a53091b348a2cdc0c76f4e8fa4ac52d4bJean-Michel Trivi paint.setFilterBitmap(true); 11346e679d5a53091b348a2cdc0c76f4e8fa4ac52d4bJean-Michel Trivi canvas.drawBitmap(bitmap, null, 11356e679d5a53091b348a2cdc0c76f4e8fa4ac52d4bJean-Michel Trivi new RectF(0, 0, outBitmap.getWidth(), outBitmap.getHeight()), paint); 11366e679d5a53091b348a2cdc0c76f4e8fa4ac52d4bJean-Michel Trivi bitmap = outBitmap; 11376e679d5a53091b348a2cdc0c76f4e8fa4ac52d4bJean-Michel Trivi } 11384426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 11394426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi return bitmap; 11405ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi } 11414426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi 11425ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi /** 11435ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi * Fast routine to go through an array of allowed keys and return whether the key is part 11445ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi * of that array 11455ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi * @param key the key value 11465ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi * @param validKeys the array of valid keys for a given type 11475ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi * @return true if the key is part of the array, false otherwise 11485ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi */ 11495ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi private static boolean validTypeForKey(int key, int[] validKeys) { 11505ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi try { 11515ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi for (int i = 0 ; ; i++) { 11525ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi if (key == validKeys[i]) { 11535ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi return true; 11545ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi } 11555ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi } 11565ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi } catch (ArrayIndexOutOfBoundsException e) { 11575ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi return false; 11585ad4b9fb96089e460902ffac9f3649366afd3750Jean-Michel Trivi } 11594426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi } 1160178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi} 1161