Add edit and delete buttons to zen rules

Test: atest ZenModeScheduleRuleSettingsTest ZenModeEventRuleSettingsTest
Test: manual
Bug: 111475013
Fixes: 120787343
Fixes: 120758763
Change-Id: If81ce2972e6887fb2a85d4b7262e81b26162e19c
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 44d43c3..e2a5857 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -7123,6 +7123,9 @@
     <!--  Do not disturb: Delete text button presented in a dialog to confirm the user would like to delete the selected DND rules. [CHAR LIMIT=30] -->
     <string name="zen_mode_schedule_delete">Delete</string>
 
+    <!--  Do not disturb: Edit label for button that allows user to edit the dnd schedule name. [CHAR LIMIT=30] -->
+    <string name="zen_mode_rule_name_edit">Edit</string>
+
     <!--  Do not disturb: Title for the zen mode automatic rules page in settings. [CHAR LIMIT=30] -->
     <string name="zen_mode_automation_settings_page_title">Schedules</string>
 
@@ -7893,7 +7896,7 @@
         <item quantity="other"><xliff:g id="num_people" example="3">%d</xliff:g> others</item>
     </plurals>
 
-    <!-- [CHAR LIMIT=20] Zen mode settings: Messages option -->
+    <!-- [CHAR LIMIT=40] Zen mode settings: Messages option -->
     <string name="zen_mode_messages">Allow text messages</string>
 
     <!-- Do not disturb settings, messages, events and reminders footer [CHAR LIMIT=NONE]-->
diff --git a/res/xml/zen_mode_event_rule_settings.xml b/res/xml/zen_mode_event_rule_settings.xml
index c871fe1..a70b46c 100644
--- a/res/xml/zen_mode_event_rule_settings.xml
+++ b/res/xml/zen_mode_event_rule_settings.xml
@@ -17,12 +17,17 @@
 
 <PreferenceScreen
     xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:settings="http://schemas.android.com/apk/res-auto"
     android:key="zen_mode_event_rule_settings"
     android:title="@string/zen_mode_automatic_rule_settings_page_title">
 
     <com.android.settingslib.widget.LayoutPreference
         android:key="pref_app_header"
-        android:layout="@layout/settings_entity_header" />
+        android:layout="@layout/settings_entity_header"
+        settings:allowDividerBelow="true" />
+
+    <com.android.settingslib.widget.ActionButtonsPreference
+        android:key="zen_action_buttons" />
 
     <com.android.settingslib.widget.LayoutPreference
         android:key="zen_automatic_rule_switch"
diff --git a/res/xml/zen_mode_schedule_rule_settings.xml b/res/xml/zen_mode_schedule_rule_settings.xml
index c257d87..7de10b3 100644
--- a/res/xml/zen_mode_schedule_rule_settings.xml
+++ b/res/xml/zen_mode_schedule_rule_settings.xml
@@ -17,12 +17,17 @@
 
 <PreferenceScreen
     xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:settings="http://schemas.android.com/apk/res-auto"
     android:key="zen_mode_schedule_rule_settings"
     android:title="@string/zen_mode_automatic_rule_settings_page_title">
 
     <com.android.settingslib.widget.LayoutPreference
         android:key="pref_app_header"
-        android:layout="@layout/settings_entity_header" />
+        android:layout="@layout/settings_entity_header"
+        settings:allowDividerBelow="true"/>
+
+    <com.android.settingslib.widget.ActionButtonsPreference
+        android:key="zen_action_buttons"/>
 
     <com.android.settingslib.widget.LayoutPreference
         android:key="zen_automatic_rule_switch"
diff --git a/src/com/android/settings/notification/ZenAutomaticRuleHeaderPreferenceController.java b/src/com/android/settings/notification/ZenAutomaticRuleHeaderPreferenceController.java
index c2db773..5fa3954 100644
--- a/src/com/android/settings/notification/ZenAutomaticRuleHeaderPreferenceController.java
+++ b/src/com/android/settings/notification/ZenAutomaticRuleHeaderPreferenceController.java
@@ -76,14 +76,6 @@
                 mController = EntityHeaderController
                         .newInstance(mFragment.getActivity(), mFragment,
                                 pref.findViewById(R.id.entity_header));
