Ensure session extras Bundle is copied at least once

If not copied, the extras Bundle can be accidentally changed by the
app if it modifies the instance passed into MediaSession. On the flip
side, the Bundle should be modifiable once created so that the session
can amend the extras if needed without crashing.

PiperOrigin-RevId: 688485963
This commit is contained in:
tonihei 2024-10-22 04:00:53 -07:00 committed by Copybara-Service
parent be8c58d51e
commit d9ca3c734a
2 changed files with 60 additions and 6 deletions

View File

@ -1237,8 +1237,7 @@ public class MediaSession {
* @param sessionExtras The session extras.
*/
public final void setSessionExtras(Bundle sessionExtras) {
checkNotNull(sessionExtras);
impl.setSessionExtras(sessionExtras);
impl.setSessionExtras(new Bundle(sessionExtras));
}
/**
@ -1259,8 +1258,7 @@ public class MediaSession {
*/
public final void setSessionExtras(ControllerInfo controller, Bundle sessionExtras) {
checkNotNull(controller, "controller must not be null");
checkNotNull(sessionExtras);
impl.setSessionExtras(controller, sessionExtras);
impl.setSessionExtras(controller, new Bundle(sessionExtras));
}
/** Returns the {@link BitmapLoader}. */
@ -2284,8 +2282,8 @@ public class MediaSession {
checkArgument(player.canAdvertiseSession());
id = "";
this.callback = callback;
tokenExtras = Bundle.EMPTY;
sessionExtras = Bundle.EMPTY;
tokenExtras = new Bundle();
sessionExtras = new Bundle();
customLayout = ImmutableList.of();
mediaButtonPreferences = ImmutableList.of();
playIfSuppressed = true;

View File

@ -991,6 +991,62 @@ public class MediaSessionTest {
assertThat(isEventHandled).isFalse();
}
@Test
public void builderSetExtras_doesNotKeepOriginalInstance() {
Bundle extras = new Bundle();
extras.putString("key", "value");
MediaSession session = new MediaSession.Builder(context, player).setExtras(extras).build();
extras.putString("key", "newValue");
String sessionExtraValue = session.getToken().getExtras().getString("key");
session.release();
assertThat(sessionExtraValue).isEqualTo("value");
}
@Test
public void builderSetSessionExtras_doesNotKeepOriginalInstance() {
Bundle extras = new Bundle();
extras.putString("key", "value");
MediaSession session =
new MediaSession.Builder(context, player).setSessionExtras(extras).build();
extras.putString("key", "newValue");
String sessionExtraValue = session.getSessionExtras().getString("key");
session.release();
assertThat(sessionExtraValue).isEqualTo("value");
}
@Test
public void builder_defaultExtras_createsMutableInstance() {
MediaSession session = new MediaSession.Builder(context, player).build();
session.getSessionExtras().putString("key", "value");
String sessionExtraValue = session.getSessionExtras().getString("key");
session.release();
assertThat(sessionExtraValue).isEqualTo("value");
}
@Test
public void setSessionExtras_doesNotKeepOriginalInstance() throws Exception {
MediaSession session = new MediaSession.Builder(context, player).build();
Bundle extras = new Bundle();
extras.putString("key", "value");
AtomicReference<String> sessionExtraValue = new AtomicReference<>();
handler.postAndSync(
() -> {
session.setSessionExtras(extras);
extras.putString("key", "newValue");
sessionExtraValue.set(session.getSessionExtras().getString("key"));
session.release();
});
assertThat(sessionExtraValue.get()).isEqualTo("value");
}
private static Intent getMediaButtonIntent(int keyCode) {
Intent intent = new Intent(Intent.ACTION_MEDIA_BUTTON);
intent.setComponent(