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

Commit 0e17e5bc authored by Dianne Hackborn's avatar Dianne Hackborn Committed by Android (Google) Code Review
Browse files

Merge "Fix installing applications from non-primary users." into jb-mr1-dev

parents 40edfc97 786b4404
Loading
Loading
Loading
Loading
+10 −51
Original line number Diff line number Diff line
@@ -178,11 +178,6 @@ public final class Pm {
            return;
        }

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

        try {
            if (args.length == 1) {
                if (args[0].equalsIgnoreCase("-l")) {
@@ -222,7 +217,6 @@ public final class Pm {
        String type = nextArg();
        if (type == null) {
            System.err.println("Error: didn't specify type of data to list");
            showUsage();
            return;
        }
        if ("package".equals(type) || "packages".equals(type)) {
@@ -241,7 +235,6 @@ public final class Pm {
            runListUsers();
        } else {
            System.err.println("Error: unknown list type '" + type + "'");
            showUsage();
        }
    }

@@ -276,13 +269,11 @@ public final class Pm {
                    getFlags |= PackageManager.GET_UNINSTALLED_PACKAGES;
                } else {
                    System.err.println("Error: Unknown option: " + opt);
                    showUsage();
                    return;
                }
            }
        } catch (RuntimeException ex) {
            System.err.println("Error: " + ex.toString());
            showUsage();
            return;
        }

@@ -431,13 +422,11 @@ public final class Pm {
                    targetPackage = opt;
                } else {
                    System.err.println("Error: Unknown option: " + opt);
                    showUsage();
                    return;
                }
            }
        } catch (RuntimeException ex) {
            System.err.println("Error: " + ex.toString());
            showUsage();
            return;
        }

@@ -529,7 +518,6 @@ public final class Pm {
                    dangerousOnly = true;
                } else {
                    System.err.println("Error: Unknown option: " + opt);
                    showUsage();
                    return;
                }
            }
