1/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.commands.monkey;
18
19import java.util.ArrayList;
20import java.util.Random;
21
22/**
23 * Class for generating MonkeyEvents from multiple scripts.
24 */
25public class MonkeySourceRandomScript implements MonkeyEventSource {
26    /** The verbose level of the source (currently not used) */
27    private int mVerbose = 0;
28
29    /** The source for the setup script if it exists */
30    private MonkeySourceScript mSetupSource = null;
31
32    /** The list of MonkeySourceScript instances to be played in random order */
33    private ArrayList<MonkeySourceScript> mScriptSources = new ArrayList<MonkeySourceScript>();
34
35    /** The current source, set to the setup source and then a random script */
36    private MonkeySourceScript mCurrentSource = null;
37
38    /** The random number generator */
39    private Random mRandom;
40
41    private boolean mRandomizeScript = false;
42
43    private int mScriptCount = 0;
44
45    /**
46     * Creates a MonkeySourceRandomScript instance with an additional setup script.
47     *
48     * @param setupFileName The name of the setup script file on the device.
49     * @param scriptFileNames An ArrayList of the names of the script files to be run randomly.
50     * @param throttle The amount of time to sleep in ms between events.
51     * @param randomizeThrottle Whether to randomize throttle.
52     * @param random The random number generator.
53     */
54    public MonkeySourceRandomScript(String setupFileName, ArrayList<String> scriptFileNames,
55            long throttle, boolean randomizeThrottle, Random random, long profileWaitTime,
56            long deviceSleepTime, boolean randomizeScript) {
57        if (setupFileName != null) {
58            mSetupSource = new MonkeySourceScript(random, setupFileName, throttle,
59                    randomizeThrottle, profileWaitTime, deviceSleepTime);
60            mCurrentSource = mSetupSource;
61        }
62
63        for (String fileName: scriptFileNames) {
64            mScriptSources.add(new MonkeySourceScript(random, fileName, throttle,
65                    randomizeThrottle, profileWaitTime, deviceSleepTime));
66        }
67
68        mRandom = random;
69        mRandomizeScript = randomizeScript;
70    }
71
72    /**
73     * Creates a MonkeySourceRandomScript instance without an additional setup script.
74     *
75     * @param scriptFileNames An ArrayList of the names of the script files to be run randomly.
76     * @param throttle The amount of time to sleep in ms between events.
77     * @param randomizeThrottle Whether to randomize throttle.
78     * @param random The random number generator.
79     */
80    public MonkeySourceRandomScript(ArrayList<String> scriptFileNames, long throttle,
81            boolean randomizeThrottle, Random random, long profileWaitTime, long deviceSleepTime,
82            boolean randomizeScript) {
83        this(null, scriptFileNames, throttle, randomizeThrottle, random, profileWaitTime,
84                deviceSleepTime, randomizeScript);
85    }
86
87    /**
88     * Gets the next event from the current event source.  If the event source is null, a new
89     * script event source is chosen randomly from the list of script sources and the next event is
90     * chosen from that.
91     *
92     * @return The first event in the event queue or null if the end of the file
93     *         is reached or if an error is encountered reading the file.
94     */
95    public MonkeyEvent getNextEvent() {
96        if (mCurrentSource == null) {
97            int numSources = mScriptSources.size();
98            if (numSources == 1) {
99                mCurrentSource = mScriptSources.get(0);
100            } else if (numSources > 1 ) {
101                if (mRandomizeScript) {
102                    mCurrentSource = mScriptSources.get(mRandom.nextInt(numSources));
103                } else {
104                    mCurrentSource = mScriptSources.get(mScriptCount % numSources);
105                    mScriptCount++;
106                }
107            }
108        }
109
110        if (mCurrentSource != null) {
111            MonkeyEvent nextEvent = mCurrentSource.getNextEvent();
112            if (nextEvent == null) {
113                mCurrentSource = null;
114            }
115            return nextEvent;
116        }
117        return null;
118    }
119
120    /**
121     * Sets the verbosity for the source as well as all sub event sources.
122     *
123     * @param verbose The verbose level.
124     */
125    public void setVerbose(int verbose) {
126        mVerbose = verbose;
127
128        if (mSetupSource != null) {
129            mSetupSource.setVerbose(verbose);
130        }
131
132        for (MonkeySourceScript source: mScriptSources) {
133            source.setVerbose(verbose);
134        }
135    }
136
137    /**
138     * Validates that all the underlying event sources are valid
139     *
140     * @return True if all the script files are valid.
141     *
142     * @see MonkeySourceScript#validate()
143     */
144    public boolean validate() {
145        if (mSetupSource != null && !mSetupSource.validate()) {
146            return false;
147        }
148
149        for (MonkeySourceScript source: mScriptSources) {
150            if (!source.validate()) {
151                return false;
152            }
153        }
154
155        return true;
156    }
157}
158