Home | History | Annotate | Download | only in dpm
      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