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
This commit is contained in:
@@ -2151,7 +2151,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
|
||||
MagnificationController getMagnificationController() {
|
||||
synchronized (mLock) {
|
||||
if (mMagnificationController == null) {
|
||||
mMagnificationController = new MagnificationController(mContext, this);
|
||||
mMagnificationController = new MagnificationController(mContext, this, mLock);
|
||||
mMagnificationController.register();
|
||||
mMagnificationController.setUserId(mCurrentUserId);
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ class MagnificationController {
|
||||
*/
|
||||
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 @@ class MagnificationController {
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -724,9 +724,7 @@ class AppErrors {
|
||||
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 @@ class AppErrors {
|
||||
}
|
||||
}
|
||||
}
|
||||
// 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 @@ class AppErrors {
|
||||
}
|
||||
|
||||
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 @@ class AppErrors {
|
||||
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 @@ class AppErrors {
|
||||
mService.killAppAtUsersRequest(proc, null);
|
||||
}
|
||||
}
|
||||
// If we've created a crash dialog, show it without the lock held
|
||||
if (d != null) {
|
||||
d.show();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user