Settings preference for choosing long-term conditions.

Requires change Icba2b8b2 in frameworks/base

Change-Id: I9d7a4f668e3b0e721646e42fa080f201c53a7fe9
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 123a8bf..77af1fd 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -5182,8 +5182,17 @@
     <!-- [CHAR LIMIT=40] Zen mode settings: Automatic category text -->
     <string name="zen_mode_automatic_category">At night</string>
 
-    <!-- [CHAR LIMIT=40] Zen mode settings: Security category text -->
-    <string name="zen_mode_security_category">Security</string>
+    <!-- [CHAR LIMIT=40] Zen mode settings: Automation category text -->
+    <string name="zen_mode_automation_category">Other automation</string>
+
+    <!-- [CHAR LIMIT=40] Zen mode settings: Entry conditions option: title -->
+    <string name="zen_mode_entry_conditions_title">Automatically turn on</string>
+
+    <!-- [CHAR LIMIT=40] Zen mode settings: Entry conditions option: summary condition divider -->
+    <string name="zen_mode_entry_conditions_summary_divider">, </string>
+
+    <!-- [CHAR LIMIT=40] Zen mode settings: Entry conditions option: value when blank -->
+    <string name="zen_mode_entry_conditions_summary_none">Never</string>
 
     <!-- [CHAR LIMIT=20] Zen mode settings: Phone calls option -->
     <string name="zen_mode_phone_calls">Phone calls</string>
diff --git a/res/xml/zen_mode_settings.xml b/res/xml/zen_mode_settings.xml
index 75f01d8..b1ec8ad 100644
--- a/res/xml/zen_mode_settings.xml
+++ b/res/xml/zen_mode_settings.xml
@@ -49,9 +49,13 @@
         android:title="@string/zen_mode_automatic_category" />
 
     <PreferenceCategory
-        android:key="security"
+        android:key="automation"
         android:layout="@layout/zen_mode_section"
-        android:title="@string/zen_mode_security_category" >
+        android:title="@string/zen_mode_automation_category" >
+        <Preference
+            android:key="entry"
+            android:title="@string/zen_mode_entry_conditions_title"
+            android:persistent="false" />
         <Preference
                 android:key="manage_condition_providers"
                 android:title="@string/manage_condition_providers"
