Fix links to notification settings activities.
Additionally, we now show the user a list of "app-like"
things (packages with launchable activities) instead of only
non-system things. This way you can make (some) changes to
system package notifications while not having to page
through reams of random non-app packages.
Bug: 17277023
Change-Id: I920d6b941070efb75a816e6ad38b798b09a83d08
diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java
index 4fb166a..47ff6af 100644
--- a/src/com/android/settings/Utils.java
+++ b/src/com/android/settings/Utils.java
@@ -30,9 +30,11 @@
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
+import android.content.pm.Signature;
import android.content.pm.UserInfo;
import android.content.res.Resources;
import android.content.res.Resources.NotFoundException;
@@ -839,4 +841,34 @@
return tm.getSimCount() > 0;
}
+
+ /**
+ * Determine whether a package is a "system package", in which case certain things (like
+ * disabling notifications or disabling the package altogether) should be disallowed.
+ */
+ public static boolean isSystemPackage(PackageManager pm, PackageInfo pkg) {
+ if (sSystemSignature == null) {
+ sSystemSignature = new Signature[]{ getSystemSignature(pm) };
+ }
+ return sSystemSignature[0] != null && sSystemSignature[0].equals(getFirstSignature(pkg));
+ }
+
+ private static Signature[] sSystemSignature;
+
+ private static Signature getFirstSignature(PackageInfo pkg) {
+ if (pkg != null && pkg.signatures != null && pkg.signatures.length > 0) {
+ return pkg.signatures[0];
+ }
+ return null;
+ }
+
+ private static Signature getSystemSignature(PackageManager pm) {
+ try {
+ final PackageInfo sys = pm.getPackageInfo("android", PackageManager.GET_SIGNATURES);
+ return getFirstSignature(sys);
+ } catch (NameNotFoundException e) {
+ }
+ return null;
+ }
+
}
diff --git a/src/com/android/settings/applications/InstalledAppDetails.java b/src/com/android/settings/applications/InstalledAppDetails.java
index adec63a..4b1bc10 100755
--- a/src/com/android/settings/applications/InstalledAppDetails.java
+++ b/src/com/android/settings/applications/InstalledAppDetails.java
@@ -316,22 +316,13 @@
}
}
- private boolean isThisASystemPackage() {
- try {
- PackageInfo sys = mPm.getPackageInfo("android", PackageManager.GET_SIGNATURES);
- return (mPackageInfo != null && mPackageInfo.signatures != null &&
- sys.signatures[0].equals(mPackageInfo.signatures[0]));
- } catch (PackageManager.NameNotFoundException e) {
- return false;
- }
- }
-
private boolean handleDisableable(Button button) {
boolean disableable = false;
// Try to prevent the user from bricking their phone
// by not allowing disabling of apps signed with the
// system cert and any launcher app in the system.
- if (mHomePackages.contains(mAppEntry.info.packageName) || isThisASystemPackage()) {
+ if (mHomePackages.contains(mAppEntry.info.packageName)
+ || Utils.isSystemPackage(mPm, mPackageInfo)) {
// Disable button for core system applications.
button.setText(R.string.disable_text);
} else if (mAppEntry.info.enabled) {
@@ -427,7 +418,7 @@
// this does not bode well
}
mNotificationSwitch.setChecked(enabled);
- if (isThisASystemPackage()) {
+ if (Utils.isSystemPackage(mPm, mPackageInfo)) {
mNotificationSwitch.setEnabled(false);
} else {
mNotificationSwitch.setEnabled(true);
diff --git a/src/com/android/settings/notification/NotificationAppList.java b/src/com/android/settings/notification/NotificationAppList.java
index 3879bef..7ca4b18 100644
--- a/src/com/android/settings/notification/NotificationAppList.java
+++ b/src/com/android/settings/notification/NotificationAppList.java
@@ -193,30 +193,6 @@
parent.getPaddingEnd() - eat, parent.getPaddingBottom());
}
- private boolean isSystemApp(PackageInfo pkg) {
- if (mSystemSignature == null) {
- mSystemSignature = new Signature[]{ getSystemSignature() };
- }
- return mSystemSignature[0] != null && mSystemSignature[0].equals(getFirstSignature(pkg));
- }
-
- private static Signature getFirstSignature(PackageInfo pkg) {
- if (pkg != null && pkg.signatures != null && pkg.signatures.length > 0) {
- return pkg.signatures[0];
- }
- return null;
- }
-
- private Signature getSystemSignature() {
- final PackageManager pm = mContext.getPackageManager();
- try {
- final PackageInfo sys = pm.getPackageInfo("android", PackageManager.GET_SIGNATURES);
- return getFirstSignature(sys);
- } catch (NameNotFoundException e) {
- }
- return null;
- }
-
private static class ViewHolder {
ViewGroup row;
ImageView icon;
@@ -375,6 +351,7 @@
public boolean priority;
public boolean sensitive;
public boolean first; // first app in section
+ public boolean isSystem;
}
private static final Comparator<AppRow> mRowComparator = new Comparator<AppRow>() {
@@ -385,6 +362,7 @@
}
};
+
public static AppRow loadAppRow(PackageManager pm, PackageInfo pkg, Backend backend) {
final AppRow row = new AppRow();
row.pkg = pkg.packageName;
@@ -399,16 +377,28 @@
row.banned = backend.getNotificationsBanned(row.pkg, row.uid);
row.priority = backend.getHighPriority(row.pkg, row.uid);
row.sensitive = backend.getSensitive(row.pkg, row.uid);
+ row.isSystem = Utils.isSystemPackage(pm, pkg);
return row;
}
- public static void collectConfigActivities(PackageManager pm, ArrayMap<String, AppRow> rows) {
+ public static List<ResolveInfo> queryNotificationConfigActivities(PackageManager pm) {
if (DEBUG) Log.d(TAG, "APP_NOTIFICATION_PREFS_CATEGORY_INTENT is "
+ APP_NOTIFICATION_PREFS_CATEGORY_INTENT);
final List<ResolveInfo> resolveInfos = pm.queryIntentActivities(
APP_NOTIFICATION_PREFS_CATEGORY_INTENT,
- PackageManager.MATCH_DEFAULT_ONLY);
- if (DEBUG) Log.d(TAG, "Found " + resolveInfos.size() + " preference activities");
+ 0 //PackageManager.MATCH_DEFAULT_ONLY
+ );
+ return resolveInfos;
+ }
+ public static void collectConfigActivities(PackageManager pm, ArrayMap<String, AppRow> rows) {
+ final List<ResolveInfo> resolveInfos = queryNotificationConfigActivities(pm);
+ applyConfigActivities(pm, rows, resolveInfos);
+ }
+
+ public static void applyConfigActivities(PackageManager pm, ArrayMap<String, AppRow> rows,
+ List<ResolveInfo> resolveInfos) {
+ if (DEBUG) Log.d(TAG, "Found " + resolveInfos.size() + " preference activities"
+ + (resolveInfos.size() == 0 ? " ;_;" : ""));
for (ResolveInfo ri : resolveInfos) {
final ActivityInfo activityInfo = ri.activityInfo;
final ApplicationInfo appInfo = activityInfo.applicationInfo;
@@ -425,7 +415,7 @@
+ activityInfo.packageName);
continue;
}
- row.settingsIntent = new Intent(Intent.ACTION_MAIN)
+ row.settingsIntent = new Intent(APP_NOTIFICATION_PREFS_CATEGORY_INTENT)
.setClassName(activityInfo.packageName, activityInfo.name);
}
}
@@ -439,18 +429,41 @@
mRows.clear();
mSortedRows.clear();
- // collect all non-system apps
+ // collect all launchable apps, plus any packages that have notification settings
final PackageManager pm = mContext.getPackageManager();
- for (PackageInfo pkg : pm.getInstalledPackages(PackageManager.GET_SIGNATURES)) {
- if (pkg.applicationInfo == null || isSystemApp(pkg)) {
- if (DEBUG) Log.d(TAG, "Skipping " + pkg.packageName);
+ final List<ResolveInfo> resolvedApps = pm.queryIntentActivities(
+ new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_LAUNCHER),
+ PackageManager.MATCH_DEFAULT_ONLY
+ );
+ final List<ResolveInfo> resolvedConfigActivities
+ = queryNotificationConfigActivities(pm);
+ resolvedApps.addAll(resolvedConfigActivities);
+
+ for (ResolveInfo info : resolvedApps) {
+ String pkgName = info.activityInfo.packageName;
+ if (mRows.containsKey(pkgName)) {
+ // we already have this app, thanks
+ continue;
+ }
+
+ PackageInfo pkg = null;
+ try {
+ pkg = pm.getPackageInfo(pkgName,
+ PackageManager.GET_SIGNATURES);
+ } catch (NameNotFoundException e) {
+ if (DEBUG) Log.d(TAG, "Skipping (NNFE): " + pkg.packageName);
+ continue;
+ }
+ if (info.activityInfo.applicationInfo == null) {
+ if (DEBUG) Log.d(TAG, "Skipping (no applicationInfo): " + pkg.packageName);
continue;
}
final AppRow row = loadAppRow(pm, pkg, mBackend);
- mRows.put(row.pkg, row);
+ mRows.put(pkgName, row);
}
- // collect config activities
- collectConfigActivities(pm, mRows);
+
+ // add config activities to the list
+ applyConfigActivities(pm, mRows, resolvedConfigActivities);
// sort rows
mSortedRows.addAll(mRows.values());
Collections.sort(mSortedRows, mRowComparator);