Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8243c9a7 authored by Christopher Tate's avatar Christopher Tate
Browse files

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
parent 6741d4db
Loading
Loading
Loading
Loading
+10 −2
Original line number Diff line number Diff line
@@ -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() {
+52 −24
Original line number Diff line number Diff line
@@ -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);
        }
    }