Loading api/current.txt +8 −4 Original line number Diff line number Diff line Loading @@ -15103,6 +15103,7 @@ package android.media.routeprovider { package android.media.session { public final class MediaMetadata implements android.os.Parcelable { method public boolean containsKey(java.lang.String); method public int describeContents(); method public android.graphics.Bitmap getBitmap(java.lang.String); method public long getLong(java.lang.String); Loading @@ -15118,6 +15119,7 @@ package android.media.session { field public static final java.lang.String METADATA_KEY_ARTIST = "android.media.metadata.ARTIST"; field public static final java.lang.String METADATA_KEY_ART_URI = "android.media.metadata.ART_URI"; field public static final java.lang.String METADATA_KEY_AUTHOR = "android.media.metadata.AUTHOR"; field public static final java.lang.String METADATA_KEY_COMPILATION = "android.media.metadata.COMPILATION"; field public static final java.lang.String METADATA_KEY_COMPOSER = "android.media.metadata.COMPOSER"; field public static final java.lang.String METADATA_KEY_DATE = "android.media.metadata.DATE"; field public static final java.lang.String METADATA_KEY_DISC_NUMBER = "android.media.metadata.DISC_NUMBER"; Loading Loading @@ -15150,25 +15152,25 @@ package android.media.session { method public long getBufferPosition(); method public java.lang.String getErrorMessage(); method public long getPosition(); method public float getSpeed(); method public float getRate(); method public int getState(); method public void setActions(long); method public void setBufferPosition(long); method public void setErrorMessage(java.lang.String); method public void setPosition(long); method public void setSpeed(float); method public void setState(int); method public void setState(int, long, float); method public void writeToParcel(android.os.Parcel, int); field public static final long ACTION_FASTFORWARD = 64L; // 0x40L field public static final long ACTION_NEXT_ITEM = 32L; // 0x20L field public static final long ACTION_PAUSE = 2L; // 0x2L field public static final long ACTION_PLAY = 4L; // 0x4L field public static final long ACTION_PLAY_PAUSE = 512L; // 0x200L field public static final long ACTION_PREVIOUS_ITEM = 16L; // 0x10L field public static final long ACTION_RATING = 128L; // 0x80L field public static final long ACTION_REWIND = 8L; // 0x8L field public static final long ACTION_SEEK_TO = 256L; // 0x100L field public static final long ACTION_STOP = 1L; // 0x1L field public static final android.os.Parcelable.Creator CREATOR; field public static final long PLAYBACK_POSITION_UNKNOWN = -1L; // 0xffffffffffffffffL field public static final int PLAYSTATE_BUFFERING = 6; // 0x6 field public static final int PLAYSTATE_CONNECTING = 8; // 0x8 field public static final int PLAYSTATE_ERROR = 7; // 0x7 Loading @@ -15177,6 +15179,8 @@ package android.media.session { field public static final int PLAYSTATE_PAUSED = 2; // 0x2 field public static final int PLAYSTATE_PLAYING = 3; // 0x3 field public static final int PLAYSTATE_REWINDING = 5; // 0x5 field public static final int PLAYSTATE_SKIPPING_BACKWARDS = 9; // 0x9 field public static final int PLAYSTATE_SKIPPING_FORWARDS = 10; // 0xa field public static final int PLAYSTATE_STOPPED = 1; // 0x1 } media/java/android/media/AudioManager.java +23 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.media.RemoteController.OnClientUpdateListener; import android.media.session.MediaSessionLegacyHelper; import android.os.Binder; import android.os.Handler; import android.os.IBinder; Loading @@ -48,6 +49,12 @@ import java.util.HashMap; */ public class AudioManager { // If we should use the new sessions APIs. private final static boolean USE_SESSIONS = true; // If we should use the legacy APIs. If both are true information will be // duplicated through both paths. Currently this flag isn't used. private final static boolean USE_LEGACY = true; private final Context mContext; private long mVolumeKeyUpTime; private final boolean mUseMasterVolume; Loading Loading @@ -421,6 +428,7 @@ public class AudioManager { public static final int USE_DEFAULT_STREAM_TYPE = Integer.MIN_VALUE; private static IAudioService sService; private MediaSessionLegacyHelper mSessionHelper; /** * @hide Loading @@ -431,6 +439,9 @@ public class AudioManager { com.android.internal.R.bool.config_useMasterVolume); mUseVolumeKeySounds = mContext.getResources().getBoolean( com.android.internal.R.bool.config_useVolumeKeySounds); if (USE_SESSIONS) { mSessionHelper = MediaSessionLegacyHelper.getHelper(context); } } private static IAudioService getService() Loading Loading @@ -2166,6 +2177,9 @@ public class AudioManager { } catch (RemoteException e) { Log.e(TAG, "Dead object in registerMediaButtonIntent"+e); } if (USE_SESSIONS) { mSessionHelper.addMediaButtonListener(pi, mContext); } } /** Loading Loading @@ -2239,6 +2253,9 @@ public class AudioManager { } catch (RemoteException e) { Log.e(TAG, "Dead object in unregisterMediaButtonIntent"+e); } if (USE_SESSIONS) { mSessionHelper.removeMediaButtonListener(pi); } } /** Loading @@ -2263,6 +2280,9 @@ public class AudioManager { } catch (RemoteException e) { Log.e(TAG, "Dead object in registerRemoteControlClient"+e); } if (USE_SESSIONS) { rcClient.registerWithSession(mSessionHelper); } } /** Loading @@ -2282,6 +2302,9 @@ public class AudioManager { } catch (RemoteException e) { Log.e(TAG, "Dead object in unregisterRemoteControlClient"+e); } if (USE_SESSIONS) { rcClient.unregisterWithSession(mSessionHelper); } } /** Loading media/java/android/media/MediaMetadataEditor.java +6 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package android.media; import android.graphics.Bitmap; import android.media.session.MediaMetadata; import android.os.Bundle; import android.os.Parcelable; import android.util.Log; Loading Loading @@ -106,6 +107,10 @@ public abstract class MediaMetadataEditor { */ protected Bundle mEditorMetadata; /** * @hide */ protected MediaMetadata.Builder mMetadataBuilder; /** * Clears all the pending metadata changes set since the MediaMetadataEditor instance was Loading @@ -120,6 +125,7 @@ public abstract class MediaMetadataEditor { } mEditorMetadata.clear(); mEditorArtwork = null; mMetadataBuilder = new MediaMetadata.Builder(); } /** Loading media/java/android/media/RemoteControlClient.java +117 −12 Original line number Diff line number Diff line Loading @@ -24,6 +24,11 @@ import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.RectF; import android.media.session.MediaMetadata; import android.media.session.MediaSessionLegacyHelper; import android.media.session.PlaybackState; import android.media.session.Session; import android.media.session.TransportPerformer; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; Loading Loading @@ -336,6 +341,8 @@ public class RemoteControlClient */ public final static int FLAG_INFORMATION_REQUEST_ALBUM_ART = 1 << 3; private Session mSession; /** * Class constructor. * @param mediaButtonIntent The intent that will be sent for the media button events sent Loading Loading @@ -384,6 +391,22 @@ public class RemoteControlClient mEventHandler = new EventHandler(this, looper); } /** * @hide */ public void registerWithSession(MediaSessionLegacyHelper helper) { helper.addRccListener(mRcMediaIntent, mTransportListener); mSession = helper.getSession(mRcMediaIntent); } /** * @hide */ public void unregisterWithSession(MediaSessionLegacyHelper helper) { helper.removeRccListener(mRcMediaIntent); mSession = null; } /** * Class used to modify metadata in a {@link RemoteControlClient} object. * Use {@link RemoteControlClient#editMetadata(boolean)} to create an instance of an editor, Loading Loading @@ -438,6 +461,15 @@ public class RemoteControlClient public synchronized MetadataEditor putString(int key, String value) throws IllegalArgumentException { super.putString(key, value); if (mMetadataBuilder != null) { // MediaMetadata supports all the same fields as MetadataEditor String metadataKey = MediaMetadata.getKeyFromMetadataEditorKey(key); // But just in case, don't add things we don't understand if (metadataKey != null) { mMetadataBuilder.putString(metadataKey, value); } } return this; } Loading @@ -459,6 +491,14 @@ public class RemoteControlClient public synchronized MetadataEditor putLong(int key, long value) throws IllegalArgumentException { super.putLong(key, value); if (mMetadataBuilder != null) { // MediaMetadata supports all the same fields as MetadataEditor String metadataKey = MediaMetadata.getKeyFromMetadataEditorKey(key); // But just in case, don't add things we don't understand if (metadataKey != null) { mMetadataBuilder.putLong(metadataKey, value); } } return this; } Loading @@ -476,6 +516,14 @@ public class RemoteControlClient public synchronized MetadataEditor putBitmap(int key, Bitmap bitmap) throws IllegalArgumentException { super.putBitmap(key, bitmap); if (mMetadataBuilder != null) { // MediaMetadata supports all the same fields as MetadataEditor String metadataKey = MediaMetadata.getKeyFromMetadataEditorKey(key); // But just in case, don't add things we don't understand if (metadataKey != null) { mMetadataBuilder.putBitmap(metadataKey, bitmap); } } return this; } Loading Loading @@ -521,6 +569,11 @@ public class RemoteControlClient // send to remote control display if conditions are met sendArtwork_syncCacheLock(null, 0, 0); } // USE_SESSIONS if (mSession != null && mMetadataBuilder != null) { mSession.getTransportPerformer().setMetadata(mMetadataBuilder.build()); } mApplied = true; } } Loading @@ -546,6 +599,12 @@ public class RemoteControlClient editor.mMetadataChanged = false; editor.mArtworkChanged = false; } // USE_SESSIONS if (startEmpty || mMediaMetadata == null) { editor.mMetadataBuilder = new MediaMetadata.Builder(); } else { editor.mMetadataBuilder = new MediaMetadata.Builder(mMediaMetadata); } return editor; } Loading Loading @@ -624,6 +683,15 @@ public class RemoteControlClient // handle automatic playback position refreshes initiateCheckForDrift_syncCacheLock(); // USE_SESSIONS if (mSession != null) { int pbState = PlaybackState.getStateFromRccState(state); mSessionPlaybackState.setState(pbState, hasPosition ? mPlaybackPositionMs : PlaybackState.PLAYBACK_POSITION_UNKNOWN, playbackSpeed); mSession.getTransportPerformer().setPlaybackState(mSessionPlaybackState); } } } } Loading Loading @@ -704,6 +772,13 @@ public class RemoteControlClient // send to remote control display if conditions are met sendTransportControlInfo_syncCacheLock(null); // USE_SESSIONS if (mSession != null) { mSessionPlaybackState.setActions(PlaybackState .getActionsFromRccControlFlags(transportControlFlags)); mSession.getTransportPerformer().setPlaybackState(mSessionPlaybackState); } } } Loading Loading @@ -1037,6 +1112,16 @@ public class RemoteControlClient // TODO consider using a ref count for IRemoteControlDisplay requiring sync instead private boolean mNeedsPositionSync = false; /** * Cache for the current playback state using Session APIs. */ private final PlaybackState mSessionPlaybackState = new PlaybackState(); /** * Cache for metadata using Session APIs. This is re-initialized in apply(). */ private MediaMetadata mMediaMetadata; /** * A class to encapsulate all the information about a remote control display. * A RemoteControlClient's metadata and state may be displayed on multiple IRemoteControlDisplay Loading Loading @@ -1219,6 +1304,26 @@ public class RemoteControlClient return mRcseId; } // USE_SESSIONS private TransportPerformer.Listener mTransportListener = new TransportPerformer.Listener() { @Override public void onSeekTo(long pos) { RemoteControlClient.this.onSeekTo(mCurrentClientGenId, pos); } @Override public void onRate(Rating rating) { if ((mTransportControlFlags & FLAG_KEY_MEDIA_RATING) != 0) { if (mEventHandler != null) { mEventHandler.sendMessage(mEventHandler.obtainMessage( MSG_UPDATE_METADATA, mCurrentClientGenId, MetadataEditor.RATING_KEY_BY_USER, rating)); } } } }; private EventHandler mEventHandler; private final static int MSG_REQUEST_PLAYBACK_STATE = 1; private final static int MSG_REQUEST_METADATA = 2; Loading Loading @@ -1325,7 +1430,7 @@ public class RemoteControlClient // target == null implies all displays must be updated final Iterator<DisplayInfoForClient> displayIterator = mRcDisplays.iterator(); while (displayIterator.hasNext()) { final DisplayInfoForClient di = (DisplayInfoForClient) displayIterator.next(); final DisplayInfoForClient di = displayIterator.next(); if (di.mEnabled) { try { di.mRcDisplay.setPlaybackState(mInternalClientGenId, Loading Loading @@ -1353,7 +1458,7 @@ public class RemoteControlClient // target == null implies all displays must be updated final Iterator<DisplayInfoForClient> displayIterator = mRcDisplays.iterator(); while (displayIterator.hasNext()) { final DisplayInfoForClient di = (DisplayInfoForClient) displayIterator.next(); final DisplayInfoForClient di = displayIterator.next(); if (di.mEnabled) { try { di.mRcDisplay.setMetadata(mInternalClientGenId, mMetadata); Loading Loading @@ -1381,7 +1486,7 @@ public class RemoteControlClient // target == null implies all displays must be updated final Iterator<DisplayInfoForClient> displayIterator = mRcDisplays.iterator(); while (displayIterator.hasNext()) { final DisplayInfoForClient di = (DisplayInfoForClient) displayIterator.next(); final DisplayInfoForClient di = displayIterator.next(); if (di.mEnabled) { try { di.mRcDisplay.setTransportControlInfo(mInternalClientGenId, Loading @@ -1407,7 +1512,7 @@ public class RemoteControlClient // target == null implies all displays must be updated final Iterator<DisplayInfoForClient> displayIterator = mRcDisplays.iterator(); while (displayIterator.hasNext()) { if (!sendArtworkToDisplay((DisplayInfoForClient) displayIterator.next())) { if (!sendArtworkToDisplay(displayIterator.next())) { displayIterator.remove(); } } Loading Loading @@ -1453,7 +1558,7 @@ public class RemoteControlClient // target == null implies all displays must be updated final Iterator<DisplayInfoForClient> displayIterator = mRcDisplays.iterator(); while (displayIterator.hasNext()) { final DisplayInfoForClient di = (DisplayInfoForClient) displayIterator.next(); final DisplayInfoForClient di = displayIterator.next(); try { if (di.mEnabled) { if ((di.mArtworkExpectedWidth > 0) && (di.mArtworkExpectedHeight > 0)) { Loading Loading @@ -1537,7 +1642,7 @@ public class RemoteControlClient boolean displayKnown = false; final Iterator<DisplayInfoForClient> displayIterator = mRcDisplays.iterator(); while (displayIterator.hasNext() && !displayKnown) { final DisplayInfoForClient di = (DisplayInfoForClient) displayIterator.next(); final DisplayInfoForClient di = displayIterator.next(); displayKnown = di.mRcDisplay.asBinder().equals(rcd.asBinder()); if (displayKnown) { // this display was known but the change in artwork size will cause the Loading @@ -1562,7 +1667,7 @@ public class RemoteControlClient synchronized(mCacheLock) { Iterator<DisplayInfoForClient> displayIterator = mRcDisplays.iterator(); while (displayIterator.hasNext()) { final DisplayInfoForClient di = (DisplayInfoForClient) displayIterator.next(); final DisplayInfoForClient di = displayIterator.next(); if (di.mRcDisplay.asBinder().equals(rcd.asBinder())) { displayIterator.remove(); break; Loading @@ -1573,7 +1678,7 @@ public class RemoteControlClient boolean newNeedsPositionSync = false; displayIterator = mRcDisplays.iterator(); while (displayIterator.hasNext()) { final DisplayInfoForClient di = (DisplayInfoForClient) displayIterator.next(); final DisplayInfoForClient di = displayIterator.next(); if (di.mWantsPositionSync) { newNeedsPositionSync = true; break; Loading @@ -1592,7 +1697,7 @@ public class RemoteControlClient synchronized(mCacheLock) { final Iterator<DisplayInfoForClient> displayIterator = mRcDisplays.iterator(); while (displayIterator.hasNext()) { final DisplayInfoForClient di = (DisplayInfoForClient) displayIterator.next(); final DisplayInfoForClient di = displayIterator.next(); if (di.mRcDisplay.asBinder().equals(rcd.asBinder()) && ((di.mArtworkExpectedWidth != w) || (di.mArtworkExpectedHeight != h))) { di.mArtworkExpectedWidth = w; Loading @@ -1617,7 +1722,7 @@ public class RemoteControlClient // go through the list of RCDs and for each entry, check both whether this is the RCD // that gets upated, and whether the list has one entry that wants position sync while (displayIterator.hasNext()) { final DisplayInfoForClient di = (DisplayInfoForClient) displayIterator.next(); final DisplayInfoForClient di = displayIterator.next(); if (di.mEnabled) { if (di.mRcDisplay.asBinder().equals(rcd.asBinder())) { di.mWantsPositionSync = wantsSync; Loading @@ -1640,7 +1745,7 @@ public class RemoteControlClient synchronized(mCacheLock) { final Iterator<DisplayInfoForClient> displayIterator = mRcDisplays.iterator(); while (displayIterator.hasNext()) { final DisplayInfoForClient di = (DisplayInfoForClient) displayIterator.next(); final DisplayInfoForClient di = displayIterator.next(); if (di.mRcDisplay.asBinder().equals(rcd.asBinder())) { di.mEnabled = enable; } Loading media/java/android/media/session/MediaMetadata.java +69 −7 Original line number Diff line number Diff line Loading @@ -16,12 +16,15 @@ package android.media.session; import android.graphics.Bitmap; import android.media.MediaMetadataEditor; import android.media.MediaMetadataRetriever; import android.media.Rating; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; import android.util.ArrayMap; import android.util.Log; import android.util.SparseArray; /** * Contains metadata about an item, such as the title, artist, etc. Loading @@ -40,7 +43,8 @@ public final class MediaMetadata implements Parcelable { public static final String METADATA_KEY_ARTIST = "android.media.metadata.ARTIST"; /** * The duration of the media in ms. A duration of 0 is the default. * The duration of the media in ms. A negative duration indicates that the * duration is unknown (or infinite). */ public static final String METADATA_KEY_DURATION = "android.media.metadata.DURATION"; Loading @@ -64,13 +68,18 @@ public final class MediaMetadata implements Parcelable { */ public static final String METADATA_KEY_COMPOSER = "android.media.metadata.COMPOSER"; /** * The compilation status of the media. */ public static final String METADATA_KEY_COMPILATION = "android.media.metadata.COMPILATION"; /** * The date the media was created or published as TODO determine format. */ public static final String METADATA_KEY_DATE = "android.media.metadata.DATE"; /** * The year the media was created or published as a numeric String. * The year the media was created or published as a long. */ public static final String METADATA_KEY_YEAR = "android.media.metadata.YEAR"; Loading Loading @@ -151,8 +160,9 @@ public final class MediaMetadata implements Parcelable { METADATA_KEYS_TYPE.put(METADATA_KEY_AUTHOR, METADATA_TYPE_STRING); METADATA_KEYS_TYPE.put(METADATA_KEY_WRITER, METADATA_TYPE_STRING); METADATA_KEYS_TYPE.put(METADATA_KEY_COMPOSER, METADATA_TYPE_STRING); METADATA_KEYS_TYPE.put(METADATA_KEY_COMPILATION, METADATA_TYPE_STRING); METADATA_KEYS_TYPE.put(METADATA_KEY_DATE, METADATA_TYPE_STRING); METADATA_KEYS_TYPE.put(METADATA_KEY_YEAR, METADATA_TYPE_STRING); METADATA_KEYS_TYPE.put(METADATA_KEY_YEAR, METADATA_TYPE_LONG); METADATA_KEYS_TYPE.put(METADATA_KEY_GENRE, METADATA_TYPE_STRING); METADATA_KEYS_TYPE.put(METADATA_KEY_TRACK_NUMBER, METADATA_TYPE_LONG); METADATA_KEYS_TYPE.put(METADATA_KEY_NUM_TRACKS, METADATA_TYPE_LONG); Loading @@ -165,6 +175,36 @@ public final class MediaMetadata implements Parcelable { METADATA_KEYS_TYPE.put(METADATA_KEY_USER_RATING, METADATA_TYPE_RATING); METADATA_KEYS_TYPE.put(METADATA_KEY_RATING, METADATA_TYPE_RATING); } private static final SparseArray<String> EDITOR_KEY_MAPPING; static { EDITOR_KEY_MAPPING = new SparseArray<String>(); EDITOR_KEY_MAPPING.put(MediaMetadataEditor.BITMAP_KEY_ARTWORK, METADATA_KEY_ART); EDITOR_KEY_MAPPING.put(MediaMetadataEditor.RATING_KEY_BY_OTHERS, METADATA_KEY_RATING); EDITOR_KEY_MAPPING.put(MediaMetadataEditor.RATING_KEY_BY_USER, METADATA_KEY_USER_RATING); EDITOR_KEY_MAPPING.put(MediaMetadataRetriever.METADATA_KEY_ALBUM, METADATA_KEY_ALBUM); EDITOR_KEY_MAPPING.put(MediaMetadataRetriever.METADATA_KEY_ALBUMARTIST, METADATA_KEY_ALBUM_ARTIST); EDITOR_KEY_MAPPING.put(MediaMetadataRetriever.METADATA_KEY_ARTIST, METADATA_KEY_ARTIST); EDITOR_KEY_MAPPING.put(MediaMetadataRetriever.METADATA_KEY_AUTHOR, METADATA_KEY_AUTHOR); EDITOR_KEY_MAPPING.put(MediaMetadataRetriever.METADATA_KEY_CD_TRACK_NUMBER, METADATA_KEY_TRACK_NUMBER); EDITOR_KEY_MAPPING.put(MediaMetadataRetriever.METADATA_KEY_COMPOSER, METADATA_KEY_COMPOSER); EDITOR_KEY_MAPPING.put(MediaMetadataRetriever.METADATA_KEY_COMPILATION, METADATA_KEY_COMPILATION); EDITOR_KEY_MAPPING.put(MediaMetadataRetriever.METADATA_KEY_DATE, METADATA_KEY_DATE); EDITOR_KEY_MAPPING.put(MediaMetadataRetriever.METADATA_KEY_DISC_NUMBER, METADATA_KEY_DISC_NUMBER); EDITOR_KEY_MAPPING.put(MediaMetadataRetriever.METADATA_KEY_DURATION, METADATA_KEY_DURATION); EDITOR_KEY_MAPPING.put(MediaMetadataRetriever.METADATA_KEY_GENRE, METADATA_KEY_GENRE); EDITOR_KEY_MAPPING.put(MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS, METADATA_KEY_NUM_TRACKS); EDITOR_KEY_MAPPING.put(MediaMetadataRetriever.METADATA_KEY_TITLE, METADATA_KEY_TITLE); EDITOR_KEY_MAPPING.put(MediaMetadataRetriever.METADATA_KEY_WRITER, METADATA_KEY_WRITER); EDITOR_KEY_MAPPING.put(MediaMetadataRetriever.METADATA_KEY_YEAR, METADATA_KEY_YEAR); } private final Bundle mBundle; private MediaMetadata(Bundle bundle) { Loading @@ -175,6 +215,16 @@ public final class MediaMetadata implements Parcelable { mBundle = in.readBundle(); } /** * Returns true if the given key is contained in the metadata * * @param key a String key * @return true if the key exists in this metadata, false otherwise */ public boolean containsKey(String key) { return mBundle.containsKey(key); } /** * Returns the value associated with the given key, or null if no mapping of * the desired type exists for the given key or a null value is explicitly Loading @@ -195,7 +245,7 @@ public final class MediaMetadata implements Parcelable { * @return a long value */ public long getLong(String key) { return mBundle.getLong(key); return mBundle.getLong(key, 0); } /** Loading Loading @@ -244,6 +294,18 @@ public final class MediaMetadata implements Parcelable { dest.writeBundle(mBundle); } /** * Helper for getting the String key used by {@link MediaMetadata} from the * integer key that {@link MediaMetadataEditor} uses. * * @param editorKey The key used by the editor * @return The key used by this class or null if no mapping exists * @hide */ public static String getKeyFromMetadataEditorKey(int editorKey) { return EDITOR_KEY_MAPPING.get(editorKey, null); } public static final Parcelable.Creator<MediaMetadata> CREATOR = new Parcelable.Creator<MediaMetadata>() { @Override Loading Loading @@ -295,10 +357,9 @@ public final class MediaMetadata implements Parcelable { * <li>{@link #METADATA_KEY_WRITER}</li> * <li>{@link #METADATA_KEY_COMPOSER}</li> * <li>{@link #METADATA_KEY_DATE}</li> * <li>{@link #METADATA_KEY_YEAR}</li> * <li>{@link #METADATA_KEY_GENRE}</li> * <li>{@link #METADATA_KEY_ALBUM_ARTIST}</li>li> * <li>{@link #METADATA_KEY_ART_URI}</li>li> * <li>{@link #METADATA_KEY_ALBUM_ARTIST}</li> * <li>{@link #METADATA_KEY_ART_URI}</li> * <li>{@link #METADATA_KEY_ALBUM_ART_URI}</li> * </ul> * Loading Loading @@ -326,6 +387,7 @@ public final class MediaMetadata implements Parcelable { * <li>{@link #METADATA_KEY_TRACK_NUMBER}</li> * <li>{@link #METADATA_KEY_NUM_TRACKS}</li> * <li>{@link #METADATA_KEY_DISC_NUMBER}</li> * <li>{@link #METADATA_KEY_YEAR}</li> * </ul> * * @param key The key for referencing this value Loading Loading
api/current.txt +8 −4 Original line number Diff line number Diff line Loading @@ -15103,6 +15103,7 @@ package android.media.routeprovider { package android.media.session { public final class MediaMetadata implements android.os.Parcelable { method public boolean containsKey(java.lang.String); method public int describeContents(); method public android.graphics.Bitmap getBitmap(java.lang.String); method public long getLong(java.lang.String); Loading @@ -15118,6 +15119,7 @@ package android.media.session { field public static final java.lang.String METADATA_KEY_ARTIST = "android.media.metadata.ARTIST"; field public static final java.lang.String METADATA_KEY_ART_URI = "android.media.metadata.ART_URI"; field public static final java.lang.String METADATA_KEY_AUTHOR = "android.media.metadata.AUTHOR"; field public static final java.lang.String METADATA_KEY_COMPILATION = "android.media.metadata.COMPILATION"; field public static final java.lang.String METADATA_KEY_COMPOSER = "android.media.metadata.COMPOSER"; field public static final java.lang.String METADATA_KEY_DATE = "android.media.metadata.DATE"; field public static final java.lang.String METADATA_KEY_DISC_NUMBER = "android.media.metadata.DISC_NUMBER"; Loading Loading @@ -15150,25 +15152,25 @@ package android.media.session { method public long getBufferPosition(); method public java.lang.String getErrorMessage(); method public long getPosition(); method public float getSpeed(); method public float getRate(); method public int getState(); method public void setActions(long); method public void setBufferPosition(long); method public void setErrorMessage(java.lang.String); method public void setPosition(long); method public void setSpeed(float); method public void setState(int); method public void setState(int, long, float); method public void writeToParcel(android.os.Parcel, int); field public static final long ACTION_FASTFORWARD = 64L; // 0x40L field public static final long ACTION_NEXT_ITEM = 32L; // 0x20L field public static final long ACTION_PAUSE = 2L; // 0x2L field public static final long ACTION_PLAY = 4L; // 0x4L field public static final long ACTION_PLAY_PAUSE = 512L; // 0x200L field public static final long ACTION_PREVIOUS_ITEM = 16L; // 0x10L field public static final long ACTION_RATING = 128L; // 0x80L field public static final long ACTION_REWIND = 8L; // 0x8L field public static final long ACTION_SEEK_TO = 256L; // 0x100L field public static final long ACTION_STOP = 1L; // 0x1L field public static final android.os.Parcelable.Creator CREATOR; field public static final long PLAYBACK_POSITION_UNKNOWN = -1L; // 0xffffffffffffffffL field public static final int PLAYSTATE_BUFFERING = 6; // 0x6 field public static final int PLAYSTATE_CONNECTING = 8; // 0x8 field public static final int PLAYSTATE_ERROR = 7; // 0x7 Loading @@ -15177,6 +15179,8 @@ package android.media.session { field public static final int PLAYSTATE_PAUSED = 2; // 0x2 field public static final int PLAYSTATE_PLAYING = 3; // 0x3 field public static final int PLAYSTATE_REWINDING = 5; // 0x5 field public static final int PLAYSTATE_SKIPPING_BACKWARDS = 9; // 0x9 field public static final int PLAYSTATE_SKIPPING_FORWARDS = 10; // 0xa field public static final int PLAYSTATE_STOPPED = 1; // 0x1 }
media/java/android/media/AudioManager.java +23 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.media.RemoteController.OnClientUpdateListener; import android.media.session.MediaSessionLegacyHelper; import android.os.Binder; import android.os.Handler; import android.os.IBinder; Loading @@ -48,6 +49,12 @@ import java.util.HashMap; */ public class AudioManager { // If we should use the new sessions APIs. private final static boolean USE_SESSIONS = true; // If we should use the legacy APIs. If both are true information will be // duplicated through both paths. Currently this flag isn't used. private final static boolean USE_LEGACY = true; private final Context mContext; private long mVolumeKeyUpTime; private final boolean mUseMasterVolume; Loading Loading @@ -421,6 +428,7 @@ public class AudioManager { public static final int USE_DEFAULT_STREAM_TYPE = Integer.MIN_VALUE; private static IAudioService sService; private MediaSessionLegacyHelper mSessionHelper; /** * @hide Loading @@ -431,6 +439,9 @@ public class AudioManager { com.android.internal.R.bool.config_useMasterVolume); mUseVolumeKeySounds = mContext.getResources().getBoolean( com.android.internal.R.bool.config_useVolumeKeySounds); if (USE_SESSIONS) { mSessionHelper = MediaSessionLegacyHelper.getHelper(context); } } private static IAudioService getService() Loading Loading @@ -2166,6 +2177,9 @@ public class AudioManager { } catch (RemoteException e) { Log.e(TAG, "Dead object in registerMediaButtonIntent"+e); } if (USE_SESSIONS) { mSessionHelper.addMediaButtonListener(pi, mContext); } } /** Loading Loading @@ -2239,6 +2253,9 @@ public class AudioManager { } catch (RemoteException e) { Log.e(TAG, "Dead object in unregisterMediaButtonIntent"+e); } if (USE_SESSIONS) { mSessionHelper.removeMediaButtonListener(pi); } } /** Loading @@ -2263,6 +2280,9 @@ public class AudioManager { } catch (RemoteException e) { Log.e(TAG, "Dead object in registerRemoteControlClient"+e); } if (USE_SESSIONS) { rcClient.registerWithSession(mSessionHelper); } } /** Loading @@ -2282,6 +2302,9 @@ public class AudioManager { } catch (RemoteException e) { Log.e(TAG, "Dead object in unregisterRemoteControlClient"+e); } if (USE_SESSIONS) { rcClient.unregisterWithSession(mSessionHelper); } } /** Loading
media/java/android/media/MediaMetadataEditor.java +6 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package android.media; import android.graphics.Bitmap; import android.media.session.MediaMetadata; import android.os.Bundle; import android.os.Parcelable; import android.util.Log; Loading Loading @@ -106,6 +107,10 @@ public abstract class MediaMetadataEditor { */ protected Bundle mEditorMetadata; /** * @hide */ protected MediaMetadata.Builder mMetadataBuilder; /** * Clears all the pending metadata changes set since the MediaMetadataEditor instance was Loading @@ -120,6 +125,7 @@ public abstract class MediaMetadataEditor { } mEditorMetadata.clear(); mEditorArtwork = null; mMetadataBuilder = new MediaMetadata.Builder(); } /** Loading
media/java/android/media/RemoteControlClient.java +117 −12 Original line number Diff line number Diff line Loading @@ -24,6 +24,11 @@ import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.RectF; import android.media.session.MediaMetadata; import android.media.session.MediaSessionLegacyHelper; import android.media.session.PlaybackState; import android.media.session.Session; import android.media.session.TransportPerformer; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; Loading Loading @@ -336,6 +341,8 @@ public class RemoteControlClient */ public final static int FLAG_INFORMATION_REQUEST_ALBUM_ART = 1 << 3; private Session mSession; /** * Class constructor. * @param mediaButtonIntent The intent that will be sent for the media button events sent Loading Loading @@ -384,6 +391,22 @@ public class RemoteControlClient mEventHandler = new EventHandler(this, looper); } /** * @hide */ public void registerWithSession(MediaSessionLegacyHelper helper) { helper.addRccListener(mRcMediaIntent, mTransportListener); mSession = helper.getSession(mRcMediaIntent); } /** * @hide */ public void unregisterWithSession(MediaSessionLegacyHelper helper) { helper.removeRccListener(mRcMediaIntent); mSession = null; } /** * Class used to modify metadata in a {@link RemoteControlClient} object. * Use {@link RemoteControlClient#editMetadata(boolean)} to create an instance of an editor, Loading Loading @@ -438,6 +461,15 @@ public class RemoteControlClient public synchronized MetadataEditor putString(int key, String value) throws IllegalArgumentException { super.putString(key, value); if (mMetadataBuilder != null) { // MediaMetadata supports all the same fields as MetadataEditor String metadataKey = MediaMetadata.getKeyFromMetadataEditorKey(key); // But just in case, don't add things we don't understand if (metadataKey != null) { mMetadataBuilder.putString(metadataKey, value); } } return this; } Loading @@ -459,6 +491,14 @@ public class RemoteControlClient public synchronized MetadataEditor putLong(int key, long value) throws IllegalArgumentException { super.putLong(key, value); if (mMetadataBuilder != null) { // MediaMetadata supports all the same fields as MetadataEditor String metadataKey = MediaMetadata.getKeyFromMetadataEditorKey(key); // But just in case, don't add things we don't understand if (metadataKey != null) { mMetadataBuilder.putLong(metadataKey, value); } } return this; } Loading @@ -476,6 +516,14 @@ public class RemoteControlClient public synchronized MetadataEditor putBitmap(int key, Bitmap bitmap) throws IllegalArgumentException { super.putBitmap(key, bitmap); if (mMetadataBuilder != null) { // MediaMetadata supports all the same fields as MetadataEditor String metadataKey = MediaMetadata.getKeyFromMetadataEditorKey(key); // But just in case, don't add things we don't understand if (metadataKey != null) { mMetadataBuilder.putBitmap(metadataKey, bitmap); } } return this; } Loading Loading @@ -521,6 +569,11 @@ public class RemoteControlClient // send to remote control display if conditions are met sendArtwork_syncCacheLock(null, 0, 0); } // USE_SESSIONS if (mSession != null && mMetadataBuilder != null) { mSession.getTransportPerformer().setMetadata(mMetadataBuilder.build()); } mApplied = true; } } Loading @@ -546,6 +599,12 @@ public class RemoteControlClient editor.mMetadataChanged = false; editor.mArtworkChanged = false; } // USE_SESSIONS if (startEmpty || mMediaMetadata == null) { editor.mMetadataBuilder = new MediaMetadata.Builder(); } else { editor.mMetadataBuilder = new MediaMetadata.Builder(mMediaMetadata); } return editor; } Loading Loading @@ -624,6 +683,15 @@ public class RemoteControlClient // handle automatic playback position refreshes initiateCheckForDrift_syncCacheLock(); // USE_SESSIONS if (mSession != null) { int pbState = PlaybackState.getStateFromRccState(state); mSessionPlaybackState.setState(pbState, hasPosition ? mPlaybackPositionMs : PlaybackState.PLAYBACK_POSITION_UNKNOWN, playbackSpeed); mSession.getTransportPerformer().setPlaybackState(mSessionPlaybackState); } } } } Loading Loading @@ -704,6 +772,13 @@ public class RemoteControlClient // send to remote control display if conditions are met sendTransportControlInfo_syncCacheLock(null); // USE_SESSIONS if (mSession != null) { mSessionPlaybackState.setActions(PlaybackState .getActionsFromRccControlFlags(transportControlFlags)); mSession.getTransportPerformer().setPlaybackState(mSessionPlaybackState); } } } Loading Loading @@ -1037,6 +1112,16 @@ public class RemoteControlClient // TODO consider using a ref count for IRemoteControlDisplay requiring sync instead private boolean mNeedsPositionSync = false; /** * Cache for the current playback state using Session APIs. */ private final PlaybackState mSessionPlaybackState = new PlaybackState(); /** * Cache for metadata using Session APIs. This is re-initialized in apply(). */ private MediaMetadata mMediaMetadata; /** * A class to encapsulate all the information about a remote control display. * A RemoteControlClient's metadata and state may be displayed on multiple IRemoteControlDisplay Loading Loading @@ -1219,6 +1304,26 @@ public class RemoteControlClient return mRcseId; } // USE_SESSIONS private TransportPerformer.Listener mTransportListener = new TransportPerformer.Listener() { @Override public void onSeekTo(long pos) { RemoteControlClient.this.onSeekTo(mCurrentClientGenId, pos); } @Override public void onRate(Rating rating) { if ((mTransportControlFlags & FLAG_KEY_MEDIA_RATING) != 0) { if (mEventHandler != null) { mEventHandler.sendMessage(mEventHandler.obtainMessage( MSG_UPDATE_METADATA, mCurrentClientGenId, MetadataEditor.RATING_KEY_BY_USER, rating)); } } } }; private EventHandler mEventHandler; private final static int MSG_REQUEST_PLAYBACK_STATE = 1; private final static int MSG_REQUEST_METADATA = 2; Loading Loading @@ -1325,7 +1430,7 @@ public class RemoteControlClient // target == null implies all displays must be updated final Iterator<DisplayInfoForClient> displayIterator = mRcDisplays.iterator(); while (displayIterator.hasNext()) { final DisplayInfoForClient di = (DisplayInfoForClient) displayIterator.next(); final DisplayInfoForClient di = displayIterator.next(); if (di.mEnabled) { try { di.mRcDisplay.setPlaybackState(mInternalClientGenId, Loading Loading @@ -1353,7 +1458,7 @@ public class RemoteControlClient // target == null implies all displays must be updated final Iterator<DisplayInfoForClient> displayIterator = mRcDisplays.iterator(); while (displayIterator.hasNext()) { final DisplayInfoForClient di = (DisplayInfoForClient) displayIterator.next(); final DisplayInfoForClient di = displayIterator.next(); if (di.mEnabled) { try { di.mRcDisplay.setMetadata(mInternalClientGenId, mMetadata); Loading Loading @@ -1381,7 +1486,7 @@ public class RemoteControlClient // target == null implies all displays must be updated final Iterator<DisplayInfoForClient> displayIterator = mRcDisplays.iterator(); while (displayIterator.hasNext()) { final DisplayInfoForClient di = (DisplayInfoForClient) displayIterator.next(); final DisplayInfoForClient di = displayIterator.next(); if (di.mEnabled) { try { di.mRcDisplay.setTransportControlInfo(mInternalClientGenId, Loading @@ -1407,7 +1512,7 @@ public class RemoteControlClient // target == null implies all displays must be updated final Iterator<DisplayInfoForClient> displayIterator = mRcDisplays.iterator(); while (displayIterator.hasNext()) { if (!sendArtworkToDisplay((DisplayInfoForClient) displayIterator.next())) { if (!sendArtworkToDisplay(displayIterator.next())) { displayIterator.remove(); } } Loading Loading @@ -1453,7 +1558,7 @@ public class RemoteControlClient // target == null implies all displays must be updated final Iterator<DisplayInfoForClient> displayIterator = mRcDisplays.iterator(); while (displayIterator.hasNext()) { final DisplayInfoForClient di = (DisplayInfoForClient) displayIterator.next(); final DisplayInfoForClient di = displayIterator.next(); try { if (di.mEnabled) { if ((di.mArtworkExpectedWidth > 0) && (di.mArtworkExpectedHeight > 0)) { Loading Loading @@ -1537,7 +1642,7 @@ public class RemoteControlClient boolean displayKnown = false; final Iterator<DisplayInfoForClient> displayIterator = mRcDisplays.iterator(); while (displayIterator.hasNext() && !displayKnown) { final DisplayInfoForClient di = (DisplayInfoForClient) displayIterator.next(); final DisplayInfoForClient di = displayIterator.next(); displayKnown = di.mRcDisplay.asBinder().equals(rcd.asBinder()); if (displayKnown) { // this display was known but the change in artwork size will cause the Loading @@ -1562,7 +1667,7 @@ public class RemoteControlClient synchronized(mCacheLock) { Iterator<DisplayInfoForClient> displayIterator = mRcDisplays.iterator(); while (displayIterator.hasNext()) { final DisplayInfoForClient di = (DisplayInfoForClient) displayIterator.next(); final DisplayInfoForClient di = displayIterator.next(); if (di.mRcDisplay.asBinder().equals(rcd.asBinder())) { displayIterator.remove(); break; Loading @@ -1573,7 +1678,7 @@ public class RemoteControlClient boolean newNeedsPositionSync = false; displayIterator = mRcDisplays.iterator(); while (displayIterator.hasNext()) { final DisplayInfoForClient di = (DisplayInfoForClient) displayIterator.next(); final DisplayInfoForClient di = displayIterator.next(); if (di.mWantsPositionSync) { newNeedsPositionSync = true; break; Loading @@ -1592,7 +1697,7 @@ public class RemoteControlClient synchronized(mCacheLock) { final Iterator<DisplayInfoForClient> displayIterator = mRcDisplays.iterator(); while (displayIterator.hasNext()) { final DisplayInfoForClient di = (DisplayInfoForClient) displayIterator.next(); final DisplayInfoForClient di = displayIterator.next(); if (di.mRcDisplay.asBinder().equals(rcd.asBinder()) && ((di.mArtworkExpectedWidth != w) || (di.mArtworkExpectedHeight != h))) { di.mArtworkExpectedWidth = w; Loading @@ -1617,7 +1722,7 @@ public class RemoteControlClient // go through the list of RCDs and for each entry, check both whether this is the RCD // that gets upated, and whether the list has one entry that wants position sync while (displayIterator.hasNext()) { final DisplayInfoForClient di = (DisplayInfoForClient) displayIterator.next(); final DisplayInfoForClient di = displayIterator.next(); if (di.mEnabled) { if (di.mRcDisplay.asBinder().equals(rcd.asBinder())) { di.mWantsPositionSync = wantsSync; Loading @@ -1640,7 +1745,7 @@ public class RemoteControlClient synchronized(mCacheLock) { final Iterator<DisplayInfoForClient> displayIterator = mRcDisplays.iterator(); while (displayIterator.hasNext()) { final DisplayInfoForClient di = (DisplayInfoForClient) displayIterator.next(); final DisplayInfoForClient di = displayIterator.next(); if (di.mRcDisplay.asBinder().equals(rcd.asBinder())) { di.mEnabled = enable; } Loading
media/java/android/media/session/MediaMetadata.java +69 −7 Original line number Diff line number Diff line Loading @@ -16,12 +16,15 @@ package android.media.session; import android.graphics.Bitmap; import android.media.MediaMetadataEditor; import android.media.MediaMetadataRetriever; import android.media.Rating; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; import android.util.ArrayMap; import android.util.Log; import android.util.SparseArray; /** * Contains metadata about an item, such as the title, artist, etc. Loading @@ -40,7 +43,8 @@ public final class MediaMetadata implements Parcelable { public static final String METADATA_KEY_ARTIST = "android.media.metadata.ARTIST"; /** * The duration of the media in ms. A duration of 0 is the default. * The duration of the media in ms. A negative duration indicates that the * duration is unknown (or infinite). */ public static final String METADATA_KEY_DURATION = "android.media.metadata.DURATION"; Loading @@ -64,13 +68,18 @@ public final class MediaMetadata implements Parcelable { */ public static final String METADATA_KEY_COMPOSER = "android.media.metadata.COMPOSER"; /** * The compilation status of the media. */ public static final String METADATA_KEY_COMPILATION = "android.media.metadata.COMPILATION"; /** * The date the media was created or published as TODO determine format. */ public static final String METADATA_KEY_DATE = "android.media.metadata.DATE"; /** * The year the media was created or published as a numeric String. * The year the media was created or published as a long. */ public static final String METADATA_KEY_YEAR = "android.media.metadata.YEAR"; Loading Loading @@ -151,8 +160,9 @@ public final class MediaMetadata implements Parcelable { METADATA_KEYS_TYPE.put(METADATA_KEY_AUTHOR, METADATA_TYPE_STRING); METADATA_KEYS_TYPE.put(METADATA_KEY_WRITER, METADATA_TYPE_STRING); METADATA_KEYS_TYPE.put(METADATA_KEY_COMPOSER, METADATA_TYPE_STRING); METADATA_KEYS_TYPE.put(METADATA_KEY_COMPILATION, METADATA_TYPE_STRING); METADATA_KEYS_TYPE.put(METADATA_KEY_DATE, METADATA_TYPE_STRING); METADATA_KEYS_TYPE.put(METADATA_KEY_YEAR, METADATA_TYPE_STRING); METADATA_KEYS_TYPE.put(METADATA_KEY_YEAR, METADATA_TYPE_LONG); METADATA_KEYS_TYPE.put(METADATA_KEY_GENRE, METADATA_TYPE_STRING); METADATA_KEYS_TYPE.put(METADATA_KEY_TRACK_NUMBER, METADATA_TYPE_LONG); METADATA_KEYS_TYPE.put(METADATA_KEY_NUM_TRACKS, METADATA_TYPE_LONG); Loading @@ -165,6 +175,36 @@ public final class MediaMetadata implements Parcelable { METADATA_KEYS_TYPE.put(METADATA_KEY_USER_RATING, METADATA_TYPE_RATING); METADATA_KEYS_TYPE.put(METADATA_KEY_RATING, METADATA_TYPE_RATING); } private static final SparseArray<String> EDITOR_KEY_MAPPING; static { EDITOR_KEY_MAPPING = new SparseArray<String>(); EDITOR_KEY_MAPPING.put(MediaMetadataEditor.BITMAP_KEY_ARTWORK, METADATA_KEY_ART); EDITOR_KEY_MAPPING.put(MediaMetadataEditor.RATING_KEY_BY_OTHERS, METADATA_KEY_RATING); EDITOR_KEY_MAPPING.put(MediaMetadataEditor.RATING_KEY_BY_USER, METADATA_KEY_USER_RATING); EDITOR_KEY_MAPPING.put(MediaMetadataRetriever.METADATA_KEY_ALBUM, METADATA_KEY_ALBUM); EDITOR_KEY_MAPPING.put(MediaMetadataRetriever.METADATA_KEY_ALBUMARTIST, METADATA_KEY_ALBUM_ARTIST); EDITOR_KEY_MAPPING.put(MediaMetadataRetriever.METADATA_KEY_ARTIST, METADATA_KEY_ARTIST); EDITOR_KEY_MAPPING.put(MediaMetadataRetriever.METADATA_KEY_AUTHOR, METADATA_KEY_AUTHOR); EDITOR_KEY_MAPPING.put(MediaMetadataRetriever.METADATA_KEY_CD_TRACK_NUMBER, METADATA_KEY_TRACK_NUMBER); EDITOR_KEY_MAPPING.put(MediaMetadataRetriever.METADATA_KEY_COMPOSER, METADATA_KEY_COMPOSER); EDITOR_KEY_MAPPING.put(MediaMetadataRetriever.METADATA_KEY_COMPILATION, METADATA_KEY_COMPILATION); EDITOR_KEY_MAPPING.put(MediaMetadataRetriever.METADATA_KEY_DATE, METADATA_KEY_DATE); EDITOR_KEY_MAPPING.put(MediaMetadataRetriever.METADATA_KEY_DISC_NUMBER, METADATA_KEY_DISC_NUMBER); EDITOR_KEY_MAPPING.put(MediaMetadataRetriever.METADATA_KEY_DURATION, METADATA_KEY_DURATION); EDITOR_KEY_MAPPING.put(MediaMetadataRetriever.METADATA_KEY_GENRE, METADATA_KEY_GENRE); EDITOR_KEY_MAPPING.put(MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS, METADATA_KEY_NUM_TRACKS); EDITOR_KEY_MAPPING.put(MediaMetadataRetriever.METADATA_KEY_TITLE, METADATA_KEY_TITLE); EDITOR_KEY_MAPPING.put(MediaMetadataRetriever.METADATA_KEY_WRITER, METADATA_KEY_WRITER); EDITOR_KEY_MAPPING.put(MediaMetadataRetriever.METADATA_KEY_YEAR, METADATA_KEY_YEAR); } private final Bundle mBundle; private MediaMetadata(Bundle bundle) { Loading @@ -175,6 +215,16 @@ public final class MediaMetadata implements Parcelable { mBundle = in.readBundle(); } /** * Returns true if the given key is contained in the metadata * * @param key a String key * @return true if the key exists in this metadata, false otherwise */ public boolean containsKey(String key) { return mBundle.containsKey(key); } /** * Returns the value associated with the given key, or null if no mapping of * the desired type exists for the given key or a null value is explicitly Loading @@ -195,7 +245,7 @@ public final class MediaMetadata implements Parcelable { * @return a long value */ public long getLong(String key) { return mBundle.getLong(key); return mBundle.getLong(key, 0); } /** Loading Loading @@ -244,6 +294,18 @@ public final class MediaMetadata implements Parcelable { dest.writeBundle(mBundle); } /** * Helper for getting the String key used by {@link MediaMetadata} from the * integer key that {@link MediaMetadataEditor} uses. * * @param editorKey The key used by the editor * @return The key used by this class or null if no mapping exists * @hide */ public static String getKeyFromMetadataEditorKey(int editorKey) { return EDITOR_KEY_MAPPING.get(editorKey, null); } public static final Parcelable.Creator<MediaMetadata> CREATOR = new Parcelable.Creator<MediaMetadata>() { @Override Loading Loading @@ -295,10 +357,9 @@ public final class MediaMetadata implements Parcelable { * <li>{@link #METADATA_KEY_WRITER}</li> * <li>{@link #METADATA_KEY_COMPOSER}</li> * <li>{@link #METADATA_KEY_DATE}</li> * <li>{@link #METADATA_KEY_YEAR}</li> * <li>{@link #METADATA_KEY_GENRE}</li> * <li>{@link #METADATA_KEY_ALBUM_ARTIST}</li>li> * <li>{@link #METADATA_KEY_ART_URI}</li>li> * <li>{@link #METADATA_KEY_ALBUM_ARTIST}</li> * <li>{@link #METADATA_KEY_ART_URI}</li> * <li>{@link #METADATA_KEY_ALBUM_ART_URI}</li> * </ul> * Loading Loading @@ -326,6 +387,7 @@ public final class MediaMetadata implements Parcelable { * <li>{@link #METADATA_KEY_TRACK_NUMBER}</li> * <li>{@link #METADATA_KEY_NUM_TRACKS}</li> * <li>{@link #METADATA_KEY_DISC_NUMBER}</li> * <li>{@link #METADATA_KEY_YEAR}</li> * </ul> * * @param key The key for referencing this value Loading