Wire up condition providers to zen mode exit triggers.

Bug:13743109
Change-Id: I4e45d7050d1f9aaa379f46379a3203e61e216a3d
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index 045fab1..ad4027d 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -18,13 +18,15 @@
 package android.app;
 
 import android.app.ITransientNotification;
-import android.service.notification.StatusBarNotification;
 import android.app.Notification;
 import android.content.ComponentName;
 import android.content.Intent;
+import android.net.Uri;
 import android.service.notification.Condition;
+import android.service.notification.IConditionListener;
 import android.service.notification.IConditionProvider;
 import android.service.notification.INotificationListener;
+import android.service.notification.StatusBarNotification;
 import android.service.notification.ZenModeConfig;
 
 /** {@hide} */
@@ -55,5 +57,7 @@
 
     ZenModeConfig getZenModeConfig();
     boolean setZenModeConfig(in ZenModeConfig config);
-    void notifyCondition(in IConditionProvider provider, in Condition condition);
+    oneway void notifyConditions(String pkg, in IConditionProvider provider, in Condition[] conditions);
+    oneway void requestZenModeConditions(in IConditionListener callback, boolean requested);
+    oneway void setZenModeCondition(in Uri conditionId);
 }
\ No newline at end of file
diff --git a/core/java/android/service/notification/Condition.java b/core/java/android/service/notification/Condition.java
index cfd40f3..71e3166 100644
--- a/core/java/android/service/notification/Condition.java
+++ b/core/java/android/service/notification/Condition.java
@@ -16,6 +16,7 @@
 
 package android.service.notification;
 
+import android.content.Context;
 import android.net.Uri;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -29,18 +30,25 @@
  */
 public class Condition implements Parcelable {
 
+    public static final String SCHEME = "condition";
+
+    public static final int STATE_FALSE = 0;
+    public static final int STATE_TRUE = 1;
+    public static final int STATE_UNKNOWN = 2;
+    public static final int STATE_ERROR = 3;
+
     public static final int FLAG_RELEVANT_NOW = 1 << 0;
     public static final int FLAG_RELEVANT_ALWAYS = 1 << 1;
 
     public final Uri id;
     public String caption;
-    public boolean state;
+    public int state;
     public int flags;
 
-
-    public Condition(Uri id, String caption, boolean state, int flags) {
+    public Condition(Uri id, String caption, int state, int flags) {
         if (id == null) throw new IllegalArgumentException("id is required");
         if (caption == null) throw new IllegalArgumentException("caption is required");
+        if (!isValidState(state)) throw new IllegalArgumentException("state is invalid: " + state);
         this.id = id;
         this.caption = caption;
         this.state = state;
@@ -48,17 +56,21 @@
     }
 
     private Condition(Parcel source) {
-        id = Uri.CREATOR.createFromParcel(source);
-        caption = source.readString();
-        state = source.readInt() == 1;
-        flags = source.readInt();
+        this((Uri)source.readParcelable(Condition.class.getClassLoader()),
+                source.readString(),
+                source.readInt(),
+                source.readInt());
+    }
+
+    private static boolean isValidState(int state) {
+        return state >= STATE_FALSE && state <= STATE_ERROR;
     }
 
     @Override
     public void writeToParcel(Parcel dest, int flags) {
         dest.writeParcelable(id, 0);
         dest.writeString(caption);
-        dest.writeInt(state ? 1 : 0);
+        dest.writeInt(state);
         dest.writeInt(flags);
     }
 
@@ -67,11 +79,19 @@
         return new StringBuilder(Condition.class.getSimpleName()).append('[')
             .append("id=").append(id)
             .append(",caption=").append(caption)
-            .append(",state=").append(state)
+            .append(",state=").append(stateToString(state))
             .append(",flags=").append(flags)
             .append(']').toString();
     }
 
+    public static String stateToString(int state) {
+        if (state == STATE_FALSE) return "STATE_FALSE";
+        if (state == STATE_TRUE) return "STATE_TRUE";
+        if (state == STATE_UNKNOWN) return "STATE_UNKNOWN";
+        if (state == STATE_ERROR) return "STATE_ERROR";
+        throw new IllegalArgumentException("state is invalid: " + state);
+    }
+
     @Override
     public boolean equals(Object o) {
         if (!(o instanceof Condition)) return false;
@@ -104,6 +124,14 @@
         }
     }
 
