Fix for shell uiautomator to support monkey flag

Change-Id: I95f5e7567954940464c51289344ca53d7bd7d81f
diff --git a/uiautomator/library/core-src/com/android/uiautomator/core/UiAutomatorBridge.java b/uiautomator/library/core-src/com/android/uiautomator/core/UiAutomatorBridge.java
index 59dd450..3b9887d 100644
--- a/uiautomator/library/core-src/com/android/uiautomator/core/UiAutomatorBridge.java
+++ b/uiautomator/library/core-src/com/android/uiautomator/core/UiAutomatorBridge.java
@@ -5,7 +5,6 @@
 import android.app.UiAutomation.AccessibilityEventFilter;
 import android.app.UiAutomation.OnAccessibilityEventListener;
 import android.graphics.Bitmap;
-import android.util.AndroidException;
 import android.util.Log;
 import android.view.Display;
 import android.view.InputEvent;
@@ -59,23 +58,6 @@
         return mQueryController;
     }
 
-    /**
-     * Enable or disable monkey test run mode.
-     *
-     * Setting test as "monkey" indicates to some applications that a test framework is
-     * running and specifically as a "monkey" type. Such applications may choose
-     * then not to perform actions that do submits so to avoid allowing monkey tests
-     * from doing harm or performing annoying actions such as dialing 911 or posting messages
-     * to public forums, etc.
-     *
-     * @param b True to set as monkey test. False to set as regular functional test (default).
-     * @throws AndroidException
-     */
-
-    public void setRunAsMonkey(boolean b) throws AndroidException {
-        mUiAutomation.setRunAsMonkey(b);
-    }
-
     public void setOnAccessibilityEventListener(OnAccessibilityEventListener listener) {
         mUiAutomation.setOnAccessibilityEventListener(listener);
     }
diff --git a/uiautomator/library/testrunner-src/com/android/uiautomator/core/UiAutomationShellWrapper.java b/uiautomator/library/testrunner-src/com/android/uiautomator/core/UiAutomationShellWrapper.java
index e06024f..77283cd 100644
--- a/uiautomator/library/testrunner-src/com/android/uiautomator/core/UiAutomationShellWrapper.java
+++ b/uiautomator/library/testrunner-src/com/android/uiautomator/core/UiAutomationShellWrapper.java
@@ -2,9 +2,14 @@
 
 import android.accessibilityservice.AccessibilityServiceInfo;
 import android.app.ActivityManager;
+import android.app.ActivityManagerNative;
+import android.app.IActivityController;
+import android.app.IActivityManager;
 import android.app.UiAutomation;
 import android.app.UiAutomationConnection;
+import android.content.Intent;
 import android.os.HandlerThread;
+import android.os.RemoteException;
 
 /**
  * @hide
@@ -39,7 +44,19 @@
      * @see {@link ActivityManager#isUserAMonkey()}
      */
     public void setRunAsMonkey(boolean isSet) {
-        mUiAutomation.setRunAsMonkey(isSet);
+        IActivityManager am = ActivityManagerNative.getDefault();
+        if (am == null) {
+            throw new RuntimeException("Can't manage monkey status; is the system running?");
+        }
+        try {
+            if (isSet) {
+                am.setActivityController(new DummyActivityController());
+            } else {
+                am.setActivityController(null);
+            }
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
     }
 
     public void disconnect() {
@@ -62,4 +79,42 @@
             info.flags |= AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
         mUiAutomation.setServiceInfo(info);
     }
+
+    /**
+     * Dummy, no interference, activity controller.
+     */
+    private class DummyActivityController extends IActivityController.Stub {
+        @Override
+        public boolean activityStarting(Intent intent, String pkg) throws RemoteException {
+            /* do nothing and let activity proceed normally */
+            return true;
+        }
+
+        @Override
+        public boolean activityResuming(String pkg) throws RemoteException {
+            /* do nothing and let activity proceed normally */
+            return true;
+        }
+
+        @Override
+        public boolean appCrashed(String processName, int pid, String shortMsg, String longMsg,
+                long timeMillis, String stackTrace) throws RemoteException {
+            /* do nothing and let activity proceed normally */
+            return true;
+        }
+
+        @Override
+        public int appEarlyNotResponding(String processName, int pid, String annotation)
+                throws RemoteException {
+            /* do nothing and let activity proceed normally */
+            return 0;
+        }
+
+        @Override
+        public int appNotResponding(String processName, int pid, String processStats)
+                throws RemoteException {
+            /* do nothing and let activity proceed normally */
+            return 0;
+        }
+    }
 }
