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

Commit e4451f1a authored by Kevin Rocard's avatar Kevin Rocard Committed by Automerger Merge Worker
Browse files

Merge "[Bugfix][Media] Fix ISessionControllerCallback leaks in the...

Merge "[Bugfix][Media] Fix ISessionControllerCallback leaks in the system_server when the far side died" am: 04eeb94b am: b882a036 am: d96b16da am: 87463e8e

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1978026

Change-Id: I72a6b7bc21e31df820ded25f0cd61a82351e0112
parents 90cec3e2 87463e8e
Loading
Loading
Loading
Loading
+25 −3
Original line number Original line Diff line number Diff line
@@ -61,6 +61,7 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Collection;
import java.util.List;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.NoSuchElementException;


/**
/**
 * This is the system implementation of a Session. Apps will interact with the
 * This is the system implementation of a Session. Apps will interact with the
@@ -792,7 +793,10 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR
        }
        }
        for (ISessionControllerCallbackHolder holder : mControllerCallbackHolders) {
        for (ISessionControllerCallbackHolder holder : mControllerCallbackHolders) {
            try {
            try {
                holder.mCallback.asBinder().unlinkToDeath(holder.mDeathMonitor, 0);
                holder.mCallback.onSessionDestroyed();
                holder.mCallback.onSessionDestroyed();
            } catch (NoSuchElementException e) {
                logCallbackException("error unlinking to binder death", holder, e);
            } catch (DeadObjectException e) {
            } catch (DeadObjectException e) {
                logCallbackException("Removing dead callback in pushSessionDestroyed", holder, e);
                logCallbackException("Removing dead callback in pushSessionDestroyed", holder, e);
            } catch (RemoteException e) {
            } catch (RemoteException e) {
@@ -1375,12 +1379,22 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR
                    return;
                    return;
                }
                }
                if (getControllerHolderIndexForCb(cb) < 0) {
                if (getControllerHolderIndexForCb(cb) < 0) {
                    mControllerCallbackHolders.add(new ISessionControllerCallbackHolder(cb,
                    ISessionControllerCallbackHolder holder = new ISessionControllerCallbackHolder(
                            packageName, Binder.getCallingUid()));
                        cb, packageName, Binder.getCallingUid(), () -> unregisterCallback(cb));
                    mControllerCallbackHolders.add(holder);
                    if (DEBUG) {
                    if (DEBUG) {
                        Log.d(TAG, "registering controller callback " + cb + " from controller"
                        Log.d(TAG, "registering controller callback " + cb + " from controller"
                                + packageName);
                                + packageName);
                    }
                    }
                    // Avoid callback leaks
                    try {
                        // cb is not referenced outside of the MediaSessionRecord, so the death
                        // handler won't prevent MediaSessionRecord to be garbage collected.
                        cb.asBinder().linkToDeath(holder.mDeathMonitor, 0);
                    } catch (RemoteException e) {
                        unregisterCallback(cb);
                        Log.w(TAG, "registerCallback failed to linkToDeath", e);
                    }
                }
                }
            }
            }
        }
        }
@@ -1390,6 +1404,12 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR
            synchronized (mLock) {
            synchronized (mLock) {
                int index = getControllerHolderIndexForCb(cb);
                int index = getControllerHolderIndexForCb(cb);
                if (index != -1) {
                if (index != -1) {
                    try {
                        cb.asBinder().unlinkToDeath(
                          mControllerCallbackHolders.get(index).mDeathMonitor, 0);
                    } catch (NoSuchElementException e) {
                        Log.w(TAG, "error unlinking to binder death", e);
                    }
                    mControllerCallbackHolders.remove(index);
                    mControllerCallbackHolders.remove(index);
                }
                }
                if (DEBUG) {
                if (DEBUG) {
@@ -1600,12 +1620,14 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR
        private final ISessionControllerCallback mCallback;
        private final ISessionControllerCallback mCallback;
        private final String mPackageName;
        private final String mPackageName;
        private final int mUid;
        private final int mUid;
        private final IBinder.DeathRecipient mDeathMonitor;


        ISessionControllerCallbackHolder(ISessionControllerCallback callback, String packageName,
        ISessionControllerCallbackHolder(ISessionControllerCallback callback, String packageName,
                int uid) {
                int uid, IBinder.DeathRecipient deathMonitor) {
            mCallback = callback;
            mCallback = callback;
            mPackageName = packageName;
            mPackageName = packageName;
            mUid = uid;
            mUid = uid;
            mDeathMonitor = deathMonitor;
        }
        }
    }
    }