media/src/main/java/androidx/media/MediaController2ImplBase.java
void onConnectedNotLocked(Bundle data) {
        data.setClassLoader(MediaSession2.class.getClassLoader());
        // is enough or should we pass it while connecting?
        final SessionCommandGroup2 allowedCommands = SessionCommandGroup2.fromBundle(
                data.getBundle(ARGUMENT_ALLOWED_COMMANDS));
        final int playerState = data.getInt(ARGUMENT_PLAYER_STATE);
        final int bufferingState = data.getInt(ARGUMENT_BUFFERING_STATE);
        final PlaybackStateCompat playbackStateCompat = data.getParcelable(
                ARGUMENT_PLAYBACK_STATE_COMPAT);
        final int repeatMode = data.getInt(ARGUMENT_REPEAT_MODE);
        final int shuffleMode = data.getInt(ARGUMENT_SHUFFLE_MODE);
        final List<MediaItem2> playlist = MediaUtils2.fromMediaItem2ParcelableArray(
                data.getParcelableArray(ARGUMENT_PLAYLIST));
        final MediaItem2 currentMediaItem = MediaItem2.fromBundle(
                data.getBundle(ARGUMENT_MEDIA_ITEM));
        final PlaybackInfo playbackInfo =
                PlaybackInfo.fromBundle(data.getBundle(ARGUMENT_PLAYBACK_INFO));
        final MediaMetadata2 metadata = MediaMetadata2.fromBundle(
                data.getBundle(ARGUMENT_PLAYLIST_METADATA));
        if (DEBUG) {
            Log.d(TAG, "onConnectedNotLocked sessionCompatToken=" + mToken.getSessionCompatToken()
                    + ", allowedCommands=" + allowedCommands);
        }
        boolean close = false;
        try {
            synchronized (mLock) {
                if (mIsReleased) {
                    return;
                }
                if (mConnected) {
                    Log.e(TAG, "Cannot be notified about the connection result many times."
                            + " Probably a bug or malicious app.");
                    close = true;
                    return;
                }
                mAllowedCommands = allowedCommands;
                mPlayerState = playerState;
                mBufferingState = bufferingState;
                mPlaybackStateCompat = playbackStateCompat;
                mRepeatMode = repeatMode;
                mShuffleMode = shuffleMode;
                mPlaylist = playlist;
                mCurrentMediaItem = currentMediaItem;
                mPlaylistMetadata = metadata;
                mConnected = true;
                mPlaybackInfo = playbackInfo;
            }
            mCallbackExecutor.execute(new Runnable() {
                @Override
                public void run() {
                    // Note: We may trigger ControllerCallbacks with the initial values
                    // But it's hard to define the order of the controller callbacks
                    // Only notify about the
                    mCallback.onConnected(mInstance, allowedCommands);
                }
            });
        } finally {
            if (close) {
                // Trick to call release() without holding the lock, to prevent potential deadlock
                // with the developer's custom lock within the ControllerCallback.onDisconnected().
                close();
            }
        }
    }
// Should be used without a lock to prevent potential deadlock.
Should be used without a lock to prevent potential deadlock.
Should be used without a lock to prevent potential deadlock .
void onConnectedNotLocked(Bundle data) {
        data.setClassLoader(MediaSession2.class.getClassLoader());
        final SessionCommandGroup2 allowedCommands = SessionCommandGroup2.fromBundle(
                data.getBundle(ARGUMENT_ALLOWED_COMMANDS));
        final int playerState = data.getInt(ARGUMENT_PLAYER_STATE);
        final int bufferingState = data.getInt(ARGUMENT_BUFFERING_STATE);
        final PlaybackStateCompat playbackStateCompat = data.getParcelable(
                ARGUMENT_PLAYBACK_STATE_COMPAT);
        final int repeatMode = data.getInt(ARGUMENT_REPEAT_MODE);
        final int shuffleMode = data.getInt(ARGUMENT_SHUFFLE_MODE);
        final List<MediaItem2> playlist = MediaUtils2.fromMediaItem2ParcelableArray(
                data.getParcelableArray(ARGUMENT_PLAYLIST));
        final MediaItem2 currentMediaItem = MediaItem2.fromBundle(
                data.getBundle(ARGUMENT_MEDIA_ITEM));
        final PlaybackInfo playbackInfo =
                PlaybackInfo.fromBundle(data.getBundle(ARGUMENT_PLAYBACK_INFO));
        final MediaMetadata2 metadata = MediaMetadata2.fromBundle(
                data.getBundle(ARGUMENT_PLAYLIST_METADATA));
        if (DEBUG) {
            Log.d(TAG, "onConnectedNotLocked sessionCompatToken=" + mToken.getSessionCompatToken()
                    + ", allowedCommands=" + allowedCommands);
        }
        boolean close = false;
        try {
            synchronized (mLock) {
                if (mIsReleased) {
                    return;
                }
                if (mConnected) {
                    Log.e(TAG, "Cannot be notified about the connection result many times."
                            + " Probably a bug or malicious app.");
                    close = true;
                    return;
                }
                mAllowedCommands = allowedCommands;
                mPlayerState = playerState;
                mBufferingState = bufferingState;
                mPlaybackStateCompat = playbackStateCompat;
                mRepeatMode = repeatMode;
                mShuffleMode = shuffleMode;
                mPlaylist = playlist;
                mCurrentMediaItem = currentMediaItem;
                mPlaylistMetadata = metadata;
                mConnected = true;
                mPlaybackInfo = playbackInfo;
            }
            mCallbackExecutor.execute(new Runnable() {
                @Override
                public void run() {
                    mCallback.onConnected(mInstance, allowedCommands);
                }
            });
        } finally {
            if (close) {
                close();
            }
        }
    }
