Android访客用户支持安装第三方应用

Android访客模式即guest用户下操作文件管理器里的apk安装是被限制的,且安装时会提示“该用户无法安装未知应用”。现需求是放开此限制且修改不影响平台的EDLA认证。

APK安装限制

安装apk的弹窗提示流程可以跟踪PackageInstaller下的PackageInstallerActivity.java。此处通过unknownSourcesRestrictionSource判断限制了apk安装。

private void checkIfAllowedAndInitiateInstall() {
        // Check for install apps user restriction first.
        final int installAppsRestrictionSource = mUserManager.getUserRestrictionSource(
                UserManager.DISALLOW_INSTALL_APPS, Process.myUserHandle());
        if ((installAppsRestrictionSource & UserManager.RESTRICTION_SOURCE_SYSTEM) != 0) {
            if (mLocalLOGV) Log.i(TAG, "install not allowed: " + UserManager.DISALLOW_INSTALL_APPS);
            showDialogInner(DLG_INSTALL_APPS_RESTRICTED_FOR_USER);
            return;
        } else if (installAppsRestrictionSource != UserManager.RESTRICTION_NOT_SET) {
            if (mLocalLOGV) {
                Log.i(TAG, "install not allowed by admin; showing "
                        + Settings.ACTION_SHOW_ADMIN_SUPPORT_DETAILS);
            }
            startActivity(new Intent(Settings.ACTION_SHOW_ADMIN_SUPPORT_DETAILS));
            finish();
            return;
        }

        if (mAllowUnknownSources || !isInstallRequestFromUnknownSource(getIntent())) {
            if (mLocalLOGV) Log.i(TAG, "install allowed");
            initiateInstall();
        } else {
            // Check for unknown sources restrictions.
            final int unknownSourcesRestrictionSource = mUserManager.getUserRestrictionSource(
                    UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, Process.myUserHandle());
            final int unknownSourcesGlobalRestrictionSource = mUserManager.getUserRestrictionSource(
                    UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY, Process.myUserHandle());
            final int systemRestriction = UserManager.RESTRICTION_SOURCE_SYSTEM
                    & (unknownSourcesRestrictionSource | unknownSourcesGlobalRestrictionSource);
            if (systemRestriction != 0) {
                if (mLocalLOGV) Log.i(TAG, "Showing DLG_UNKNOWN_SOURCES_RESTRICTED_FOR_USER");
                showDialogInner(DLG_UNKNOWN_SOURCES_RESTRICTED_FOR_USER);//该用户无法安装未知应用
            } else if (unknownSourcesRestrictionSource != UserManager.RESTRICTION_NOT_SET) {
                startAdminSupportDetailsActivity(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES);
            } else if (unknownSourcesGlobalRestrictionSource != UserManager.RESTRICTION_NOT_SET) {
                startAdminSupportDetailsActivity(
                        UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY);
            } else {
                handleUnknownSources();
            }
        }
    }

由于该认证平台用的/vendor/partner_gms/apps/GooglePackageInstaller,纯apk无源码无法修改,所以需寻找另外一种修改方式来支持。

多用户Restrictions

由以上启发,得知这是一个多用户unknown sources restrictions限制问题。具体源码可以查看:frameworks/base/services/core/java/com/android/server/pm/UserManagerService.java。

1、设置中添加访客,查看系统多用户目录/data/system/users下的文件:
在这里插入图片描述

2、我们分别看下多用户列表userlist.xml和访客用户10.xml下的内容:

<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<users nextSerialNumber="11" version="9" userTypeConfigVersion="0">
    <guestRestrictions>
        <restrictions no_sms="true" no_install_unknown_sources="true" no_config_wifi="true" no_config_credentials="true" no_outgoing_calls="true" />
    </guestRestrictions>
    <deviceOwnerUserId id="-10000" />
    <user id="0" />
    <user id="10" />
</users>

<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<user id="10" serialNumber="10" flags="1044" type="android.os.usertype.full.GUEST" created="1701933606874" lastLoggedIn="1701933612138" lastLoggedInFingerprint="aa085250b2813ee81e5fd4fa9d7d49f5e05a74c9" profileBadge="0">
    <restrictions no_sms="true" no_install_unknown_sources="true" no_config_wifi="true" no_config_credentials="true" no_outgoing_calls="true" />
    <device_policy_local_restrictions />
    <ignorePrepareStorageErrors>false</ignorePrepareStorageErrors>
</user>

可以得知guestRestrictions已经默认明确了一些访客权限限制,具体可以看下UserManagerService类中的Bundle对象mGuestRestrictions的数据生成过程。

3、我们尝试在访客用户生成时赋予UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES使用者权限。上层可以监听ACTION_USER_SWITCHED用户切换广播时处理。
其中SystemUI中GuestResumeSessionReceiver已经有了该广播处理过程,修改如下:

        if (Intent.ACTION_USER_SWITCHED.equals(action)) {
            cancelDialog();

            int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
            if (userId == UserHandle.USER_NULL) {
                Log.e(TAG, intent + " sent to " + TAG + " without EXTRA_USER_HANDLE");
                return;
            }

            UserInfo currentUser = mUserTracker.getUserInfo();
            if (!currentUser.isGuest()) {
                return;
            }

            int notFirstLogin = mSecureSettings.getIntForUser(
                    SETTING_GUEST_HAS_LOGGED_IN, 0, userId);
			//add by liuke
			boolean hasUserRestriction =  mUserManager.hasUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, new UserHandle(userId));
			Log.i(TAG, "notFirstLogin = " + notFirstLogin + ", userId = " + userId + ", hasUserRestriction = " + hasUserRestriction);
			mUserManager.setUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, false, UserHandle.of(userId));
			//end by liuke
            if (notFirstLogin != 0) {
                mNewSessionDialog = new ResetSessionDialog(context, mUserSwitcherController,
                        mUiEventLogger, userId);
				mNewSessionDialog.show();
            } else {
                mSecureSettings.putIntForUser(SETTING_GUEST_HAS_LOGGED_IN, 1, userId);
            }
        }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值