美文网首页高级Android开发Android开发经验谈
Android:多用户的UserHandle的东东记录

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

作者: 我在等你回复可你没回 | 来源:发表于2017-12-03 18:44 被阅读201次
    废纸.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的东东记录

        本文链接:https://www.haomeiwen.com/subject/ejczbxtx.html