Android:多用户的UserHandle的东东记录

Android:多用户的UserHandle的东东记录_第1张图片
废纸.png

Android的多用户有个东西,叫UserHandle,跟多用户相关。现在记录一下。

一.每个进程看看

root      3051  2     0      0     rescuer_th 0000000000 S kbase_event
system    3138  522   2002840 89588 SyS_epoll_ 70add58a60 S com.hehe.usbselection
u0_a23    3342  523   1475732 94212 SyS_epoll_ 00edb6b538 S com.android.mms
u0_a2     3395  522   2010492 95944 SyS_epoll_ 70add58a60 S com.android.providers.calendar
u0_a101   3518  523   1445740 79736 SyS_epoll_ 00edb6b538 S com.hehe.activation
root      3623  2     0      0     worker_thr 0000000000 S kworker/2:3
u0_a13    4307  522   2332516 150276 SyS_epoll_ 70add58a60 S com.google.android.gms.unstable
root      4487  2     0      0     rescuer_th 0000000000 S kbase_event
system    4503  522   2008192 92252 SyS_epoll_ 70add58a60 S com.hehe.ota

第一个字段就是进程所属的uid,普通应用的uid都是单独的。例如com.android.mms,com.hehe.activation的uid都是单独的,一个叫u0_a23,一个叫u0_a101。
而也可以看到com.hehe.usbselection,com.hehe.ota两个进程的uid都是system,两个进程同享了同一个uid。这种可以同享的uid叫做shareuid。同享uid的进程可以相互同享资源。

二.uid不会改变

应用安装后,系统重启和应用重启都不会改变uid。uid记录在data/system/packages.xml中。可以dumpsys出来看看。

 dumpsys package com.android.mms |grep "uid"
    uid=10023 gids=null type=0 prot=signature|privileged

三.UserHandle结构侃侃

/frameworks/base/core/java/android/os/UserHandle.java

public final class UserHandle implements Parcelable {
    /**
     * @hide Range of uids allocated for a user.
     */
    public static final int PER_USER_RANGE = 100000; //每个用户可以有十万个uid

    /** @hide A user id to indicate all users on the device */
    public static final @UserIdInt int USER_ALL = -1;

    /** @hide A user handle to indicate all users on the device */
    public static final UserHandle ALL = new UserHandle(USER_ALL);

    /** @hide A user id to indicate the currently active user */
    public static final @UserIdInt int USER_CURRENT = -2;

    /** @hide A user handle to indicate the current user of the device */
    public static final UserHandle CURRENT = new UserHandle(USER_CURRENT);

    /** @hide A user id to indicate that we would like to send to the current
     *  user, but if this is calling from a user process then we will send it
     *  to the caller's user instead of failing with a security exception */
    public static final @UserIdInt int USER_CURRENT_OR_SELF = -3;

    /** @hide A user handle to indicate that we would like to send to the current
     *  user, but if this is calling from a user process then we will send it
     *  to the caller's user instead of failing with a security exception */
    public static final UserHandle CURRENT_OR_SELF = new UserHandle(USER_CURRENT_OR_SELF);

    /** @hide An undefined user id */
    public static final @UserIdInt int USER_NULL = -10000;

    /**
     * @hide A user id constant to indicate the "owner" user of the device
     * @deprecated Consider using either {@link UserHandle#USER_SYSTEM} constant or
     * check the target user's flag {@link android.content.pm.UserInfo#isAdmin}.
     */
    public static final @UserIdInt int USER_OWNER = 0;

    /**
     * @hide A user handle to indicate the primary/owner user of the device
     * @deprecated Consider using either {@link UserHandle#SYSTEM} constant or
     * check the target user's flag {@link android.content.pm.UserInfo#isAdmin}.
     */
    public static final UserHandle OWNER = new UserHandle(USER_OWNER);

    /** @hide A user id constant to indicate the "system" user of the device */
    public static final @UserIdInt int USER_SYSTEM = 0;

    /** @hide A user serial constant to indicate the "system" user of the device */
    public static final int USER_SERIAL_SYSTEM = 0;

    /** @hide A user handle to indicate the "system" user of the device */
    public static final UserHandle SYSTEM = new UserHandle(USER_SYSTEM);

    /**
     * @hide Enable multi-user related side effects. Set this to false if
     * there are problems with single user use-cases.
     */
    public static final boolean MU_ENABLED = true;

    final int mHandle;

    /**
     * Checks to see if the user id is the same for the two uids, i.e., they belong to the same
     * user.
     * @hide
     */
    //判断两个应用是否属于同一个用户。例如微信和微博是否都是属于老爸的。
    public static boolean isSameUser(int uid1, int uid2) {
        return getUserId(uid1) == getUserId(uid2);
    }

    /**
     * Checks to see if both uids are referring to the same app id, ignoring the user id part of the
     * uids.
     * @param uid1 uid to compare
     * @param uid2 other uid to compare
     * @return whether the appId is the same for both uids
     * @hide
     */
     //判断两个应用是否是同一个应用。例如老爸和儿子的微信的uid传进去,返回true。
    public static boolean isSameApp(int uid1, int uid2) {
        return getAppId(uid1) == getAppId(uid2);
    }

    /** @hide */
    public static boolean isIsolated(int uid) {
        if (uid > 0) {
            final int appId = getAppId(uid);
            return appId >= Process.FIRST_ISOLATED_UID && appId <= Process.LAST_ISOLATED_UID;
        } else {
            return false;
        }
    }

    /** @hide */
    public static boolean isApp(int uid) {
        if (uid > 0) {
            final int appId = getAppId(uid);
            return appId >= Process.FIRST_APPLICATION_UID && appId <= Process.LAST_APPLICATION_UID;
        } else {
            return false;
        }
    }

    //传入uid,获取userid。例如老爸的微信的uid是10080,则儿子的微信的uid是1000000+10080。最后老爸的返回值是10080/1000000=0,儿子的返回值是(1000000+10080)/1000000=1。
    public static @UserIdInt int getUserId(int uid) {
        if (MU_ENABLED) {
            return uid / PER_USER_RANGE;
        } else {
            return UserHandle.USER_SYSTEM;
        }
    }

   //传入uid,获取appid。例如老爸的微信的uid是10080,则儿子的微信的uid是1000000+10080。最后老爸的返回值是10080%1000000=10080,儿子的返回值是(1000000+10080)%1000000=10080。
    public static @AppIdInt int getAppId(int uid) {
        return uid % PER_USER_RANGE;
    }
....................省略

可以看到,UserHandle包含三种概念:userid,uid,appid
userid:就是有多少个实际的用户罗,例如老爸很穷,要跟儿子共用一台手机,那可以跟手机将两个用户,user 0和user 1。两个用户的应用和数据是独立的。

uid:跟应用进程相关。除了sharduid的应用,每个用户的每个应用的uid不一样的。用户0的应用的uid从一万开始算。

appid:跟app相关,包名相同的appid都一样。即使是不同用户。例如你和儿子都在这台手机装了微信,但这两个微信的appid是一样的。

你可能感兴趣的:(Android:多用户的UserHandle的东东记录)