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 android.app.ActivityManager;
     20 import android.app.IActivityManager;
     21 import android.content.pm.IPackageManager;
     22 import android.os.ParcelFileDescriptor;
     23 import android.os.RemoteException;
     24 import android.os.ResultReceiver;
     25 import android.os.SELinux;
     26 import android.os.ServiceManager;
     27 import android.os.ShellCallback;
     28 import android.os.UserHandle;
     29 import android.util.AndroidException;
     30 
     31 import com.android.internal.os.BaseCommand;
     32 
     33 import java.io.File;
     34 import java.io.FileDescriptor;
     35 import java.io.FileNotFoundException;
     36 import java.io.IOException;
     37 import java.io.PrintStream;
     38 
     39 public class Am extends BaseCommand {
     40 
     41     private IActivityManager mAm;
     42     private IPackageManager mPm;
     43 
     44     /**
     45      * Command-line entry point.
     46      *
     47      * @param args The command-line arguments
     48      */
     49     public static void main(String[] args) {
     50         (new Am()).run(args);
     51     }
     52 
     53     @Override
     54     public void onShowUsage(PrintStream out) {
     55         try {
     56             runAmCmd(new String[] { "help" });
     57         } catch (AndroidException e) {
     58             e.printStackTrace(System.err);
     59         }
     60     }
     61 
     62     @Override
     63     public void onRun() throws Exception {
     64 
     65         mAm = ActivityManager.getService();
     66         if (mAm == null) {
     67             System.err.println(NO_SYSTEM_ERROR_CODE);
     68             throw new AndroidException("Can't connect to activity manager; is the system running?");
     69         }
     70 
     71         mPm = IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
     72         if (mPm == null) {
     73             System.err.println(NO_SYSTEM_ERROR_CODE);
     74             throw new AndroidException("Can't connect to package manager; is the system running?");
     75         }
     76 
     77         String op = nextArgRequired();
     78 
     79         if (op.equals("instrument")) {
     80             runInstrument();
     81         } else {
     82             runAmCmd(getRawArgs());
     83         }
     84     }
     85 
     86     int parseUserArg(String arg) {
     87         int userId;
     88         if ("all".equals(arg)) {
     89             userId = UserHandle.USER_ALL;
     90         } else if ("current".equals(arg) || "cur".equals(arg)) {
     91             userId = UserHandle.USER_CURRENT;
     92         } else {
     93             userId = Integer.parseInt(arg);
     94         }
     95         return userId;
     96     }
     97 
     98     static final class MyShellCallback extends ShellCallback {
     99         boolean mActive = true;
    100 
    101         @Override public ParcelFileDescriptor onOpenFile(String path, String seLinuxContext,
    102                 String mode) {
    103             if (!mActive) {
    104                 System.err.println("Open attempt after active for: " + path);
    105                 return null;
    106             }
    107             File file = new File(path);
    108             //System.err.println("Opening file: " + file.getAbsolutePath());
    109             //Log.i("Am", "Opening file: " + file.getAbsolutePath());
    110             final ParcelFileDescriptor fd;
    111             try {
    112                 fd = ParcelFileDescriptor.open(file,
    113                         ParcelFileDescriptor.MODE_CREATE |
    114                         ParcelFileDescriptor.MODE_TRUNCATE |
    115                         ParcelFileDescriptor.MODE_WRITE_ONLY);
    116             } catch (FileNotFoundException e) {
    117                 String msg = "Unable to open file " + path + ": " + e;
    118                 System.err.println(msg);
    119                 throw new IllegalArgumentException(msg);
    120             }
    121             if (seLinuxContext != null) {
    122                 final String tcon = SELinux.getFileContext(file.getAbsolutePath());
    123                 if (!SELinux.checkSELinuxAccess(seLinuxContext, tcon, "file", "write")) {
    124                     try {
    125                         fd.close();
    126                     } catch (IOException e) {
    127                     }
    128                     String msg = "System server has no access to file context " + tcon;
    129                     System.err.println(msg + " (from path " + file.getAbsolutePath()
    130                             + ", context " + seLinuxContext + ")");
    131                     throw new IllegalArgumentException(msg);
    132                 }
    133             }
    134             return fd;
    135         }
    136     }
    137 
    138     void runAmCmd(String[] args) throws AndroidException {
    139         final MyShellCallback cb = new MyShellCallback();
    140         try {
    141             mAm.asBinder().shellCommand(FileDescriptor.in, FileDescriptor.out, FileDescriptor.err,
    142                     args, cb, new ResultReceiver(null) { });
    143         } catch (RemoteException e) {
    144             System.err.println(NO_SYSTEM_ERROR_CODE);
    145             throw new AndroidException("Can't call activity manager; is the system running?");
    146         } finally {
    147             cb.mActive = false;
    148         }
    149     }
    150 
    151     public void runInstrument() throws Exception {
    152         Instrument instrument = new Instrument(mAm, mPm);
    153 
    154         String opt;
    155         while ((opt=nextOption()) != null) {
    156             if (opt.equals("-p")) {
    157                 instrument.profileFile = nextArgRequired();
    158             } else if (opt.equals("-w")) {
    159                 instrument.wait = true;
    160             } else if (opt.equals("-r")) {
    161                 instrument.rawMode = true;
    162             } else if (opt.equals("-m")) {
    163                 instrument.protoStd = true;
    164             } else if (opt.equals("-f")) {
    165                 instrument.protoFile = true;
    166                 if (peekNextArg() != null && !peekNextArg().startsWith("-"))
    167                     instrument.logPath = nextArg();
    168             } else if (opt.equals("-e")) {
    169                 final String argKey = nextArgRequired();
    170                 final String argValue = nextArgRequired();
    171                 instrument.args.putString(argKey, argValue);
    172             } else if (opt.equals("--no_window_animation")
    173                     || opt.equals("--no-window-animation")) {
    174                 instrument.noWindowAnimation = true;
    175             } else if (opt.equals("--no-hidden-api-checks")) {
    176                 instrument.disableHiddenApiChecks = true;
    177             } else if (opt.equals("--user")) {
    178                 instrument.userId = parseUserArg(nextArgRequired());
    179             } else if (opt.equals("--abi")) {
    180                 instrument.abi = nextArgRequired();
    181             } else {
    182                 System.err.println("Error: Unknown option: " + opt);
    183                 return;
    184             }
    185         }
    186 
    187         if (instrument.userId == UserHandle.USER_ALL) {
    188             System.err.println("Error: Can't start instrumentation with user 'all'");
    189             return;
    190         }
    191 
    192         instrument.componentNameArg = nextArgRequired();
    193 
    194         instrument.run();
    195     }
    196 }
    197