Merge "wifi-display: mark certification strings as not tranlatable" into klp-dev
diff --git a/src/com/android/settings/HomeSettings.java b/src/com/android/settings/HomeSettings.java
index 6d937fd..bac94d6 100644
--- a/src/com/android/settings/HomeSettings.java
+++ b/src/com/android/settings/HomeSettings.java
@@ -18,12 +18,14 @@
import java.util.ArrayList;
+import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.ColorFilter;
@@ -94,7 +96,7 @@
void uninstallApp(HomeAppPreference pref) {
// Uninstallation is done by asking the OS to do it
- Uri packageURI = Uri.parse("package:" + pref.activityName.getPackageName());
+ Uri packageURI = Uri.parse("package:" + pref.uninstallTarget);
Intent uninstallIntent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE, packageURI);
uninstallIntent.putExtra(Intent.EXTRA_UNINSTALL_ALL_USERS, false);
int requestCode = REQUESTING_UNINSTALL + (pref.isChecked ? 1 : 0);
@@ -144,9 +146,8 @@
try {
Drawable icon = info.loadIcon(mPm);
CharSequence name = info.loadLabel(mPm);
- boolean isSystem = (info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
HomeAppPreference pref = new HomeAppPreference(context, activityName, prefIndex,
- icon, name, this, isSystem);
+ icon, name, this, info);
mPrefs.add(pref);
mPrefGroup.addPreference(pref);
pref.setEnabled(true);
@@ -186,14 +187,16 @@
class HomeAppPreference extends Preference {
ComponentName activityName;
int index;
- boolean isSystem;
HomeSettings fragment;
final ColorFilter grayscaleFilter;
boolean isChecked;
+ boolean isSystem;
+ String uninstallTarget;
+
public HomeAppPreference(Context context, ComponentName activity,
int i, Drawable icon, CharSequence title,
- HomeSettings parent, boolean sys) {
+ HomeSettings parent, ActivityInfo info) {
super(context);
setLayoutResource(R.layout.preference_home_app);
setIcon(icon);
@@ -201,13 +204,41 @@
activityName = activity;
fragment = parent;
index = i;
- isSystem = sys;
ColorMatrix colorMatrix = new ColorMatrix();
colorMatrix.setSaturation(0f);
float[] matrix = colorMatrix.getArray();
matrix[18] = 0.5f;
grayscaleFilter = new ColorMatrixColorFilter(colorMatrix);
+
+ determineTargets(info);
+ }
+
+ // Check whether this activity is bundled on the system, with awareness
+ // of the META_HOME_ALTERNATE mechanism.
+ private void determineTargets(ActivityInfo info) {
+ final Bundle meta = info.metaData;
+ if (meta != null) {
+ final String altHomePackage = meta.getString(ActivityManager.META_HOME_ALTERNATE);
+ if (altHomePackage != null) {
+ try {
+ final int match = mPm.checkSignatures(info.packageName, altHomePackage);
+ if (match >= PackageManager.SIGNATURE_MATCH) {
+ PackageInfo altInfo = mPm.getPackageInfo(altHomePackage, 0);
+ final int altFlags = altInfo.applicationInfo.flags;
+ isSystem = (altFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
+ uninstallTarget = altInfo.packageName;
+ return;
+ }
+ } catch (Exception e) {
+ // e.g. named alternate package not found during lookup
+ Log.w(TAG, "Unable to compare/resolve alternate", e);
+ }
+ }
+ }
+ // No suitable metadata redirect, so use the package's own info
+ isSystem = (info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
+ uninstallTarget = info.packageName;
}
@Override
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index 6b6e704..5c77a97 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -564,7 +564,9 @@
int headerIndex = i + 1;
i = insertAccountsHeaders(target, headerIndex);
} else if (id == R.id.home_settings) {
- updateHomeSettingHeaders(header);
+ if (!updateHomeSettingHeaders(header)) {
+ target.remove(i);
+ }
} else if (id == R.id.user_settings) {
if (!UserHandle.MU_ENABLED
|| !UserManager.supportsMultipleUsers()
@@ -669,11 +671,16 @@
return ((ri.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0);
}
- private void updateHomeSettingHeaders(Header header) {
+ private boolean updateHomeSettingHeaders(Header header) {
final PackageManager pm = getPackageManager();
final ArrayList<ResolveInfo> homeApps = new ArrayList<ResolveInfo>();
try {
ComponentName currentHome = pm.getHomeActivities(homeApps);
+ if (homeApps.size() < 2) {
+ // When there's only one available home app, omit this settings
+ // category entirely at the top level UI.
+ return false;
+ }
ResolveInfo iconSource = null;
if (currentHome == null) {
// no current default, so find the system home app and use that
@@ -708,6 +715,7 @@
// Can't look up the home activity; bail on configuring the icon
Log.w(LOG_TAG, "Problem looking up home activity!", e);
}
+ return true;
}
private void getMetaData() {
diff --git a/src/com/android/settings/applications/InstalledAppDetails.java b/src/com/android/settings/applications/InstalledAppDetails.java
index 37c33db..1b3938c 100644
--- a/src/com/android/settings/applications/InstalledAppDetails.java
+++ b/src/com/android/settings/applications/InstalledAppDetails.java
@@ -66,6 +66,7 @@
import java.lang.ref.WeakReference;
import java.util.ArrayList;
+import java.util.HashSet;
import java.util.List;
import android.view.LayoutInflater;
import android.view.Menu;
@@ -143,6 +144,8 @@
private PackageMoveObserver mPackageMoveObserver;
+ private final HashSet<String> mHomePackages = new HashSet<String>();
+
private boolean mDisableAfterUninstall;
private boolean mHaveSizes = false;
@@ -320,29 +323,20 @@
private boolean handleDisableable(Button button) {
boolean disableable = false;
- try {
- // 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.
- PackageInfo sys = mPm.getPackageInfo("android",
- PackageManager.GET_SIGNATURES);
- Intent intent = new Intent(Intent.ACTION_MAIN);
- intent.addCategory(Intent.CATEGORY_HOME);
- intent.setPackage(mAppEntry.info.packageName);
- List<ResolveInfo> homes = mPm.queryIntentActivities(intent, 0);
- if ((homes != null && homes.size() > 0) || isThisASystemPackage()) {
- // Disable button for core system applications.
- button.setText(R.string.disable_text);
- } else if (mAppEntry.info.enabled) {
- button.setText(R.string.disable_text);
- disableable = true;
- } else {
- button.setText(R.string.enable_text);
- disableable = true;
- }
- } catch (PackageManager.NameNotFoundException e) {
- Log.w(TAG, "Unable to get package info", e);
+ // 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()) {
+ // Disable button for core system applications.
+ button.setText(R.string.disable_text);
+ } else if (mAppEntry.info.enabled) {
+ button.setText(R.string.disable_text);
+ disableable = true;
+ } else {
+ button.setText(R.string.enable_text);
+ disableable = true;
}
+
return disableable;
}
@@ -638,6 +632,21 @@
return packageName;
}
+ private boolean signaturesMatch(String pkg1, String pkg2) {
+ if (pkg1 != null && pkg2 != null) {
+ try {
+ final int match = mPm.checkSignatures(pkg1, pkg2);
+ if (match >= PackageManager.SIGNATURE_MATCH) {
+ return true;
+ }
+ } catch (Exception e) {
+ // e.g. named alternate package not found during lookup;
+ // this is an expected case sometimes
+ }
+ }
+ return false;
+ }
+
private boolean refreshUi() {
if (mMoveInProgress) {
return true;
@@ -652,6 +661,25 @@
return false; // onCreate must have failed, make sure to exit
}
+ // Get list of "home" apps and trace through any meta-data references
+ List<ResolveInfo> homeActivities = new ArrayList<ResolveInfo>();
+ mPm.getHomeActivities(homeActivities);
+ mHomePackages.clear();
+ for (int i = 0; i< homeActivities.size(); i++) {
+ ResolveInfo ri = homeActivities.get(i);
+ final String activityPkg = ri.activityInfo.packageName;
+ mHomePackages.add(activityPkg);
+
+ // Also make sure to include anything proxying for the home app
+ final Bundle metadata = ri.activityInfo.metaData;
+ if (metadata != null) {
+ final String metaPkg = metadata.getString(ActivityManager.META_HOME_ALTERNATE);
+ if (signaturesMatch(metaPkg, activityPkg)) {
+ mHomePackages.add(metaPkg);
+ }
+ }
+ }
+
// Get list of preferred activities
List<ComponentName> prefActList = new ArrayList<ComponentName>();
@@ -1237,8 +1265,8 @@
intent.putExtra(Intent.EXTRA_PACKAGES, new String[] { mAppEntry.info.packageName });
intent.putExtra(Intent.EXTRA_UID, mAppEntry.info.uid);
intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(mAppEntry.info.uid));
- getActivity().sendOrderedBroadcast(intent, null, mCheckKillProcessesReceiver, null,
- Activity.RESULT_CANCELED, null, null);
+ getActivity().sendOrderedBroadcastAsUser(intent, UserHandle.CURRENT, null,
+ mCheckKillProcessesReceiver, null, Activity.RESULT_CANCELED, null, null);
}
}