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

Commit 1ef7d131 authored by Amith Yamasani's avatar Amith Yamasani Committed by Android (Google) Code Review
Browse files

Merge "Multi-user - 1st major checkin"

parents 2d315df6 742a6712
Loading
Loading
Loading
Loading
+13 −1
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import android.content.Intent;
import android.content.pm.IPackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
@@ -135,6 +136,8 @@ public class Am {
            runToUri(false);
        } else if (op.equals("to-intent-uri")) {
            runToUri(true);
        } else if (op.equals("switch-profile")) {
            runSwitchUser();
        } else {
            throw new IllegalArgumentException("Unknown command: " + op);
        }
@@ -531,7 +534,8 @@ public class Am {
        Intent intent = makeIntent();
        IntentReceiver receiver = new IntentReceiver();
        System.out.println("Broadcasting: " + intent);
        mAm.broadcastIntent(null, intent, null, receiver, 0, null, null, null, true, false);
        mAm.broadcastIntent(null, intent, null, receiver, 0, null, null, null, true, false,
                Binder.getOrigCallingUser());
        receiver.waitForFinish();
    }

@@ -722,6 +726,14 @@ public class Am {
        mAm.setDebugApp(null, false, true);
    }

    private void runSwitchUser() throws Exception {
        if (android.os.Process.myUid() != 0) {
            throw new RuntimeException("switchuser can only be run as root");
        }
        String user = nextArgRequired();
        mAm.switchUser(Integer.parseInt(user));
    }

    class MyActivityController extends IActivityController.Stub {
        final String mGdbPort;

+42 −0
Original line number Diff line number Diff line
@@ -148,6 +148,48 @@ int delete_persona(uid_t persona)
    return delete_dir_contents(pkgdir, 1, NULL);
}

int clone_persona_data(uid_t src_persona, uid_t target_persona, int copy)
{
    char src_data_dir[PKG_PATH_MAX];
    char pkg_path[PKG_PATH_MAX];
    DIR *d;
    struct dirent *de;
    struct stat s;
    uid_t uid;

    if (create_persona_path(src_data_dir, src_persona)) {
        return -1;
    }

    d = opendir(src_data_dir);
    if (d != NULL) {
        while ((de = readdir(d))) {
            const char *name = de->d_name;

            if (de->d_type == DT_DIR) {
                int subfd;
                    /* always skip "." and ".." */
                if (name[0] == '.') {
                    if (name[1] == 0) continue;
                    if ((name[1] == '.') && (name[2] == 0)) continue;
                }
                /* Create the full path to the package's data dir */
                create_pkg_path(pkg_path, name, PKG_DIR_POSTFIX, src_persona);
                /* Get the file stat */
                if (stat(pkg_path, &s) < 0) continue;
                /* Get the uid of the package */
                ALOGI("Adding datadir for uid = %d\n", s.st_uid);
                uid = (uid_t) s.st_uid % PER_USER_RANGE;
                /* Create the directory for the target */
                make_user_data(name, uid + target_persona * PER_USER_RANGE,
                               target_persona);
            }
        }
        closedir(d);
    }
    return 0;
}

int delete_cache(const char *pkgname)
{
    char cachedir[PKG_PATH_MAX];
+6 −0
Original line number Diff line number Diff line
@@ -107,6 +107,11 @@ static int do_rm_user(char **arg, char reply[REPLY_MAX])
    return delete_persona(atoi(arg[0])); /* userid */
}

static int do_clone_user_data(char **arg, char reply[REPLY_MAX])
{
    return clone_persona_data(atoi(arg[0]), atoi(arg[1]), atoi(arg[2]));
}

static int do_movefiles(char **arg, char reply[REPLY_MAX])
{
    return movefiles();
@@ -146,6 +151,7 @@ struct cmdinfo cmds[] = {
    { "unlinklib",            1, do_unlinklib },
    { "mkuserdata",           3, do_mk_user_data },
    { "rmuser",               1, do_rm_user },
    { "cloneuserdata",        3, do_clone_user_data },
};

static int readx(int s, void *_buf, int count)
+4 −0
Original line number Diff line number Diff line
@@ -72,6 +72,9 @@
#define PKG_NAME_MAX  128   /* largest allowed package name */
#define PKG_PATH_MAX  256   /* max size of any path we use */

#define PER_USER_RANGE ((uid_t)100000)   /* range of uids per user
                                            uid = persona * PER_USER_RANGE + appid */

/* data structures */

typedef struct {
@@ -143,6 +146,7 @@ int renamepkg(const char *oldpkgname, const char *newpkgname);
int delete_user_data(const char *pkgname, uid_t persona);
int make_user_data(const char *pkgname, uid_t uid, uid_t persona);
int delete_persona(uid_t persona);
int clone_persona_data(uid_t src_persona, uid_t target_persona, int copy);
int delete_cache(const char *pkgname);
int move_dex(const char *src, const char *dst);
int rm_dex(const char *path);
+44 −16
Original line number Diff line number Diff line
@@ -16,8 +16,6 @@

package com.android.commands.pm;

import com.android.internal.content.PackageHelper;

import android.app.ActivityManagerNative;
import android.content.ComponentName;
import android.content.pm.ApplicationInfo;
@@ -33,14 +31,17 @@ import android.content.pm.PackageManager;
import android.content.pm.ParceledListSlice;
import android.content.pm.PermissionGroupInfo;
import android.content.pm.PermissionInfo;
import android.content.pm.UserInfo;
import android.content.res.AssetManager;
import android.content.res.Resources;
import android.net.Uri;
import android.os.Parcel;
import android.os.Binder;
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;

import com.android.internal.content.PackageHelper;

import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
@@ -135,13 +136,18 @@ public final class Pm {
            return;
        }

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

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

        if ("removeUser".equals(op)) {
            runRemoveUser();
        if ("list-profiles".equals(op)) {
            runListProfiles();
            return;
        }

@@ -829,10 +835,10 @@ public final class Pm {
        }
    }

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

    }

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

    public void runListProfiles() {
        // Need to be run as root
        if (Process.myUid() != ROOT_UID) {
            System.err.println("Error: list-profiles must be run as root");
            return;
        }
        try {
            List<UserInfo> users = mPm.getUsers();
            if (users == null) {
                System.err.println("Error: couldn't get users");
            } else {
                System.out.println("Users:");
                for (int i = 0; i < users.size(); i++) {
                    System.out.println("\t" + users.get(i).toString());
                }
            }
        } catch (RemoteException e) {
            System.err.println(e.toString());
            System.err.println(PM_NOT_RUNNING_ERR);
        }
    }
    class PackageDeleteObserver extends IPackageDeleteObserver.Stub {
        boolean finished;
        boolean result;
@@ -966,7 +993,8 @@ public final class Pm {

        ClearDataObserver obs = new ClearDataObserver();
        try {
            if (!ActivityManagerNative.getDefault().clearApplicationUserData(pkg, obs)) {
            if (!ActivityManagerNative.getDefault().clearApplicationUserData(pkg, obs,
                    Binder.getOrigCallingUser())) {
                System.err.println("Failed");
            }

@@ -1132,8 +1160,8 @@ public final class Pm {
        System.err.println("       pm disable-user PACKAGE_OR_COMPONENT");
        System.err.println("       pm set-install-location [0/auto] [1/internal] [2/external]");
        System.err.println("       pm get-install-location");
        System.err.println("       pm createUser USER_NAME");
        System.err.println("       pm removeUser USER_ID");
        System.err.println("       pm create-profile USER_NAME");
        System.err.println("       pm remove-profile 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:");
Loading