Home | History | Annotate | Download | only in am
      1 /*
      2  * Copyright (C) 2007 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.am;
     18 
     19 import static android.app.ActivityManager.RESIZE_MODE_SYSTEM;
     20 import static android.app.ActivityManager.RESIZE_MODE_USER;
     21 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
     22 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
     23 
     24 import android.app.ActivityManager;
     25 import android.app.ActivityManager.StackInfo;
     26 import android.app.IActivityContainer;
     27 import android.app.IActivityController;
     28 import android.app.IActivityManager;
     29 import android.app.IInstrumentationWatcher;
     30 import android.app.Instrumentation;
     31 import android.app.IStopUserCallback;
     32 import android.app.ProfilerInfo;
     33 import android.app.UiAutomationConnection;
     34 import android.app.usage.ConfigurationStats;
     35 import android.app.usage.IUsageStatsManager;
     36 import android.app.usage.UsageStatsManager;
     37 import android.content.ComponentCallbacks2;
     38 import android.content.ComponentName;
     39 import android.content.Context;
     40 import android.content.IIntentReceiver;
     41 import android.content.Intent;
     42 import android.content.pm.IPackageManager;
     43 import android.content.pm.InstrumentationInfo;
     44 import android.content.pm.ParceledListSlice;
     45 import android.content.pm.UserInfo;
     46 import android.content.res.Configuration;
     47 import android.graphics.Rect;
     48 import android.os.Binder;
     49 import android.os.Build;
     50 import android.os.Bundle;
     51 import android.os.ParcelFileDescriptor;
     52 import android.os.RemoteException;
     53 import android.os.ResultReceiver;
     54 import android.os.SELinux;
     55 import android.os.ServiceManager;
     56 import android.os.ShellCallback;
     57 import android.os.ShellCommand;
     58 import android.os.SystemProperties;
     59 import android.os.UserHandle;
     60 import android.text.TextUtils;
     61 import android.util.AndroidException;
     62 import android.util.ArrayMap;
     63 import android.util.Log;
     64 import android.view.IWindowManager;
     65 
     66 import com.android.internal.os.BaseCommand;
     67 import com.android.internal.util.HexDump;
     68 import com.android.internal.util.Preconditions;
     69 
     70 import java.io.BufferedReader;
     71 import java.io.File;
     72 import java.io.FileDescriptor;
     73 import java.io.FileNotFoundException;
     74 import java.io.IOException;
     75 import java.io.InputStreamReader;
     76 import java.io.PrintStream;
     77 import java.io.PrintWriter;
     78 import java.net.URISyntaxException;
     79 import java.util.ArrayList;
     80 import java.util.Collections;
     81 import java.util.Comparator;
     82 import java.util.List;
     83 
     84 public class Am extends BaseCommand {
     85 
     86     private IActivityManager mAm;
     87     private IPackageManager mPm;
     88 
     89     /**
     90      * Command-line entry point.
     91      *
     92      * @param args The command-line arguments
     93      */
     94     public static void main(String[] args) {
     95         (new Am()).run(args);
     96     }
     97 
     98     @Override
     99     public void onShowUsage(PrintStream out) {
    100         try {
    101             runAmCmd(new String[] { "help" });
    102         } catch (AndroidException e) {
    103             e.printStackTrace(System.err);
    104         }
    105     }
    106 
    107     @Override
    108     public void onRun() throws Exception {
    109 
    110         mAm = ActivityManager.getService();
    111         if (mAm == null) {
    112             System.err.println(NO_SYSTEM_ERROR_CODE);
    113             throw new AndroidException("Can't connect to activity manager; is the system running?");
    114         }
    115 
    116         mPm = IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
    117         if (mPm == null) {
    118             System.err.println(NO_SYSTEM_ERROR_CODE);
    119             throw new AndroidException("Can't connect to package manager; is the system running?");
    120         }
    121 
    122         String op = nextArgRequired();
    123 
    124         if (op.equals("instrument")) {
    125             runInstrument();
    126         } else {
    127             runAmCmd(getRawArgs());
    128         }
    129     }
    130 
    131     int parseUserArg(String arg) {
    132         int userId;
    133         if ("all".equals(arg)) {
    134             userId = UserHandle.USER_ALL;
    135         } else if ("current".equals(arg) || "cur".equals(arg)) {
    136             userId = UserHandle.USER_CURRENT;
    137         } else {
    138             userId = Integer.parseInt(arg);
    139         }
    140         return userId;
    141     }
    142 
    143     static final class MyShellCallback extends ShellCallback {
    144         boolean mActive = true;
    145 
    146         @Override public ParcelFileDescriptor onOpenOutputFile(String path, String seLinuxContext) {
    147             if (!mActive) {
    148                 System.err.println("Open attempt after active for: " + path);
    149                 return null;
    150             }
    151             File file = new File(path);
    152             //System.err.println("Opening file: " + file.getAbsolutePath());
    153             //Log.i("Am", "Opening file: " + file.getAbsolutePath());
    154             final ParcelFileDescriptor fd;
    155             try {
    156                 fd = ParcelFileDescriptor.open(file,
    157                         ParcelFileDescriptor.MODE_CREATE |
    158                         ParcelFileDescriptor.MODE_TRUNCATE |
    159                         ParcelFileDescriptor.MODE_WRITE_ONLY);
    160             } catch (FileNotFoundException e) {
    161                 String msg = "Unable to open file " + path + ": " + e;
    162                 System.err.println(msg);
    163                 throw new IllegalArgumentException(msg);
    164             }
    165             if (seLinuxContext != null) {
    166                 final String tcon = SELinux.getFileContext(file.getAbsolutePath());
    167                 if (!SELinux.checkSELinuxAccess(seLinuxContext, tcon, "file", "write")) {
    168                     try {
    169                         fd.close();
    170                     } catch (IOException e) {
    171                     }
    172                     String msg = "System server has no access to file context " + tcon;
    173                     System.err.println(msg + " (from path " + file.getAbsolutePath()
    174                             + ", context " + seLinuxContext + ")");
    175                     throw new IllegalArgumentException(msg);
    176                 }
    177             }
    178             return fd;
    179         }
    180     }
    181 
    182     void runAmCmd(String[] args) throws AndroidException {
    183         final MyShellCallback cb = new MyShellCallback();
    184         try {
    185             mAm.asBinder().shellCommand(FileDescriptor.in, FileDescriptor.out, FileDescriptor.err,
    186                     args, cb, new ResultReceiver(null) { });
    187         } catch (RemoteException e) {
    188             System.err.println(NO_SYSTEM_ERROR_CODE);
    189             throw new AndroidException("Can't call activity manager; is the system running?");
    190         } finally {
    191             cb.mActive = false;
    192         }
    193     }
    194 
    195     public void runInstrument() throws Exception {
    196         Instrument instrument = new Instrument(mAm, mPm);
    197 
    198         String opt;
    199         while ((opt=nextOption()) != null) {
    200             if (opt.equals("-p")) {
    201                 instrument.profileFile = nextArgRequired();
    202             } else if (opt.equals("-w")) {
    203                 instrument.wait = true;
    204             } else if (opt.equals("-r")) {
    205                 instrument.rawMode = true;
    206             } else if (opt.equals("-m")) {
    207                 instrument.proto = true;
    208             } else if (opt.equals("-e")) {
    209                 final String argKey = nextArgRequired();
    210                 final String argValue = nextArgRequired();
    211                 instrument.args.putString(argKey, argValue);
    212             } else if (opt.equals("--no_window_animation")
    213                     || opt.equals("--no-window-animation")) {
    214                 instrument.noWindowAnimation = true;
    215             } else if (opt.equals("--user")) {
    216                 instrument.userId = parseUserArg(nextArgRequired());
    217             } else if (opt.equals("--abi")) {
    218                 instrument.abi = nextArgRequired();
    219             } else {
    220                 System.err.println("Error: Unknown option: " + opt);
    221                 return;
    222             }
    223         }
    224 
    225         if (instrument.userId == UserHandle.USER_ALL) {
    226             System.err.println("Error: Can't start instrumentation with user 'all'");
    227             return;
    228         }
    229 
    230         instrument.componentNameArg = nextArgRequired();
    231 
    232         instrument.run();
    233     }
    234 }
    235