diff --git a/src/com/android/settings/notification/ZenModeAutomaticConditionSelection.java b/src/com/android/settings/notification/ZenModeAutomaticConditionSelection.java
new file mode 100644
index 0000000..7661f6f
--- /dev/null
+++ b/src/com/android/settings/notification/ZenModeAutomaticConditionSelection.java
@@ -0,0 +1,157 @@
+/*
+ * 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 com.android.settings.notification;
+
+import android.animation.LayoutTransition;
+import android.app.INotificationManager;
+import android.content.Context;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.Message;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.service.notification.Condition;
+import android.service.notification.IConditionListener;
+import android.util.ArraySet;
+import android.util.Log;
+import android.widget.CheckBox;
+import android.widget.CompoundButton;
+import android.widget.LinearLayout;
+
+import com.android.settings.R;
+
+public class ZenModeAutomaticConditionSelection extends LinearLayout {
+    private static final String TAG = "ZenModeAutomaticConditionSelection";
+    private static final boolean DEBUG = true;
+
+    private final INotificationManager mNoMan;
+    private final H mHandler = new H();
+    private final Context mContext;
+    private final ArraySet<Uri> mSelectedConditions = new ArraySet<Uri>();
+
+    public ZenModeAutomaticConditionSelection(Context context) {
+        super(context);
+        mContext = context;
+        setOrientation(VERTICAL);
+        setLayoutTransition(new LayoutTransition());
+        final int p = mContext.getResources().getDimensionPixelSize(R.dimen.content_margin_left);
+        setPadding(p, p, p, 0);
+        mNoMan = INotificationManager.Stub.asInterface(
+                ServiceManager.getService(Context.NOTIFICATION_SERVICE));
+        refreshSelectedConditions();
+    }
+
+    private void refreshSelectedConditions() {
+        try {
+            final Condition[] automatic = mNoMan.getAutomaticZenModeConditions();
+            mSelectedConditions.clear();
+            if (automatic != null) {
+                for (Condition c : automatic) {
+                    mSelectedConditions.add(c.id);
+                }
+            }
+        } catch (RemoteException e) {
+            Log.w(TAG, "Error calling getAutomaticZenModeConditions", e);
+        }
+    }
+
+    private CheckBox newCheckBox(Object tag) {
+        final CheckBox button = new CheckBox(mContext);
+        button.setTag(tag);
+        button.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+            @Override
+            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+                 setSelectedCondition((Uri)button.getTag(), isChecked);
+            }
+        });
+        addView(button);
+        return button;
+    }
+
+    private void setSelectedCondition(Uri conditionId, boolean selected) {
+        if (DEBUG) Log.d(TAG, "setSelectedCondition conditionId=" + conditionId
+                + " selected=" + selected);
+        if (selected) {
+            mSelectedConditions.add(conditionId);
+        } else {
+            mSelectedConditions.remove(conditionId);
+        }
+        final Uri[] automatic = new Uri[mSelectedConditions.size()];
+        for (int i = 0; i < automatic.length; i++) {
+            automatic[i] = mSelectedConditions.valueAt(i);
+        }
+        try {
+            mNoMan.setAutomaticZenModeConditions(automatic);
+        } catch (RemoteException e) {
+            Log.w(TAG, "Error calling setAutomaticZenModeConditions", e);
+        }
+    }
+
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        requestZenModeConditions(Condition.FLAG_RELEVANT_ALWAYS);
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+        requestZenModeConditions(0 /*none*/);
+    }
+
+    protected void requestZenModeConditions(int relevance) {
+        if (DEBUG) Log.d(TAG, "requestZenModeConditions " + Condition.relevanceToString(relevance));
+        try {
+            mNoMan.requestZenModeConditions(mListener, relevance);
+        } catch (RemoteException e) {
+            Log.w(TAG, "Error calling requestZenModeConditions", e);
+        }
+    }
+
+    protected void handleConditions(Condition[] conditions) {
+        for (final Condition c : conditions) {
+            CheckBox v = (CheckBox) findViewWithTag(c.id);
+            if (c.state != Condition.STATE_ERROR) {
+                if (v == null) {
+                    v = newCheckBox(c.id);
+                }
+            }
+            if (v != null) {
+                v.setText(c.caption);
+                v.setEnabled(c.state != Condition.STATE_ERROR);
+                v.setChecked(mSelectedConditions.contains(c.id));
+            }
+        }
+    }
+
+    private final IConditionListener mListener = new IConditionListener.Stub() {
+        @Override
+        public void onConditionsReceived(Condition[] conditions) {
+            if (conditions == null || conditions.length == 0) return;
+            mHandler.obtainMessage(H.CONDITIONS, conditions).sendToTarget();
+        }
+    };
+
+    private final class H extends Handler {
+        private static final int CONDITIONS = 1;
+
+        @Override
+        public void handleMessage(Message msg) {
+            if (msg.what == CONDITIONS) handleConditions((Condition[])msg.obj);
+        }
+    }
+}
diff --git a/src/com/android/settings/notification/ZenModeConditionSelection.java b/src/com/android/settings/notification/ZenModeConditionSelection.java
index 031d785..134fb61 100644
--- a/src/com/android/settings/notification/ZenModeConditionSelection.java
+++ b/src/com/android/settings/notification/ZenModeConditionSelection.java
@@ -72,19 +72,19 @@
     @Override
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
-        requestZenModeConditions(true);
+        requestZenModeConditions(Condition.FLAG_RELEVANT_NOW);
     }
 
     @Override
     protected void onDetachedFromWindow() {
         super.onDetachedFromWindow();
-        requestZenModeConditions(false);
+        requestZenModeConditions(0 /*none*/);
     }
 
