Avoid bundling PlayerInfo for in-process calls

PlayerInfo bundling is costly and we can add a shortcut for
in-process binder calls where we store the direct object
reference in a live Binder object that can be written to the
Bundle instead of the individual data fields.

#minor-release

PiperOrigin-RevId: 572816784
This commit is contained in:
tonihei 2023-10-12 01:13:22 -07:00 committed by Copybara-Service
parent 4ebe630a80
commit d1fc15f207
2 changed files with 30 additions and 2 deletions

View File

@ -1915,9 +1915,13 @@ import java.util.concurrent.ExecutionException;
if (controllerInterfaceVersion >= 2) { if (controllerInterfaceVersion >= 2) {
PlayerInfo filteredPlayerInfo = PlayerInfo filteredPlayerInfo =
playerInfo.filterByAvailableCommands(availableCommands, excludeTimeline, excludeTracks); playerInfo.filterByAvailableCommands(availableCommands, excludeTimeline, excludeTracks);
Bundle playerInfoBundle =
iController instanceof MediaControllerStub
? filteredPlayerInfo.toBundleInProcess()
: filteredPlayerInfo.toBundle();
iController.onPlayerInfoChangedWithExclusions( iController.onPlayerInfoChangedWithExclusions(
sequenceNumber, sequenceNumber,
filteredPlayerInfo.toBundle(), playerInfoBundle,
new PlayerInfo.BundlingExclusions(bundlingExclusionsTimeline, bundlingExclusionsTracks) new PlayerInfo.BundlingExclusions(bundlingExclusionsTimeline, bundlingExclusionsTracks)
.toBundle()); .toBundle());
} else { } else {

View File

@ -22,7 +22,9 @@ import static androidx.media3.common.Player.PLAY_WHEN_READY_CHANGE_REASON_USER_R
import static androidx.media3.common.Player.STATE_IDLE; import static androidx.media3.common.Player.STATE_IDLE;
import static androidx.media3.common.Player.TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED; import static androidx.media3.common.Player.TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED;
import android.os.Binder;
import android.os.Bundle; import android.os.Bundle;
import android.os.IBinder;
import androidx.annotation.CheckResult; import androidx.annotation.CheckResult;
import androidx.annotation.FloatRange; import androidx.annotation.FloatRange;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
@ -44,6 +46,7 @@ import androidx.media3.common.Tracks;
import androidx.media3.common.VideoSize; import androidx.media3.common.VideoSize;
import androidx.media3.common.text.CueGroup; import androidx.media3.common.text.CueGroup;
import androidx.media3.common.util.Assertions; import androidx.media3.common.util.Assertions;
import androidx.media3.common.util.BundleUtil;
import androidx.media3.common.util.UnstableApi; import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util; import androidx.media3.common.util.Util;
import com.google.common.base.Objects; import com.google.common.base.Objects;
@ -824,8 +827,9 @@ import com.google.errorprone.annotations.CanIgnoreReturnValue;
private static final String FIELD_TRACK_SELECTION_PARAMETERS = Util.intToStringMaxRadix(29); private static final String FIELD_TRACK_SELECTION_PARAMETERS = Util.intToStringMaxRadix(29);
private static final String FIELD_CURRENT_TRACKS = Util.intToStringMaxRadix(30); private static final String FIELD_CURRENT_TRACKS = Util.intToStringMaxRadix(30);
private static final String FIELD_TIMELINE_CHANGE_REASON = Util.intToStringMaxRadix(31); private static final String FIELD_TIMELINE_CHANGE_REASON = Util.intToStringMaxRadix(31);
private static final String FIELD_IN_PROCESS_BINDER = Util.intToStringMaxRadix(32);
// Next field key = 32 // Next field key = 33
/** /**
* Returns a copy of this player info, filtered by the specified available commands. * Returns a copy of this player info, filtered by the specified available commands.
@ -882,6 +886,16 @@ import com.google.errorprone.annotations.CanIgnoreReturnValue;
return builder.build(); return builder.build();
} }
/**
* Returns a {@link Bundle} that stores a direct object reference to this class for in-process
* sharing.
*/
public Bundle toBundleInProcess() {
Bundle bundle = new Bundle();
BundleUtil.putBinder(bundle, FIELD_IN_PROCESS_BINDER, new InProcessBinder());
return bundle;
}
@Override @Override
public Bundle toBundle() { public Bundle toBundle() {
Bundle bundle = new Bundle(); Bundle bundle = new Bundle();
@ -985,6 +999,10 @@ import com.google.errorprone.annotations.CanIgnoreReturnValue;
public static final Creator<PlayerInfo> CREATOR = PlayerInfo::fromBundle; public static final Creator<PlayerInfo> CREATOR = PlayerInfo::fromBundle;
private static PlayerInfo fromBundle(Bundle bundle) { private static PlayerInfo fromBundle(Bundle bundle) {
@Nullable IBinder inProcessBinder = BundleUtil.getBinder(bundle, FIELD_IN_PROCESS_BINDER);
if (inProcessBinder instanceof InProcessBinder) {
return ((InProcessBinder) inProcessBinder).getPlayerInfo();
}
@Nullable Bundle playerErrorBundle = bundle.getBundle(FIELD_PLAYBACK_ERROR); @Nullable Bundle playerErrorBundle = bundle.getBundle(FIELD_PLAYBACK_ERROR);
@Nullable @Nullable
PlaybackException playerError = PlaybackException playerError =
@ -1115,4 +1133,10 @@ import com.google.errorprone.annotations.CanIgnoreReturnValue;
currentTracks, currentTracks,
trackSelectionParameters); trackSelectionParameters);
} }
private final class InProcessBinder extends Binder {
public PlayerInfo getPlayerInfo() {
return PlayerInfo.this;
}
}
} }