Merge "[Bugfix][Media] Fix ISessionControllerCallback leaks in the system_server when the far side died"
This commit is contained in:
@@ -62,6 +62,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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user