-    protected void requestZenModeConditions(boolean requested) {
-        if (DEBUG) Log.d(TAG, "requestZenModeConditions " + requested);
+    protected void requestZenModeConditions(int relevance) {
+        if (DEBUG) Log.d(TAG, "requestZenModeConditions " + Condition.relevanceToString(relevance));
         try {
-            mNoMan.requestZenModeConditions(mListener, requested);
+            mNoMan.requestZenModeConditions(mListener, relevance);
         } catch (RemoteException e) {
             // noop
         }
@@ -93,14 +93,14 @@
     protected void handleConditions(Condition[] conditions) {
         for (final Condition c : conditions) {
             RadioButton v = (RadioButton) findViewWithTag(c.id);
-            if (c.state == Condition.STATE_FALSE || c.state == Condition.STATE_UNKNOWN) {
+            if (c.state == Condition.STATE_TRUE || c.state == Condition.STATE_UNKNOWN) {
                 if (v == null) {
                     v = newRadioButton(c.id);
                 }
             }
             if (v != null) {
                 v.setText(c.caption);
-                v.setEnabled(c.state == Condition.STATE_FALSE);
+                v.setEnabled(c.state == Condition.STATE_TRUE);
             }
         }
     }
diff --git a/src/com/android/settings/notification/ZenModeSettings.java b/src/com/android/settings/notification/ZenModeSettings.java
index 7f7dafa..4ce2351 100644
--- a/src/com/android/settings/notification/ZenModeSettings.java
+++ b/src/com/android/settings/notification/ZenModeSettings.java
@@ -24,6 +24,7 @@
 import android.app.TimePickerDialog;
 import android.content.Context;
 import android.content.DialogInterface;
+import android.content.DialogInterface.OnDismissListener;
 import android.content.pm.PackageManager;
 import android.content.res.Resources;
 import android.database.ContentObserver;
@@ -35,11 +36,12 @@
 import android.os.ServiceManager;
 import android.preference.Preference;
 import android.preference.Preference.OnPreferenceChangeListener;
+import android.preference.Preference.OnPreferenceClickListener;
 import android.preference.PreferenceCategory;
 import android.preference.PreferenceScreen;
 import android.preference.SwitchPreference;
-import android.provider.Settings;
 import android.provider.Settings.Global;
+import android.service.notification.Condition;
 import android.service.notification.ZenModeConfig;
 import android.text.format.DateFormat;
 import android.util.Log;
@@ -71,7 +73,8 @@
     private static final String KEY_AUTOMATIC = "automatic";
     private static final String KEY_WHEN = "when";
 
-    private static final String KEY_SECURITY = "security";
+    private static final String KEY_AUTOMATION = "automation";
+    private static final String KEY_ENTRY = "entry";
     private static final String KEY_CONDITION_PROVIDERS = "manage_condition_providers";
 
     private final Handler mHandler = new Handler();
@@ -88,7 +91,8 @@
     private DropDownPreference mWhen;
     private TimePickerPreference mStart;
     private TimePickerPreference mEnd;
-    private PreferenceCategory mSecurityCategory;
+    private PreferenceCategory mAutomationCategory;
+    private Preference mEntry;
     private Preference mConditionProviders;
     private AlertDialog mDialog;
 
@@ -231,9 +235,27 @@
         mStart.setDependency(mWhen.getKey());
         mEnd.setDependency(mWhen.getKey());
 
-        mSecurityCategory = (PreferenceCategory) findPreference(KEY_SECURITY);
+        mAutomationCategory = (PreferenceCategory) findPreference(KEY_AUTOMATION);
+        mEntry = findPreference(KEY_ENTRY);
+        mEntry.setOnPreferenceClickListener(new OnPreferenceClickListener() {
+            @Override
+            public boolean onPreferenceClick(Preference preference) {
+                new AlertDialog.Builder(mContext)
+                    .setTitle(R.string.zen_mode_entry_conditions_title)
+                    .setView(new ZenModeAutomaticConditionSelection(mContext))
+                    .setOnDismissListener(new OnDismissListener() {
+                        @Override
+                        public void onDismiss(DialogInterface dialog) {
+                            refreshAutomationSection();
+                        }
+                    })
+                    .setPositiveButton(R.string.dlg_ok, null)
+                    .show();
+                return true;
+            }
+        });
         mConditionProviders = findPreference(KEY_CONDITION_PROVIDERS);
-        refreshConditionProviders();
+        refreshAutomationSection();
 
         updateZenMode();
         updateControls();
@@ -252,11 +274,11 @@
         mDisableListeners = false;
     }
 
-    private void refreshConditionProviders() {
+    private void refreshAutomationSection() {
         if (mConditionProviders != null) {
             final int total = ConditionProviderSettings.getProviderCount(mPM);
             if (total == 0) {
-                getPreferenceScreen().removePreference(mSecurityCategory);
+                getPreferenceScreen().removePreference(mAutomationCategory);
             } else {
                 final int n = ConditionProviderSettings.getEnabledProviderCount(mContext);
                 if (n == 0) {
@@ -267,13 +289,41 @@
                             R.plurals.manage_condition_providers_summary_nonzero,
                             n, n)));
                 }
+                final String entrySummary = getEntryConditionSummary();
+                if (n == 0 || entrySummary == null) {
+                    mEntry.setSummary(R.string.zen_mode_entry_conditions_summary_none);
+                } else {
+                    mEntry.setSummary(entrySummary);
+                }
             }
         }
     }
+
+    private String getEntryConditionSummary() {
+        final INotificationManager nm = INotificationManager.Stub.asInterface(
+                ServiceManager.getService(Context.NOTIFICATION_SERVICE));
+        try {
+            final Condition[] automatic = nm.getAutomaticZenModeConditions();
+            if (automatic == null || automatic.length == 0) {
+                return null;
+            }
+            final String divider = getString(R.string.zen_mode_entry_conditions_summary_divider);
+            final StringBuilder sb = new StringBuilder();
+            for (int i = 0; i < automatic.length; i++) {
+                if (i > 0) sb.append(divider);
+                sb.append(automatic[i].caption);
+            }
+            return sb.toString();
+        } catch (Exception e) {
+            Log.w(TAG, "Error calling getAutomaticZenModeConditions", e);
+            return null;
+        }
+    }
+
     @Override
     public void onResume() {
         super.onResume();
-        refreshConditionProviders();
+        refreshAutomationSection();
         updateZenMode();
         mSettingsObserver.register();
     }