DevicePolicyManagerService之DeviceOwner和ProfileOwner
Posted Ansen360
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了DevicePolicyManagerService之DeviceOwner和ProfileOwner相关的知识,希望对你有一定的参考价值。
目录
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,