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.ActivityManager; 20 import android.app.IActivityManager; 21 import android.app.admin.DevicePolicyManager; 22 import android.app.admin.IDevicePolicyManager; 23 import android.content.ComponentName; 24 import android.content.Context; 25 import android.os.RemoteException; 26 import android.os.ServiceManager; 27 import android.os.UserHandle; 28 29 import com.android.internal.os.BaseCommand; 30 31 import java.io.PrintStream; 32 33 public final class Dpm extends BaseCommand { 34 35 /** 36 * Command-line entry point. 37 * 38 * @param args The command-line arguments 39 */ 40 public static void main(String[] args) { 41 (new Dpm()).run(args); 42 } 43 44 private static final String COMMAND_SET_ACTIVE_ADMIN = "set-active-admin"; 45 private static final String COMMAND_SET_DEVICE_OWNER = "set-device-owner"; 46 private static final String COMMAND_SET_PROFILE_OWNER = "set-profile-owner"; 47 private static final String COMMAND_REMOVE_ACTIVE_ADMIN = "remove-active-admin"; 48 private static final String COMMAND_CLEAR_FREEZE_PERIOD_RECORD = "clear-freeze-period-record"; 49 private static final String COMMAND_FORCE_NETWORK_LOGS = "force-network-logs"; 50 private static final String COMMAND_FORCE_SECURITY_LOGS = "force-security-logs"; 51 private static final String COMMAND_GRANT_PO_DEVICE_ID_ACCESS = 52 "grant-profile-owner-device-ids-access"; 53 54 private IDevicePolicyManager mDevicePolicyManager; 55 private int mUserId = UserHandle.USER_SYSTEM; 56 private String mName = ""; 57 private ComponentName mComponent = null; 58 59 @Override 60 public void onShowUsage(PrintStream out) { 61 out.println( 62 "usage: dpm [subcommand] [options]\n" + 63 "usage: dpm set-active-admin [ --user <USER_ID> | current ] <COMPONENT>\n" + 64 // STOPSHIP Finalize it 65 "usage: dpm set-device-owner [ --user <USER_ID> | current *EXPERIMENTAL* ] " + 66 "[ --name <NAME> ] <COMPONENT>\n" + 67 "usage: dpm set-profile-owner [ --user <USER_ID> | current ] [ --name <NAME> ] " + 68 "<COMPONENT>\n" + 69 "usage: dpm remove-active-admin [ --user <USER_ID> | current ] [ --name <NAME> ] " + 70 "<COMPONENT>\n" + 71 "\n" + 72 "dpm set-active-admin: Sets the given component as active admin" + 73 " for an existing user.\n" + 74 "\n" + 75 "dpm set-device-owner: Sets the given component as active admin, and its" + 76 " package as device owner.\n" + 77 "\n" + 78 "dpm set-profile-owner: Sets the given component as active admin and profile" + 79 " owner for an existing user.\n" + 80 "\n" + 81 "dpm remove-active-admin: Disables an active admin, the admin must have declared" + 82 " android:testOnly in the application in its manifest. This will also remove" + 83 " device and profile owners.\n" + 84 "\n" + 85 "dpm " + COMMAND_CLEAR_FREEZE_PERIOD_RECORD + ": clears framework-maintained " + 86 "record of past freeze periods that the device went through. For use during " + 87 "feature development to prevent triggering restriction on setting freeze " + 88 "periods.\n" + 89 "\n" + 90 "dpm " + COMMAND_FORCE_NETWORK_LOGS + ": makes all network logs available to " + 91 "the DPC and triggers DeviceAdminReceiver.onNetworkLogsAvailable() if needed.\n" + 92 "\n" + 93 "dpm " + COMMAND_FORCE_SECURITY_LOGS + ": makes all security logs available to " + 94 "the DPC and triggers DeviceAdminReceiver.onSecurityLogsAvailable() if needed." 95 + "\n" 96 + "usage: dpm " + COMMAND_GRANT_PO_DEVICE_ID_ACCESS + ": " 97 + "[ --user <USER_ID> | current ] <COMPONENT>\n"); 98 } 99 100 @Override 101 public void onRun() throws Exception { 102 mDevicePolicyManager = IDevicePolicyManager.Stub.asInterface( 103 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE)); 104 if (mDevicePolicyManager == null) { 105 showError("Error: Could not access the Device Policy Manager. Is the system running?"); 106 return; 107 } 108 109 String command = nextArgRequired(); 110 switch (command) { 111 case COMMAND_SET_ACTIVE_ADMIN: 112 runSetActiveAdmin(); 113 break; 114 case COMMAND_SET_DEVICE_OWNER: 115 runSetDeviceOwner(); 116 break; 117 case COMMAND_SET_PROFILE_OWNER: 118 runSetProfileOwner(); 119 break; 120 case COMMAND_REMOVE_ACTIVE_ADMIN: 121 runRemoveActiveAdmin(); 122 break; 123 case COMMAND_CLEAR_FREEZE_PERIOD_RECORD: 124 runClearFreezePeriodRecord(); 125 break; 126 case COMMAND_FORCE_NETWORK_LOGS: 127 runForceNetworkLogs(); 128 break; 129 case COMMAND_FORCE_SECURITY_LOGS: 130 runForceSecurityLogs(); 131 break; 132 case COMMAND_GRANT_PO_DEVICE_ID_ACCESS: 133 runGrantProfileOwnerDeviceIdsAccess(); 134 break; 135 default: 136 throw new IllegalArgumentException ("unknown command '" + command + "'"); 137 } 138 } 139 140 private void runForceNetworkLogs() throws RemoteException, InterruptedException { 141 while (true) { 142 final long toWait = mDevicePolicyManager.forceNetworkLogs(); 143 if (toWait == 0) { 144 break; 145 } 146 System.out.println("We have to wait for " + toWait + " milliseconds..."); 147 Thread.sleep(toWait); 148 } 149 System.out.println("Success"); 150 } 151 152 private void runForceSecurityLogs() throws RemoteException, InterruptedException { 153 while (true) { 154 final long toWait = mDevicePolicyManager.forceSecurityLogs(); 155 if (toWait == 0) { 156 break; 157 } 158 System.out.println("We have to wait for " + toWait + " milliseconds..."); 159 Thread.sleep(toWait); 160 } 161 System.out.println("Success"); 162 } 163 164 private void parseArgs(boolean canHaveName) { 165 String opt; 166 while ((opt = nextOption()) != null) { 167 if ("--user".equals(opt)) { 168 String arg = nextArgRequired(); 169 if ("current".equals(arg) || "cur".equals(arg)) { 170 mUserId = UserHandle.USER_CURRENT; 171 } else { 172 mUserId = parseInt(arg); 173 } 174 if (mUserId == UserHandle.USER_CURRENT) { 175 IActivityManager activityManager = ActivityManager.getService(); 176 try { 177 mUserId = activityManager.getCurrentUser().id; 178 } catch (RemoteException e) { 179 e.rethrowAsRuntimeException(); 180 } 181 } 182 } else if (canHaveName && "--name".equals(opt)) { 183 mName = nextArgRequired(); 184 } else { 185 throw new IllegalArgumentException("Unknown option: " + opt); 186 } 187 } 188 mComponent = parseComponentName(nextArgRequired()); 189 } 190 191 private void runSetActiveAdmin() throws RemoteException { 192 parseArgs(/*canHaveName=*/ false); 193 mDevicePolicyManager.setActiveAdmin(mComponent, true /*refreshing*/, mUserId); 194 195 System.out.println("Success: Active admin set to component " + mComponent.toShortString()); 196 } 197 198 private void runSetDeviceOwner() throws RemoteException { 199 parseArgs(/*canHaveName=*/ true); 200 mDevicePolicyManager.setActiveAdmin(mComponent, true /*refreshing*/, mUserId); 201 202 try { 203 if (!mDevicePolicyManager.setDeviceOwner(mComponent, mName, mUserId)) { 204 throw new RuntimeException( 205 "Can't set package " + mComponent + " as device owner."); 206 } 207 } catch (Exception e) { 208 // Need to remove the admin that we just added. 209 mDevicePolicyManager.removeActiveAdmin(mComponent, UserHandle.USER_SYSTEM); 210 throw e; 211 } 212 213 mDevicePolicyManager.setUserProvisioningState( 214 DevicePolicyManager.STATE_USER_SETUP_FINALIZED, mUserId); 215 216 System.out.println("Success: Device owner set to package " + mComponent); 217 System.out.println("Active admin set to component " + mComponent.toShortString()); 218 } 219 220 private void runRemoveActiveAdmin() throws RemoteException { 221 parseArgs(/*canHaveName=*/ false); 222 mDevicePolicyManager.forceRemoveActiveAdmin(mComponent, mUserId); 223 System.out.println("Success: Admin removed " + mComponent); 224 } 225 226 private void runSetProfileOwner() throws RemoteException { 227 parseArgs(/*canHaveName=*/ true); 228 mDevicePolicyManager.setActiveAdmin(mComponent, true /*refreshing*/, mUserId); 229 230 try { 231 if (!mDevicePolicyManager.setProfileOwner(mComponent, mName, mUserId)) { 232 throw new RuntimeException("Can't set component " + mComponent.toShortString() + 233 " as profile owner for user " + mUserId); 234 } 235 } catch (Exception e) { 236 // Need to remove the admin that we just added. 237 mDevicePolicyManager.removeActiveAdmin(mComponent, mUserId); 238 throw e; 239 } 240 241 mDevicePolicyManager.setUserProvisioningState( 242 DevicePolicyManager.STATE_USER_SETUP_FINALIZED, mUserId); 243 244 System.out.println("Success: Active admin and profile owner set to " 245 + mComponent.toShortString() + " for user " + mUserId); 246 } 247 248 private void runClearFreezePeriodRecord() throws RemoteException { 249 mDevicePolicyManager.clearSystemUpdatePolicyFreezePeriodRecord(); 250 System.out.println("Success"); 251 } 252 253 254 private void runGrantProfileOwnerDeviceIdsAccess() throws RemoteException { 255 parseArgs(/*canHaveName=*/ false); 256 mDevicePolicyManager.grantDeviceIdsAccessToProfileOwner(mComponent, mUserId); 257 System.out.println("Success"); 258 } 259 260 private ComponentName parseComponentName(String component) { 261 ComponentName cn = ComponentName.unflattenFromString(component); 262 if (cn == null) { 263 throw new IllegalArgumentException ("Invalid component " + component); 264 } 265 return cn; 266 } 267 268 private int parseInt(String argument) { 269 try { 270 return Integer.parseInt(argument); 271 } catch (NumberFormatException e) { 272 throw new IllegalArgumentException ("Invalid integer argument '" + argument + "'", e); 273 } 274 } 275 } 276