am 825e0da2: Merge "Fix race when cleaning up receivers/services in Context" into lmp-mr1-dev

* commit '825e0da22a672ada95da2175bb2d48579bf88a0d':
  Fix race when cleaning up receivers/services in Context
This commit is contained in:
Adam Lesinski
2014-11-20 20:18:51 +00:00
committed by Android Git Automerger

View File

@@ -632,55 +632,60 @@ public final class LoadedApk {
public void removeContextRegistrations(Context context, public void removeContextRegistrations(Context context,
String who, String what) { String who, String what) {
final boolean reportRegistrationLeaks = StrictMode.vmRegistrationLeaksEnabled(); final boolean reportRegistrationLeaks = StrictMode.vmRegistrationLeaksEnabled();
ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> rmap = synchronized (mReceivers) {
mReceivers.remove(context); ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> rmap =
if (rmap != null) { mReceivers.remove(context);
for (int i=0; i<rmap.size(); i++) { if (rmap != null) {
LoadedApk.ReceiverDispatcher rd = rmap.valueAt(i); for (int i = 0; i < rmap.size(); i++) {
IntentReceiverLeaked leak = new IntentReceiverLeaked( LoadedApk.ReceiverDispatcher rd = rmap.valueAt(i);
what + " " + who + " has leaked IntentReceiver " IntentReceiverLeaked leak = new IntentReceiverLeaked(
+ rd.getIntentReceiver() + " that was " + what + " " + who + " has leaked IntentReceiver "
"originally registered here. Are you missing a " + + rd.getIntentReceiver() + " that was " +
"call to unregisterReceiver()?"); "originally registered here. Are you missing a " +
leak.setStackTrace(rd.getLocation().getStackTrace()); "call to unregisterReceiver()?");
Slog.e(ActivityThread.TAG, leak.getMessage(), leak); leak.setStackTrace(rd.getLocation().getStackTrace());
if (reportRegistrationLeaks) { Slog.e(ActivityThread.TAG, leak.getMessage(), leak);
StrictMode.onIntentReceiverLeaked(leak); if (reportRegistrationLeaks) {
} StrictMode.onIntentReceiverLeaked(leak);
try { }
ActivityManagerNative.getDefault().unregisterReceiver( try {
rd.getIIntentReceiver()); ActivityManagerNative.getDefault().unregisterReceiver(
} catch (RemoteException e) { rd.getIIntentReceiver());
// system crashed, nothing we can do } catch (RemoteException e) {
// system crashed, nothing we can do
}
} }
} }
mUnregisteredReceivers.remove(context);
} }
mUnregisteredReceivers.remove(context);
//Slog.i(TAG, "Receiver registrations: " + mReceivers); synchronized (mServices) {
ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> smap = //Slog.i(TAG, "Receiver registrations: " + mReceivers);
mServices.remove(context); ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> smap =
if (smap != null) { mServices.remove(context);
for (int i=0; i<smap.size(); i++) { if (smap != null) {
LoadedApk.ServiceDispatcher sd = smap.valueAt(i); for (int i = 0; i < smap.size(); i++) {
ServiceConnectionLeaked leak = new ServiceConnectionLeaked( LoadedApk.ServiceDispatcher sd = smap.valueAt(i);
what + " " + who + " has leaked ServiceConnection " ServiceConnectionLeaked leak = new ServiceConnectionLeaked(
+ sd.getServiceConnection() + " that was originally bound here"); what + " " + who + " has leaked ServiceConnection "
leak.setStackTrace(sd.getLocation().getStackTrace()); + sd.getServiceConnection() + " that was originally bound here");
Slog.e(ActivityThread.TAG, leak.getMessage(), leak); leak.setStackTrace(sd.getLocation().getStackTrace());
if (reportRegistrationLeaks) { Slog.e(ActivityThread.TAG, leak.getMessage(), leak);
StrictMode.onServiceConnectionLeaked(leak); if (reportRegistrationLeaks) {
StrictMode.onServiceConnectionLeaked(leak);
}
try {
ActivityManagerNative.getDefault().unbindService(
sd.getIServiceConnection());
} catch (RemoteException e) {
// system crashed, nothing we can do
}
sd.doForget();
} }
try {
ActivityManagerNative.getDefault().unbindService(
sd.getIServiceConnection());
} catch (RemoteException e) {
// system crashed, nothing we can do
}
sd.doForget();
} }
mUnboundServices.remove(context);
//Slog.i(TAG, "Service registrations: " + mServices);
} }
mUnboundServices.remove(context);
//Slog.i(TAG, "Service registrations: " + mServices);
} }
public IIntentReceiver getReceiverDispatcher(BroadcastReceiver r, public IIntentReceiver getReceiverDispatcher(BroadcastReceiver r,