Disable zen rule preferences with invalid activities

While resolveActivity is used to determine whether an Intent can be handled by something, this doesn't catch the case of explicit intents whose activity class doesn't exist. Here we check for it through PackageManager.queryIntentActivities instead for existing zen rules (if they were added when the activity exists, but it no longer does).

For new rules, check the validity of the activity for external rules before adding them to the list.

Bug: 238144390
Test: manual via DND app
Change-Id: Ia920ca792f9c17a5d684baf877c882ce7fadffd6
This commit is contained in:
Yuri Lin
2022-12-13 14:55:44 -05:00
parent 410c1d28bf
commit afe52dfae5
2 changed files with 27 additions and 1 deletions

View File

@@ -22,8 +22,10 @@ import android.content.Context;
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.settings.utils.ZenServiceListing;
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 @@ public class ZenRulePreference extends PrimarySwitchPreference {
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);
}

View File

@@ -21,9 +21,11 @@ import android.app.NotificationManager;
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 com.android.settings.utils.ZenServiceListing;
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 @@ public class ZenRuleSelectionDialog extends InstrumentedDialogFragment {
}
}
// 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 @@ public class ZenRuleSelectionDialog extends InstrumentedDialogFragment {
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);