+    public static Uri.Builder newId(Context context) {
+        return new Uri.Builder().scheme(SCHEME).authority(context.getPackageName());
+    }
+
+    public static boolean isValidId(Uri id, String pkg) {
+        return id != null && id.getScheme().equals(SCHEME) && id.getAuthority().equals(pkg);
+    }
+
     public static final Parcelable.Creator<Condition> CREATOR
             = new Parcelable.Creator<Condition>() {
         @Override
diff --git a/core/java/android/service/notification/ConditionProviderService.java b/core/java/android/service/notification/ConditionProviderService.java
index 8777e50..70d474e 100644
--- a/core/java/android/service/notification/ConditionProviderService.java
+++ b/core/java/android/service/notification/ConditionProviderService.java
@@ -56,11 +56,10 @@
     public static final String SERVICE_INTERFACE
             = "android.service.notification.ConditionProviderService";
 
-
-    abstract public Condition[] queryConditions(int relevance);
-    abstract public Condition[] getConditions(Uri[] conditionIds);
-    abstract public boolean subscribe(Uri conditionId);
-    abstract public boolean unsubscribe(Uri conditionId);
+    abstract public void onConnected();
+    abstract public void onRequestConditions(int relevance);
+    abstract public void onSubscribe(Uri conditionId);
+    abstract public void onUnsubscribe(Uri conditionId);
 
     private final INotificationManager getNotificationInterface() {
         if (mNoMan == null) {
@@ -70,10 +69,10 @@
         return mNoMan;
     }
 
-    public final void notifyCondition(Condition condition) {
+    public final void notifyConditions(Condition[] conditions) {
         if (!isBound()) return;
         try {
-            getNotificationInterface().notifyCondition(mProvider, condition);
+            getNotificationInterface().notifyConditions(getPackageName(), mProvider, conditions);
         } catch (android.os.RemoteException ex) {
             Log.v(TAG, "Unable to contact notification manager", ex);
         }
@@ -99,42 +98,38 @@
         private final ConditionProviderService mService = ConditionProviderService.this;
 
         @Override
-        public Condition[] queryConditions(int relevance) {
+        public void onConnected() {
             try {
-                return mService.queryConditions(relevance);
+                mService.onConnected();
             } catch (Throwable t) {
-                Log.w(TAG, "Error running queryConditions", t);
-                return null;
+                Log.w(TAG, "Error running onConnected", t);
             }
         }
 
         @Override
-        public Condition[] getConditions(Uri[] conditionIds) {
+        public void onRequestConditions(int relevance) {
             try {
-                return mService.getConditions(conditionIds);
+                mService.onRequestConditions(relevance);
             } catch (Throwable t) {
-                Log.w(TAG, "Error running getConditions", t);
-                return null;
+                Log.w(TAG, "Error running onRequestConditions", t);
             }
         }
 
         @Override
-        public boolean subscribe(Uri conditionId) {
+        public void onSubscribe(Uri conditionId) {
             try {
-                return mService.subscribe(conditionId);
+                mService.onSubscribe(conditionId);
             } catch (Throwable t) {
-                Log.w(TAG, "Error running subscribe", t);
-                return false;
+                Log.w(TAG, "Error running onSubscribe", t);
             }
         }
 
         @Override
-        public boolean unsubscribe(Uri conditionId) {
+        public void onUnsubscribe(Uri conditionId) {
             try {
-                return mService.unsubscribe(conditionId);
+                mService.onUnsubscribe(conditionId);
             } catch (Throwable t) {
-                Log.w(TAG, "Error running unsubscribe", t);
-                return false;
+                Log.w(TAG, "Error running onUnsubscribe", t);
             }
         }
     }
diff --git a/core/java/android/service/notification/IConditionListener.aidl b/core/java/android/service/notification/IConditionListener.aidl
new file mode 100644
index 0000000..01f874f
--- /dev/null
+++ b/core/java/android/service/notification/IConditionListener.aidl
@@ -0,0 +1,25 @@
+/**
+ * Copyright (c) 2014, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.service.notification;
+
+import android.net.Uri;
+import android.service.notification.Condition;
+
+/** @hide */
+oneway interface IConditionListener {
+    void onConditionsReceived(in Condition[] conditions);
+}
\ No newline at end of file
diff --git a/core/java/android/service/notification/IConditionProvider.aidl b/core/java/android/service/notification/IConditionProvider.aidl
index cb582da..ada8939 100644
--- a/core/java/android/service/notification/IConditionProvider.aidl
+++ b/core/java/android/service/notification/IConditionProvider.aidl
@@ -20,9 +20,9 @@
 import android.service.notification.Condition;
 
 /** @hide */
-interface IConditionProvider {
-    Condition[] queryConditions(int relevance);
-    Condition[] getConditions(in Uri[] conditionIds);
-    boolean subscribe(in Uri conditionId);
-    boolean unsubscribe(in Uri conditionId);
+oneway interface IConditionProvider {
+    void onConnected();
+    void onRequestConditions(int relevance);
+    void onSubscribe(in Uri conditionId);
+    void onUnsubscribe(in Uri conditionId);
 }
\ No newline at end of file