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 */ main(String[] args)49 public static void main(String[] args) { 50 (new Am()).run(args); 51 } 52 53 @Override onShowUsage(PrintStream out)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 onRun()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 parseUserArg(String arg)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 onOpenFile(String path, String seLinuxContext, String mode)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 runAmCmd(String[] args)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 runInstrument()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("--no-test-api-access")) { 178 instrument.disableTestApiChecks = false; 179 } else if (opt.equals("--no-isolated-storage")) { 180 instrument.disableIsolatedStorage = true; 181 } else if (opt.equals("--user")) { 182 instrument.userId = parseUserArg(nextArgRequired()); 183 } else if (opt.equals("--abi")) { 184 instrument.abi = nextArgRequired(); 185 } else if (opt.equals("--no-restart")) { 186 instrument.noRestart = true; 187 } else { 188 System.err.println("Error: Unknown option: " + opt); 189 return; 190 } 191 } 192 193 if (instrument.userId == UserHandle.USER_ALL) { 194 System.err.println("Error: Can't start instrumentation with user 'all'"); 195 return; 196 } 197 198 instrument.componentNameArg = nextArgRequired(); 199 instrument.run(); 200 } 201 } 202