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