1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.commands.dpm; 18 19 import android.app.admin.IDevicePolicyManager; 20 import android.content.ComponentName; 21 import android.content.Context; 22 import android.os.RemoteException; 23 import android.os.ServiceManager; 24 import android.os.UserHandle; 25 26 import com.android.internal.os.BaseCommand; 27 28 import java.io.PrintStream; 29 30 public final class Dpm extends BaseCommand { 31 32 /** 33 * Command-line entry point. 34 * 35 * @param args The command-line arguments 36 */ main(String[] args)37 public static void main(String[] args) { 38 (new Dpm()).run(args); 39 } 40 41 private static final String COMMAND_SET_ACTIVE_ADMIN = "set-active-admin"; 42 private static final String COMMAND_SET_DEVICE_OWNER = "set-device-owner"; 43 private static final String COMMAND_SET_PROFILE_OWNER = "set-profile-owner"; 44 45 private IDevicePolicyManager mDevicePolicyManager; 46 private int mUserId = UserHandle.USER_OWNER; 47 private ComponentName mComponent = null; 48 49 @Override onShowUsage(PrintStream out)50 public void onShowUsage(PrintStream out) { 51 out.println( 52 "usage: dpm [subcommand] [options]\n" + 53 "usage: dpm set-active-admin [ --user <USER_ID> ] <COMPONENT>\n" + 54 "usage: dpm set-device-owner <COMPONENT>\n" + 55 "usage: dpm set-profile-owner <COMPONENT> <USER_ID>\n" + 56 "\n" + 57 "dpm set-active-admin: Sets the given component as active admin" + 58 " for an existing user.\n" + 59 "\n" + 60 "dpm set-device-owner: Sets the given component as active admin, and its\n" + 61 " package as device owner.\n" + 62 "\n" + 63 "dpm set-profile-owner: Sets the given component as active admin and profile" + 64 " owner for an existing user.\n"); 65 } 66 67 @Override onRun()68 public void onRun() throws Exception { 69 mDevicePolicyManager = IDevicePolicyManager.Stub.asInterface( 70 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE)); 71 if (mDevicePolicyManager == null) { 72 showError("Error: Could not access the Device Policy Manager. Is the system running?"); 73 return; 74 } 75 76 String command = nextArgRequired(); 77 switch (command) { 78 case COMMAND_SET_ACTIVE_ADMIN: 79 runSetActiveAdmin(); 80 break; 81 case COMMAND_SET_DEVICE_OWNER: 82 runSetDeviceOwner(); 83 break; 84 case COMMAND_SET_PROFILE_OWNER: 85 runSetProfileOwner(); 86 break; 87 default: 88 throw new IllegalArgumentException ("unknown command '" + command + "'"); 89 } 90 } 91 parseArgs(boolean canHaveUser)92 private void parseArgs(boolean canHaveUser) { 93 String nextArg = nextArgRequired(); 94 if (canHaveUser && "--user".equals(nextArg)) { 95 mUserId = parseInt(nextArgRequired()); 96 nextArg = nextArgRequired(); 97 } 98 mComponent = parseComponentName(nextArg); 99 } 100 runSetActiveAdmin()101 private void runSetActiveAdmin() throws RemoteException { 102 parseArgs(true); 103 mDevicePolicyManager.setActiveAdmin(mComponent, true /*refreshing*/, mUserId); 104 105 System.out.println("Success: Active admin set to component " + mComponent.toShortString()); 106 } 107 runSetDeviceOwner()108 private void runSetDeviceOwner() throws RemoteException { 109 ComponentName component = parseComponentName(nextArgRequired()); 110 mDevicePolicyManager.setActiveAdmin(component, true /*refreshing*/, UserHandle.USER_OWNER); 111 112 String packageName = component.getPackageName(); 113 try { 114 if (!mDevicePolicyManager.setDeviceOwner(packageName, null /*ownerName*/)) { 115 throw new RuntimeException( 116 "Can't set package " + packageName + " as device owner."); 117 } 118 } catch (Exception e) { 119 // Need to remove the admin that we just added. 120 mDevicePolicyManager.removeActiveAdmin(component, UserHandle.USER_OWNER); 121 throw e; 122 } 123 System.out.println("Success: Device owner set to package " + packageName); 124 System.out.println("Active admin set to component " + component.toShortString()); 125 } 126 runSetProfileOwner()127 private void runSetProfileOwner() throws RemoteException { 128 // To be refactored later to use parseArgs(boolean). Currently in use by existing tests. 129 ComponentName component = parseComponentName(nextArgRequired()); 130 int userId = parseInt(nextArgRequired()); 131 mDevicePolicyManager.setActiveAdmin(component, true /*refreshing*/, userId); 132 133 try { 134 if (!mDevicePolicyManager.setProfileOwner(component, "" /*ownerName*/, userId)) { 135 throw new RuntimeException("Can't set component " + component.toShortString() + 136 " as profile owner for user " + userId); 137 } 138 } catch (Exception e) { 139 // Need to remove the admin that we just added. 140 mDevicePolicyManager.removeActiveAdmin(component, userId); 141 throw e; 142 } 143 System.out.println("Success: Active admin and profile owner set to " 144 + component.toShortString() + " for user " + userId); 145 } 146 parseComponentName(String component)147 private ComponentName parseComponentName(String component) { 148 ComponentName cn = ComponentName.unflattenFromString(component); 149 if (cn == null) { 150 throw new IllegalArgumentException ("Invalid component " + component); 151 } 152 return cn; 153 } 154 parseInt(String argument)155 private int parseInt(String argument) { 156 try { 157 return Integer.parseInt(argument); 158 } catch (NumberFormatException e) { 159 throw new IllegalArgumentException ("Invalid integer argument '" + argument + "'", e); 160 } 161 } 162 }