Android5.1--多用户模式


Android中的多用户与Windows的多用户类似,可以支持多个用户使用系统。通常,第一个在系统中注册的用户将默认成为系统管理员。

不同用户的设置各不相同,并且不同用户安装的应用及应用数据也不相同。但是系统中和硬件相关的设置则是共用的,例如网络设置等。

Android与Windows不同,用户切换后前面用户运行的后台进程还可以继续运行。这样,进行用户切换时无须中断一些后台进行的耗时操作(如下载)。

一、管理用户的系统服务--UserManagerService

UserManagerService的主要功能是创建和删除用户,以及查询用户信息。

1、初始化

UserManagerService是在PackageManagerService的构造方法中创建的,如下:

sUserManager = new UserManagerService(context, this, mInstallLock, mPackages);
UserManagerService的构造方法,如下:

    UserManagerService(Context context, PackageManagerService pm,
            Object installLock, Object packagesLock) {
        this(context, pm, installLock, packagesLock,
                Environment.getDataDirectory(),
                new File(Environment.getDataDirectory(), "user"));
    }
调用另一个构造方法,并多传递了两个参数:/data目录和/data/user文件。如下:

    private UserManagerService(Context context, PackageManagerService pm,
            Object installLock, Object packagesLock,
            File dataDir, File baseUserPath) {
        mContext = context;
        mPm = pm;
        mInstallLock = installLock;
        mPackagesLock = packagesLock;
        mHandler = new Handler();
        synchronized (mInstallLock) {
            synchronized (mPackagesLock) {
                mUsersDir = new File(dataDir, USER_INFO_DIR);// /data/system/users
                mUsersDir.mkdirs();
                // Make zeroth user directory, for services to migrate their files to that location
                File userZeroDir = new File(mUsersDir, "0");//第一个用户的目录/data/system/users/0
                userZeroDir.mkdirs();
                mBaseUserPath = baseUserPath;// /data/user
                FileUtils.setPermissions(mUsersDir.toString(),
                        FileUtils.S_IRWXU|FileUtils.S_IRWXG
                        |FileUtils.S_IROTH|FileUtils.S_IXOTH,
                        -1, -1);
                mUserListFile = new File(mUsersDir, USER_LIST_FILENAME);// /data/system/users/userlist.xml
                initDefaultGuestRestrictions();
                readUserListLocked();//分析用户的信息文件
                // Prune out any partially created/partially removed users.
                ArrayList<UserInfo> partials = new ArrayList<UserInfo>();
                for (int i = 0; i < mUsers.size(); i++) {
                    UserInfo ui = mUsers.valueAt(i);
                    if ((ui.partial || ui.guestToRemove) && i != 0) {
                        partials.add(ui);//寻找userlist.xml文件中属性partial为true的用户
                    }
                }
                for (int i = 0; i < partials.size(); i++) {
                    UserInfo ui = partials.get(i);
                    Slog.w(LOG_TAG, "Removing partially created user #" + i
                            + " (name=" + ui.name + ")");
                    removeUserStateLocked(ui.id);//属性为partial表示创建没完成的用户,从系统中移除
                }
                sInstance = this;
            }
        }
    }
在构造方法中创建了几个目录:/data/system/users、data/system/users/0、/data/system/users/userlist.xml等。之后设置基本的限制条件,如下:

    private void initDefaultGuestRestrictions() {
        if (mGuestRestrictions.isEmpty()) {
            mGuestRestrictions.putBoolean(UserManager.DISALLOW_OUTGOING_CALLS, true);//"no_outgoing_calls"
            mGuestRestrictions.putBoolean(UserManager.DISALLOW_SMS, true);//"no_sms"
        }
    }
然后调用readUserListLocked()方法解析/data/system/users/userlist.xml文件,这个文件保存了系统中所有用户的id信息。文件内容如下:

<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<users nextSerialNumber="11" version="5">
    <guestRestrictions>
        <restrictions no_outgoing_calls="true" no_sms="true" />
    </guestRestrictions>
    <user id="0" />
    <user id="10" />
</users>
得到id信息后还有读取保存了用户注册信息的xml文件,以用户id的数字表示,如0.xml。内容如下:

<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<user id="0" serialNumber="0" flags="19" created="0" lastLoggedIn="1436392413074">
    <name>Owner</name>
    <restrictions />
</user>
读取用户的xml文件内容后,将根据文件内容来创建和初始化一个UserInfo对象来保存信息,并把该对象加入到mUsers列表中。如果xml文件中某个用户的属性中有partial="true',则表示这个用户没有完全创建成功,需要从系统中移除掉。

这样UserManagerService的初始化工作就完成了,主要的工作是分析userlist.xml文件,并创建了mUsers列表中的UserInfo对象。

2、UserInfo的定义

在UserManagerService中,UserInfo对象代表用户,定义如下:

public class UserInfo implements Parcelable {

