Fix issue #2364506: Phone locked up while listening to music and attempting to download an update

Make sure calls into the notification manager are not done with the
activity manager lock held.

Change-Id: Ib53c3b9f46160d94ee1e7079b1a5123e0d1225d8
This commit is contained in:
Dianne Hackborn
2010-01-19 15:36:42 -08:00
parent 6866daee6a
commit b1c4a2a3b3
2 changed files with 38 additions and 16 deletions

View File

@@ -10276,7 +10276,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
sInfo.applicationInfo.uid, sInfo.packageName,
sInfo.name);
}
r = new ServiceRecord(ss, name, filter, sInfo, res);
r = new ServiceRecord(this, ss, name, filter, sInfo, res);
res.setService(r);
mServices.put(name, r);
mServicesByIntent.put(filter, r);

View File

@@ -40,6 +40,7 @@ import java.util.List;
* A running application service.
*/
class ServiceRecord extends Binder {
final ActivityManagerService ams;
final BatteryStatsImpl.Uid.Pkg.Serv stats;
final ComponentName name; // service component.
final String shortName; // name.flattenToShortString().
@@ -192,8 +193,10 @@ class ServiceRecord extends Binder {
}
}
ServiceRecord(BatteryStatsImpl.Uid.Pkg.Serv servStats, ComponentName name,
ServiceRecord(ActivityManagerService ams,
BatteryStatsImpl.Uid.Pkg.Serv servStats, ComponentName name,
Intent.FilterComparison intent, ServiceInfo sInfo, Runnable restarter) {
this.ams = ams;
this.stats = servStats;
this.name = name;
shortName = name.flattenToShortString();
@@ -249,27 +252,46 @@ class ServiceRecord extends Binder {
public void postNotification() {
if (foregroundId != 0 && foregroundNoti != null) {
INotificationManager inm = NotificationManager.getService();
if (inm != null) {
try {
int[] outId = new int[1];
inm.enqueueNotification(packageName, foregroundId,
foregroundNoti, outId);
} catch (RemoteException e) {
// Do asynchronous communication with notification manager to
// avoid deadlocks.
final String localPackageName = packageName;
final int localForegroundId = foregroundId;
final Notification localForegroundNoti = foregroundNoti;
ams.mHandler.post(new Runnable() {
public void run() {
INotificationManager inm = NotificationManager.getService();
if (inm == null) {
return;
}
try {
int[] outId = new int[1];
inm.enqueueNotification(localPackageName, localForegroundId,
localForegroundNoti, outId);
} catch (RemoteException e) {
}
}
}
});
}
}
public void cancelNotification() {
if (foregroundId != 0) {
INotificationManager inm = NotificationManager.getService();
if (inm != null) {
try {
inm.cancelNotification(packageName, foregroundId);
} catch (RemoteException e) {
// Do asynchronous communication with notification manager to
// avoid deadlocks.
final String localPackageName = packageName;
final int localForegroundId = foregroundId;
ams.mHandler.post(new Runnable() {
public void run() {
INotificationManager inm = NotificationManager.getService();
if (inm == null) {
return;
}
try {
inm.cancelNotification(localPackageName, localForegroundId);
} catch (RemoteException e) {
}
}
}
});
}
}