@@ -678,7 +666,6 @@ public final class Pm {
        String pkg = nextArg();
        if (pkg == null) {
            System.err.println("Error: no package specified");
            showUsage();
            return;
        }
        displayPackageFilePath(pkg);
@@ -736,20 +723,17 @@ public final class Pm {
        String arg = nextArg();
        if (arg == null) {
            System.err.println("Error: no install location specified.");
            showUsage();
            return;
        }
        try {
            loc = Integer.parseInt(arg);
        } catch (NumberFormatException e) {
            System.err.println("Error: install location has to be a number.");
            showUsage();
            return;
        }
        try {
            if (!mPm.setInstallLocation(loc)) {
                System.err.println("Error: install location has to be a number.");
                showUsage();
            }
        } catch (RemoteException e) {
            System.err.println(e.toString());
@@ -800,7 +784,6 @@ public final class Pm {
                installerPackageName = nextOptionData();
                if (installerPackageName == null) {
                    System.err.println("Error: no value specified for -i");
                    showUsage();
                    return;
                }
            } else if (opt.equals("-t")) {
@@ -817,61 +800,52 @@ public final class Pm {
                algo = nextOptionData();
                if (algo == null) {
                    System.err.println("Error: must supply argument for --algo");
                    showUsage();
                    return;
                }
            } else if (opt.equals("--iv")) {
                iv = hexToBytes(nextOptionData());
                if (iv == null) {
                    System.err.println("Error: must supply argument for --iv");
                    showUsage();
                    return;
                }
            } else if (opt.equals("--key")) {
                key = hexToBytes(nextOptionData());
                if (key == null) {
                    System.err.println("Error: must supply argument for --key");
                    showUsage();
                    return;
                }
            } else if (opt.equals("--macalgo")) {
                macAlgo = nextOptionData();
                if (macAlgo == null) {
                    System.err.println("Error: must supply argument for --macalgo");
                    showUsage();
                    return;
                }
            } else if (opt.equals("--mackey")) {
                macKey = hexToBytes(nextOptionData());
                if (macKey == null) {
                    System.err.println("Error: must supply argument for --mackey");
                    showUsage();
                    return;
                }
            } else if (opt.equals("--tag")) {
                tag = hexToBytes(nextOptionData());
                if (tag == null) {
                    System.err.println("Error: must supply argument for --tag");
                    showUsage();
                    return;
                }
            } else if (opt.equals("--originating-uri")) {
                originatingUriString = nextOptionData();
                if (originatingUriString == null) {
                    System.err.println("Error: must supply argument for --originating-uri");
                    showUsage();
                    return;
                }
            } else if (opt.equals("--referrer")) {
                referrer = nextOptionData();
                if (referrer == null) {
                    System.err.println("Error: must supply argument for --referrer");
                    showUsage();
                    return;
                }
            } else {
                System.err.println("Error: Unknown option: " + opt);
                showUsage();
                return;
            }
        }
@@ -881,7 +855,6 @@ public final class Pm {
                || tag != null) {
            if (algo == null || iv == null || key == null) {
                System.err.println("Error: all of --algo, --iv, and --key must be specified");
                showUsage();
                return;
            }

@@ -889,7 +862,6 @@ public final class Pm {
                if (macAlgo == null || macKey == null || tag == null) {
                    System.err.println("Error: all of --macalgo, --mackey, and --tag must "
                            + "be specified");
                    showUsage();
                    return;
                }
            }
@@ -938,7 +910,6 @@ public final class Pm {
            apkURI = Uri.fromFile(new File(apkFilePath));
        } else {
            System.err.println("Error: no package specified");
            showUsage();
            return;
        }

@@ -1012,23 +983,16 @@ public final class Pm {
    }

    public void runCreateUser() {
        // Need to be run as root
        if (Process.myUid() != ROOT_UID) {
            System.err.println("Error: create-user must be run as root");
            return;
        }
        String name;
        String arg = nextArg();
        if (arg == null) {
            System.err.println("Error: no user name specified.");
            showUsage();
            return;
        }
        name = arg;
        try {
            if (mUm.createUser(name, 0) == null) {
                System.err.println("Error: couldn't create User.");
                showUsage();
            }
        } catch (RemoteException e) {
            System.err.println(e.toString());
@@ -1038,29 +1002,21 @@ public final class Pm {
    }

    public void runRemoveUser() {
        // Need to be run as root
        if (Process.myUid() != ROOT_UID) {
            System.err.println("Error: remove-user must be run as root");
            return;
        }
        int userId;
        String arg = nextArg();
        if (arg == null) {
            System.err.println("Error: no user id specified.");
            showUsage();
            return;
        }
        try {
            userId = Integer.parseInt(arg);
        } catch (NumberFormatException e) {
            System.err.println("Error: user id has to be a number.");
            showUsage();
            System.err.println("Error: user id '" + arg + "' is not a number.");
            return;
        }
        try {
            if (!mUm.removeUser(userId)) {
                System.err.println("Error: couldn't remove user.");
                showUsage();
                System.err.println("Error: couldn't remove user #" + userId + ".");
            }
        } catch (RemoteException e) {
            System.err.println(e.toString());
@@ -1069,11 +1025,6 @@ public final class Pm {
    }

    public void runListUsers() {
        // Need to be run as root
        if (Process.myUid() != ROOT_UID) {
            System.err.println("Error: list-users must be run as root");
            return;
        }
        try {
            List<UserInfo> users = mUm.getUsers();
            if (users == null) {
@@ -1521,6 +1472,8 @@ public final class Pm {
        System.err.println("");
        System.err.println("pm list features: prints all features of the system.");
        System.err.println("");
        System.err.println("pm list users: prints all users on the system.");
        System.err.println("");
        System.err.println("pm path: print the path to the .apk of the given PACKAGE.");
        System.err.println("");
        System.err.println("pm install: installs a package to the system.  Options:");
@@ -1557,5 +1510,11 @@ public final class Pm {
        System.err.println("    2 [external]: Install on external media");
        System.err.println("");
        System.err.println("pm trim-caches: trim cache files to reach the given free space.");
        System.err.println("");
        System.err.println("pm create-user: create a new user with the given USER_NAME,");
        System.err.println("  printing the new user identifier of the user.");
        System.err.println("");
        System.err.println("pm remove-user: remove the user with the given USER_IDENTIFIER,");
        System.err.println("  deleting all data associated with that user");
    }
}
+4 −1
Original line number Diff line number Diff line
@@ -173,6 +173,9 @@
    <assign-permission name="android.permission.SET_SCREEN_COMPATIBILITY" uid="shell" />
    <assign-permission name="android.permission.READ_EXTERNAL_STORAGE" uid="shell" />
    <assign-permission name="android.permission.WRITE_EXTERNAL_STORAGE" uid="shell" />
    <assign-permission name="android.permission.INTERACT_ACROSS_USERS" uid="shell" />
    <assign-permission name="android.permission.INTERACT_ACROSS_USERS_FULL" uid="shell" />
    <assign-permission name="android.permission.MANAGE_USERS" uid="shell" />
    
    <assign-permission name="android.permission.MODIFY_AUDIO_SETTINGS" uid="media" />
    <assign-permission name="android.permission.ACCESS_DRM" uid="media" />
+13 −7
Original line number Diff line number Diff line
@@ -9404,9 +9404,15 @@ public final class ActivityManagerService extends ActivityManagerNative
    boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
            int opti, boolean dumpAll, String dumpPackage) {
        boolean needSep = false;
        boolean onlyHistory = false;
        if ("history".equals(dumpPackage)) {
            onlyHistory = true;
            dumpPackage = null;
        }
        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
        if (dumpAll) {
        if (!onlyHistory && dumpAll) {
            if (mRegisteredReceivers.size() > 0) {
                boolean printed = false;
                Iterator it = mRegisteredReceivers.values().iterator();
@@ -9439,7 +9445,7 @@ public final class ActivityManagerService extends ActivityManagerNative
        needSep = true;
        
        if (mStickyBroadcasts != null && dumpPackage == null) {
        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
            if (needSep) {
                pw.println();
            }
@@ -9471,7 +9477,7 @@ public final class ActivityManagerService extends ActivityManagerNative
            needSep = true;
        }
        
        if (dumpAll) {
        if (!onlyHistory && dumpAll) {
            pw.println();
            for (BroadcastQueue queue : mBroadcastQueues) {
                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
@@ -10982,7 +10988,7 @@ public final class ActivityManagerService extends ActivityManagerNative
                    BroadcastQueue queue = broadcastQueueForIntent(intent);
                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
                            null, -1, -1, null, receivers, null, 0, null, null,
                            false, true, true, false);
                            false, true, true, false, -1);
                    queue.enqueueParallelBroadcastLocked(r);
                    queue.scheduleBroadcastsLocked();
                }
@@ -11288,7 +11294,7 @@ public final class ActivityManagerService extends ActivityManagerNative
            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
                    callerPackage, callingPid, callingUid, requiredPermission,
                    registeredReceivers, resultTo, resultCode, resultData, map,
                    ordered, sticky, false, onlySendToCaller);
                    ordered, sticky, false, onlySendToCaller, userId);
            if (DEBUG_BROADCAST) Slog.v(
                    TAG, "Enqueueing parallel broadcast " + r);
            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
@@ -11378,7 +11384,7 @@ public final class ActivityManagerService extends ActivityManagerNative
            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
                    callerPackage, callingPid, callingUid, requiredPermission,
                    receivers, resultTo, resultCode, resultData, map, ordered,
                    sticky, false, onlySendToCaller);
                    sticky, false, onlySendToCaller, userId);
            if (DEBUG_BROADCAST) Slog.v(
                    TAG, "Enqueueing ordered broadcast " + r
                    + ": prev had " + queue.mOrderedBroadcasts.size());
+13 −9
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@ class BroadcastRecord extends Binder {
    final boolean sticky;   // originated from existing sticky data?
    final boolean initialSticky; // initial broadcast from register to sticky?
    final boolean onlySendToCaller; // only allow receipt by sender's components?
    final int userId;       // user id this broadcast was for
    final String requiredPermission; // a permission the caller has required
    final List receivers;   // contains BroadcastFilter and ResolveInfo
    IIntentReceiver resultTo; // who receives final result if non-null
@@ -80,7 +81,7 @@ class BroadcastRecord extends Binder {
    void dump(PrintWriter pw, String prefix) {
        final long now = SystemClock.uptimeMillis();

        pw.print(prefix); pw.println(this);
        pw.print(prefix); pw.print(this); pw.print(" to user "); pw.println(userId);
        pw.print(prefix); pw.println(intent);
        if (sticky) {
            Bundle bundle = intent.getExtras();
@@ -141,14 +142,15 @@ class BroadcastRecord extends Binder {
                        pw.println(curReceiver.applicationInfo.sourceDir);
            }
        }
        if (state != IDLE) {
            String stateStr = " (?)";
            switch (state) {
            case IDLE:              stateStr=" (IDLE)"; break;
                case APP_RECEIVE:       stateStr=" (APP_RECEIVE)"; break;
                case CALL_IN_RECEIVE:   stateStr=" (CALL_IN_RECEIVE)"; break;
                case CALL_DONE_RECEIVE: stateStr=" (CALL_DONE_RECEIVE)"; break;
            }
            pw.print(prefix); pw.print("state="); pw.print(state); pw.println(stateStr);
        }
        final int N = receivers != null ? receivers.size() : 0;
        String p2 = prefix + "  ";
        PrintWriterPrinter printer = new PrintWriterPrinter(pw);
@@ -168,7 +170,8 @@ class BroadcastRecord extends Binder {
            int _callingPid, int _callingUid, String _requiredPermission,
            List _receivers, IIntentReceiver _resultTo, int _resultCode,
            String _resultData, Bundle _resultExtras, boolean _serialized,
            boolean _sticky, boolean _initialSticky, boolean _onlySendToCaller) {
            boolean _sticky, boolean _initialSticky, boolean _onlySendToCaller,
            int _userId) {
        queue = _queue;
        intent = _intent;
        callerApp = _callerApp;
@@ -185,6 +188,7 @@ class BroadcastRecord extends Binder {
        sticky = _sticky;
        initialSticky = _initialSticky;
        onlySendToCaller = _onlySendToCaller;
        userId = _userId;
        nextReceiver = 0;
        state = IDLE;
    }
+65 −17
Original line number Diff line number Diff line
@@ -710,20 +710,56 @@ public class PackageManagerService extends IPackageManager.Stub {
                            res.removedInfo.sendBroadcast(false, true);
                            Bundle extras = new Bundle(1);
                            extras.putInt(Intent.EXTRA_UID, res.uid);
                            // Determine the set of users who are adding this
                            // package for the first time vs. those who are seeing
                            // an update.
                            int[] firstUsers;
                            int[] updateUsers = new int[0];
                            if (res.origUsers == null || res.origUsers.length == 0) {
                                firstUsers = res.newUsers;
                            } else {
                                firstUsers = new int[0];
                                for (int i=0; i<res.newUsers.length; i++) {
                                    int user = res.newUsers[i];
                                    boolean isNew = true;
                                    for (int j=0; j<res.origUsers.length; j++) {
                                        if (res.origUsers[j] == user) {
                                            isNew = false;
                                            break;
                                        }
                                    }
                                    if (isNew) {
                                        int[] newFirst = new int[firstUsers.length+1];
                                        System.arraycopy(firstUsers, 0, newFirst, 0,
                                                firstUsers.length);
                                        newFirst[firstUsers.length] = user;
                                        firstUsers = newFirst;
                                    } else {
                                        int[] newUpdate = new int[updateUsers.length+1];
                                        System.arraycopy(updateUsers, 0, newUpdate, 0,
                                                updateUsers.length);
                                        newUpdate[updateUsers.length] = user;
                                        updateUsers = newUpdate;
                                    }
                                }
                            }
                            sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
                                    res.pkg.applicationInfo.packageName,
                                    extras, null, null, firstUsers);
                            final boolean update = res.removedInfo.removedPackage != null;
                            if (update) {
                                extras.putBoolean(Intent.EXTRA_REPLACING, true);
                            }
                            sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
                                    res.pkg.applicationInfo.packageName,
                                    extras, null, null, res.users);
                                    extras, null, null, updateUsers);
                            if (update) {
                                sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
                                        res.pkg.applicationInfo.packageName,
                                        extras, null, null, res.users);
                                        extras, null, null, updateUsers);
                                sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
                                        null, null,
                                        res.pkg.applicationInfo.packageName, null, res.users);
                                        res.pkg.applicationInfo.packageName, null, updateUsers);
                            }
                            if (res.removedInfo.args != null) {
                                // Remove the replaced package's older resources safely now
@@ -5343,8 +5379,10 @@ public class PackageManagerService extends IPackageManager.Stub {
        public void onEvent(int event, String path) {
            String removedPackage = null;
            int removedUid = -1;
            int[] removedUsers = null;
            String addedPackage = null;
            int addedUid = -1;
            int[] addedUsers = null;

            // TODO post a message to the handler to obtain serial ordering
            synchronized (mInstallLock) {
@@ -5373,6 +5411,15 @@ public class PackageManagerService extends IPackageManager.Stub {
                // reader
                synchronized (mPackages) {
                    p = mAppDirs.get(fullPathStr);
                    if (p != null) {
                        PackageSetting ps = mSettings.mPackages.get(p.applicationInfo.packageName);
                        if (ps != null) {
                            removedUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
                        } else {
                            removedUsers = sUserManager.getUserIds();
                        }
                    }
                    addedUsers = sUserManager.getUserIds();
                }
                if ((event&REMOVE_EVENTS) != 0) {
                    if (p != null) {
@@ -5390,7 +5437,7 @@ public class PackageManagerService extends IPackageManager.Stub {
                                PackageParser.PARSE_CHATTY |
                                PackageParser.PARSE_MUST_BE_APK,
                                SCAN_MONITOR | SCAN_NO_PATHS | SCAN_UPDATE_TIME,
                                System.currentTimeMillis(), null);
                                System.currentTimeMillis(), UserHandle.ALL);
                        if (p != null) {
                            /*
                             * TODO this seems dangerous as the package may have
@@ -5419,13 +5466,13 @@ public class PackageManagerService extends IPackageManager.Stub {
                extras.putInt(Intent.EXTRA_UID, removedUid);
                extras.putBoolean(Intent.EXTRA_DATA_REMOVED, false);
                sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage,
                        extras, null, null, null);
                        extras, null, null, removedUsers);
            }
            if (addedPackage != null) {
                Bundle extras = new Bundle(1);
                extras.putInt(Intent.EXTRA_UID, addedUid);
                sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, addedPackage,
                        extras, null, null, null);
                        extras, null, null, addedUsers);
            }
        }

@@ -5468,7 +5515,7 @@ public class PackageManagerService extends IPackageManager.Stub {
        if ((flags&PackageManager.INSTALL_ALL_USERS) != 0) {
            user = UserHandle.ALL;
        } else {
            user = Process.myUserHandle();
            user = new UserHandle(UserHandle.getUserId(uid));
        }

        final int filteredFlags;
@@ -7212,7 +7259,10 @@ public class PackageManagerService extends IPackageManager.Stub {
    class PackageInstalledInfo {
        String name;
        int uid;
        int[] users;
        // The set of users that originally had this package installed.
        int[] origUsers;
        // The set of users that now have this package installed.
        int[] newUsers;
        PackageParser.Package pkg;
        int returnCode;
        PackageRemovedInfo removedInfo;
@@ -7362,7 +7412,7 @@ public class PackageManagerService extends IPackageManager.Stub {
                int oldScanMode = (oldOnSd ? 0 : SCAN_MONITOR) | SCAN_UPDATE_SIGNATURE
                        | SCAN_UPDATE_TIME;
                if (scanPackageLI(restoreFile, oldParseFlags, oldScanMode,
                        origUpdateTime, user) == null) {
                        origUpdateTime, null) == null) {
                    Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade");
                    return;
                }
@@ -7511,10 +7561,6 @@ public class PackageManagerService extends IPackageManager.Stub {
                    UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0
                            ? UPDATE_PERMISSIONS_ALL : 0));
            res.name = pkgName;
            PackageSetting ps = mSettings.mPackages.get(pkgName);
            if (ps != null) {
                res.users = ps.getInstalledUsers(sUserManager.getUserIds());
            }
            res.uid = newPackage.applicationInfo.uid;
            res.pkg = newPackage;
            mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE);
@@ -7612,6 +7658,7 @@ public class PackageManagerService extends IPackageManager.Stub {
                    systemApp = (ps.pkg.applicationInfo.flags &
                            ApplicationInfo.FLAG_SYSTEM) != 0;
                }
                res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
            }
        }

@@ -7637,9 +7684,9 @@ public class PackageManagerService extends IPackageManager.Stub {
                    installerPackageName, res);
        }
        synchronized (mPackages) {
            PackageSetting ps = mSettings.mPackages.get(pkgName);
            final PackageSetting ps = mSettings.mPackages.get(pkgName);
            if (ps != null) {
                res.users = ps.getInstalledUsers(sUserManager.getUserIds());
                res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
            }
        }
    }
@@ -7865,7 +7912,8 @@ public class PackageManagerService extends IPackageManager.Stub {
            if (outInfo != null) {
                outInfo.removedPackage = packageName;
                outInfo.removedUsers = deletedPs != null
                        ? deletedPs.getInstalledUsers(sUserManager.getUserIds()) : null;
                        ? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true)
                        : null;
            }
        }
        if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
Loading