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

Commit 483f3b06 authored by Amith Yamasani's avatar Amith Yamasani
Browse files

Package restrictions per user

Packages can be enabled/disabled per user.
This requires maintaining stopped/launched states and
enabled / disabled components and packages per user.

Refactored pm.Settings and PackageSettingsBase to keep
track of states per user.

Migrated the stopped-packages.xml to users/<u>/package-restrictions.xml

Changed intent resolution to handle individual user restrictions.
Bunch of IPackageManager calls now have a userId argument.
Make AppWidgetService handle removals of packages.

Added some tests for pm.Settings and PackageManager.

Change-Id: Ia83b529e1df88dbcb3bd55ebfc952a6e9b20e861
parent 8fca15f1
Loading
Loading
Loading
Loading
+9 −3
Original line number Diff line number Diff line
@@ -62,6 +62,7 @@ public class Am {
    private boolean mStopOption = false;

    private int mRepeat = 0;
    private int mUserId = 0;

    private String mProfileFile;

@@ -135,7 +136,7 @@ public class Am {
            runToUri(false);
        } else if (op.equals("to-intent-uri")) {
            runToUri(true);
        } else if (op.equals("switch-profile")) {
        } else if (op.equals("switch-user")) {
            runSwitchUser();
        } else {
            throw new IllegalArgumentException("Unknown command: " + op);
@@ -152,6 +153,7 @@ public class Am {
        mStopOption = false;
        mRepeat = 0;
        mProfileFile = null;
        mUserId = 0;
        Uri data = null;
        String type = null;

@@ -308,6 +310,8 @@ public class Am {
                mStopOption = true;
            } else if (opt.equals("--opengl-trace")) {
                mStartFlags |= ActivityManager.START_FLAG_OPENGL_TRACES;
            } else if (opt.equals("--user")) {
                mUserId = Integer.parseInt(nextArgRequired());
            } else {
                System.err.println("Error: Unknown option: " + opt);
                showUsage();
@@ -407,7 +411,8 @@ public class Am {
                        System.err.println("Error: Package manager not running; aborting");
                        return;
                    }
                    List<ResolveInfo> activities = pm.queryIntentActivities(intent, mimeType, 0);
                    List<ResolveInfo> activities = pm.queryIntentActivities(intent, mimeType, 0,
                            mUserId);
                    if (activities == null || activities.size() <= 0) {
                        System.err.println("Error: Intent does not match any activities: "
                                + intent);
@@ -550,7 +555,7 @@ public class Am {
        IntentReceiver receiver = new IntentReceiver();
        System.out.println("Broadcasting: " + intent);
        mAm.broadcastIntent(null, intent, null, receiver, 0, null, null, null, true, false,
                Binder.getOrigCallingUser());
                mUserId);
        receiver.waitForFinish();
    }

@@ -1294,6 +1299,7 @@ public class Am {
                "       am display-size [reset|MxN]\n" +
                "       am to-uri [INTENT]\n" +
                "       am to-intent-uri [INTENT]\n" +
                "       am switch-user <USER_ID>\n" +
                "\n" +
                "am start: start an Activity.  Options are:\n" +
                "    -D: enable debugging\n" +
+50 −25
Original line number Diff line number Diff line
@@ -146,18 +146,18 @@ public final class Pm {
            return;
        }

        if ("create-profile".equals(op)) {
            runCreateProfile();
        if ("create-user".equals(op)) {
            runCreateUser();
            return;
        }

        if ("remove-profile".equals(op)) {
            runRemoveProfile();
        if ("remove-user".equals(op)) {
            runRemoveUser();
            return;
        }

        if ("list-profiles".equals(op)) {
            runListProfiles();
        if ("list-users".equals(op)) {
            runListUsers();
            return;
        }

@@ -215,6 +215,8 @@ public final class Pm {
            runListLibraries();
        } else if ("instrumentation".equals(type)) {
            runListInstrumentation();
        } else if ("users".equals(type)) {
            runListUsers();
        } else {
            System.err.println("Error: unknown list type '" + type + "'");
            showUsage();
@@ -832,10 +834,10 @@ public final class Pm {
        }
    }

    public void runCreateProfile() {
    public void runCreateUser() {
        // Need to be run as root
        if (Process.myUid() != ROOT_UID) {
            System.err.println("Error: create-profile must be run as root");
            System.err.println("Error: create-user must be run as root");
            return;
        }
        String name;
@@ -848,7 +850,7 @@ public final class Pm {
        name = arg;
        try {
            if (mPm.createUser(name, 0) == null) {
                System.err.println("Error: couldn't create profile.");
                System.err.println("Error: couldn't create User.");
                showUsage();
            }
        } catch (RemoteException e) {
@@ -858,10 +860,10 @@ public final class Pm {

    }

    public void runRemoveProfile() {
    public void runRemoveUser() {
        // Need to be run as root
        if (Process.myUid() != ROOT_UID) {
            System.err.println("Error: remove-profile must be run as root");
            System.err.println("Error: remove-user must be run as root");
            return;
        }
        int userId;
@@ -880,7 +882,7 @@ public final class Pm {
        }
        try {
            if (!mPm.removeUser(userId)) {
                System.err.println("Error: couldn't remove profile.");
                System.err.println("Error: couldn't remove user.");
                showUsage();
            }
        } catch (RemoteException e) {
@@ -889,10 +891,10 @@ public final class Pm {
        }
    }

    public void runListProfiles() {
    public void runListUsers() {
        // Need to be run as root
        if (Process.myUid() != ROOT_UID) {
            System.err.println("Error: list-profiles must be run as root");
            System.err.println("Error: list-users must be run as root");
            return;
        }
        try {
@@ -1029,7 +1031,29 @@ public final class Pm {
        return "unknown";
    }

    private boolean isNumber(String s) {
        try {
            Integer.parseInt(s);
        } catch (NumberFormatException nfe) {
            return false;
        }
        return true;
    }

    private void runSetEnabledSetting(int state) {
        int userId = 0;
        String option = nextOption();
        if (option != null && option.equals("--user")) {
            String optionData = nextOptionData();
            if (optionData == null || !isNumber(optionData)) {
                System.err.println("Error: no USER_ID specified");
                showUsage();
                return;
            } else {
                userId = Integer.parseInt(optionData);
            }
        }

        String pkg = nextArg();
        if (pkg == null) {
            System.err.println("Error: no package or component specified");
@@ -1039,20 +1063,20 @@ public final class Pm {
        ComponentName cn = ComponentName.unflattenFromString(pkg);
        if (cn == null) {
            try {
                mPm.setApplicationEnabledSetting(pkg, state, 0);
                mPm.setApplicationEnabledSetting(pkg, state, 0, userId);
                System.err.println("Package " + pkg + " new state: "
                        + enabledSettingToString(
                                mPm.getApplicationEnabledSetting(pkg)));
                        mPm.getApplicationEnabledSetting(pkg, userId)));
            } catch (RemoteException e) {
                System.err.println(e.toString());
                System.err.println(PM_NOT_RUNNING_ERR);
            }
        } else {
            try {
                mPm.setComponentEnabledSetting(cn, state, 0);
                mPm.setComponentEnabledSetting(cn, state, 0, userId);
                System.err.println("Component " + cn.toShortString() + " new state: "
                        + enabledSettingToString(
                                mPm.getComponentEnabledSetting(cn)));
                        mPm.getComponentEnabledSetting(cn, userId)));
            } catch (RemoteException e) {
                System.err.println(e.toString());
                System.err.println(PM_NOT_RUNNING_ERR);
@@ -1096,7 +1120,7 @@ public final class Pm {
     */
    private void displayPackageFilePath(String pckg) {
        try {
            PackageInfo info = mPm.getPackageInfo(pckg, 0);
            PackageInfo info = mPm.getPackageInfo(pckg, 0, 0);
            if (info != null && info.applicationInfo != null) {
                System.out.print("package:");
                System.out.println(info.applicationInfo.sourceDir);
@@ -1112,7 +1136,7 @@ public final class Pm {
        if (res != null) return res;

        try {
            ApplicationInfo ai = mPm.getApplicationInfo(pii.packageName, 0);
            ApplicationInfo ai = mPm.getApplicationInfo(pii.packageName, 0, 0);
            AssetManager am = new AssetManager();
            am.addAssetPath(ai.publicSourceDir);
            res = new Resources(am, null, null);
@@ -1178,19 +1202,20 @@ public final class Pm {
        System.err.println("       pm list instrumentation [-f] [TARGET-PACKAGE]");
        System.err.println("       pm list features");
        System.err.println("       pm list libraries");
        System.err.println("       pm list users");
        System.err.println("       pm path PACKAGE");
        System.err.println("       pm install [-l] [-r] [-t] [-i INSTALLER_PACKAGE_NAME] [-s] [-f] PATH");
        System.err.println("       pm uninstall [-k] PACKAGE");
        System.err.println("       pm clear PACKAGE");
        System.err.println("       pm enable PACKAGE_OR_COMPONENT");
        System.err.println("       pm disable PACKAGE_OR_COMPONENT");
        System.err.println("       pm disable-user PACKAGE_OR_COMPONENT");
        System.err.println("       pm enable [--user USER_ID] PACKAGE_OR_COMPONENT");
        System.err.println("       pm disable [--user USER_ID] PACKAGE_OR_COMPONENT");
        System.err.println("       pm disable-user [--user USER_ID] PACKAGE_OR_COMPONENT");
        System.err.println("       pm grant PACKAGE PERMISSION");
        System.err.println("       pm revoke PACKAGE PERMISSION");
        System.err.println("       pm set-install-location [0/auto] [1/internal] [2/external]");
        System.err.println("       pm get-install-location");
        System.err.println("       pm create-profile USER_NAME");
        System.err.println("       pm remove-profile USER_ID");
        System.err.println("       pm create-user USER_NAME");
        System.err.println("       pm remove-user USER_ID");
        System.err.println("");
        System.err.println("pm list packages: prints all packages, optionally only");
        System.err.println("  those whose package name contains the text in FILTER.  Options:");
+1 −1
Original line number Diff line number Diff line
@@ -1586,7 +1586,7 @@ public final class ActivityThread {
        ApplicationInfo ai = null;
        try {
            ai = getPackageManager().getApplicationInfo(packageName,
                    PackageManager.GET_SHARED_LIBRARY_FILES);
                    PackageManager.GET_SHARED_LIBRARY_FILES, UserId.myUserId());
        } catch (RemoteException e) {
            // Ignore
        }
+25 −19
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@ import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Process;
import android.os.RemoteException;
import android.os.UserId;
import android.util.Log;

import java.lang.ref.WeakReference;
@@ -67,7 +68,7 @@ final class ApplicationPackageManager extends PackageManager {
    public PackageInfo getPackageInfo(String packageName, int flags)
            throws NameNotFoundException {
        try {
            PackageInfo pi = mPM.getPackageInfo(packageName, flags);
            PackageInfo pi = mPM.getPackageInfo(packageName, flags, UserId.myUserId());
            if (pi != null) {
                return pi;
            }
@@ -197,7 +198,7 @@ final class ApplicationPackageManager extends PackageManager {
    public ApplicationInfo getApplicationInfo(String packageName, int flags)
            throws NameNotFoundException {
        try {
            ApplicationInfo ai = mPM.getApplicationInfo(packageName, flags);
            ApplicationInfo ai = mPM.getApplicationInfo(packageName, flags, UserId.myUserId());
            if (ai != null) {
                return ai;
            }
@@ -212,7 +213,7 @@ final class ApplicationPackageManager extends PackageManager {
    public ActivityInfo getActivityInfo(ComponentName className, int flags)
            throws NameNotFoundException {
        try {
            ActivityInfo ai = mPM.getActivityInfo(className, flags);
            ActivityInfo ai = mPM.getActivityInfo(className, flags, UserId.myUserId());
            if (ai != null) {
                return ai;
            }
@@ -227,7 +228,7 @@ final class ApplicationPackageManager extends PackageManager {
    public ActivityInfo getReceiverInfo(ComponentName className, int flags)
            throws NameNotFoundException {
        try {
            ActivityInfo ai = mPM.getReceiverInfo(className, flags);
            ActivityInfo ai = mPM.getReceiverInfo(className, flags, UserId.myUserId());
            if (ai != null) {
                return ai;
            }
@@ -242,7 +243,7 @@ final class ApplicationPackageManager extends PackageManager {
    public ServiceInfo getServiceInfo(ComponentName className, int flags)
            throws NameNotFoundException {
        try {
            ServiceInfo si = mPM.getServiceInfo(className, flags);
            ServiceInfo si = mPM.getServiceInfo(className, flags, UserId.myUserId());
            if (si != null) {
                return si;
            }
@@ -257,7 +258,7 @@ final class ApplicationPackageManager extends PackageManager {
    public ProviderInfo getProviderInfo(ComponentName className, int flags)
            throws NameNotFoundException {
        try {
            ProviderInfo pi = mPM.getProviderInfo(className, flags);
            ProviderInfo pi = mPM.getProviderInfo(className, flags, UserId.myUserId());
            if (pi != null) {
                return pi;
            }
@@ -422,6 +423,7 @@ final class ApplicationPackageManager extends PackageManager {
    @SuppressWarnings("unchecked")
    @Override
    public List<ApplicationInfo> getInstalledApplications(int flags) {
        int userId = UserId.getUserId(Process.myUid());
        try {
            final List<ApplicationInfo> applicationInfos = new ArrayList<ApplicationInfo>();
            ApplicationInfo lastItem = null;
@@ -429,7 +431,7 @@ final class ApplicationPackageManager extends PackageManager {

            do {
                final String lastKey = lastItem != null ? lastItem.packageName : null;
                slice = mPM.getInstalledApplications(flags, lastKey);
                slice = mPM.getInstalledApplications(flags, lastKey, userId);
                lastItem = slice.populateList(applicationInfos, ApplicationInfo.CREATOR);
            } while (!slice.isLastSlice());

@@ -445,7 +447,7 @@ final class ApplicationPackageManager extends PackageManager {
            return mPM.resolveIntent(
                intent,
                intent.resolveTypeIfNeeded(mContext.getContentResolver()),
                flags);
                    flags, UserId.myUserId());
        } catch (RemoteException e) {
            throw new RuntimeException("Package manager has died", e);
        }
@@ -458,7 +460,8 @@ final class ApplicationPackageManager extends PackageManager {
            return mPM.queryIntentActivities(
                intent,
                intent.resolveTypeIfNeeded(mContext.getContentResolver()),
                flags);
                flags,
                UserId.myUserId());
        } catch (RemoteException e) {
            throw new RuntimeException("Package manager has died", e);
        }
@@ -490,7 +493,7 @@ final class ApplicationPackageManager extends PackageManager {
        try {
            return mPM.queryIntentActivityOptions(caller, specifics,
                                                  specificTypes, intent, intent.resolveTypeIfNeeded(resolver),
                                                  flags);
                                                  flags, UserId.myUserId());
        } catch (RemoteException e) {
            throw new RuntimeException("Package manager has died", e);
        }
@@ -502,7 +505,8 @@ final class ApplicationPackageManager extends PackageManager {
            return mPM.queryIntentReceivers(
                intent,
                intent.resolveTypeIfNeeded(mContext.getContentResolver()),
                flags);
                flags,
                UserId.myUserId());
        } catch (RemoteException e) {
            throw new RuntimeException("Package manager has died", e);
        }
@@ -514,7 +518,8 @@ final class ApplicationPackageManager extends PackageManager {
            return mPM.resolveService(
                intent,
                intent.resolveTypeIfNeeded(mContext.getContentResolver()),
                flags);
                flags,
                UserId.myUserId());
        } catch (RemoteException e) {
            throw new RuntimeException("Package manager has died", e);
        }
@@ -526,7 +531,8 @@ final class ApplicationPackageManager extends PackageManager {
            return mPM.queryIntentServices(
                intent,
                intent.resolveTypeIfNeeded(mContext.getContentResolver()),
                flags);
                flags,
                UserId.myUserId());
        } catch (RemoteException e) {
            throw new RuntimeException("Package manager has died", e);
        }
@@ -536,7 +542,7 @@ final class ApplicationPackageManager extends PackageManager {
    public ProviderInfo resolveContentProvider(String name,
                                               int flags) {
        try {
            return mPM.resolveContentProvider(name, flags);
            return mPM.resolveContentProvider(name, flags, UserId.myUserId());
        } catch (RemoteException e) {
            throw new RuntimeException("Package manager has died", e);
        }
@@ -1026,7 +1032,7 @@ final class ApplicationPackageManager extends PackageManager {
    public void clearApplicationUserData(String packageName,
                                         IPackageDataObserver observer) {
        try {
            mPM.clearApplicationUserData(packageName, observer);
            mPM.clearApplicationUserData(packageName, observer, UserId.myUserId());
        } catch (RemoteException e) {
            // Should never happen!
        }
@@ -1139,7 +1145,7 @@ final class ApplicationPackageManager extends PackageManager {
    public void setComponentEnabledSetting(ComponentName componentName,
                                           int newState, int flags) {
        try {
            mPM.setComponentEnabledSetting(componentName, newState, flags);
            mPM.setComponentEnabledSetting(componentName, newState, flags, UserId.myUserId());
        } catch (RemoteException e) {
            // Should never happen!
        }
@@ -1148,7 +1154,7 @@ final class ApplicationPackageManager extends PackageManager {
    @Override
    public int getComponentEnabledSetting(ComponentName componentName) {
        try {
            return mPM.getComponentEnabledSetting(componentName);
            return mPM.getComponentEnabledSetting(componentName, UserId.myUserId());
        } catch (RemoteException e) {
            // Should never happen!
        }
@@ -1159,7 +1165,7 @@ final class ApplicationPackageManager extends PackageManager {
    public void setApplicationEnabledSetting(String packageName,
                                             int newState, int flags) {
        try {
            mPM.setApplicationEnabledSetting(packageName, newState, flags);
            mPM.setApplicationEnabledSetting(packageName, newState, flags, UserId.myUserId());
        } catch (RemoteException e) {
            // Should never happen!
        }
@@ -1168,7 +1174,7 @@ final class ApplicationPackageManager extends PackageManager {
    @Override
    public int getApplicationEnabledSetting(String packageName) {
        try {
            return mPM.getApplicationEnabledSetting(packageName);
            return mPM.getApplicationEnabledSetting(packageName, UserId.myUserId());
        } catch (RemoteException e) {
            // Should never happen!
        }
+2 −2
Original line number Diff line number Diff line
@@ -194,7 +194,7 @@ public final class LoadedApk {
        ApplicationInfo ai = null;
        try {
            ai = ActivityThread.getPackageManager().getApplicationInfo(packageName,
                    PackageManager.GET_SHARED_LIBRARY_FILES);
                    PackageManager.GET_SHARED_LIBRARY_FILES, UserId.myUserId());
        } catch (RemoteException e) {
            throw new AssertionError(e);
        }
@@ -351,7 +351,7 @@ public final class LoadedApk {
        IPackageManager pm = ActivityThread.getPackageManager();
        android.content.pm.PackageInfo pi;
        try {
            pi = pm.getPackageInfo(mPackageName, 0);
            pi = pm.getPackageInfo(mPackageName, 0, UserId.myUserId());
        } catch (RemoteException e) {
            throw new AssertionError(e);
        }
Loading