-
-                mController.setEditListener(new View.OnClickListener() {
-                    @Override
-                    public void onClick(View v) {
-                        ZenRuleNameDialog.show(mFragment, mRule.getName(), null,
-                                new RuleNameChangeListener());
-                    }
-                });
             }
 
             pref = mController.setIcon(getIcon())
@@ -123,20 +115,4 @@
         mRule = rule;
         mId = id;
     }
-
-    public class RuleNameChangeListener implements ZenRuleNameDialog.PositiveClickListener {
-        public RuleNameChangeListener() {}
-
-        @Override
-        public void onOk(String ruleName, Fragment parent) {
-            if (TextUtils.equals(ruleName, mRule.getName())) {
-                return;
-            }
-            mMetricsFeatureProvider.action(mContext,
-                    MetricsProto.MetricsEvent.ACTION_ZEN_MODE_RULE_NAME_CHANGE_OK);
-            mRule.setName(ruleName);
-            mRule.setModified(true);
-            mBackend.updateZenRule(mId, mRule);
-        }
-    }
 }
diff --git a/src/com/android/settings/notification/ZenModeAutomationSettings.java b/src/com/android/settings/notification/ZenModeAutomationSettings.java
index c559a28..d6a7d72 100644
--- a/src/com/android/settings/notification/ZenModeAutomationSettings.java
+++ b/src/com/android/settings/notification/ZenModeAutomationSettings.java
@@ -20,6 +20,7 @@
 import android.app.AutomaticZenRule;
 import android.content.Context;
 import android.content.DialogInterface;
+import android.os.Bundle;
 import android.provider.SearchIndexableResource;
 import android.service.notification.ConditionProviderService;
 import android.view.Menu;
@@ -44,12 +45,23 @@
 
 @SearchIndexable
 public class ZenModeAutomationSettings extends ZenModeSettingsBase {
+    public static final String DELETE = "DELETE_RULE";
     protected final ManagedServiceSettings.Config CONFIG = getConditionProviderConfig();
     private CharSequence[] mDeleteDialogRuleNames;
     private String[] mDeleteDialogRuleIds;
     private boolean[] mDeleteDialogChecked;
 
     @Override
+    public void onAttach(Context context) {
+        super.onAttach(context);
+        Bundle bundle = getArguments();
+        if (bundle != null && bundle.containsKey(DELETE)) {
+            mBackend.removeZenRule(bundle.getString(DELETE));
+            bundle.remove(DELETE);
+        }
+    }
+
+    @Override
     protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
         ZenServiceListing serviceListing = new ZenServiceListing(getContext(), CONFIG);
         serviceListing.reloadApprovedServices();
diff --git a/src/com/android/settings/notification/ZenModeEventRuleSettings.java b/src/com/android/settings/notification/ZenModeEventRuleSettings.java
index c11a672..ee3ed1c 100644
--- a/src/com/android/settings/notification/ZenModeEventRuleSettings.java
+++ b/src/com/android/settings/notification/ZenModeEventRuleSettings.java
@@ -27,6 +27,11 @@
 import android.service.notification.ZenModeConfig;
 import android.service.notification.ZenModeConfig.EventInfo;
 
+import androidx.preference.DropDownPreference;
+import androidx.preference.Preference;
+import androidx.preference.Preference.OnPreferenceChangeListener;
+import androidx.preference.PreferenceScreen;
+
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
@@ -38,11 +43,6 @@
 import java.util.List;
 import java.util.Objects;
 
-import androidx.preference.DropDownPreference;
-import androidx.preference.Preference;
-import androidx.preference.Preference.OnPreferenceChangeListener;
-import androidx.preference.PreferenceScreen;
-
 public class ZenModeEventRuleSettings extends ZenModeRuleSettingsBase {
     private static final String KEY_CALENDAR = "calendar";
     private static final String KEY_REPLY = "reply";
@@ -85,9 +85,12 @@
         List<AbstractPreferenceController> controllers = new ArrayList<>();
         mHeader = new ZenAutomaticRuleHeaderPreferenceController(context, this,
                 getSettingsLifecycle());
+        mActionButtons = new ZenRuleButtonsPreferenceController(context, this,
+                getSettingsLifecycle());
         mSwitch = new ZenAutomaticRuleSwitchPreferenceController(context, this,
                 getSettingsLifecycle());
         controllers.add(mHeader);
+        controllers.add(mActionButtons);
         controllers.add(mSwitch);
         return controllers;
     }
@@ -107,8 +110,16 @@
                 mEvent.calendarId = calendar.calendarId;
             }
         }
