Eliminate deadlock in magnification.
Use the lock from AccessibilityManagerService in
MagnificationController, since the two services call each other with
locks held.
Bug: 27725795
Change-Id: Iaed6749bf217210457325c3912da0f7aa0f6319a
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index e256ecd..2741733 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -2151,7 +2151,7 @@
MagnificationController getMagnificationController() {
synchronized (mLock) {
if (mMagnificationController == null) {
- mMagnificationController = new MagnificationController(mContext, this);
+ mMagnificationController = new MagnificationController(mContext, this, mLock);
mMagnificationController.register();
mMagnificationController.setUserId(mCurrentUserId);
}
diff --git a/services/accessibility/java/com/android/server/accessibility/MagnificationController.java b/services/accessibility/java/com/android/server/accessibility/MagnificationController.java
index e15b785..b2196bf 100644
--- a/services/accessibility/java/com/android/server/accessibility/MagnificationController.java
+++ b/services/accessibility/java/com/android/server/accessibility/MagnificationController.java
@@ -72,7 +72,7 @@
*/
private static final float MIN_PERSISTED_SCALE = 2.0f;
- private final Object mLock = new Object();
+ private final Object mLock;
/**
* The current magnification spec. If an animation is running, this
@@ -97,12 +97,13 @@
private int mUserId;
- public MagnificationController(Context context, AccessibilityManagerService ams) {
+ public MagnificationController(Context context, AccessibilityManagerService ams, Object lock) {
mAms = ams;
mContentResolver = context.getContentResolver();
mScreenStateObserver = new ScreenStateObserver(context, this);
mWindowStateObserver = new WindowStateObserver(context, this);
mSpecAnimationBridge = new SpecAnimationBridge(context);
+ mLock = lock;
}
/**
diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java
index 6cd7561..68bd2fd 100644
--- a/services/core/java/com/android/server/am/AppErrors.java
+++ b/services/core/java/com/android/server/am/AppErrors.java
@@ -724,9 +724,7 @@
final boolean crashSilenced = mAppsNotReportingCrashes != null &&
mAppsNotReportingCrashes.contains(proc.info.packageName);
if (mService.canShowErrorDialogs() && !crashSilenced) {
- Dialog d = new AppErrorDialog(mContext, mService, data);
- d.show();
- proc.crashDialog = d;
+ proc.crashDialog = new AppErrorDialog(mContext, mService, data);
} else {
// The device is asleep, so just pretend that the user
// saw a crash dialog and hit "force quit".
@@ -735,6 +733,10 @@
}
}
}
+ // If we've created a crash dialog, show it without the lock held
+ if(data.proc.crashDialog != null) {
+ data.proc.crashDialog.show();
+ }
}
void stopReportingCrashesLocked(ProcessRecord proc) {
@@ -924,6 +926,7 @@
}
void handleShowAnrUi(Message msg) {
+ Dialog d = null;
synchronized (mService) {
HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
ProcessRecord proc = (ProcessRecord)data.get("app");
@@ -944,10 +947,9 @@
null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
if (mService.canShowErrorDialogs()) {
- Dialog d = new AppNotRespondingDialog(mService,
+ d = new AppNotRespondingDialog(mService,
mContext, proc, (ActivityRecord)data.get("activity"),
msg.arg1 != 0);
- d.show();
proc.anrDialog = d;
} else {
MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_ANR,
@@ -956,6 +958,10 @@
mService.killAppAtUsersRequest(proc, null);
}
}
+ // If we've created a crash dialog, show it without the lock held
+ if (d != null) {
+ d.show();
+ }
}
/**