OSDN Git Service

Eliminate deadlock in magnification.
authorPhil Weaver <pweaver@google.com>
Fri, 18 Mar 2016 00:26:24 +0000 (17:26 -0700)
committerPhil Weaver <pweaver@google.com>
Wed, 6 Apr 2016 16:43:44 +0000 (16:43 +0000)
Use the lock from AccessibilityManagerService in
MagnificationController, since the two services call each other with
locks held.

Bug: 27725795
Change-Id: Iaed6749bf217210457325c3912da0f7aa0f6319a

services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
services/accessibility/java/com/android/server/accessibility/MagnificationController.java
services/core/java/com/android/server/am/AppErrors.java

index e256ecd..2741733 100644 (file)
@@ -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);
             }
index e15b785..b2196bf 100644 (file)
@@ -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;
     }
 
     /**
index 6cd7561..68bd2fd 100644 (file)
@@ -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();
+        }
     }
 
     /**