ZenModeHelper: fix cross deadlock with AudioService

Processing ZenModeHelper.setConfig() synchronously in
ZenModeConditions.onConditionChanged() can cause a cross deadlock between
ConditionProviders.mMutex and AudioService.mSettingsLock.

Add a method to set Zen mode config asynchronously.

Bug: 24528290.
Change-Id: I9c1701ca6bef084527821175d84002b612241995
diff --git a/services/core/java/com/android/server/notification/ZenModeConditions.java b/services/core/java/com/android/server/notification/ZenModeConditions.java
index b89a654..c2e4349 100644
--- a/services/core/java/com/android/server/notification/ZenModeConditions.java
+++ b/services/core/java/com/android/server/notification/ZenModeConditions.java
@@ -104,7 +104,7 @@
     public void onServiceAdded(ComponentName component) {
         if (DEBUG) Log.d(TAG, "onServiceAdded " + component);
         if (isAutomaticActive(component)) {
-            mHelper.setConfig(mHelper.getConfig(), "zmc.onServiceAdded");
+            mHelper.setConfigAsync(mHelper.getConfig(), "zmc.onServiceAdded");
         }
     }
 
@@ -120,7 +120,7 @@
             updated |= updateSnoozing(automaticRule);
         }
         if (updated) {
-            mHelper.setConfig(config, "conditionChanged");
+            mHelper.setConfigAsync(config, "conditionChanged");
         }
     }
 
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 57d7758..461c3a2 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -315,6 +315,10 @@
         return setConfig(config, reason, true /*setRingerMode*/);
     }
 
+    public void setConfigAsync(ZenModeConfig config, String reason) {
+        mHandler.postSetConfig(config, reason);
+    }
+
     private boolean setConfig(ZenModeConfig config, String reason, boolean setRingerMode) {
         if (config == null || !config.isValid()) {
             Log.w(TAG, "Invalid config in setConfig; " + config);
@@ -743,6 +747,17 @@
     private final class H extends Handler {
         private static final int MSG_DISPATCH = 1;
         private static final int MSG_METRICS = 2;
+        private static final int MSG_SET_CONFIG = 3;
+
+        private final class ConfigMessageData {
+            public final ZenModeConfig config;
+            public final String reason;
+
+            ConfigMessageData(ZenModeConfig config, String reason) {
+                this.config = config;
+                this.reason = reason;
+            }
+        }
 
         private static final long METRICS_PERIOD_MS = 6 * 60 * 60 * 1000;
 
@@ -760,6 +775,10 @@
             sendEmptyMessageDelayed(MSG_METRICS, METRICS_PERIOD_MS);
         }
 
+        private void postSetConfig(ZenModeConfig config, String reason) {
+            sendMessage(obtainMessage(MSG_SET_CONFIG, new ConfigMessageData(config, reason)));
+        }
+
         @Override
         public void handleMessage(Message msg) {
             switch (msg.what) {
@@ -769,6 +788,10 @@
                 case MSG_METRICS:
                     mMetrics.emit();
                     break;
+                case MSG_SET_CONFIG:
+                    ConfigMessageData configData = (ConfigMessageData)msg.obj;
+                    setConfig(configData.config, configData.reason);
+                    break;
             }
         }
     }