Incorporate home metadata into app details UI
Just as we don't expose disable/uninstall of home applications in this UI, we now also don't allow disable/uninstall of packages that are proxying for home apps via the android.app.home.alternate meta-data mechanism. Also, don't display the 'Home' settings top-level category at all when there is only a single available home app. Finally, explicitly note the current user when sending broadcasts, otherwise API sanity checks get suspicious. Bug 10749961 Change-Id: I13e11032cb571df19798c4e13c91a572d1ee61a7
This commit is contained in:
@@ -564,7 +564,9 @@ public class Settings extends PreferenceActivity
|
||||
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 @@ public class Settings extends PreferenceActivity
|
||||
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 @@ public class Settings extends PreferenceActivity
|
||||
// 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() {
|
||||
|
@@ -66,6 +66,7 @@ import android.util.Log;
|
||||
|
||||
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 @@ public class InstalledAppDetails extends Fragment
|
||||
|
||||
private PackageMoveObserver mPackageMoveObserver;
|
||||
|
||||
private final HashSet<String> mHomePackages = new HashSet<String>();
|
||||
|
||||
private boolean mDisableAfterUninstall;
|
||||
|
||||
private boolean mHaveSizes = false;
|
||||
@@ -320,17 +323,10 @@ public class InstalledAppDetails extends Fragment
|
||||
|
||||
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()) {
|
||||
if (mHomePackages.contains(mAppEntry.info.packageName) || isThisASystemPackage()) {
|
||||
// Disable button for core system applications.
|
||||
button.setText(R.string.disable_text);
|
||||
} else if (mAppEntry.info.enabled) {
|
||||
@@ -340,9 +336,7 @@ public class InstalledAppDetails extends Fragment
|
||||
button.setText(R.string.enable_text);
|
||||
disableable = true;
|
||||
}
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
Log.w(TAG, "Unable to get package info", e);
|
||||
}
|
||||
|
||||
return disableable;
|
||||
}
|
||||
|
||||
@@ -638,6 +632,21 @@ public class InstalledAppDetails extends Fragment
|
||||
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 @@ public class InstalledAppDetails extends Fragment
|
||||
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 @@ public class InstalledAppDetails extends Fragment
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user