void onConnectedNotLocked ( Bundle data ) { data . setClassLoader ( MediaSession2 . class . getClassLoader ( ) ) ; final SessionCommandGroup2 allowedCommands = SessionCommandGroup2 . fromBundle ( data . getBundle ( ARGUMENT_ALLOWED_COMMANDS ) ) ; final int playerState = data . getInt ( ARGUMENT_PLAYER_STATE ) ; final int bufferingState = data . getInt ( ARGUMENT_BUFFERING_STATE ) ; final PlaybackStateCompat playbackStateCompat = data . getParcelable ( ARGUMENT_PLAYBACK_STATE_COMPAT ) ; final int repeatMode = data . getInt ( ARGUMENT_REPEAT_MODE ) ; final int shuffleMode = data . getInt ( ARGUMENT_SHUFFLE_MODE ) ; final List < MediaItem2 > playlist = MediaUtils2 . fromMediaItem2ParcelableArray ( data . getParcelableArray ( ARGUMENT_PLAYLIST ) ) ; final MediaItem2 currentMediaItem = MediaItem2 . fromBundle ( data . getBundle ( ARGUMENT_MEDIA_ITEM ) ) ; final PlaybackInfo playbackInfo = PlaybackInfo . fromBundle ( data . getBundle ( ARGUMENT_PLAYBACK_INFO ) ) ; final MediaMetadata2 metadata = MediaMetadata2 . fromBundle ( data . getBundle ( ARGUMENT_PLAYLIST_METADATA ) ) ; if ( DEBUG ) { Log . d ( TAG , "onConnectedNotLocked sessionCompatToken=" + mToken . getSessionCompatToken ( ) + ", allowedCommands=" + allowedCommands ) ; } boolean close = false ; try { synchronized ( mLock ) { if ( mIsReleased ) { return ; } if ( mConnected ) { Log . e ( TAG , "Cannot be notified about the connection result many times." + " Probably a bug or malicious app." ) ; close = true ; return ; } mAllowedCommands = allowedCommands ; mPlayerState = playerState ; mBufferingState = bufferingState ; mPlaybackStateCompat = playbackStateCompat ; mRepeatMode = repeatMode ; mShuffleMode = shuffleMode ; mPlaylist = playlist ; mCurrentMediaItem = currentMediaItem ; mPlaylistMetadata = metadata ; mConnected = true ; mPlaybackInfo = playbackInfo ; } mCallbackExecutor . execute ( new Runnable ( ) { @ Override public void run ( ) { mCallback . onConnected ( mInstance , allowedCommands ) ; } } ) ; } finally { if ( close ) { close ( ) ; } } }
Should be used without a lock to prevent potential deadlock.
Should be used without a lock to prevent potential deadlock .
// is enough or should we pass it while connecting? // Note: We may trigger ControllerCallbacks with the initial values // But it's hard to define the order of the controller callbacks // Only notify about the // Trick to call release() without holding the lock, to prevent potential deadlock // with the developer's custom lock within the ControllerCallback.onDisconnected().