Link to the appropriate config activity for dnd rules

Test: atest, manual
Bug: 111474881
Change-Id: I0c1d7b14abe3cf65762167f3c412fa8f2be1d842
diff --git a/src/com/android/settings/notification/AbstractZenModeAutomaticRulePreferenceController.java b/src/com/android/settings/notification/AbstractZenModeAutomaticRulePreferenceController.java
index d0f1ee6..1499656 100644
--- a/src/com/android/settings/notification/AbstractZenModeAutomaticRulePreferenceController.java
+++ b/src/com/android/settings/notification/AbstractZenModeAutomaticRulePreferenceController.java
@@ -21,6 +21,8 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ComponentInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ServiceInfo;
 import android.provider.Settings;
@@ -82,33 +84,47 @@
         return intent;
     }
 
-    public static ZenRuleInfo getRuleInfo(PackageManager pm, ServiceInfo si) {
-        if (si == null || si.metaData == null) {
+    public static ZenRuleInfo getRuleInfo(PackageManager pm, ComponentInfo ci) {
+        if (ci == null || ci.metaData == null) {
             return null;
         }
-        final String ruleType = si.metaData.getString(ConditionProviderService.META_DATA_RULE_TYPE);
-        final ComponentName configurationActivity = getSettingsActivity(si);
+        final String ruleType = (ci instanceof ServiceInfo)
+                ? ci.metaData.getString(ConditionProviderService.META_DATA_RULE_TYPE)
+                : ci.metaData.getString(NotificationManager.META_DATA_AUTOMATIC_RULE_TYPE);
+
+        final ComponentName configurationActivity = getSettingsActivity(null, ci);
         if (ruleType != null && !ruleType.trim().isEmpty() && configurationActivity != null) {
             final ZenRuleInfo ri = new ZenRuleInfo();
-            ri.serviceComponent = new ComponentName(si.packageName, si.name);
+            ri.serviceComponent =
+                    (ci instanceof ServiceInfo) ? new ComponentName(ci.packageName, ci.name) : null;
             ri.settingsAction = Settings.ACTION_ZEN_MODE_EXTERNAL_RULE_SETTINGS;
             ri.title = ruleType;
-            ri.packageName = si.packageName;
-            ri.configurationActivity = getSettingsActivity(si);
-            ri.packageLabel = si.applicationInfo.loadLabel(pm);
-            ri.ruleInstanceLimit =
-                    si.metaData.getInt(ConditionProviderService.META_DATA_RULE_INSTANCE_LIMIT, -1);
+            ri.packageName = ci.packageName;
+            ri.configurationActivity = configurationActivity;
+            ri.packageLabel = ci.applicationInfo.loadLabel(pm);
+            ri.ruleInstanceLimit = (ci instanceof ServiceInfo)
+                    ? ci.metaData.getInt(ConditionProviderService.META_DATA_RULE_INSTANCE_LIMIT, -1)
+                    : ci.metaData.getInt(NotificationManager.META_DATA_RULE_INSTANCE_LIMIT, -1);
             return ri;
         }
         return null;
     }
 
-    protected static ComponentName getSettingsActivity(ServiceInfo si) {
-        if (si == null || si.metaData == null) {
+    protected static ComponentName getSettingsActivity(AutomaticZenRule rule, ComponentInfo ci) {
+        // prefer config activity on the rule itself; fallback to manifest definition
+        if (rule != null && rule.getConfigurationActivity() != null) {
+            return rule.getConfigurationActivity();
+        }
+        if (ci == null) {
             return null;
         }
+        // new activity backed rule
+        if (ci instanceof ActivityInfo) {
+            return new ComponentName(ci.packageName, ci.name);
+        }
+        // old service backed rule
         final String configurationActivity =
-                si.metaData.getString(ConditionProviderService.META_DATA_CONFIGURATION_ACTIVITY);
+                ci.metaData.getString(ConditionProviderService.META_DATA_CONFIGURATION_ACTIVITY);
         if (configurationActivity != null) {
             return ComponentName.unflattenFromString(configurationActivity);
         }
@@ -127,7 +143,7 @@
             mMetricsFeatureProvider.action(mContext,
                     MetricsProto.MetricsEvent.ACTION_ZEN_MODE_RULE_NAME_CHANGE_OK);
             AutomaticZenRule rule = new AutomaticZenRule(ruleName, mRuleInfo.serviceComponent,
-                    mRuleInfo.defaultConditionId,
+                    mRuleInfo.configurationActivity, mRuleInfo.defaultConditionId, null,
                     NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
             String savedRuleId = mBackend.addZenRule(rule);
             if (savedRuleId != null) {
diff --git a/src/com/android/settings/notification/ZenModeAutomationSettings.java b/src/com/android/settings/notification/ZenModeAutomationSettings.java
index d6a7d72..57ee545 100644
--- a/src/com/android/settings/notification/ZenModeAutomationSettings.java
+++ b/src/com/android/settings/notification/ZenModeAutomationSettings.java
@@ -18,6 +18,7 @@
 
 import android.app.AlertDialog;
 import android.app.AutomaticZenRule;
+import android.app.NotificationManager;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.os.Bundle;
@@ -92,6 +93,7 @@
         return new ManagedServiceSettings.Config.Builder()
                 .setTag(TAG)
                 .setIntentAction(ConditionProviderService.SERVICE_INTERFACE)
+                .setConfigurationIntentAction(NotificationManager.ACTION_AUTOMATIC_ZEN_RULE)
                 .setPermission(android.Manifest.permission.BIND_CONDITION_PROVIDER_SERVICE)
                 .setNoun("condition provider")
                 .build();
diff --git a/src/com/android/settings/notification/ZenRuleInfo.java b/src/com/android/settings/notification/ZenRuleInfo.java
index 2d7abf8..1a1539b 100644
--- a/src/com/android/settings/notification/ZenRuleInfo.java
+++ b/src/com/android/settings/notification/ZenRuleInfo.java
@@ -24,6 +24,8 @@
                 that.defaultConditionId) : that.defaultConditionId != null) return false;
         if (serviceComponent != null ? !serviceComponent.equals(
                 that.serviceComponent) : that.serviceComponent != null) return false;
+        if (id != null ? !id.equals(that.id) : that.id != null)
+            return false;
         return packageLabel != null ? packageLabel.equals(
                 that.packageLabel) : that.packageLabel == null;
 
@@ -38,4 +40,5 @@
     public boolean isSystem;
     public CharSequence packageLabel;
     public int ruleInstanceLimit = -1;
+    public String id;
 }
diff --git a/src/com/android/settings/notification/ZenRulePreference.java b/src/com/android/settings/notification/ZenRulePreference.java
index 10b49eb..91f68e8 100644
--- a/src/com/android/settings/notification/ZenRulePreference.java
+++ b/src/com/android/settings/notification/ZenRulePreference.java
@@ -21,6 +21,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ApplicationInfo;
+import android.content.pm.ComponentInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ServiceInfo;
 import android.service.notification.ZenModeConfig;
@@ -45,7 +46,6 @@
     private static final ManagedServiceSettings.Config CONFIG =
             ZenModeAutomationSettings.getConditionProviderConfig();
     final String mId;
-    boolean appExists;
     final Fragment mParent;
     final Preference mPref;
     final Context mContext;
@@ -56,7 +56,6 @@
     final AutomaticZenRule mRule;
     CharSequence mName;
 
-    private boolean mIsSystemRule;
     private Intent mIntent;
     private boolean mChecked;
     private CheckBox mCheckBox;
@@ -163,25 +162,17 @@
         final boolean isSchedule = ZenModeConfig.isValidScheduleConditionId(
                 rule.getConditionId(), true);
         final boolean isEvent = ZenModeConfig.isValidEventConditionId(rule.getConditionId());
-        mIsSystemRule = isSchedule || isEvent;
 
-        try {
-            ApplicationInfo info = mPm.getApplicationInfo(rule.getOwner().getPackageName(), 0);
-            setSummary(computeRuleSummary(rule));
-        } catch (PackageManager.NameNotFoundException e) {
-            appExists = false;
-            return;
-        }
+        setSummary(computeRuleSummary(rule));
 
-        appExists = true;
         setTitle(mName);
         setPersistent(false);
 
         final String action = isSchedule ? ZenModeScheduleRuleSettings.ACTION
                 : isEvent ? ZenModeEventRuleSettings.ACTION : "";
-        ServiceInfo si = mServiceListing.findService(rule.getOwner());
+        ComponentInfo si = mServiceListing.findService(rule.getOwner());
         ComponentName settingsActivity = AbstractZenModeAutomaticRulePreferenceController.
-                getSettingsActivity(si);
+                getSettingsActivity(rule, si);
         mIntent = AbstractZenModeAutomaticRulePreferenceController.getRuleIntent(action,
                 settingsActivity, mId);
         setKey(mId);
diff --git a/src/com/android/settings/notification/ZenRuleSelectionDialog.java b/src/com/android/settings/notification/ZenRuleSelectionDialog.java
index abda376..7f0b4c2 100644
--- a/src/com/android/settings/notification/ZenRuleSelectionDialog.java
+++ b/src/com/android/settings/notification/ZenRuleSelectionDialog.java
@@ -23,6 +23,7 @@
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.pm.ApplicationInfo;
+import android.content.pm.ComponentInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ServiceInfo;
 import android.graphics.drawable.Drawable;
@@ -192,16 +193,17 @@
     private final ZenServiceListing.Callback mServiceListingCallback = new
             ZenServiceListing.Callback() {
         @Override
-        public void onServicesReloaded(Set<ServiceInfo> services) {
-            if (DEBUG) Log.d(TAG, "Services reloaded: count=" + services.size());
+        public void onComponentsReloaded(Set<ComponentInfo> componentInfos) {
+            if (DEBUG) Log.d(TAG, "Reloaded: count=" + componentInfos.size());
+
             Set<ZenRuleInfo> externalRuleTypes = new TreeSet<>(RULE_TYPE_COMPARATOR);
-            for (ServiceInfo serviceInfo : services) {
+            for (ComponentInfo ci : componentInfos) {
                 final ZenRuleInfo ri = AbstractZenModeAutomaticRulePreferenceController.
-                        getRuleInfo(mPm, serviceInfo);
+                        getRuleInfo(mPm, ci);
                 if (ri != null && ri.configurationActivity != null
                         && mNm.isNotificationPolicyAccessGrantedForPackage(ri.packageName)
                         && (ri.ruleInstanceLimit <= 0 || ri.ruleInstanceLimit
-                        >= (mNm.getRuleInstanceCount(serviceInfo.getComponentName()) + 1))) {
+                        >= (mNm.getRuleInstanceCount(ci.getComponentName()) + 1))) {
                     externalRuleTypes.add(ri);
                 }
             }
diff --git a/src/com/android/settings/utils/ManagedServiceSettings.java b/src/com/android/settings/utils/ManagedServiceSettings.java
index e5dfb06..16f79c2 100644
--- a/src/com/android/settings/utils/ManagedServiceSettings.java
+++ b/src/com/android/settings/utils/ManagedServiceSettings.java
@@ -240,9 +240,11 @@
         public final int warningDialogTitle;
         public final int warningDialogSummary;
         public final int emptyText;
+        public final String configIntentAction;
 
-        private Config(String tag, String setting, String intentAction, String permission,
-                String noun, int warningDialogTitle, int warningDialogSummary, int emptyText) {
+        private Config(String tag, String setting, String intentAction, String configIntentAction,
+                String permission, String noun, int warningDialogTitle, int warningDialogSummary,
+                int emptyText) {
             this.tag = tag;
             this.setting = setting;
             this.intentAction = intentAction;
@@ -251,6 +253,7 @@
             this.warningDialogTitle = warningDialogTitle;
             this.warningDialogSummary = warningDialogSummary;
             this.emptyText = emptyText;
+            this.configIntentAction = configIntentAction;
         }
 
         public static class Builder{
@@ -262,6 +265,7 @@
             private int mWarningDialogTitle;
             private int mWarningDialogSummary;
             private int mEmptyText;
+            private String mConfigIntentAction;
 
             public Builder setTag(String tag) {
                 mTag = tag;
@@ -278,6 +282,11 @@
                 return this;
             }
 
+            public Builder setConfigurationIntentAction(String action) {
+                mConfigIntentAction = action;
+                return this;
+            }
+
             public Builder setPermission(String permission) {
                 mPermission = permission;
                 return this;
@@ -304,8 +313,8 @@
             }
 
             public Config build() {
-                return new Config(mTag, mSetting, mIntentAction, mPermission, mNoun,
-                        mWarningDialogTitle, mWarningDialogSummary, mEmptyText);
+                return new Config(mTag, mSetting, mIntentAction, mConfigIntentAction, mPermission,
+                        mNoun, mWarningDialogTitle, mWarningDialogSummary, mEmptyText);
             }
         }
     }
diff --git a/src/com/android/settings/utils/ZenServiceListing.java b/src/com/android/settings/utils/ZenServiceListing.java
index e87cc51..99f56f6 100644
--- a/src/com/android/settings/utils/ZenServiceListing.java
+++ b/src/com/android/settings/utils/ZenServiceListing.java
@@ -20,6 +20,8 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ComponentInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
@@ -34,7 +36,7 @@
 
     private final Context mContext;
     private final ManagedServiceSettings.Config mConfig;
-    private final Set<ServiceInfo> mApprovedServices = new ArraySet<ServiceInfo>();
+    private final Set<ComponentInfo> mApprovedComponents = new ArraySet<>();
     private final List<Callback> mZenCallbacks = new ArrayList<>();
     private final NotificationManager mNm;
 
@@ -44,11 +46,14 @@
         mNm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
     }
 
-    public ServiceInfo findService(final ComponentName cn) {
-        for (ServiceInfo service : mApprovedServices) {
-            final ComponentName serviceCN = new ComponentName(service.packageName, service.name);
-            if (serviceCN.equals(cn)) {
-                return service;
+    public ComponentInfo findService(final ComponentName cn) {
+        if (cn == null) {
+            return null;
+        }
+        for (ComponentInfo component : mApprovedComponents) {
+            final ComponentName ci = new ComponentName(component.packageName, component.name);
+            if (ci.equals(cn)) {
+                return component;
             }
         }
         return null;
@@ -63,32 +68,29 @@
     }
 
     public void reloadApprovedServices() {
-        mApprovedServices.clear();
+        mApprovedComponents.clear();
 
         List<String> enabledNotificationListenerPkgs = mNm.getEnabledNotificationListenerPackages();
-        List<ServiceInfo> services = new ArrayList<>();
-        getServices(mConfig, services, mContext.getPackageManager());
-        for (ServiceInfo service : services) {
-            final String servicePackage = service.getComponentName().getPackageName();
-            if (mNm.isNotificationPolicyAccessGrantedForPackage(servicePackage)
-                || enabledNotificationListenerPkgs.contains(servicePackage)) {
-                mApprovedServices.add(service);
+        List<ComponentInfo> components = new ArrayList<>();
+        getServices(mConfig, components, mContext.getPackageManager());
+        getActivities(mConfig, components, mContext.getPackageManager());
+        for (ComponentInfo componentInfo : components) {
+            final String pkg = componentInfo.getComponentName().getPackageName();
+            if (mNm.isNotificationPolicyAccessGrantedForPackage(pkg)
+                || enabledNotificationListenerPkgs.contains(pkg)) {
+                mApprovedComponents.add(componentInfo);
             }
         }
 
-        if (!mApprovedServices.isEmpty()) {
+        if (!mApprovedComponents.isEmpty()) {
             for (Callback callback : mZenCallbacks) {
-                callback.onServicesReloaded(mApprovedServices);
+                callback.onComponentsReloaded(mApprovedComponents);
             }
         }
     }
 
-    private static int getServices(ManagedServiceSettings.Config c, List<ServiceInfo> list,
+    private static void getServices(ManagedServiceSettings.Config c, List<ComponentInfo> list,
             PackageManager pm) {
-        int services = 0;
-        if (list != null) {
-            list.clear();
-        }
         final int user = ActivityManager.getCurrentUser();
 
         List<ResolveInfo> installedServices = pm.queryIntentServicesAsUser(
@@ -110,12 +112,28 @@
             if (list != null) {
                 list.add(info);
             }
-            services++;
         }
-        return services;
+    }
+
+    private static void getActivities(ManagedServiceSettings.Config c, List<ComponentInfo> list,
+            PackageManager pm) {
+        final int user = ActivityManager.getCurrentUser();
+
+        List<ResolveInfo> resolveInfos = pm.queryIntentActivitiesAsUser(
+                new Intent(c.configIntentAction),
+                PackageManager.GET_ACTIVITIES | PackageManager.GET_META_DATA,
+                user);
+
+        for (int i = 0, count = resolveInfos.size(); i < count; i++) {
+            ResolveInfo resolveInfo = resolveInfos.get(i);
+            ActivityInfo info = resolveInfo.activityInfo;
+            if (list != null) {
+                list.add(info);
+            }
+        }
     }
 
     public interface Callback {
-        void onServicesReloaded(Set<ServiceInfo> services);
+        void onComponentsReloaded(Set<ComponentInfo> components);
     }
 }
diff --git a/tests/robotests/src/com/android/settings/notification/ZenModeAutomaticRulesPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ZenModeAutomaticRulesPreferenceControllerTest.java
index 5e3d6e9..41227c5 100644
--- a/tests/robotests/src/com/android/settings/notification/ZenModeAutomaticRulesPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/ZenModeAutomaticRulesPreferenceControllerTest.java
@@ -83,12 +83,12 @@
         String ruleId2 = "test2_id";
         String ruleId3 = "test3_id";
 
-        AutomaticZenRule autoRule1 = new AutomaticZenRule("test_rule_1", null,
-            null, Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, true, 10);
-        AutomaticZenRule autoRule2 = new AutomaticZenRule("test_rule_2", null,
-            null, Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, true, 20);
-        AutomaticZenRule autoRule3 = new AutomaticZenRule("test_rule_3", null,
-            null, Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, true, 30);
+        AutomaticZenRule autoRule1 = new AutomaticZenRule("test_rule_1", null, null,
+            null, null, Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, true, 10);
+        AutomaticZenRule autoRule2 = new AutomaticZenRule("test_rule_2", null, null,
+            null, null, Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, true, 20);
+        AutomaticZenRule autoRule3 = new AutomaticZenRule("test_rule_3", null, null,
+            null, null, Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, true, 30);
 
         rMap.put(ruleId1, autoRule1);
         rMap.put(ruleId2, autoRule2);
@@ -109,10 +109,10 @@
         String ruleId1 = "test1_id";
         String ruleId2 = "test2_id";
 
-        AutomaticZenRule autoRule1 = new AutomaticZenRule("test_rule_1", null,
-            null, Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, true, 10);
-        AutomaticZenRule autoRule2 = new AutomaticZenRule("test_rule_2", null,
-            null, Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, true, 20);
+        AutomaticZenRule autoRule1 = new AutomaticZenRule("test_rule_1", null, null,
+            null, null, Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, true, 10);
+        AutomaticZenRule autoRule2 = new AutomaticZenRule("test_rule_2", null, null,
+            null, null, Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, true, 20);
 
         rMap.put(ruleId1, autoRule1);
         rMap.put(ruleId2, autoRule2);
@@ -130,8 +130,8 @@
         final int NUM_RULES = 1;
         Map<String, AutomaticZenRule> rMap = new HashMap<>();
         String testId = "test1_id";
-        AutomaticZenRule rule = new AutomaticZenRule("rule_name", null,
-            null, Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, true, 10);
+        AutomaticZenRule rule = new AutomaticZenRule("rule_name", null, null,
+            null, null, Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, true, 10);
         rMap.put(testId, rule);
 
         when(mockPref.getPreferenceCount()).thenReturn(NUM_RULES);
diff --git a/tests/robotests/src/com/android/settings/notification/ZenModeBackendTest.java b/tests/robotests/src/com/android/settings/notification/ZenModeBackendTest.java
index 3feff0d..6169f92 100644
--- a/tests/robotests/src/com/android/settings/notification/ZenModeBackendTest.java
+++ b/tests/robotests/src/com/android/settings/notification/ZenModeBackendTest.java
@@ -69,13 +69,14 @@
 
         for (int i = 0; i < numRules; i++) {
             ruleMap.put(GENERIC_RULE_NAME + i, new AutomaticZenRule(GENERIC_RULE_NAME + i, null,
-                    null, Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, true, i * 2));
+                    null, null, null, Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, true,
+                    i * 2));
         }
 
         if (addDefaultRules) {
-            ruleMap.put(DEFAULT_ID_1, new AutomaticZenRule("DEFAULT_1_NAME", null,
+            ruleMap.put(DEFAULT_ID_1, new AutomaticZenRule("DEFAULT_1_NAME", null, null, null,
                     null, Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, true, 20));
-            ruleMap.put(DEFAULT_ID_2, new AutomaticZenRule("DEFAULT_2_NAME", null,
+            ruleMap.put(DEFAULT_ID_2, new AutomaticZenRule("DEFAULT_2_NAME", null, null, null,
                     null, Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, true, 10));
         }
 
@@ -90,13 +91,14 @@
 
         for (int i = 0; i < numRules; i++) {
             ruleMap.put(GENERIC_RULE_NAME + i, new AutomaticZenRule(GENERIC_RULE_NAME + i, null,
-                    null, Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, true, numRules - i));
+                    null, null, null, Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, true,
+                    numRules - i));
         }
 
         if (addDefaultRules) {
-            ruleMap.put(DEFAULT_ID_1, new AutomaticZenRule("DEFAULT_1_NAME", null,
+            ruleMap.put(DEFAULT_ID_1, new AutomaticZenRule("DEFAULT_1_NAME", null, null, null,
                     null, Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, true, 10));
-            ruleMap.put(DEFAULT_ID_2, new AutomaticZenRule("DEFAULT_2_NAME", null,
+            ruleMap.put(DEFAULT_ID_2, new AutomaticZenRule("DEFAULT_2_NAME", null, null, null,
                     null, Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, true, 20));
         }