Android: East East Record of Multiuser UserHandle

Waste paper.png

Android's multiuser has something called UserHandle, which is related to multiuser.Now record it.

1. Look at each process

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

The first field is the uid to which the process belongs, and common UIDs are individual.for exampleCom.android.mms,Com.hehe.activationThe UIDs are all separate, one called u0_a23, a u0_a101.
And you can also seeCom.hehe.usbselection,Com.hehe.otaThe UIDs of both processes are system s, and both processes share the same uid.This shared uid is called shareuid.The process of sharing UIDs can share resources with each other.

2. uid will not change

After application installation, system restart and application restart will not change the uid.Uid recorded in data/system/Packages.xmlMedium.Let's take a look at dumpsys.

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

3. UserHandle structure is ridiculous

/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; //You can have 100,000 UIDs per user

    /** @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
     */
    //Determine if two applications belong to the same user.For example, whether WeChat and Weibo belong to father or not.
    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
     */
     //Determine if two applications are the same application.For example, the uid of WeChat from father and son came in, returning 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;
        }
    }

    //Pass in the uid and get the userid.For example, if the uid of Dad's WeChat is 10080, the uid of Son's WeChat is 1000000+10080.Finally, the return value of father is 10080/1000000=0, and that of son is (1000000+10080)/1000000=1.
    public static @UserIdInt int getUserId(int uid) {
        if (MU_ENABLED) {
            return uid / PER_USER_RANGE;
        } else {
            return UserHandle.USER_SYSTEM;
        }
    }

   //Pass in the uid and get the appid.For example, if the uid of Dad's WeChat is 10080, the uid of Son's WeChat is 1000000+10080.Finally, the return value of father is 10080%1000000=10080, and that of son is (1000000+10080)%1000000=10080.
    public static @AppIdInt int getAppId(int uid) {
        return uid % PER_USER_RANGE;
    }
....................ellipsis

As you can see, UserHandle has three concepts: userid,uid,appid
userid: Just how many actual users there are, such as a poor father who wants to share a mobile phone with his son, can have two users, user 0 and user 1.The application and data for both users are independent.

Uid: related to the application process.Except for sharduid apps, each user's uid is different for each app.User 0's application uid starts at 10,000.

appid: Appids with the same package name are the same as apps.Even different users.For example, you and your son both have WeChat installed on this phone, but the appids of the two WeChat are the same.

Tags: Android Java Google Mobile

Posted on Sun, 19 Jul 2020 11:42:50 -0400 by voltrader