-        mCalendar.setEntries(entries.toArray(new CharSequence[entries.size()]));
-        mCalendar.setEntryValues(values.toArray(new CharSequence[values.size()]));
+
+        CharSequence[] entriesArr = entries.toArray(new CharSequence[entries.size()]);
+        CharSequence[] valuesArr = values.toArray(new CharSequence[values.size()]);
+        if (!Objects.equals(mCalendar.getEntries(), entriesArr)) {
+            mCalendar.setEntries(entriesArr);
+        }
+
+        if (!Objects.equals(mCalendar.getEntryValues(), valuesArr)) {
+            mCalendar.setEntryValues(valuesArr);
+        }
     }
 
     @Override
@@ -159,8 +170,12 @@
 
     @Override
     protected void updateControlsInternal() {
-        mCalendar.setValue(key(mEvent));
-        mReply.setValue(Integer.toString(mEvent.reply));
+        if (!Objects.equals(mCalendar.getValue(), key(mEvent))) {
+            mCalendar.setValue(key(mEvent));
+        }
+        if (!Objects.equals(mReply.getValue(), Integer.toString(mEvent.reply))) {
+            mReply.setValue(Integer.toString(mEvent.reply));
+        }
     }
 
     @Override
@@ -233,7 +248,7 @@
 
     private static String key(int userId, Long calendarId, String displayName) {
         return EventInfo.resolveUserId(userId) + ":" + (calendarId == null ? "" : calendarId)
-                + ":" + displayName;
+                + ":" + (displayName == null ? "" : displayName);
     }
 
     private static final Comparator<CalendarInfo> CALENDAR_NAME = new Comparator<CalendarInfo>() {
diff --git a/src/com/android/settings/notification/ZenModeRuleSettingsBase.java b/src/com/android/settings/notification/ZenModeRuleSettingsBase.java
index 11b8084..e573884 100644
--- a/src/com/android/settings/notification/ZenModeRuleSettingsBase.java
+++ b/src/com/android/settings/notification/ZenModeRuleSettingsBase.java
@@ -43,6 +43,7 @@
     protected String mId;
 
     protected ZenAutomaticRuleHeaderPreferenceController mHeader;
+    protected ZenRuleButtonsPreferenceController mActionButtons;
     protected ZenAutomaticRuleSwitchPreferenceController mSwitch;
 
     abstract protected void onCreateInternal();
@@ -104,6 +105,10 @@
         mHeader.onResume(mRule, mId);
         mHeader.displayPreference(screen);
         updatePreference(mHeader);
+
+        mActionButtons.onResume(mRule, mId);
+        mActionButtons.displayPreference(screen);
+        updatePreference(mActionButtons);
     }
 
     private void updatePreference(AbstractPreferenceController controller) {
@@ -147,7 +152,8 @@
 
     private void toastAndFinish() {
         Toast.makeText(mContext, R.string.zen_mode_rule_not_found_text, Toast.LENGTH_SHORT)
-                    .show();
+                .show();
+
         getActivity().finish();
     }
 
diff --git a/src/com/android/settings/notification/ZenModeScheduleRuleSettings.java b/src/com/android/settings/notification/ZenModeScheduleRuleSettings.java
index 0b2e1bc..8aa993f 100644
--- a/src/com/android/settings/notification/ZenModeScheduleRuleSettings.java
+++ b/src/com/android/settings/notification/ZenModeScheduleRuleSettings.java
@@ -199,10 +199,12 @@
         List<AbstractPreferenceController> controllers = new ArrayList<>();
         mHeader = new ZenAutomaticRuleHeaderPreferenceController(context, this,
                 getSettingsLifecycle());
+        mActionButtons = new ZenRuleButtonsPreferenceController(context, this,
+                getSettingsLifecycle());
         mSwitch = new ZenAutomaticRuleSwitchPreferenceController(context, this,
                 getSettingsLifecycle());
-
         controllers.add(mHeader);
+        controllers.add(mActionButtons);
         controllers.add(mSwitch);
         return controllers;
     }
diff --git a/src/com/android/settings/notification/ZenModeSettingsBase.java b/src/com/android/settings/notification/ZenModeSettingsBase.java
index 2aecae4..b9a14ee 100644
--- a/src/com/android/settings/notification/ZenModeSettingsBase.java
+++ b/src/com/android/settings/notification/ZenModeSettingsBase.java
@@ -52,9 +52,14 @@
     }
 
     @Override
