DevicePolicyManagerService之DeviceOwner和ProfileOwner

Posted Ansen360

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了DevicePolicyManagerService之DeviceOwner和ProfileOwner相关的知识,希望对你有一定的参考价值。

目录

1.ProfileOwner

2.DeviceOwner

3.DO或PO授权后获取设备信息:

3.1.获取设备IMEI(Android10及以上版本)

3.2.获取IMSI,ICCID及电话号码


1.ProfileOwner

ProfileOwner是android5.0系统推出.ProfileOwner包含了所有DeviceAdmin用户的管理能力.系统只能设置一个Profile Owner程序,并且设置为ProfileOwner后应用无法卸载.

设置ProfileOwner

具有MANAGE_PROFILE_AND_DEVICE_OWNERS权限和shell uid的应用程序才能调用此方法

public boolean setProfileOwner(ComponentName, String, int) 

应用反射调用:

 public void  setProfileOwner()
        try 
            Method setDeviceOwner = mDevicePolicyManager.getClass().getDeclaredMethod("setActiveProfileOwner", ComponentName.class,String.class);
            setDeviceOwner.setAccessible(true);
            setDeviceOwner.invoke(mDevicePolicyManager,admin,"ansen");
         catch (IllegalAccessException e) 
            e.printStackTrace();
         catch (InvocationTargetException e) 
            e.printStackTrace();
         catch (NoSuchMethodException e) 
            e.printStackTrace();
        
    
// APP需要系统签名和如下权限
    <uses-permission android:name="android.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS" />
    <uses-permission android:name="android.permission.MANAGE_DEVICE_ADMINS" />
    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />

DPMS接口:

    public boolean setProfileOwner(ComponentName who, String ownerName, int userHandle) 
        if (!mHasFeature) 
            return false;
        
        if (who == null
                || !isPackageInstalledForUser(who.getPackageName(), userHandle)) 
            throw new IllegalArgumentException("Component " + who
                    + " not installed for userId:" + userHandle);
        


        final boolean hasIncompatibleAccountsOrNonAdb =
                hasIncompatibleAccountsOrNonAdbNoLock(userHandle, who);
        synchronized (getLockObject()) 
            enforceCanSetProfileOwnerLocked(who, userHandle, hasIncompatibleAccountsOrNonAdb);


            final ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
            if (admin == null || getUserData(userHandle).mRemovingAdmins.contains(who)) 
                throw new IllegalArgumentException("Not active admin: " + who);
            


            if (isAdb()) 
                // Log profile owner provisioning was started using adb.
                MetricsLogger.action(mContext, PROVISIONING_ENTRY_POINT_ADB, LOG_TAG_PROFILE_OWNER);
                DevicePolicyEventLogger
                        .createEvent(DevicePolicyEnums.PROVISIONING_ENTRY_POINT_ADB)
                        .setAdmin(who)
                        .setStrings(LOG_TAG_PROFILE_OWNER)
                        .write();
            


            // Shutting down backup manager service permanently.
            toggleBackupServiceActive(userHandle, /* makeActive= */ false);


            mOwners.setProfileOwner(who, ownerName, userHandle);
            mOwners.writeProfileOwner(userHandle);
            Slog.i(LOG_TAG, "Profile owner set: " + who + " on user " + userHandle);


            final long id = mInjector.binderClearCallingIdentity();
            try 
                if (mUserManager.isManagedProfile(userHandle)) 
                    maybeSetDefaultRestrictionsForAdminLocked(userHandle, admin,
                            UserRestrictionsUtils.getDefaultEnabledForManagedProfiles());
                    ensureUnknownSourcesRestrictionForProfileOwnerLocked(userHandle, admin,
                            true /* newOwner */);
                
                sendOwnerChangedBroadcast(DevicePolicyManager.ACTION_PROFILE_OWNER_CHANGED,
                        userHandle);
             finally 
                mInjector.binderRestoreCallingIdentity(id);
            
            mDeviceAdminServiceController.startServiceForOwner(
                    who.getPackageName(), userHandle, "set-profile-owner");
            return true;
        
    

ProfileOwner支持的管控能力:

是否为ProfileOwner

mDevicePolicyManager.isProfileOwnerApp(mComponentName.getPackageName());

隐藏应用

可停用制定应用并且不再界面显示,除非调用相应API恢复可用,否则该应用永远无法运行.可以用来开发应用黑白名单功能

mDevicePolicyManager.setApplicationHidden(admin, "packageName", true);
// 应用是否隐藏
mDevicePolicyManager.isApplicationHidden(admin, "packageName");

禁止卸载应用

被设置为禁止卸载的应用将成为受保护应用,无法被用户卸载,除非取消保护

mDevicePolicyManager.setUninstallBlocked(admin, "packageName", true);
mDevicePolicyManager.isUninstallBlocked(admin, "packageName");

DPMS实现

    public void setUninstallBlocked(ComponentName who, String callerPackage, String packageName,
            boolean uninstallBlocked) 
        final int userId = UserHandle.getCallingUserId();
        synchronized (getLockObject()) 
            // Ensure the caller is a DO/PO or a block uninstall delegate
            enforceCanManageScope(who, callerPackage, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER,
                    DELEGATION_BLOCK_UNINSTALL); // 调用者权限检查


            long id = mInjector.binderClearCallingIdentity(); //清空远程调用端的uid和pid,用当前本地进程的uid和pid替代
            try 
                mIPackageManager.setBlockUninstallForUser(packageName, uninstallBlocked, userId); // 通过binder调用PMS来设置
             catch (RemoteException re) 
                // Shouldn't happen.
                Slog.e(LOG_TAG, "Failed to setBlockUninstallForUser", re);
             finally 
                mInjector.binderRestoreCallingIdentity(id);// 恢复远程调用端的uid和pid信息
            
        
        final boolean isDelegate = (who == null);
        DevicePolicyEventLogger
                .createEvent(DevicePolicyEnums.SET_UNINSTALL_BLOCKED)
                .setAdmin(callerPackage)
                .setBoolean(isDelegate)
                .setStrings(packageName)
                .write();
    

首先对调用者权限检查,只有device owner,profile owner或指定DELEGATION_BLOCK_UNINSTALL作用域的委托调用,然后使用SystemServer的权限来调用PMS的setBlockUninstallForUser()方法来设置调用者用户的应用是否可卸载.

修改系统设置

mDevicePolicyManager.setSecureSetting(admin, "setting", "value");

    public void setSecureSetting(ComponentName who, String setting, String value) 
        Preconditions.checkNotNull(who, "ComponentName is null");
        int callingUserId = mInjector.userHandleGetCallingUserId();
  // ... ...
// 对调用者的权限判断
            long id = mInjector.binderClearCallingIdentity(); //清空远程调用端的uid和pid,用当前本地进程的uid和pid替代
            try 
                if (Settings.Secure.DEFAULT_INPUT_METHOD.equals(setting)) 
                    final String currentValue = mInjector.settingsSecureGetStringForUser(
                            Settings.Secure.DEFAULT_INPUT_METHOD,以上是关于DevicePolicyManagerService之DeviceOwner和ProfileOwner的主要内容,如果未能解决你的问题,请参考以下文章