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
This commit is contained in:
@@ -30,9 +30,11 @@ import android.content.Context;
|
|||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.ApplicationInfo;
|
import android.content.pm.ApplicationInfo;
|
||||||
|
import android.content.pm.PackageInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.PackageManager.NameNotFoundException;
|
import android.content.pm.PackageManager.NameNotFoundException;
|
||||||
import android.content.pm.ResolveInfo;
|
import android.content.pm.ResolveInfo;
|
||||||
|
import android.content.pm.Signature;
|
||||||
import android.content.pm.UserInfo;
|
import android.content.pm.UserInfo;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.content.res.Resources.NotFoundException;
|
import android.content.res.Resources.NotFoundException;
|
||||||
@@ -839,4 +841,34 @@ public final class Utils {
|
|||||||
|
|
||||||
return tm.getSimCount() > 0;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -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) {
|
private boolean handleDisableable(Button button) {
|
||||||
boolean disableable = false;
|
boolean disableable = false;
|
||||||
// Try to prevent the user from bricking their phone
|
// Try to prevent the user from bricking their phone
|
||||||
// by not allowing disabling of apps signed with the
|
// by not allowing disabling of apps signed with the
|
||||||
// system cert and any launcher app in the system.
|
// 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.
|
// Disable button for core system applications.
|
||||||
button.setText(R.string.disable_text);
|
button.setText(R.string.disable_text);
|
||||||
} else if (mAppEntry.info.enabled) {
|
} else if (mAppEntry.info.enabled) {
|
||||||
@@ -427,7 +418,7 @@ public class InstalledAppDetails extends Fragment
|
|||||||
// this does not bode well
|
// this does not bode well
|
||||||
}
|
}
|
||||||
mNotificationSwitch.setChecked(enabled);
|
mNotificationSwitch.setChecked(enabled);
|
||||||
if (isThisASystemPackage()) {
|
if (Utils.isSystemPackage(mPm, mPackageInfo)) {
|
||||||
mNotificationSwitch.setEnabled(false);
|
mNotificationSwitch.setEnabled(false);
|
||||||
} else {
|
} else {
|
||||||
mNotificationSwitch.setEnabled(true);
|
mNotificationSwitch.setEnabled(true);
|
||||||
|
@@ -193,30 +193,6 @@ public class NotificationAppList extends PinnedHeaderListFragment
|
|||||||
parent.getPaddingEnd() - eat, parent.getPaddingBottom());
|
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 {
|
private static class ViewHolder {
|
||||||
ViewGroup row;
|
ViewGroup row;
|
||||||
ImageView icon;
|
ImageView icon;
|
||||||
@@ -375,6 +351,7 @@ public class NotificationAppList extends PinnedHeaderListFragment
|
|||||||
public boolean priority;
|
public boolean priority;
|
||||||
public boolean sensitive;
|
public boolean sensitive;
|
||||||
public boolean first; // first app in section
|
public boolean first; // first app in section
|
||||||
|
public boolean isSystem;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Comparator<AppRow> mRowComparator = new Comparator<AppRow>() {
|
private static final Comparator<AppRow> mRowComparator = new Comparator<AppRow>() {
|
||||||
@@ -385,6 +362,7 @@ public class NotificationAppList extends PinnedHeaderListFragment
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
public static AppRow loadAppRow(PackageManager pm, PackageInfo pkg, Backend backend) {
|
public static AppRow loadAppRow(PackageManager pm, PackageInfo pkg, Backend backend) {
|
||||||
final AppRow row = new AppRow();
|
final AppRow row = new AppRow();
|
||||||
row.pkg = pkg.packageName;
|
row.pkg = pkg.packageName;
|
||||||
@@ -399,16 +377,28 @@ public class NotificationAppList extends PinnedHeaderListFragment
|
|||||||
row.banned = backend.getNotificationsBanned(row.pkg, row.uid);
|
row.banned = backend.getNotificationsBanned(row.pkg, row.uid);
|
||||||
row.priority = backend.getHighPriority(row.pkg, row.uid);
|
row.priority = backend.getHighPriority(row.pkg, row.uid);
|
||||||
row.sensitive = backend.getSensitive(row.pkg, row.uid);
|
row.sensitive = backend.getSensitive(row.pkg, row.uid);
|
||||||
|
row.isSystem = Utils.isSystemPackage(pm, pkg);
|
||||||
return row;
|
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 "
|
if (DEBUG) Log.d(TAG, "APP_NOTIFICATION_PREFS_CATEGORY_INTENT is "
|
||||||
+ APP_NOTIFICATION_PREFS_CATEGORY_INTENT);
|
+ APP_NOTIFICATION_PREFS_CATEGORY_INTENT);
|
||||||
final List<ResolveInfo> resolveInfos = pm.queryIntentActivities(
|
final List<ResolveInfo> resolveInfos = pm.queryIntentActivities(
|
||||||
APP_NOTIFICATION_PREFS_CATEGORY_INTENT,
|
APP_NOTIFICATION_PREFS_CATEGORY_INTENT,
|
||||||
PackageManager.MATCH_DEFAULT_ONLY);
|
0 //PackageManager.MATCH_DEFAULT_ONLY
|
||||||
if (DEBUG) Log.d(TAG, "Found " + resolveInfos.size() + " preference activities");
|
);
|
||||||
|
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) {
|
for (ResolveInfo ri : resolveInfos) {
|
||||||
final ActivityInfo activityInfo = ri.activityInfo;
|
final ActivityInfo activityInfo = ri.activityInfo;
|
||||||
final ApplicationInfo appInfo = activityInfo.applicationInfo;
|
final ApplicationInfo appInfo = activityInfo.applicationInfo;
|
||||||
@@ -425,7 +415,7 @@ public class NotificationAppList extends PinnedHeaderListFragment
|
|||||||
+ activityInfo.packageName);
|
+ activityInfo.packageName);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
row.settingsIntent = new Intent(Intent.ACTION_MAIN)
|
row.settingsIntent = new Intent(APP_NOTIFICATION_PREFS_CATEGORY_INTENT)
|
||||||
.setClassName(activityInfo.packageName, activityInfo.name);
|
.setClassName(activityInfo.packageName, activityInfo.name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -439,18 +429,41 @@ public class NotificationAppList extends PinnedHeaderListFragment
|
|||||||
mRows.clear();
|
mRows.clear();
|
||||||
mSortedRows.clear();
|
mSortedRows.clear();
|
||||||
|
|
||||||
// collect all non-system apps
|
// collect all launchable apps, plus any packages that have notification settings
|
||||||
final PackageManager pm = mContext.getPackageManager();
|
final PackageManager pm = mContext.getPackageManager();
|
||||||
for (PackageInfo pkg : pm.getInstalledPackages(PackageManager.GET_SIGNATURES)) {
|
final List<ResolveInfo> resolvedApps = pm.queryIntentActivities(
|
||||||
if (pkg.applicationInfo == null || isSystemApp(pkg)) {
|
new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_LAUNCHER),
|
||||||
if (DEBUG) Log.d(TAG, "Skipping " + pkg.packageName);
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
final AppRow row = loadAppRow(pm, pkg, mBackend);
|
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
|
// sort rows
|
||||||
mSortedRows.addAll(mRows.values());
|
mSortedRows.addAll(mRows.values());
|
||||||
Collections.sort(mSortedRows, mRowComparator);
|
Collections.sort(mSortedRows, mRowComparator);
|
||||||
|
Reference in New Issue
Block a user