diff options
Diffstat (limited to 'cmds/am')
-rw-r--r-- | cmds/am/Android.mk | 17 | ||||
-rw-r--r-- | cmds/am/src/com/android/commands/am/Am.java | 143 |
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" + |