目录
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