    /** 8 bits for user type 用户类型 */
    public static final int FLAG_MASK_USER_TYPE = 0x000000FF;

    /**
     * Primary user. Only one user can have this flag set. Meaning of this
     * flag TBD.主用户的标志,通常是第一个Id为0的用户
     */
    public static final int FLAG_PRIMARY = 0x00000001;

    /**
     * User with administrative privileges. Such a user can create and
     * delete users.admin用户标志,有此标志才能创建和删除用户
     */
    public static final int FLAG_ADMIN   = 0x00000002;

    /**
     * Indicates a guest user that may be transient.guest用户标志
     */
    public static final int FLAG_GUEST   = 0x00000004;

    /**
     * Indicates the user has restrictions in privileges, 标识权限受限的用户,具体受限功能未定。
     * Exact meaning TBD. For instance, maybe they can't install apps or administer WiFi access pts.
     */
    public static final int FLAG_RESTRICTED = 0x00000008;

    /**
     * Indicates that this user has gone through its first-time initialization.标识该用户是否已经初始化
     */
    public static final int FLAG_INITIALIZED = 0x00000010;

    /**
     * Indicates that this user is a profile of another user, for example holding a users
     * corporate data.标识该UserInfo是用户的信息,还是一份profile
     */
    public static final int FLAG_MANAGED_PROFILE = 0x00000020;

    /**
     * Indicates that this user is disabled.标识该用户是否已经被“禁止”
     */
    public static final int FLAG_DISABLED = 0x00000040;

    public static final int NO_PROFILE_GROUP_ID = -1;//profile group id 的无效值定义

    public int id;//用户id
    public int serialNumber;//用户的序列号,不会重复
    public String name;//用户的名称
    public String iconPath;//用户的头像路径
    public int flags;//用户的标志
    public long creationTime;//创建用户的时间
    public long lastLoggedInTime;//上次登录的时间
    public int profileGroupId;//用户的profile group id

    /** User is only partially created. */
    public boolean partial;//此标志为true,表示用户没有创建完成
    public boolean guestToRemove;
注意:用户id用来标识用户,用户删除后它的id会分配给下一个新建的用户,保持id号的连续;而serialNumber则是一个在设备中不会重复的数字,用来唯一标识一个用户,如果应用中希望记录和某个用户相关的信息,最好使用serialNumber来表示用户,而不是用户id。

3、用户限制(Restriction)

Android5.1的UserManager中定义了很多和用户相关的限制,这样管理员在创建用户时就能通过这些限制来给予不同用户不同的权限,介绍如下:

    public static final String DISALLOW_MODIFY_ACCOUNTS = "no_modify_accounts";//限制修改用户账号
    public static final String DISALLOW_CONFIG_WIFI = "no_config_wifi";//限制配置WiFi
    public static final String DISALLOW_INSTALL_APPS = "no_install_apps";//限制安装app
    public static final String DISALLOW_UNINSTALL_APPS = "no_uninstall_apps";//限制卸载app
    public static final String DISALLOW_SHARE_LOCATION = "no_share_location";//限制共享地理位置
    public static final String DISALLOW_INSTALL_UNKNOWN_SOURCES = "no_install_unknown_sources";//限制安装本地应用
    public static final String DISALLOW_CONFIG_BLUETOOTH = "no_config_bluetooth";//限制配置蓝牙
    public static final String DISALLOW_USB_FILE_TRANSFER = "no_usb_file_transfer";//限制通过usb传输文件
    public static final String DISALLOW_CONFIG_CREDENTIALS = "no_config_credentials";//限制配置设备的安全设置
    public static final String DISALLOW_REMOVE_USER = "no_remove_user";//限制删除用户
    public static final String DISALLOW_DEBUGGING_FEATURES = "no_debugging_features";//限制使用调试功能
    public static final String DISALLOW_CONFIG_VPN = "no_config_vpn";//限制配置VPN
    public static final String DISALLOW_CONFIG_TETHERING = "no_config_tethering";//限制配置Tether
    public static final String DISALLOW_FACTORY_RESET = "no_factory_reset";//限制进行出厂设置
    public static final String DISALLOW_ADD_USER = "no_add_user";//限制创建用户
    public static final String ENSURE_VERIFY_APPS = "ensure_verify_apps";//对该用户安装的app要进行校验
    public static final String DISALLOW_CONFIG_CELL_BROADCASTS = "no_config_cell_broadcasts";//限制用户配置小区广播
    public static final String DISALLOW_CONFIG_MOBILE_NETWORKS = "no_config_mobile_networks";//限制配置移动网络
    public static final String DISALLOW_APPS_CONTROL = "no_control_apps";//限制进行清除应用数据和缓存的操作
    public static final String DISALLOW_MOUNT_PHYSICAL_MEDIA = "no_physical_media";//限制挂载
    public static final String DISALLOW_UNMUTE_MICROPHONE = "no_unmute_microphone";//限制对microphone进行静音
    public static final String DISALLOW_ADJUST_VOLUME = "no_adjust_volume";//限制调节音量
    public static final String DISALLOW_OUTGOING_CALLS = "no_outgoing_calls";//限制拨打电话
    public static final String DISALLOW_SMS = "no_sms";//限制发送短信
    public static final String DISALLOW_CREATE_WINDOWS = "no_create_windows";//限制用户的应用进行弹窗功能
    public static final String DISALLOW_CROSS_PROFILE_COPY_PASTE = "no_cross_profile_copy_paste";//限制对profile进行复制、粘贴
    public static final String DISALLOW_OUTGOING_BEAM = "no_outgoing_beam";//限制

4、添加用户

UserManagerService服务中添加用户的接口是createUser(),如下:

