Allow third party condition providers.

Bug: 22977552
Change-Id: I3d8689f52daa9376496e14997a6dd7862fb3ade6
diff --git a/core/java/android/service/notification/Condition.java b/core/java/android/service/notification/Condition.java
index 80bdbf1..2c7bf65 100644
--- a/core/java/android/service/notification/Condition.java
+++ b/core/java/android/service/notification/Condition.java
@@ -16,7 +16,6 @@
 
 package android.service.notification;
 
-import android.annotation.SystemApi;
 import android.content.Context;
 import android.net.Uri;
 import android.os.Parcel;
@@ -26,10 +25,7 @@
 
 /**
  * Condition information from condition providers.
- *
- * @hide
  */
-@SystemApi
 public class Condition implements Parcelable {
 
     public static final String SCHEME = "condition";
diff --git a/core/java/android/service/notification/ConditionProviderService.java b/core/java/android/service/notification/ConditionProviderService.java
index 03ee726..2a8fb2c 100644
--- a/core/java/android/service/notification/ConditionProviderService.java
+++ b/core/java/android/service/notification/ConditionProviderService.java
@@ -17,9 +17,9 @@
 package android.service.notification;
 
 import android.annotation.SdkConstant;
-import android.annotation.SystemApi;
 import android.app.INotificationManager;
 import android.app.Service;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.net.Uri;
@@ -33,7 +33,10 @@
  * A service that provides conditions about boolean state.
  * <p>To extend this class, you must declare the service in your manifest file with
  * the {@link android.Manifest.permission#BIND_CONDITION_PROVIDER_SERVICE} permission
- * and include an intent filter with the {@link #SERVICE_INTERFACE} action. For example:</p>
+ * and include an intent filter with the {@link #SERVICE_INTERFACE} action. If you want users to be
+ * able to create and update conditions for this service to monitor, include the
+ * {@link #META_DATA_RULE_TYPE}, {@link #META_DATA_DEFAULT_CONDITION_ID}, and
+ * {@link #META_DATA_CONFIGURATION_ACTIVITY} tags. For example:</p>
  * <pre>
  * &lt;service android:name=".MyConditionProvider"
  *          android:label="&#64;string/service_name"
@@ -41,11 +44,21 @@
  *     &lt;intent-filter>
  *         &lt;action android:name="android.service.notification.ConditionProviderService" />
  *     &lt;/intent-filter>
+ *     &lt;meta-data
+ *               android:name="android.service.zen.automatic.ruleType"
+ *               android:value="@string/my_condition_rule">
+ *           &lt;/meta-data>
+ *           &lt;meta-data
+ *               android:name="android.service.zen.automatic.defaultConditionId"
+ *               android:value="condition://com.my.package/mycondition">
+ *           &lt;/meta-data>
+ *           &lt;meta-data
+ *               android:name="android.service.zen.automatic.configurationActivity"
+ *               android:value="com.my.package/.MyConditionConfigurationActivity">
+ *           &lt;/meta-data>
  * &lt;/service></pre>
  *
- * @hide
  */
-@SystemApi
 public abstract class ConditionProviderService extends Service {
     private final String TAG = ConditionProviderService.class.getSimpleName()
             + "[" + getClass().getSimpleName() + "]";
@@ -62,9 +75,63 @@
     public static final String SERVICE_INTERFACE
             = "android.service.notification.ConditionProviderService";
 
+    /**
+     * The name of the {@code meta-data} tag containing a localized name of the type of zen rules
+     * provided by this service.
+     */
+    public static final String META_DATA_RULE_TYPE = "android.service.zen.automatic.ruleType";
+
+    /**
+     * The name of the {@code meta-data} tag containing a default Condition {@link Uri} that can
+     * be parsed by this service.
+     */
+    public static final String META_DATA_DEFAULT_CONDITION_ID =
+            "android.service.zen.automatic.defaultConditionId";
+
+    /**
+     * The name of the {@code meta-data} tag containing the {@link ComponentName} of an activity
+     * that allows users to configure the conditions provided by this service.
+     */
+    public static final String META_DATA_CONFIGURATION_ACTIVITY =
+            "android.service.zen.automatic.configurationActivity";
+
+    /**
+     * A condition {@link Uri} extra passed to {@link #META_DATA_CONFIGURATION_ACTIVITY}. If the
+     * condition Uri is modified by that activity, it must be included in the result Intent extras
+     * in order to be persisted.
+     */
+    public static final String EXTRA_CONDITION_ID = "android.content.automatic.conditionId";
+
+    /**
+     * A String rule name extra passed to {@link #META_DATA_CONFIGURATION_ACTIVITY}. This extra is
+     * informative only, and will be ignored if included in the result Intent extras.
+     */
+    public static final String EXTRA_RULE_NAME = "android.content.automatic.ruleName";
+
+    /**
+     * Called when this service is connected.
+     */
     abstract public void onConnected();
+
+    /**
+     * Called when the system wants to know the state of Conditions managed by this provider.
+     *
+     * Implementations should evaluate the state of all subscribed conditions, and provide updates
+     * by calling {@link #notifyCondition(Condition)} or {@link #notifyConditions(Condition...)}.
+     * @param relevance
+     */
     abstract public void onRequestConditions(int relevance);
+
+    /**
+     * Called by the system when there is a new {@link Condition} to be managed by this provider.
+     * @param conditionId the Uri describing the criteria of the condition.
+     */
     abstract public void onSubscribe(Uri conditionId);
+
+    /**
+     * Called by the system when a {@link Condition} has been deleted.
+     * @param conditionId the Uri describing the criteria of the deleted condition.
+     */
     abstract public void onUnsubscribe(Uri conditionId);
 
     private final INotificationManager getNotificationInterface() {
@@ -75,11 +142,19 @@
         return mNoMan;
     }
 
+    /**
+     * Informs the notification manager that the state of a Condition has changed.
+     * @param condition the condition that has changed.
+     */
     public final void notifyCondition(Condition condition) {
         if (condition == null) return;
         notifyConditions(new Condition[]{ condition });
     }
 
+    /**
+     * Informs the notification manager that the state of one or more Conditions has changed.
+     * @param conditions the changed conditions.
+     */
     public final void notifyConditions(Condition... conditions) {
         if (!isBound() || conditions == null) return;
         try {
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index fefd5a7..5d9ca72 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2567,10 +2567,11 @@
     <permission android:name="android.permission.BIND_CHOOSER_TARGET_SERVICE"
         android:protectionLevel="signature" />
 
-    <!-- @SystemApi Must be required by a {@link
+    <!-- Must be required by a {@link
          android.service.notification.ConditionProviderService},
          to ensure that only the system can bind to it.
-         @hide -->
+         <p>Protection level: signature
+         -->
     <permission android:name="android.permission.BIND_CONDITION_PROVIDER_SERVICE"
         android:protectionLevel="signature" />