Index: chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java |
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java |
index 3f9e8ac998e6d9d59a5dcc90e9172bd9d70f7802..b5c90862d2bc6faab62b98fb6dde38c79f5e7f2d 100644 |
--- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java |
+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java |
@@ -145,13 +145,16 @@ public class CustomTabsConnection extends ICustomTabsService.Stub { |
public final int mUid; |
public final Referrer mReferrer; |
public final ICustomTabsCallback mCallback; |
+ public final IBinder.DeathRecipient mDeathRecipient; |
private ServiceConnection mServiceConnection; |
private String mPredictedUrl; |
private long mLastMayLaunchUrlTimestamp; |
- public SessionParams(Context context, int uid, ICustomTabsCallback callback) { |
+ public SessionParams(Context context, int uid, ICustomTabsCallback callback, |
+ IBinder.DeathRecipient deathRecipient) { |
mUid = uid; |
mCallback = callback; |
+ mDeathRecipient = deathRecipient; |
mServiceConnection = null; |
mPredictedUrl = null; |
mLastMayLaunchUrlTimestamp = 0; |
@@ -219,19 +222,27 @@ public class CustomTabsConnection extends ICustomTabsService.Stub { |
public boolean newSession(ICustomTabsCallback callback) { |
if (callback == null) return false; |
final int uid = Binder.getCallingUid(); |
- SessionParams sessionParams = new SessionParams(mApplication, uid, callback); |
final IBinder session = callback.asBinder(); |
- synchronized (mLock) { |
- if (mSessionParams.containsKey(session)) return false; |
- try { |
- callback.asBinder().linkToDeath(new IBinder.DeathRecipient() { |
+ IBinder.DeathRecipient deathRecipient = |
+ new IBinder.DeathRecipient() { |
@Override |
public void binderDied() { |
- synchronized (mLock) { |
- cleanupAlreadyLocked(session); |
- } |
+ ThreadUtils.postOnUiThread(new Runnable() { |
+ @Override |
+ public void run() { |
+ synchronized (mLock) { |
+ cleanupAlreadyLocked(session); |
+ } |
+ } |
+ }); |
} |
- }, 0); |
+ }; |
+ SessionParams sessionParams = |
+ new SessionParams(mApplication, uid, callback, deathRecipient); |
+ synchronized (mLock) { |
+ if (mSessionParams.containsKey(session)) return false; |
+ try { |
+ callback.asBinder().linkToDeath(deathRecipient, 0); |
} catch (RemoteException e) { |
// The return code doesn't matter, because this executes when |
// the caller has died. |
@@ -607,6 +618,7 @@ public class CustomTabsConnection extends ICustomTabsService.Stub { |
@VisibleForTesting |
void cleanupAll() { |
+ ThreadUtils.assertOnUiThread(); |
synchronized (mLock) { |
List<IBinder> sessions = new ArrayList<>(mSessionParams.keySet()); |
for (IBinder session : sessions) cleanupAlreadyLocked(session); |
@@ -617,7 +629,12 @@ public class CustomTabsConnection extends ICustomTabsService.Stub { |
* Called when a remote client has died. |
*/ |
private void cleanupAlreadyLocked(IBinder session) { |
+ ThreadUtils.assertOnUiThread(); |
+ SessionParams params = mSessionParams.get(session); |
+ if (params == null) return; |
mSessionParams.remove(session); |
+ IBinder binder = params.mCallback.asBinder(); |
+ binder.unlinkToDeath(params.mDeathRecipient, 0); |
if (mPrerender != null && session.equals(mPrerender.mSession)) { |
prerenderUrl(session, null, null); // Cancels the pre-render. |
} |