1) add the bugreport option which allow the scripted monkey to capature the bugrepor and save it to the sdcard wherenever there is a ANR, java crash and native crash.
2) Add a new option in the scripted monkey which can enter a string through the shell command input text <string>

Change-Id: Iab7478fdc594c07e5166091d29dc644e430e43cb
diff --git a/cmds/monkey/src/com/android/commands/monkey/Monkey.java b/cmds/monkey/src/com/android/commands/monkey/Monkey.java
index 47c9cd8..68c9411 100644
--- a/cmds/monkey/src/com/android/commands/monkey/Monkey.java
+++ b/cmds/monkey/src/com/android/commands/monkey/Monkey.java
@@ -125,6 +125,21 @@
     private boolean mRequestDumpsysMemInfo = false;
 
     /**
+     * This is set by the ActivityController thread to request a
+     * bugreport after ANR
+     */
+    private boolean mRequestAnrBugreport = false;
+
+    /**
+     * This is set by the ActivityController thread to request a
+     * bugreport after java application crash
+     */
+    private boolean mRequestAppCrashBugreport = false;
+
+    /** Failure process name */
+    private String mReportProcessName;
+
+    /**
      * This is set by the ActivityController thread to request a "procrank"
      */
     private boolean mRequestProcRank = false;
@@ -187,6 +202,9 @@
 
     boolean mScriptLog = false;
 
+    /** Capture bugreprot whenever there is a crash. **/
+    private boolean mRequestBugreport = false;
+
     /** a filename to the setup script (if any) */
     private String mSetupFileName = null;
 
@@ -281,11 +299,16 @@
             System.err.println("// " + stackTrace.replace("\n", "\n// "));
             StrictMode.setThreadPolicy(savedPolicy);
 
