diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java index 4fb166ab551..47ff6afbb5d 100644 --- a/src/com/android/settings/Utils.java +++ b/src/com/android/settings/Utils.java @@ -30,9 +30,11 @@ import android.content.Context; 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 @@ public final class Utils { 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 adec63a49b9..4b1bc1051d8 100755 --- a/src/com/android/settings/applications/InstalledAppDetails.java +++ b/src/com/android/settings/applications/InstalledAppDetails.java @@ -316,22 +316,13 @@ public class InstalledAppDetails extends Fragment } } - 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 @@ public class InstalledAppDetails extends Fragment // 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 3879bef67e6..7ca4b18136b 100644 --- a/src/com/android/settings/notification/NotificationAppList.java +++ b/src/com/android/settings/notification/NotificationAppList.java @@ -193,30 +193,6 @@ public class NotificationAppList extends PinnedHeaderListFragment 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 class NotificationAppList extends PinnedHeaderListFragment public boolean priority; public boolean sensitive; public boolean first; // first app in section + public boolean isSystem; } private static final Comparator mRowComparator = new Comparator() { @@ -385,6 +362,7 @@ public class NotificationAppList extends PinnedHeaderListFragment } }; + public static AppRow loadAppRow(PackageManager pm, PackageInfo pkg, Backend backend) { final AppRow row = new AppRow(); row.pkg = pkg.packageName; @@ -399,16 +377,28 @@ public class NotificationAppList extends PinnedHeaderListFragment 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 rows) { + public static List queryNotificationConfigActivities(PackageManager pm) { if (DEBUG) Log.d(TAG, "APP_NOTIFICATION_PREFS_CATEGORY_INTENT is " + APP_NOTIFICATION_PREFS_CATEGORY_INTENT); final List 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 rows) { + final List resolveInfos = queryNotificationConfigActivities(pm); + applyConfigActivities(pm, rows, resolveInfos); + } + + public static void applyConfigActivities(PackageManager pm, ArrayMap rows, + List 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 @@ public class NotificationAppList extends PinnedHeaderListFragment + 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 @@ public class NotificationAppList extends PinnedHeaderListFragment 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 resolvedApps = pm.queryIntentActivities( + new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_LAUNCHER), + PackageManager.MATCH_DEFAULT_ONLY + ); + final List 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);