-    public void onCreate(Bundle icicle) {
-        mContext = getActivity();
+    public void onAttach(Context context) {
+        super.onAttach(context);
+        mContext = context;
         mBackend = ZenModeBackend.getInstance(mContext);
+    }
+
+    @Override
+    public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
         updateZenMode(false /*fireChanged*/);
     }
diff --git a/src/com/android/settings/notification/ZenRuleButtonsPreferenceController.java b/src/com/android/settings/notification/ZenRuleButtonsPreferenceController.java
new file mode 100644
index 0000000..1d43f6d
--- /dev/null
+++ b/src/com/android/settings/notification/ZenRuleButtonsPreferenceController.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2018 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.app.AutomaticZenRule;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.View;
+
+import androidx.fragment.app.Fragment;
+import androidx.preference.PreferenceFragmentCompat;
+import androidx.preference.PreferenceScreen;
+
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.settings.R;
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settings.core.SubSettingLauncher;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.ActionButtonsPreference;
+
+public class ZenRuleButtonsPreferenceController extends AbstractZenModePreferenceController
+    implements PreferenceControllerMixin {
+    public static final String KEY = "zen_action_buttons";
+
+    private AutomaticZenRule mRule;
+    private String mId;
+    private PreferenceFragmentCompat mFragment;
+    private ActionButtonsPreference mButtonsPref;
+
+
+    public ZenRuleButtonsPreferenceController(Context context, PreferenceFragmentCompat fragment,
+            Lifecycle lc) {
+        super(context, KEY, lc);
+        mFragment = fragment;
+    }
+
+
+    @Override
+    public boolean isAvailable() {
+        return mRule != null;
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        if (isAvailable()) {
+            mButtonsPref = ((ActionButtonsPreference) screen.findPreference(KEY))
+                    .setButton1Text(R.string.zen_mode_rule_name_edit)
+                    .setButton1Icon(R.drawable.ic_mode_edit)
+                    .setButton1OnClickListener(new EditRuleNameClickListener())
+                    .setButton2Text(R.string.zen_mode_delete_rule_button)
+                    .setButton2Icon(R.drawable.ic_settings_delete)
+                    .setButton2OnClickListener(new DeleteRuleClickListener());
+        }
+    }
+
+    public class EditRuleNameClickListener implements View.OnClickListener {
+        public EditRuleNameClickListener() {}
+
+        @Override
+        public void onClick(View v) {
+            ZenRuleNameDialog.show(mFragment, mRule.getName(), null,
+                    new ZenRuleNameDialog.PositiveClickListener() {
+                        @Override
+                        public void onOk(String ruleName, Fragment parent) {
+                            if (TextUtils.equals(ruleName, mRule.getName())) {
+                                return;
+                            }
+                            mMetricsFeatureProvider.action(mContext,
+                                    MetricsProto.MetricsEvent.ACTION_ZEN_MODE_RULE_NAME_CHANGE_OK);
+                            mRule.setName(ruleName);
+                            mRule.setModified(true);
+                            mBackend.updateZenRule(mId, mRule);
+                        }
+                    });
+        }
+    }
+
+    public class DeleteRuleClickListener implements View.OnClickListener {
+        public DeleteRuleClickListener() {}
+
+        @Override
+        public void onClick(View v) {
+            ZenDeleteRuleDialog.show(mFragment, mRule.getName(), mId,
+                    new ZenDeleteRuleDialog.PositiveClickListener() {
+                        @Override
+                        public void onOk(String id) {
+                            Bundle bundle = new Bundle();
+                            bundle.putString(ZenModeAutomationSettings.DELETE, id);
+                            mMetricsFeatureProvider.action(mContext,
+                                    MetricsProto.MetricsEvent.ACTION_ZEN_DELETE_RULE_OK);
+                            new SubSettingLauncher(mContext)
+                                    .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
+                                    .setDestination(ZenModeAutomationSettings.class.getName())
+                                    .setSourceMetricsCategory(MetricsProto.MetricsEvent
+                                            .NOTIFICATION_ZEN_MODE_AUTOMATION)
+                                    .setArguments(bundle)
+                                    .launch();
+                        }
+            });
+        }
+    }
+
+    protected void onResume(AutomaticZenRule rule, String id) {
+        mRule = rule;
+        mId = id;
+    }
+}