From 445fd2afe9336cecf76e41d78aa0b6f3b7053700 Mon Sep 17 00:00:00 2001 From: Phil Weaver Date: Thu, 17 Mar 2016 17:26:24 -0700 Subject: [PATCH] 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 --- .../accessibility/AccessibilityManagerService.java | 2 +- .../server/accessibility/MagnificationController.java | 5 +++-- services/core/java/com/android/server/am/AppErrors.java | 16 +++++++++++----- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java index e256ecd6b85e..27417332f7d1 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 @@ 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); } diff --git a/services/accessibility/java/com/android/server/accessibility/MagnificationController.java b/services/accessibility/java/com/android/server/accessibility/MagnificationController.java index e15b785ba718..b2196bf946e2 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 @@ 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; } /** diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java index 6cd756186ab7..68bd2fd3ce3e 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 @@ 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 data = (HashMap) 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(); + } } /** -- 2.11.0