Create way to run monkey with multiple scripts.

By giving multiple -f arguments, the monkey will randomly choose between the
scripts.  Also, add the --setup argument which will run a setup script before
starting to play the other scripts in random order.
diff --git a/cmds/monkey/src/com/android/commands/monkey/Monkey.java b/cmds/monkey/src/com/android/commands/monkey/Monkey.java
index 838f274..4310323 100644
--- a/cmds/monkey/src/com/android/commands/monkey/Monkey.java
+++ b/cmds/monkey/src/com/android/commands/monkey/Monkey.java
@@ -144,8 +144,11 @@
 
     long mDroppedFlipEvents = 0;
 
-    /** a filename to the script (if any) **/
-    private String mScriptFileName = null;
+    /** a filename to the setup script (if any) */
+    private String mSetupFileName = null;
+
+    /** filenames of the script (if any) */
+    private ArrayList<String> mScriptFileNames = new ArrayList<String>();
 
     /** a TCP port to listen on for remote commands. */
     private int mServerPort = -1;
@@ -398,12 +401,22 @@
             return -4;
         }
 
-        if (mScriptFileName != null) {
+        if (mScriptFileNames != null && mScriptFileNames.size() == 1) {
             // script mode, ignore other options
-            mEventSource = new MonkeySourceScript(mScriptFileName, mThrottle);
+            mEventSource = new MonkeySourceScript(mScriptFileNames.get(0), mThrottle);
             mEventSource.setVerbose(mVerbose);
 
             mCountEvents = false;
+        } else if (mScriptFileNames != null) {
+            if (mSetupFileName != null) {
+                mEventSource = new MonkeySourceRandomScript(mSetupFileName, mScriptFileNames,
+                        mThrottle, mSeed);
+                mCount++;
+            } else {
+                mEventSource = new MonkeySourceRandomScript(mScriptFileNames, mThrottle, mSeed);
+            }
+            mEventSource.setVerbose(mVerbose);
+            mCountEvents = false;
         } else if (mServerPort != -1) {
             try {
                 mEventSource = new MonkeySourceNetwork(mServerPort);
@@ -568,8 +581,10 @@
                     mSendNoEvents = true;
                 } else if (opt.equals("--port")) {
                     mServerPort = (int) nextOptionLong("Server port to listen on for commands");
+                } else if (opt.equals("--setup")) {
+                    mSetupFileName = nextOptionData();
                 } else if (opt.equals("-f")) {
-                    mScriptFileName = nextOptionData();
+                    mScriptFileNames.add(nextOptionData());
                 } else if (opt.equals("-h")) {
                     showUsage();
                     return false;
@@ -967,7 +982,8 @@
         usage.append("              [--pct-nav PERCENT] [--pct-majornav PERCENT]\n");
         usage.append("              [--pct-appswitch PERCENT] [--pct-flip PERCENT]\n");
         usage.append("              [--pct-anyevent PERCENT]\n");
-        usage.append("              [--wait-dbg] [--dbg-no-events] [-f scriptfile]\n");
+        usage.append("              [--wait-dbg] [--dbg-no-events]\n");
+        usage.append("              [--setup scriptfile] [-f scriptfile [-f scriptfile] ...]\n");
         usage.append("              [--port port]\n");
         usage.append("              [-s SEED] [-v [-v] ...] [--throttle MILLISEC]\n");
         usage.append("              COUNT");
diff --git a/cmds/monkey/src/com/android/commands/monkey/MonkeySourceRandomScript.java b/cmds/monkey/src/com/android/commands/monkey/MonkeySourceRandomScript.java
new file mode 100644
index 0000000..a937398
--- /dev/null
+++ b/cmds/monkey/src/com/android/commands/monkey/MonkeySourceRandomScript.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.commands.monkey;
+
+import java.security.SecureRandom;
+import java.util.ArrayList;
+
+/**
+ * Class for generating MonkeyEvents from multiple scripts.
+ */
+public class MonkeySourceRandomScript implements MonkeyEventSource {
+    /** The verbose level of the source (currently not used) */
+    private int mVerbose = 0;
+
+    /** The source for the setup script if it exists */
+    private MonkeySourceScript mSetupSource = null;
+
+    /** The list of MonkeySourceScript instances to be played in random order */
+    private ArrayList<MonkeySourceScript> mScriptSources = new ArrayList<MonkeySourceScript>();
+
+    /** The current source, set to the setup source and then a random script */
+    private MonkeySourceScript mCurrentSource = null;
+
+    /** The random number generator */
+    private SecureRandom mRandom;
+
+    /**
+     * Creates a MonkeySourceRandomScript instance with an additional setup script.
+     *
+     * @param setupFileName The name of the setup script file on the device.
+     * @param scriptFileNames An ArrayList of the names of the script files to be run randomly.
+     * @param throttle The amount of time to sleep in ms between events.
+     * @param seed The seed of the random number generator.
+     */
+    public MonkeySourceRandomScript(String setupFileName, ArrayList<String> scriptFileNames,
+            long throttle, long seed) {
+        if (setupFileName != null) {
+            mSetupSource = new MonkeySourceScript(setupFileName, throttle);
+            mCurrentSource = mSetupSource;
+        }
+
+        for (String fileName: scriptFileNames) {
+            mScriptSources.add(new MonkeySourceScript(fileName, throttle));
+        }
+
+        mRandom = new SecureRandom();
+        mRandom.setSeed((seed == 0) ? -1 : seed);
+    }
+
+    /**
+     * Creates a MonkeySourceRandomScript instance without an additional setup script.
+     *
+     * @param scriptFileNames An ArrayList of the names of the script files to be run randomly.
+     * @param throttle The amount of time to sleep in ms between events.
+     * @param seed The seed of the random number generator.
+     */
+    public MonkeySourceRandomScript(ArrayList<String> scriptFileNames, long throttle, long seed) {
+        this(null, scriptFileNames, throttle, seed);
+    }
+
+    /**
+     * Gets the next event from the current event source.  If the event source is null, a new
+     * script event source is chosen randomly from the list of script sources and the next event is
+     * chosen from that.
+     *
+     * @return The first event in the event queue or null if the end of the file
+     *         is reached or if an error is encountered reading the file.
+     */
+    public MonkeyEvent getNextEvent() {
+        if (mCurrentSource == null) {
+            int numSources = mScriptSources.size();
+            if (numSources == 1) {
+                mCurrentSource = mScriptSources.get(0);
+            } else if (numSources > 1) {
+                mCurrentSource = mScriptSources.get(mRandom.nextInt(numSources));
+            }
+        }
+
+        if (mCurrentSource != null) {
+            MonkeyEvent nextEvent = mCurrentSource.getNextEvent();
+            if (nextEvent == null) {
+                mCurrentSource = null;
+            }
+            return nextEvent;
+        }
+        return null;
+    }
+
+    /**
+     * Sets the verbosity for the source as well as all sub event sources.
+     *
+     * @param verbose The verbose level.
+     */
+    public void setVerbose(int verbose) {
+        mVerbose = verbose;
+
+        if (mSetupSource != null) {
+            mSetupSource.setVerbose(verbose);
+        }
+
+        for (MonkeySourceScript source: mScriptSources) {
+            source.setVerbose(verbose);
+        }
+    }
+
+    /**
+     * Validates that all the underlying event sources are valid
+     *
+     * @return True if all the script files are valid.
+     *
+     * @see MonkeySourceScript#validate()
+     */
+    public boolean validate() {
+        if (mSetupSource != null && !mSetupSource.validate()) {
+            return false;
+        }
+
+        for (MonkeySourceScript source: mScriptSources) {
+            if (!source.validate()) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+}