Merge "Disable zen rule preferences with invalid activities" into tm-qpr-dev
diff --git a/src/com/android/settings/notification/zen/ZenRulePreference.java b/src/com/android/settings/notification/zen/ZenRulePreference.java
index 8cf3106..fb056fe 100644
--- a/src/com/android/settings/notification/zen/ZenRulePreference.java
+++ b/src/com/android/settings/notification/zen/ZenRulePreference.java
@@ -22,8 +22,10 @@
 import android.content.Intent;
 import android.content.pm.ComponentInfo;
 import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
 import android.service.notification.ZenModeConfig;
 import android.service.notification.ZenModeConfig.ScheduleInfo;
+import android.util.Log;
 
 import androidx.fragment.app.Fragment;
 import androidx.preference.Preference;
@@ -34,9 +36,11 @@
 import com.android.settingslib.PrimarySwitchPreference;
 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
+import java.util.List;
 import java.util.Map;
 
 public class ZenRulePreference extends PrimarySwitchPreference {
+    private static final String TAG = "ZenRulePreference";
     private static final ManagedServiceSettings.Config CONFIG =
             ZenModeAutomationSettings.getConditionProviderConfig();
     final String mId;
@@ -119,8 +123,14 @@
                 getSettingsActivity(mPm, rule, si);
         mIntent = AbstractZenModeAutomaticRulePreferenceController.getRuleIntent(action,
                 settingsActivity, mId);
-        if (mIntent.resolveActivity(mPm) == null) {
+        // If the intent's activity for this rule doesn't exist or resolve to anything, disable the
+        // preference and rule.
+        List<ResolveInfo> results = mPm.queryIntentActivities(
+                mIntent, PackageManager.ResolveInfoFlags.of(0));
+        if (mIntent.resolveActivity(mPm) == null || results.size() == 0) {
+            Log.w(TAG, "intent for zen rule invalid: " + mIntent);
             mIntent = null;
+            setEnabled(false);
         }
         setKey(mId);
     }
diff --git a/src/com/android/settings/notification/zen/ZenRuleSelectionDialog.java b/src/com/android/settings/notification/zen/ZenRuleSelectionDialog.java
index b159a01..71df014 100644
--- a/src/com/android/settings/notification/zen/ZenRuleSelectionDialog.java
+++ b/src/com/android/settings/notification/zen/ZenRuleSelectionDialog.java
@@ -21,9 +21,11 @@
 import android.app.settings.SettingsEnums;
 import android.content.Context;
 import android.content.DialogInterface;
+import android.content.Intent;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.ComponentInfo;
 import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
 import android.graphics.drawable.Drawable;
 import android.os.AsyncTask;
 import android.os.Bundle;
@@ -45,6 +47,7 @@
 import java.lang.ref.WeakReference;
 import java.text.Collator;
 import java.util.Comparator;
+import java.util.List;
 import java.util.Set;
 import java.util.TreeSet;
 
@@ -113,6 +116,14 @@
         }
     }
 
+    // Returns whether the rule's configuration activity exists and is valid.
+    private boolean isRuleActivityValid(final ZenRuleInfo ri) {
+        Intent intent = new Intent().setComponent(ri.configurationActivity);
+        List<ResolveInfo> results = mPm.queryIntentActivities(
+                intent, PackageManager.ResolveInfoFlags.of(0));
+        return intent.resolveActivity(mPm) != null && results.size() > 0;
+    }
+
     private void bindType(final ZenRuleInfo ri) {
         try {
             ApplicationInfo info = mPm.getApplicationInfo(ri.packageName, 0);
@@ -122,6 +133,11 @@
             ImageView iconView = v.findViewById(R.id.icon);
             ((TextView) v.findViewById(R.id.title)).setText(ri.title);
             if (!ri.isSystem) {
+                // Omit rule if the externally provided rule activity is not valid.
+                if (!isRuleActivityValid(ri)) {
+                    Log.w(TAG, "rule configuration activity invalid: " + ri.configurationActivity);
+                    return;
+                }
                 LoadIconTask task = new LoadIconTask(iconView);
                 task.execute(info);