1b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera/* 2b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera * Copyright (C) 2014 The Android Open Source Project 3b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera * 4b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera * Licensed under the Apache License, Version 2.0 (the "License"); 5b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera * you may not use this file except in compliance with the License. 6b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera * You may obtain a copy of the License at 7b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera * 8b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera * http://www.apache.org/licenses/LICENSE-2.0 9b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera * 10b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera * Unless required by applicable law or agreed to in writing, software 11b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera * distributed under the License is distributed on an "AS IS" BASIS, 12b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera * See the License for the specific language governing permissions and 14b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera * limitations under the License. 15b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera */ 16b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera 17b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talaverapackage com.android.commands.dpm; 18b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera 19b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talaveraimport android.app.admin.IDevicePolicyManager; 209c17388cff98fba9679ce6457ac5003a660c6013Esteban Talaveraimport android.content.ComponentName; 21b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talaveraimport android.content.Context; 22b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talaveraimport android.os.RemoteException; 23b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talaveraimport android.os.ServiceManager; 249c17388cff98fba9679ce6457ac5003a660c6013Esteban Talaveraimport android.os.UserHandle; 25b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera 26b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talaveraimport com.android.internal.os.BaseCommand; 27b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera 28b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talaveraimport java.io.PrintStream; 29b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera 30b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talaverapublic final class Dpm extends BaseCommand { 31b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera 32b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera /** 33b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera * Command-line entry point. 34b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera * 35b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera * @param args The command-line arguments 36b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera */ 37b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera public static void main(String[] args) { 38b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera (new Dpm()).run(args); 39b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera } 40b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera 41e9119876a21575ee7a7d058da85d04c4c4b8a971Zoltan Szatmary-Ban private static final String COMMAND_SET_ACTIVE_ADMIN = "set-active-admin"; 42b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera private static final String COMMAND_SET_DEVICE_OWNER = "set-device-owner"; 4341de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera private static final String COMMAND_SET_PROFILE_OWNER = "set-profile-owner"; 44b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera 45b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera private IDevicePolicyManager mDevicePolicyManager; 46e9119876a21575ee7a7d058da85d04c4c4b8a971Zoltan Szatmary-Ban private int mUserId = UserHandle.USER_OWNER; 47e9119876a21575ee7a7d058da85d04c4c4b8a971Zoltan Szatmary-Ban private ComponentName mComponent = null; 48b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera 49b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera @Override 50b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera public void onShowUsage(PrintStream out) { 519c17388cff98fba9679ce6457ac5003a660c6013Esteban Talavera out.println( 529c17388cff98fba9679ce6457ac5003a660c6013Esteban Talavera "usage: dpm [subcommand] [options]\n" + 53e9119876a21575ee7a7d058da85d04c4c4b8a971Zoltan Szatmary-Ban "usage: dpm set-active-admin [ --user <USER_ID> ] <COMPONENT>\n" + 549c17388cff98fba9679ce6457ac5003a660c6013Esteban Talavera "usage: dpm set-device-owner <COMPONENT>\n" + 5541de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera "usage: dpm set-profile-owner <COMPONENT> <USER_ID>\n" + 56b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera "\n" + 57e9119876a21575ee7a7d058da85d04c4c4b8a971Zoltan Szatmary-Ban "dpm set-active-admin: Sets the given component as active admin" + 58e9119876a21575ee7a7d058da85d04c4c4b8a971Zoltan Szatmary-Ban " for an existing user.\n" + 59e9119876a21575ee7a7d058da85d04c4c4b8a971Zoltan Szatmary-Ban "\n" + 609c17388cff98fba9679ce6457ac5003a660c6013Esteban Talavera "dpm set-device-owner: Sets the given component as active admin, and its\n" + 6141de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera " package as device owner.\n" + 6241de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera "\n" + 6341de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera "dpm set-profile-owner: Sets the given component as active admin and profile" + 6441de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera " owner for an existing user.\n"); 65b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera } 66b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera 67b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera @Override 68b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera public void onRun() throws Exception { 69b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera mDevicePolicyManager = IDevicePolicyManager.Stub.asInterface( 70b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera ServiceManager.getService(Context.DEVICE_POLICY_SERVICE)); 71b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera if (mDevicePolicyManager == null) { 72b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera showError("Error: Could not access the Device Policy Manager. Is the system running?"); 73b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera return; 74b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera } 75b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera 76b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera String command = nextArgRequired(); 77b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera switch (command) { 78e9119876a21575ee7a7d058da85d04c4c4b8a971Zoltan Szatmary-Ban case COMMAND_SET_ACTIVE_ADMIN: 79e9119876a21575ee7a7d058da85d04c4c4b8a971Zoltan Szatmary-Ban runSetActiveAdmin(); 80e9119876a21575ee7a7d058da85d04c4c4b8a971Zoltan Szatmary-Ban break; 81b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera case COMMAND_SET_DEVICE_OWNER: 8241de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera runSetDeviceOwner(); 8341de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera break; 8441de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera case COMMAND_SET_PROFILE_OWNER: 8541de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera runSetProfileOwner(); 86b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera break; 87b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera default: 889c17388cff98fba9679ce6457ac5003a660c6013Esteban Talavera throw new IllegalArgumentException ("unknown command '" + command + "'"); 89b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera } 90b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera } 91b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera 92e9119876a21575ee7a7d058da85d04c4c4b8a971Zoltan Szatmary-Ban private void parseArgs(boolean canHaveUser) { 93e9119876a21575ee7a7d058da85d04c4c4b8a971Zoltan Szatmary-Ban String nextArg = nextArgRequired(); 94e9119876a21575ee7a7d058da85d04c4c4b8a971Zoltan Szatmary-Ban if (canHaveUser && "--user".equals(nextArg)) { 95e9119876a21575ee7a7d058da85d04c4c4b8a971Zoltan Szatmary-Ban mUserId = parseInt(nextArgRequired()); 96e9119876a21575ee7a7d058da85d04c4c4b8a971Zoltan Szatmary-Ban nextArg = nextArgRequired(); 97e9119876a21575ee7a7d058da85d04c4c4b8a971Zoltan Szatmary-Ban } 98e9119876a21575ee7a7d058da85d04c4c4b8a971Zoltan Szatmary-Ban mComponent = parseComponentName(nextArg); 99e9119876a21575ee7a7d058da85d04c4c4b8a971Zoltan Szatmary-Ban } 100e9119876a21575ee7a7d058da85d04c4c4b8a971Zoltan Szatmary-Ban 101e9119876a21575ee7a7d058da85d04c4c4b8a971Zoltan Szatmary-Ban private void runSetActiveAdmin() throws RemoteException { 102e9119876a21575ee7a7d058da85d04c4c4b8a971Zoltan Szatmary-Ban parseArgs(true); 103e9119876a21575ee7a7d058da85d04c4c4b8a971Zoltan Szatmary-Ban mDevicePolicyManager.setActiveAdmin(mComponent, true /*refreshing*/, mUserId); 104e9119876a21575ee7a7d058da85d04c4c4b8a971Zoltan Szatmary-Ban 105e9119876a21575ee7a7d058da85d04c4c4b8a971Zoltan Szatmary-Ban System.out.println("Success: Active admin set to component " + mComponent.toShortString()); 106e9119876a21575ee7a7d058da85d04c4c4b8a971Zoltan Szatmary-Ban } 107e9119876a21575ee7a7d058da85d04c4c4b8a971Zoltan Szatmary-Ban 10841de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera private void runSetDeviceOwner() throws RemoteException { 10941de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera ComponentName component = parseComponentName(nextArgRequired()); 11041de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera mDevicePolicyManager.setActiveAdmin(component, true /*refreshing*/, UserHandle.USER_OWNER); 1119c17388cff98fba9679ce6457ac5003a660c6013Esteban Talavera 1129c17388cff98fba9679ce6457ac5003a660c6013Esteban Talavera String packageName = component.getPackageName(); 1139c17388cff98fba9679ce6457ac5003a660c6013Esteban Talavera try { 11441de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera if (!mDevicePolicyManager.setDeviceOwner(packageName, null /*ownerName*/)) { 11541de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera throw new RuntimeException( 11641de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera "Can't set package " + packageName + " as device owner."); 1179c17388cff98fba9679ce6457ac5003a660c6013Esteban Talavera } 1189c17388cff98fba9679ce6457ac5003a660c6013Esteban Talavera } catch (Exception e) { 1199c17388cff98fba9679ce6457ac5003a660c6013Esteban Talavera // Need to remove the admin that we just added. 1209c17388cff98fba9679ce6457ac5003a660c6013Esteban Talavera mDevicePolicyManager.removeActiveAdmin(component, UserHandle.USER_OWNER); 1219c17388cff98fba9679ce6457ac5003a660c6013Esteban Talavera throw e; 1229c17388cff98fba9679ce6457ac5003a660c6013Esteban Talavera } 123c48bca50fa64765d3019b0bf82511e030cabcc7aEsteban Talavera System.out.println("Success: Device owner set to package " + packageName); 1249c17388cff98fba9679ce6457ac5003a660c6013Esteban Talavera System.out.println("Active admin set to component " + component.toShortString()); 125b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera } 12641de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera 12741de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera private void runSetProfileOwner() throws RemoteException { 128e9119876a21575ee7a7d058da85d04c4c4b8a971Zoltan Szatmary-Ban // To be refactored later to use parseArgs(boolean). Currently in use by existing tests. 12941de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera ComponentName component = parseComponentName(nextArgRequired()); 13041de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera int userId = parseInt(nextArgRequired()); 13141de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera mDevicePolicyManager.setActiveAdmin(component, true /*refreshing*/, userId); 13241de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera 13341de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera try { 13441de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera if (!mDevicePolicyManager.setProfileOwner(component, "" /*ownerName*/, userId)) { 13541de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera throw new RuntimeException("Can't set component " + component.toShortString() + 13641de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera " as profile owner for user " + userId); 13741de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera } 13841de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera } catch (Exception e) { 13941de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera // Need to remove the admin that we just added. 14041de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera mDevicePolicyManager.removeActiveAdmin(component, userId); 14141de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera throw e; 14241de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera } 143c48bca50fa64765d3019b0bf82511e030cabcc7aEsteban Talavera System.out.println("Success: Active admin and profile owner set to " 144c48bca50fa64765d3019b0bf82511e030cabcc7aEsteban Talavera + component.toShortString() + " for user " + userId); 14541de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera } 14641de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera 14741de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera private ComponentName parseComponentName(String component) { 14841de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera ComponentName cn = ComponentName.unflattenFromString(component); 14941de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera if (cn == null) { 15041de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera throw new IllegalArgumentException ("Invalid component " + component); 15141de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera } 15241de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera return cn; 15341de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera } 15441de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera 15541de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera private int parseInt(String argument) { 15641de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera try { 15741de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera return Integer.parseInt(argument); 15841de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera } catch (NumberFormatException e) { 15941de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera throw new IllegalArgumentException ("Invalid integer argument '" + argument + "'", e); 16041de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera } 16141de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera } 162b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera}