am 825e0da2: Merge "Fix race when cleaning up receivers/services in Context" into lmp-mr1-dev
automerge: b7ce6d6
* commit 'b7ce6d6db1409ec785d2d7146cbcc897fd02d85b':
Fix race when cleaning up receivers/services in Context
This commit is contained in:
@@ -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,
|
||||||
|
|||||||
Reference in New Issue
Block a user