Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 20d37aa1 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Notify callbacks outside lock from MediaSession" into sc-dev

parents 85c0b240 5a0152ba
Loading
Loading
Loading
Loading
+131 −83
Original line number Diff line number Diff line
@@ -55,7 +55,9 @@ import android.view.KeyEvent;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * This is the system implementation of a Session. Apps will interact with the
@@ -120,8 +122,8 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR
    private final Context mContext;

    private final Object mLock = new Object();
    private final ArrayList<ISessionControllerCallbackHolder> mControllerCallbackHolders =
            new ArrayList<>();
    private final CopyOnWriteArrayList<ISessionControllerCallbackHolder>
            mControllerCallbackHolders = new CopyOnWriteArrayList<>();

    private long mFlags;
    private MediaButtonReceiverHolder mMediaButtonReceiverHolder;
@@ -545,51 +547,66 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR
    }

    private void pushPlaybackStateUpdate() {
        PlaybackState playbackState;
        synchronized (mLock) {
            if (mDestroyed) {
                return;
            }
            for (int i = mControllerCallbackHolders.size() - 1; i >= 0; i--) {
                ISessionControllerCallbackHolder holder = mControllerCallbackHolders.get(i);
            playbackState = mPlaybackState;
        }
        Collection<ISessionControllerCallbackHolder> deadCallbackHolders = null;
        for (ISessionControllerCallbackHolder holder : mControllerCallbackHolders) {
            try {
                    holder.mCallback.onPlaybackStateChanged(mPlaybackState);
                holder.mCallback.onPlaybackStateChanged(playbackState);
            } catch (DeadObjectException e) {
                    mControllerCallbackHolders.remove(i);
                    logCallbackException("Removing dead callback in pushPlaybackStateUpdate",
                            holder, e);
                if (deadCallbackHolders == null) {
                    deadCallbackHolders = new ArrayList<>();
                }
                deadCallbackHolders.add(holder);
                logCallbackException("Removing dead callback in pushPlaybackStateUpdate", holder,
                        e);
            } catch (RemoteException e) {
                    logCallbackException("unexpected exception in pushPlaybackStateUpdate",
                            holder, e);
                logCallbackException("unexpected exception in pushPlaybackStateUpdate", holder, e);
            }
        }
        if (deadCallbackHolders != null) {
            mControllerCallbackHolders.removeAll(deadCallbackHolders);
        }
    }

    private void pushMetadataUpdate() {
        MediaMetadata metadata;
        synchronized (mLock) {
            if (mDestroyed) {
                return;
            }
            for (int i = mControllerCallbackHolders.size() - 1; i >= 0; i--) {
                ISessionControllerCallbackHolder holder = mControllerCallbackHolders.get(i);
            metadata = mMetadata;
        }
        Collection<ISessionControllerCallbackHolder> deadCallbackHolders = null;
        for (ISessionControllerCallbackHolder holder : mControllerCallbackHolders) {
            try {
                    holder.mCallback.onMetadataChanged(mMetadata);
                holder.mCallback.onMetadataChanged(metadata);
            } catch (DeadObjectException e) {
                    mControllerCallbackHolders.remove(i);
                if (deadCallbackHolders == null) {
                    deadCallbackHolders = new ArrayList<>();
                }
                deadCallbackHolders.add(holder);
                logCallbackException("Removing dead callback in pushMetadataUpdate", holder, e);
            } catch (RemoteException e) {
                logCallbackException("unexpected exception in pushMetadataUpdate", holder, e);
            }
        }
        if (deadCallbackHolders != null) {
            mControllerCallbackHolders.removeAll(deadCallbackHolders);
        }
    }

    private void pushQueueUpdate() {
        ParceledListSlice<QueueItem> parcelableQueue;
        synchronized (mLock) {
            if (mDestroyed) {
                return;
            }
            ParceledListSlice<QueueItem> parcelableQueue;
            if (mQueue == null) {
                parcelableQueue = null;
            } else {
@@ -598,76 +615,104 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR
                // as onQueueChanged is an async binder call.
                parcelableQueue.setInlineCountLimit(1);
            }
            for (int i = mControllerCallbackHolders.size() - 1; i >= 0; i--) {
                ISessionControllerCallbackHolder holder = mControllerCallbackHolders.get(i);
        }
        Collection<ISessionControllerCallbackHolder> deadCallbackHolders = null;
        for (ISessionControllerCallbackHolder holder : mControllerCallbackHolders) {
            try {
                holder.mCallback.onQueueChanged(parcelableQueue);
            } catch (DeadObjectException e) {
                    mControllerCallbackHolders.remove(i);
                if (deadCallbackHolders == null) {
                    deadCallbackHolders = new ArrayList<>();
                }
                deadCallbackHolders.add(holder);
                logCallbackException("Removing dead callback in pushQueueUpdate", holder, e);
            } catch (RemoteException e) {
                logCallbackException("unexpected exception in pushQueueUpdate", holder, e);
            }
        }
        if (deadCallbackHolders != null) {
            mControllerCallbackHolders.removeAll(deadCallbackHolders);
        }
    }

    private void pushQueueTitleUpdate() {
        CharSequence queueTitle;
        synchronized (mLock) {
            if (mDestroyed) {
                return;
            }
            for (int i = mControllerCallbackHolders.size() - 1; i >= 0; i--) {
                ISessionControllerCallbackHolder holder = mControllerCallbackHolders.get(i);
            queueTitle = mQueueTitle;
        }
        Collection<ISessionControllerCallbackHolder> deadCallbackHolders = null;
        for (ISessionControllerCallbackHolder holder : mControllerCallbackHolders) {
            try {
                    holder.mCallback.onQueueTitleChanged(mQueueTitle);
                holder.mCallback.onQueueTitleChanged(queueTitle);
            } catch (DeadObjectException e) {
                    mControllerCallbackHolders.remove(i);
                    logCallbackException("Removing dead callback in pushQueueTitleUpdate",
                            holder, e);
                if (deadCallbackHolders == null) {
                    deadCallbackHolders = new ArrayList<>();
                }
                deadCallbackHolders.add(holder);
                logCallbackException("Removing dead callback in pushQueueTitleUpdate", holder, e);
            } catch (RemoteException e) {
                logCallbackException("unexpected exception in pushQueueTitleUpdate", holder, e);
            }
        }
        if (deadCallbackHolders != null) {
            mControllerCallbackHolders.removeAll(deadCallbackHolders);
        }
    }

    private void pushExtrasUpdate() {
        Bundle extras;
        synchronized (mLock) {
            if (mDestroyed) {
                return;
            }
            for (int i = mControllerCallbackHolders.size() - 1; i >= 0; i--) {
                ISessionControllerCallbackHolder holder = mControllerCallbackHolders.get(i);
            extras = mExtras;
        }
        Collection<ISessionControllerCallbackHolder> deadCallbackHolders = null;
        for (ISessionControllerCallbackHolder holder : mControllerCallbackHolders) {
            try {
                    holder.mCallback.onExtrasChanged(mExtras);
                holder.mCallback.onExtrasChanged(extras);
            } catch (DeadObjectException e) {
                    mControllerCallbackHolders.remove(i);
                if (deadCallbackHolders == null) {
                    deadCallbackHolders = new ArrayList<>();
                }
                deadCallbackHolders.add(holder);
                logCallbackException("Removing dead callback in pushExtrasUpdate", holder, e);
            } catch (RemoteException e) {
                logCallbackException("unexpected exception in pushExtrasUpdate", holder, e);
            }
        }
        if (deadCallbackHolders != null) {
            mControllerCallbackHolders.removeAll(deadCallbackHolders);
        }
    }

    private void pushVolumeUpdate() {
        PlaybackInfo info;
        synchronized (mLock) {
            if (mDestroyed) {
                return;
            }
            PlaybackInfo info = getVolumeAttributes();
            for (int i = mControllerCallbackHolders.size() - 1; i >= 0; i--) {
                ISessionControllerCallbackHolder holder = mControllerCallbackHolders.get(i);
            info = getVolumeAttributes();
        }
        Collection<ISessionControllerCallbackHolder> deadCallbackHolders = null;
        for (ISessionControllerCallbackHolder holder : mControllerCallbackHolders) {
            try {
                holder.mCallback.onVolumeInfoChanged(info);
            } catch (DeadObjectException e) {
                    mControllerCallbackHolders.remove(i);
                if (deadCallbackHolders == null) {
                    deadCallbackHolders = new ArrayList<>();
                }
                deadCallbackHolders.add(holder);
                logCallbackException("Removing dead callback in pushVolumeUpdate", holder, e);
            } catch (RemoteException e) {
                logCallbackException("unexpected exception in pushVolumeUpdate", holder, e);
            }
        }
        if (deadCallbackHolders != null) {
            mControllerCallbackHolders.removeAll(deadCallbackHolders);
        }
    }

@@ -676,17 +721,23 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR
            if (mDestroyed) {
                return;
            }
            for (int i = mControllerCallbackHolders.size() - 1; i >= 0; i--) {
                ISessionControllerCallbackHolder holder = mControllerCallbackHolders.get(i);
        }
        Collection<ISessionControllerCallbackHolder> deadCallbackHolders = null;
        for (ISessionControllerCallbackHolder holder : mControllerCallbackHolders) {
            try {
                holder.mCallback.onEvent(event, data);
            } catch (DeadObjectException e) {
                    mControllerCallbackHolders.remove(i);
                if (deadCallbackHolders == null) {
                    deadCallbackHolders = new ArrayList<>();
                }
                deadCallbackHolders.add(holder);
                logCallbackException("Removing dead callback in pushEvent", holder, e);
            } catch (RemoteException e) {
                logCallbackException("unexpected exception in pushEvent", holder, e);
            }
        }
        if (deadCallbackHolders != null) {
            mControllerCallbackHolders.removeAll(deadCallbackHolders);
        }
    }

@@ -697,14 +748,12 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR
            if (!mDestroyed) {
                return;
            }
            for (int i = mControllerCallbackHolders.size() - 1; i >= 0; i--) {
                ISessionControllerCallbackHolder holder = mControllerCallbackHolders.get(i);
        }
        for (ISessionControllerCallbackHolder holder : mControllerCallbackHolders) {
            try {
                holder.mCallback.onSessionDestroyed();
            } catch (DeadObjectException e) {
                    mControllerCallbackHolders.remove(i);
                    logCallbackException("Removing dead callback in pushSessionDestroyed",
                            holder, e);
                logCallbackException("Removing dead callback in pushSessionDestroyed", holder, e);
            } catch (RemoteException e) {
                logCallbackException("unexpected exception in pushSessionDestroyed", holder, e);
            }
@@ -712,7 +761,6 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR
        // After notifying clear all listeners
        mControllerCallbackHolders.clear();
    }
    }

    private PlaybackState getStateWithUpdatedPosition() {
        PlaybackState state;