一 、设置device owner命令:
adb shell dpm set-device-owner 'packagename/ReceiverClass'
dpm主要是和DevicePolicyManage进行交互,通过用户授权应用设备管理权限后,可以在代码修改很多系统设置。
激活命令:
DevicePolicyManager.setActiveAdmin
源码路径frameworks/base/core/java/android/app/admin/DevicePolicyManager.java,代码如下:
/**
* @hide
*/
public void setActiveAdmin(@NonNull ComponentName policyReceiver, boolean refreshing,
int userHandle) {
if (mService != null) {
try {
mService.setActiveAdmin(policyReceiver, refreshing, userHandle);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
}
}
这里的setActiveAdmin调用的是DevicePolicyManagerService中的setActiveAdmin
DevicePolicyManagerService中setActiveAdmin实现代码如下:
/**
* @param adminReceiver The admin to add
* @param refreshing true = update an active admin, no error
*/
@Override
public void setActiveAdmin(ComponentName adminReceiver, boolean refreshing, int userHandle) {
if (!mHasFeature) {
return;
}
setActiveAdmin(adminReceiver, refreshing, userHandle, null); //这里调用的是私有方法setActiveAdmin
}
private void setActiveAdmin(ComponentName adminReceiver, boolean refreshing, int userHandle,
Bundle onEnableData) {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.MANAGE_DEVICE_ADMINS, null); //权限检查,这里检查的是用户是否有android.Manifest.permission.MANAGE_DEVICE_ADMINS权限,这个权限是需要签名权限或者priv-app下的应用才能使用
enforceFullCrossUsersPermission(userHandle); //权限检查,这里检查的是不同用户之间的权限
DevicePolicyData policy = getUserData(userHandle); //获取当前用户的DevicePolicyData
DeviceAdminInfo info = findAdmin(adminReceiver, userHandle,
/* throwForMissionPermission= */ true); //获取当前用户的ComponentName获取DeviceAdminInfo
if (info == null) {
throw new IllegalArgumentException("Bad admin: " + adminReceiver);
}
if (!info.getActivityInfo().applicationInfo.isInternal()) {
throw new IllegalArgumentException("Only apps in internal storage can be active admin: "
+ adminReceiver);
}
synchronized (this) {
long ident = mInjector.binderClearCallingIdentity();
try {
final ActiveAdmin existingAdmin
= getActiveAdminUncheckedLocked(adminReceiver, userHandle); //取出系统当前默认的设备管理器
if (!refreshing && existingAdmin != null) {
throw new IllegalArgumentException("Admin is already added"); //如果refreshing为false,并且不存在默认设备管理器,直接报错~
}
if (policy.mRemovingAdmins.contains(adminReceiver)) { //如果设置当前用户DevicePolicyData中已经移除过的设备管理器,直接报错
throw new IllegalArgumentException(
"Trying to set an admin which is being removed");
}
ActiveAdmin newAdmin = new ActiveAdmin(info, /* parent */ false); //新创建一个设备管理器
newAdmin.testOnlyAdmin =
(existingAdmin != null) ? existingAdmin.testOnlyAdmin
: isPackageTestOnly(adminReceiver.getPackageName(), userHandle);
policy.mAdminMap.put(adminReceiver, newAdmin); //把componentName和ActiveAdmin放到当前用户的DevicePolicyData的ArrayMap中
int replaceIndex = -1;
final int N = policy.mAdminList.size(); //获取当前DevicePolicyData中的mAdminList的大小
for (int i=0; i < N; i++) {
ActiveAdmin oldAdmin = policy.mAdminList.get(i);
if (oldAdmin.info.getComponent().equals(adminReceiver)) { //找到默认设备管理器的位置,并将位置标记
replaceIndex = i;
break;
}
}
if (replaceIndex == -1) {
policy.mAdminList.add(newAdmin); //如果替换位置没有找到,添加新的AdminActive到mAdminList中
enableIfNecessary(info.getPackageName(), userHandle);
} else {
policy.mAdminList.set(replaceIndex, newAdmin); //如果替换位置已经找到,就将当前的ActiveAdmin插入到该位置,替换为新的默认设备管理器
}
saveSettingsLocked(userHandle); //保存当前用户的设置
sendAdminCommandLocked(newAdmin, DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED,
onEnableData, null); //发送通知给新的默认设备管理器
} finally {
mInjector.binderRestoreCallingIdentity(ident);
}
}
}
设置设备权限命令:
DevicePolicyManager.setDeviceOwner
源码路径frameworks/base/core/java/android/app/admin/DevicePolicyManager.java,代码如下:
/**
* @hide
* Sets the given package as the device owner. The package must already be installed. There
* must not already be a device owner.
* Only apps with the MANAGE_PROFILE_AND_DEVICE_OWNERS permission and the shell uid can call
* this method.
* Calling this after the setup phase of the primary user has completed is allowed only if
* the caller is the shell uid, and there are no additional users and no accounts.
* @param packageName the package name of the application to be registered as the device owner.
* @param ownerName the human readable name of the institution that owns this device.
* @return whether the package was successfully registered as the device owner.
* @throws IllegalArgumentException if the package name is null or invalid
* @throws IllegalStateException If the preconditions mentioned are not met.
*/
public boolean setDeviceOwner(String packageName, String ownerName)
throws IllegalArgumentException, IllegalStateException {
if (mService != null) {
try {
return mService.setDeviceOwner(packageName, ownerName);
} catch (RemoteException re) {
Log.w(TAG, "Failed to set device owner");
}
}
return false;
}
这里的setDeviceOwner调用的是DevicePolicyManagerService中的setDeviceOwner
DevicePolicyManagerService中setDeviceOwner实现代码如下:
@Override
public boolean setDeviceOwner(String packageName, String ownerName) {
if (!mHasFeature) {
return false;
}
if (packageName == null
|| !DeviceOwner.isInstalled(packageName, mContext.getPackageManager())) {
throw new IllegalArgumentException("Invalid package name " + packageName
+ " for device owner");
}
synchronized (this) {
enforceCanSetDeviceOwner();
// Shutting down backup manager service permanently.
long ident = Binder.clearCallingIdentity();
try {
IBackupManager ibm = IBackupManager.Stub.asInterface(
ServiceManager.getService(Context.BACKUP_SERVICE));
ibm.setBackupServiceActive(UserHandle.USER_OWNER, false);
} catch (RemoteException e) {
throw new IllegalStateException("Failed deactivating backup service.", e);
} finally {
Binder.restoreCallingIdentity(ident);
}
if (mDeviceOwner == null) {
// Device owner is not set and does not exist, set it.
mDeviceOwner = DeviceOwner.createWithDeviceOwner(packageName, ownerName); //如果现在没有设置默认设备管理器,就新建一个
} else {
// Device owner state already exists, update it.
mDeviceOwner.setDeviceOwner(packageName, ownerName); //如果已经存在,就更新一下
}
mDeviceOwner.writeOwnerFile();
updateDeviceOwnerLocked(); //更新并锁定新的DeviceOwner
Intent intent = new Intent(DevicePolicyManager.ACTION_DEVICE_OWNER_CHANGED);
ident = Binder.clearCallingIdentity();
try {
mContext.sendBroadcastAsUser(intent, UserHandle.OWNER);
} finally {
Binder.restoreCallingIdentity(ident);
}
return true;
}
}
文件权限:
DevicePolicyManager.setProfileOwner
源码路径frameworks/base/core/java/android/app/admin/DevicePolicyManager.java,代码如下:
/**
* @hide
* @deprecated Use #ACTION_SET_PROFILE_OWNER
* Sets the given component as an active admin and registers the package as the profile
* owner for this user. The package must already be installed and there shouldn't be
* an existing profile owner registered for this user. Also, this method must be called
* before the user setup has been completed.
* <p>
* This method can only be called by system apps that hold MANAGE_USERS permission and
* MANAGE_DEVICE_ADMINS permission.
* @param admin The component to register as an active admin and profile owner.
* @param ownerName The user-visible name of the entity that is managing this user.
* @return whether the admin was successfully registered as the profile owner.
* @throws IllegalArgumentException if packageName is null, the package isn't installed, or
* the user has already been set up.
*/
@SystemApi
public boolean setProfileOwner(@NonNull ComponentName admin, @Deprecated String ownerName,
int userHandle) throws IllegalArgumentException {
if (admin == null) {
throw new NullPointerException("admin cannot be null");
}
if (mService != null) {
try {
if (ownerName == null) {
ownerName = "";
}
return mService.setProfileOwner(admin, ownerName, userHandle);
} catch (RemoteException re) {
Log.w(TAG, "Failed to set profile owner", re);
throw new IllegalArgumentException("Couldn't set profile owner.", re);
}
}
return false;
}
这里的setProfileOwner 调用的是DevicePolicyManagerService中的setProfileOwner
DevicePolicyManagerService中setProfileOwner 实现代码如下:
@Override
public boolean setProfileOwner(ComponentName who, String ownerName, int userHandle) {
if (!mHasFeature) {
return false;
}
if (who == null
|| !DeviceOwner.isInstalledForUser(who.getPackageName(), userHandle)) {
throw new IllegalArgumentException("Component " + who
+ " not installed for userId:" + userHandle);
}
synchronized (this) {
enforceCanSetProfileOwner(userHandle);
if (mDeviceOwner == null) {
// Device owner state does not exist, create it.
mDeviceOwner = DeviceOwner.createWithProfileOwner(who, ownerName,
userHandle);
} else {
// Device owner state already exists, update it.
mDeviceOwner.setProfileOwner(who, ownerName, userHandle);
}
mDeviceOwner.writeOwnerFile();
return true;
}
}
这些命令都是DevicePolicyManager隐藏的api,三方应用没有权限进行调用的.
对adb shell中dpm命令进行处理的是Dpm,路径为framework/base/cmds/dpm/src/com/android/commands/dpm/Dpm.java
android Dpm源码如下:
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.commands.dpm;
import android.app.admin.IDevicePolicyManager;
import android.content.ComponentName;
import android.content.Context;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
import com.android.internal.os.BaseCommand;
import java.io.PrintStream;
public final class Dpm extends BaseCommand {
/**
* Command-line entry point.
*
* @param args The command-line arguments
*/
public static void main(String[] args) {
(new Dpm()).run(args);
}
private static final String COMMAND_SET_ACTIVE_ADMIN = "set-active-admin";
private static final String COMMAND_SET_DEVICE_OWNER = "set-device-owner";
private static final String COMMAND_SET_PROFILE_OWNER = "set-profile-owner";
private IDevicePolicyManager mDevicePolicyManager;
private int mUserId = UserHandle.USER_OWNER;
private ComponentName mComponent = null;
@Override
public void onShowUsage(PrintStream out) {
out.println(
"usage: dpm [subcommand] [options]\n" +
"usage: dpm set-active-admin [ --user <USER_ID> ] <COMPONENT>\n" +
"usage: dpm set-device-owner <COMPONENT>\n" +
"usage: dpm set-profile-owner [ --user <USER_ID> ] <COMPONENT>\n" +
"\n" +
"dpm set-active-admin: Sets the given component as active admin" +
" for an existing user.\n" +
"\n" +
"dpm set-device-owner: Sets the given component as active admin, and its\n" +
" package as device owner.\n" +
"\n" +
"dpm set-profile-owner: Sets the given component as active admin and profile" +
" owner for an existing user.\n");
}
@Override
public void onRun() throws Exception {
mDevicePolicyManager = IDevicePolicyManager.Stub.asInterface(
ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
if (mDevicePolicyManager == null) {
showError("Error: Could not access the Device Policy Manager. Is the system running?");
return;
}
String command = nextArgRequired();
switch (command) {
case COMMAND_SET_ACTIVE_ADMIN:
runSetActiveAdmin();
break;
case COMMAND_SET_DEVICE_OWNER:
runSetDeviceOwner();
break;
case COMMAND_SET_PROFILE_OWNER:
runSetProfileOwner();
break;
default:
throw new IllegalArgumentException ("unknown command '" + command + "'");
}
}
private void parseArgs(boolean canHaveUser) {
String nextArg = nextArgRequired();
if (canHaveUser && "--user".equals(nextArg)) {
mUserId = parseInt(nextArgRequired());
nextArg = nextArgRequired();
}
mComponent = parseComponentName(nextArg);
}
private void runSetActiveAdmin() throws RemoteException {
parseArgs(true);
mDevicePolicyManager.setActiveAdmin(mComponent, true /*refreshing*/, mUserId);
System.out.println("Success: Active admin set to component " + mComponent.toShortString());
}
private void runSetDeviceOwner() throws RemoteException {
ComponentName component = parseComponentName(nextArgRequired());
mDevicePolicyManager.setActiveAdmin(component, true /*refreshing*/, UserHandle.USER_OWNER);
String packageName = component.getPackageName();
try {
if (!mDevicePolicyManager.setDeviceOwner(packageName, null /*ownerName*/)) {
throw new RuntimeException(
"Can't set package " + packageName + " as device owner.");
}
} catch (Exception e) {
// Need to remove the admin that we just added.
mDevicePolicyManager.removeActiveAdmin(component, UserHandle.USER_OWNER);
throw e;
}
System.out.println("Success: Device owner set to package " + packageName);
System.out.println("Active admin set to component " + component.toShortString());
}
private void runSetProfileOwner() throws RemoteException {
parseArgs(true);
mDevicePolicyManager.setActiveAdmin(mComponent, true /*refreshing*/, mUserId);
try {
if (!mDevicePolicyManager.setProfileOwner(mComponent, "" /*ownerName*/, mUserId)) {
throw new RuntimeException("Can't set component " + mComponent.toShortString() +
" as profile owner for user " + mUserId);
}
} catch (Exception e) {
// Need to remove the admin that we just added.
mDevicePolicyManager.removeActiveAdmin(mComponent, mUserId);
throw e;
}
System.out.println("Success: Active admin and profile owner set to "
+ mComponent.toShortString() + " for user " + mUserId);
}
private ComponentName parseComponentName(String component) {
ComponentName cn = ComponentName.unflattenFromString(component);
if (cn == null) {
throw new IllegalArgumentException ("Invalid component " + component);
}
return cn;
}
private int parseInt(String argument) {
try {
return Integer.parseInt(argument);
} catch (NumberFormatException e) {
throw new IllegalArgumentException ("Invalid integer argument '" + argument + "'", e);
}
}
}
device_admin 管理的权限:
<limit-password /> //设置密码规则
<watch-login /> //监控屏幕解锁尝试次数
<reset-password /> //更改屏幕解锁密码
<force-lock /> //设备自动解锁
<wipe-data /> //清除数据
<expire-password /> //激活密码
<encrypted-storage /> //数据加密
<disable-camera /> //禁用摄像头
DeviceOwner权限相关
1、设置壁纸
2、获得硬件属性(cpu使用情况、温度、转速)
3、静默卸载、设置某用户隐藏/停止某应用
4、静默安装
5、网络状态
..............