diff --git a/uiautomator/library/testrunner-src/com/android/uiautomator/testrunner/UiAutomatorTestRunner.java b/uiautomator/library/testrunner-src/com/android/uiautomator/testrunner/UiAutomatorTestRunner.java
index 0fdc984..ff3ed69 100644
--- a/uiautomator/library/testrunner-src/com/android/uiautomator/testrunner/UiAutomatorTestRunner.java
+++ b/uiautomator/library/testrunner-src/com/android/uiautomator/testrunner/UiAutomatorTestRunner.java
@@ -116,37 +116,37 @@
         mHandlerThread.start();
         UiAutomationShellWrapper automationWrapper = new UiAutomationShellWrapper();
         automationWrapper.connect();
-        automationWrapper.setRunAsMonkey(mMonkey);
-        mUiDevice = UiDevice.getInstance();
-        mUiDevice.initialize(new ShellUiAutomatorBridge(automationWrapper.getUiAutomation()));
-        List<TestCase> testCases = collector.getTestCases();
-        Bundle testRunOutput = new Bundle();
 
-        String traceType = mParams.getString("traceOutputMode");
-        if(traceType != null) {
-            Tracer.Mode mode = Tracer.Mode.valueOf(Tracer.Mode.class, traceType);
-            if (mode == Tracer.Mode.FILE || mode == Tracer.Mode.ALL) {
-                String filename = mParams.getString("traceLogFilename");
-                if (filename == null) {
-                    throw new RuntimeException("Name of log file not specified. " +
-                            "Please specify it using traceLogFilename parameter");
-                }
-                Tracer.getInstance().setOutputFilename(filename);
-            }
-            Tracer.getInstance().setOutputMode(mode);
-        }
-
+        long startTime = SystemClock.uptimeMillis();
         TestResult testRunResult = new TestResult();
         ResultReporter resultPrinter;
         String outputFormat = mParams.getString("outputFormat");
+        List<TestCase> testCases = collector.getTestCases();
+        Bundle testRunOutput = new Bundle();
         if ("simple".equals(outputFormat)) {
             resultPrinter = new SimpleResultPrinter(System.out, true);
         } else {
             resultPrinter = new WatcherResultPrinter(testCases.size());
         }
-
-        long startTime = SystemClock.uptimeMillis();
         try {
+            automationWrapper.setRunAsMonkey(mMonkey);
+            mUiDevice = UiDevice.getInstance();
+            mUiDevice.initialize(new ShellUiAutomatorBridge(automationWrapper.getUiAutomation()));
+
+            String traceType = mParams.getString("traceOutputMode");
+            if(traceType != null) {
+                Tracer.Mode mode = Tracer.Mode.valueOf(Tracer.Mode.class, traceType);
+                if (mode == Tracer.Mode.FILE || mode == Tracer.Mode.ALL) {
+                    String filename = mParams.getString("traceLogFilename");
+                    if (filename == null) {
+                        throw new RuntimeException("Name of log file not specified. " +
+                                "Please specify it using traceLogFilename parameter");
+                    }
+                    Tracer.getInstance().setOutputFilename(filename);
+                }
+                Tracer.getInstance().setOutputMode(mode);
+            }
+
             // add test listeners
             testRunResult.addListener(resultPrinter);
             // add all custom listeners