    public UserInfo createUser(String name, int flags) {
        checkManageUsersPermission("Only the system can create users");

        return createUserInternal(name, flags, UserHandle.USER_NULL);
    }
createUser()方法首先检查调用者的权限,只有system身份的进程才能调用这个方法。然后调用createUserInternal()方法继续执行,如下:

    private UserInfo createUserInternal(String name, int flags, int parentId) {
        if (getUserRestrictions(UserHandle.getCallingUserId()).getBoolean(
             
  • 1
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: Understand是一种功能强大的软件开发工具,它提供了多种语言和平台的静态代码分析功能,用于帮助开发人员理解和改进他们的代码质量。 5.1是Understand的一个特定版本号,它表示 Understad软件的第5个大版本中的一个小更新。 Windows64表示这个Understand版本适用于运行在Windows操作系统的64位机器上。 通过使用Understand 5.1-windows64,开发人员可以对代码进行全面的分析和评估,以确保代码的质量和可维护性。它可以帮助开发人员识别潜在的代码缺陷、冗余代码和性能问题,并提供解决方案来改善代码质量。 该版本还具备了适用于Windows 64位机器的优化和兼容性,以确保在这样的机器上能够运行和运行分析任务的平稳性。 总之,Understand 5.1-windows64是一款适用于在Windows 64位操作系统上运行的强大的软件开发工具,它为开发人员提供了全面的代码分析功能,帮助他们提高代码质量和可维护性。 ### 回答2: understand 5.1-windows64 指的是一个软件的版本和系统要求。Understand 是一款用于源代码分析的软件工具,用于帮助开发人员理解和浏览复杂的代码。5.1 是这个软件的版本号,表示该软件经过一系列的更新和改进。windows64 表示该软件支持 64 位的 Windows 操作系统。 对于开发人员来说,使用 Understand 5.1-windows64 有几个优势。首先,它可以帮助他们更好地理解和分析源代码。该软件提供了多种功能,如交互式图表、图形视图和搜索功能,可以帮助开发人员深入了解代码的结构和关系,从而更高效地调试和优化代码。 其次,Understand 5.1-windows64 具有良好的兼容性,可以在 Windows 64 位系统上正常运行。64 位操作系统相比于32位操作系统具有更大的内存容量和更快的处理速度,这对于处理大型代码库和复杂的分析任务非常重要。使用 64 位系统可以提高软件工具的性能和效率。 此外,Understand 5.1-windows64 的更新版本可能还会解决了一些 bug,增加了新功能或提高了软件的稳定性。开发人员可以从该软件的版本迭代中获益。 总之,Understand 5.1-windows64 是一款功能强大的源代码分析工具,适用于 Windows 64 位系统。它可以帮助开发人员更好地理解和分析源代码,提高开发效率,并且与 64 位操作系统相对应,能够更好地支持大型代码库和复杂的分析任务。 ### 回答3: understand5.1-windows64是一款用于软件开发的工具,它是在Windows操作系统下工作的64位版本。Understand是一个功能强大的代码理解工具,它可以帮助程序员对代码进行深入的分析和理解。 使用understand5.1-windows64,程序员可以对源代码进行静态分析,了解代码的结构、功能和相互关系。它支持多种编程语言,包括C、C++、C#、Java等。程序员可以快速地浏览代码,并通过各种视图和图表来可视化分析结果。 此外,understand5.1-windows64还提供了全面的代码检查和度量功能,帮助程序员评估代码的质量和健壮性。它可以检测潜在的错误、重复的代码和性能问题,并生成报告供程序员参考和改进。 另外,understand5.1-windows64还支持代码重构和搜索功能。程序员可以通过重构工具对代码进行重构,提高代码的可读性和可维护性。搜索功能可以帮助程序员快速定位特定的代码片段,提高开发效率。 总而言之,understand5.1-windows64是一款功能强大且易于使用的代码理解工具。它提供了丰富的分析和度量功能,帮助程序员更好地理解和改进源代码。无论是初学者还是经验丰富的开发人员,都可以从中受益并提高代码开发的效率和质量。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值