From 82df2c0839876d158889ea0e28e6f3adf0d4797d Mon Sep 17 00:00:00 2001 From: RoboErik Date: Wed, 8 Oct 2014 10:38:42 -0700 Subject: Ensure metadata bundles are unparceled before making them available Bundles can't be read from multiple threads safely. This adds locking around a read that had been previously overlooked and ensures that unparcel is called on the metadata before it is even available to other threads. bug:17894033 Change-Id: I9a4b86a0d0af05b1dcba28a52df2e7a87c685704 --- .../com/android/server/media/MediaSessionRecord.java | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'services/core') diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java index a0ec1d5..ebce3ad 100644 --- a/services/core/java/com/android/server/media/MediaSessionRecord.java +++ b/services/core/java/com/android/server/media/MediaSessionRecord.java @@ -625,12 +625,12 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { private PlaybackState getStateWithUpdatedPosition() { PlaybackState state; + long duration = -1; synchronized (mLock) { state = mPlaybackState; - } - long duration = -1; - if (mMetadata != null && mMetadata.containsKey(MediaMetadata.METADATA_KEY_DURATION)) { - duration = mMetadata.getLong(MediaMetadata.METADATA_KEY_DURATION); + if (mMetadata != null && mMetadata.containsKey(MediaMetadata.METADATA_KEY_DURATION)) { + duration = mMetadata.getLong(MediaMetadata.METADATA_KEY_DURATION); + } } PlaybackState result = null; if (state != null) { @@ -725,10 +725,14 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { @Override public void setMetadata(MediaMetadata metadata) { - // Make a copy of the metadata as the underlying bundle may be - // modified on this thread. synchronized (mLock) { - mMetadata = metadata == null ? null : new MediaMetadata.Builder(metadata).build(); + MediaMetadata temp = metadata == null ? null : new MediaMetadata.Builder(metadata) + .build(); + // This is to guarantee that the underlying bundle is unparceled + // before we set it to prevent concurrent reads from throwing an + // exception + temp.size(); + mMetadata = temp; } mHandler.post(MessageHandler.MSG_UPDATE_METADATA); } -- cgit v1.1