summaryrefslogtreecommitdiffstats
path: root/cmds/am
diff options
context:
space:
mode:
Diffstat (limited to 'cmds/am')
-rw-r--r--cmds/am/Android.mk17
-rw-r--r--cmds/am/src/com/android/commands/am/Am.java143
2 files changed, 159 insertions, 1 deletions
diff --git a/cmds/am/Android.mk b/cmds/am/Android.mk
index 170849d..8b321b3 100644
--- a/cmds/am/Android.mk
+++ b/cmds/am/Android.mk
@@ -12,3 +12,20 @@ ALL_PREBUILT += $(TARGET_OUT)/bin/am
$(TARGET_OUT)/bin/am : $(LOCAL_PATH)/am | $(ACP)
$(transform-prebuilt-to-target)
+NOTICE_FILE := NOTICE
+files_noticed := bin/am
+
+# Generate rules for a single file. The argument is the file path relative to
+# the installation root
+define make-notice-file
+
+$(TARGET_OUT_NOTICE_FILES)/src/$(1).txt: $(LOCAL_PATH)/$(NOTICE_FILE)
+ @echo Notice file: $$< -- $$@
+ @mkdir -p $$(dir $$@)
+ @cat $$< >> $$@
+
+$(TARGET_OUT_NOTICE_FILES)/hash-timestamp: $(TARGET_OUT_NOTICE_FILES)/src/$(1).txt
+
+endef
+
+$(foreach file,$(files_noticed),$(eval $(call make-notice-file,$(file))))
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index f2aa91f..38cacdd 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -18,12 +18,14 @@
package com.android.commands.am;
+import android.app.ActivityManager;
import android.app.ActivityManagerNative;
import android.app.IActivityController;
import android.app.IActivityManager;
import android.app.IInstrumentationWatcher;
import android.app.Instrumentation;
import android.content.ComponentName;
+import android.content.Context;
import android.content.IIntentReceiver;
import android.content.Intent;
import android.net.Uri;
@@ -102,8 +104,14 @@ public class Am {
sendBroadcast();
} else if (op.equals("profile")) {
runProfile();
+ } else if (op.equals("dumpheap")) {
+ runDumpHeap();
} else if (op.equals("monitor")) {
runMonitor();
+ } else if (op.equals("screen-compat")) {
+ runScreenCompat();
+ } else if (op.equals("display-size")) {
+ runDisplaySize();
} else {
throw new IllegalArgumentException("Unknown command: " + op);
}
@@ -146,6 +154,31 @@ public class Am {
String value = nextArgRequired();
intent.putExtra(key, Integer.valueOf(value));
hasIntentInfo = true;
+ } else if (opt.equals("--eia")) {
+ String key = nextArgRequired();
+ String value = nextArgRequired();
+ String[] strings = value.split(",");
+ int[] list = new int[strings.length];
+ for (int i = 0; i < strings.length; i++) {
+ list[i] = Integer.valueOf(strings[i]);
+ }
+ intent.putExtra(key, list);
+ hasIntentInfo = true;
+ } else if (opt.equals("--el")) {
+ String key = nextArgRequired();
+ String value = nextArgRequired();
+ intent.putExtra(key, Long.valueOf(value));
+ hasIntentInfo = true;
+ } else if (opt.equals("--ela")) {
+ String key = nextArgRequired();
+ String value = nextArgRequired();
+ String[] strings = value.split(",");
+ long[] list = new long[strings.length];
+ for (int i = 0; i < strings.length; i++) {
+ list[i] = Long.valueOf(strings[i]);
+ }
+ intent.putExtra(key, list);
+ hasIntentInfo = true;
} else if (opt.equals("--ez")) {
String key = nextArgRequired();
String value = nextArgRequired();
@@ -430,6 +463,28 @@ public class Am {
}
}
+ private void runDumpHeap() throws Exception {
+ boolean managed = !"-n".equals(nextOption());
+ String process = nextArgRequired();
+ String heapFile = nextArgRequired();
+ ParcelFileDescriptor fd = null;
+
+ try {
+ fd = ParcelFileDescriptor.open(
+ new File(heapFile),
+ ParcelFileDescriptor.MODE_CREATE |
+ ParcelFileDescriptor.MODE_TRUNCATE |
+ ParcelFileDescriptor.MODE_READ_WRITE);
+ } catch (FileNotFoundException e) {
+ System.err.println("Error: Unable to open file: " + heapFile);
+ return;
+ }
+
+ if (!mAm.dumpHeap(process, managed, heapFile, fd)) {
+ throw new AndroidException("HEAP DUMP FAILED on process " + process);
+ }
+ }
+
class MyActivityController extends IActivityController.Stub {
final String mGdbPort;
@@ -727,6 +782,78 @@ public class Am {
controller.run();
}
+ private void runScreenCompat() throws Exception {
+ String mode = nextArgRequired();
+ boolean enabled;
+ if ("on".equals(mode)) {
+ enabled = true;
+ } else if ("off".equals(mode)) {
+ enabled = false;
+ } else {
+ System.err.println("Error: enabled mode must be 'on' or 'off' at " + mode);
+ showUsage();
+ return;
+ }
+
+ String packageName = nextArgRequired();
+ do {
+ try {
+ mAm.setPackageScreenCompatMode(packageName, enabled
+ ? ActivityManager.COMPAT_MODE_ENABLED
+ : ActivityManager.COMPAT_MODE_DISABLED);
+ } catch (RemoteException e) {
+ }
+ packageName = nextArg();
+ } while (packageName != null);
+ }
+
+ private void runDisplaySize() throws Exception {
+ String size = nextArgRequired();
+ int m, n;
+ if ("reset".equals(size)) {
+ m = n = -1;
+ } else {
+ int div = size.indexOf('x');
+ if (div <= 0 || div >= (size.length()-1)) {
+ System.err.println("Error: bad size " + size);
+ showUsage();
+ return;
+ }
+ String mstr = size.substring(0, div);
+ String nstr = size.substring(div+1);
+ try {
+ m = Integer.parseInt(mstr);
+ n = Integer.parseInt(nstr);
+ } catch (NumberFormatException e) {
+ System.err.println("Error: bad number " + e);
+ showUsage();
+ return;
+ }
+ }
+
+ if (m < n) {
+ int tmp = m;
+ m = n;
+ n = tmp;
+ }
+
+ IWindowManager wm = IWindowManager.Stub.asInterface(ServiceManager.checkService(
+ Context.WINDOW_SERVICE));
+ if (wm == null) {
+ System.err.println(NO_SYSTEM_ERROR_CODE);
+ throw new AndroidException("Can't connect to window manager; is the system running?");
+ }
+
+ try {
+ if (m >= 0 && n >= 0) {
+ wm.setForcedDisplaySize(m, n);
+ } else {
+ wm.clearForcedDisplaySize();
+ }
+ } catch (RemoteException e) {
+ }
+ }
+
private class IntentReceiver extends IIntentReceiver.Stub {
private boolean mFinished = false;
@@ -894,19 +1021,33 @@ public class Am {
" -p <FILE>: write profiling data to <FILE>\n" +
" -w: wait for instrumentation to finish before returning\n" +
"\n" +
+ " run a test package against an application: am instrument [flags] <TEST_PACKAGE>/<RUNNER_CLASS>\n" +
+ " -e <testrunner_flag> <testrunner_value> [,<testrunner_value>]\n" +
+ " -w wait for the test to finish (required)\n" +
+ " -r use with -e perf true to generate raw output for performance measurements\n" +
+ "\n" +
" start profiling: am profile <PROCESS> start <FILE>\n" +
" stop profiling: am profile <PROCESS> stop\n" +
+ " dump heap: am dumpheap [flags] <PROCESS> <FILE>\n" +
+ " -n: dump native heap instead of managed heap\n" +
"\n" +
" start monitoring: am monitor [--gdb <port>]\n" +
" --gdb: start gdbserv on the given port at crash/ANR\n" +
"\n" +
+ " control screen compatibility: am screen-compat [on|off] [package]\n" +
+ "\n" +
+ " override display size: am display-size [reset|MxN]\n" +
+ "\n" +
" <INTENT> specifications include these flags:\n" +
" [-a <ACTION>] [-d <DATA_URI>] [-t <MIME_TYPE>]\n" +
" [-c <CATEGORY> [-c <CATEGORY>] ...]\n" +
" [-e|--es <EXTRA_KEY> <EXTRA_STRING_VALUE> ...]\n" +
" [--esn <EXTRA_KEY> ...]\n" +
" [--ez <EXTRA_KEY> <EXTRA_BOOLEAN_VALUE> ...]\n" +
- " [-e|--ei <EXTRA_KEY> <EXTRA_INT_VALUE> ...]\n" +
+ " [--ei <EXTRA_KEY> <EXTRA_INT_VALUE> ...]\n" +
+ " [--el <EXTRA_KEY> <EXTRA_LONG_VALUE> ...]\n" +
+ " [--eia <EXTRA_KEY> <EXTRA_INT_VALUE>[,<EXTRA_INT_VALUE...]]\n" +
+ " [--ela <EXTRA_KEY> <EXTRA_LONG_VALUE>[,<EXTRA_LONG_VALUE...]]\n" +
" [-n <COMPONENT>] [-f <FLAGS>]\n" +
" [--grant-read-uri-permission] [--grant-write-uri-permission]\n" +
" [--debug-log-resolution]\n" +