-            if (!mIgnoreCrashes) {
+            if (!mIgnoreCrashes || mRequestBugreport) {
                 synchronized (Monkey.this) {
-                    mAbort = true;
+                    if (!mIgnoreCrashes) {
+                        mAbort = true;
+                    }
+                    if (mRequestBugreport){
+                        mRequestAppCrashBugreport = true;
+                        mReportProcessName = processName;
+                    }
                 }
-
                 return !mKillProcessAfterError;
             }
             return false;
@@ -300,10 +323,15 @@
             System.err.println("// NOT RESPONDING: " + processName + " (pid " + pid + ")");
             System.err.println(processStats);
             StrictMode.setThreadPolicy(savedPolicy);
+
             synchronized (Monkey.this) {
                 mRequestAnrTraces = true;
                 mRequestDumpsysMemInfo = true;
                 mRequestProcRank = true;
+                if (mRequestBugreport){
+                  mRequestAnrBugreport = true;
+                  mReportProcessName = processName;
+                }
             }
             if (!mIgnoreTimeouts) {
                 synchronized (Monkey.this) {
@@ -359,22 +387,38 @@
     private void commandLineReport(String reportName, String command) {
         System.err.println(reportName + ":");
         Runtime rt = Runtime.getRuntime();
+        Writer logOutput = null;
+
         try {
             // Process must be fully qualified here because android.os.Process
             // is used elsewhere
             java.lang.Process p = Runtime.getRuntime().exec(command);
 
+            if (mRequestBugreport) {
+                logOutput =
+                        new BufferedWriter(new FileWriter(new File(Environment
+                                .getExternalStorageDirectory(), reportName), true));
+            }
             // pipe everything from process stdout -> System.err
             InputStream inStream = p.getInputStream();
             InputStreamReader inReader = new InputStreamReader(inStream);
             BufferedReader inBuffer = new BufferedReader(inReader);
             String s;
             while ((s = inBuffer.readLine()) != null) {
-                System.err.println(s);
+                if (mRequestBugreport) {
+                    logOutput.write(s);
+                    logOutput.write("\n");
+                } else {
+                    System.err.println(s);
+                }
             }
 
             int status = p.waitFor();
             System.err.println("// " + reportName + " status was " + status);
+
+            if (logOutput != null) {
+                logOutput.close();
+            }
         } catch (Exception e) {
             System.err.println("// Exception from " + reportName + ":");
             System.err.println(e.toString());
@@ -395,6 +439,13 @@
         }
     }
 
+    // Write the bugreport to the sdcard.
+    private void getBugreport(String reportName) {
+        reportName += MonkeyUtils.toCalendarTime(System.currentTimeMillis());
+        String bugreportName = reportName.replaceAll("[ ,:]", "_");
+        commandLineReport(bugreportName + ".txt", "bugreport");
+    }
+
     /**
      * Command-line entry point.
      *
@@ -557,6 +608,15 @@
                 reportAnrTraces();
                 mRequestAnrTraces = false;
             }
+            if (mRequestAnrBugreport){
+                System.out.println("Print the anr report");
+                getBugreport("anr_" + mReportProcessName + "_");
+                mRequestAnrBugreport = false;
+            }
+            if (mRequestAppCrashBugreport){
+                getBugreport("app_crash" + mReportProcessName + "_");
+                mRequestAnrBugreport = false;
+            }
             if (mRequestDumpsysMemInfo) {
                 reportDumpsysMemInfo();
                 mRequestDumpsysMemInfo = false;
@@ -697,9 +757,11 @@
                     mDeviceSleepTime = nextOptionLong("Device sleep time" +
                                                       "(in milliseconds)");
                 } else if (opt.equals("--randomize-script")) {
-                     mRandomizeScript = true;
+                    mRandomizeScript = true;
                 } else if (opt.equals("--script-log")) {
                     mScriptLog = true;
+                } else if (opt.equals("--bugreport")) {
+                    mRequestBugreport = true;
                 } else if (opt.equals("-h")) {
                     showUsage();
                     return false;
@@ -932,6 +994,14 @@
                     reportAnrTraces();
                     mRequestAnrTraces = false;
                 }
+                if (mRequestAnrBugreport){
+                    getBugreport("anr_" + mReportProcessName + "_");
+                    mRequestAnrBugreport = false;
+                }
+                if (mRequestAppCrashBugreport){
+                    getBugreport("app_crash" + mReportProcessName + "_");
+                    mRequestAnrBugreport = false;
+                }
                 if (mRequestDumpsysMemInfo) {
                     reportDumpsysMemInfo();
                     mRequestDumpsysMemInfo = false;
@@ -941,6 +1011,9 @@
                     // the watcher (ignore the error)
                     if (checkNativeCrashes() && (eventCounter > 0)) {
                         System.out.println("** New native crash detected.");
+                        if (mRequestBugreport) {
+                            getBugreport("native_crash_");
+                        }
                         mAbort = mAbort || !mIgnoreNativeCrashes || mKillProcessAfterError;
                     }
                 }
@@ -1177,6 +1250,7 @@
         usage.append("              [--device-sleep-time MILLISEC]\n");
         usage.append("              [--randomize-script]\n");
         usage.append("              [--script-log]\n");
+        usage.append("              [--bugreport]\n");
         usage.append("              COUNT\n");
         System.err.println(usage.toString());
     }
diff --git a/cmds/monkey/src/com/android/commands/monkey/MonkeySourceScript.java b/cmds/monkey/src/com/android/commands/monkey/MonkeySourceScript.java
index a650770..6defcb0 100644
--- a/cmds/monkey/src/com/android/commands/monkey/MonkeySourceScript.java
+++ b/cmds/monkey/src/com/android/commands/monkey/MonkeySourceScript.java
@@ -110,6 +110,8 @@
 
     private static final String EVENT_KEYWORD_DEVICE_WAKEUP = "DeviceWakeUp";
 
+    private static final String EVENT_KEYWORD_INPUT_STRING = "DispatchString";
+
     // a line at the end of the header
     private static final String STARTING_DATA_LINE = "start data >>";
 
@@ -439,6 +441,16 @@
             MonkeyCommandEvent e = new MonkeyCommandEvent(cmd);
             mQ.addLast(e);
         }
+
+        //Input the string through the shell command
+        if (s.indexOf(EVENT_KEYWORD_INPUT_STRING) >= 0 && args.length == 1) {
+            String input = args[0];
+            String cmd = "input text " + input;
+            MonkeyCommandEvent e = new MonkeyCommandEvent(cmd);
+            mQ.addLast(e);
+            return;
+        }
+
     }
 
     /**