【Android M】Monkey命令源码及是否处于monkey测试的判断方法

来源:互联网 发布:csolfps优化大全 编辑:程序博客网 时间:2024/05/16 14:43


development/cmds/monkey/src/com/android/commands/monkey/Monkey.java

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

Monkey命令源码

1. Monkey.java

/* * Copyright 2007, 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 android.app.ActivityManagerNative;import android.app.IActivityController;import android.app.IActivityManager;import android.content.ComponentName;import android.content.Intent;import android.content.pm.IPackageManager;import android.content.pm.ResolveInfo;import android.os.Build;import android.os.Debug;import android.os.Environment;import android.os.Process;import android.os.RemoteException;import android.os.ServiceManager;import android.os.StrictMode;import android.os.SystemClock;import android.os.UserHandle;import android.view.IWindowManager;import android.view.Surface;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.File;import java.io.FileReader;import java.io.FileWriter;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.Writer;import java.util.ArrayList;import java.util.HashSet;import java.util.Iterator;import java.util.List;import java.util.Random;import java.util.Set;/** * Application that injects random key events and other actions into the system. */public class Monkey {    /**     * Monkey Debugging/Dev Support     * <p>     * All values should be zero when checking in.     */    private final static int DEBUG_ALLOW_ANY_STARTS = 0;    private final static int DEBUG_ALLOW_ANY_RESTARTS = 0;    private IActivityManager mAm;    private IWindowManager mWm;    private IPackageManager mPm;    /** Command line arguments */    private String[] mArgs;    /** Current argument being parsed */    private int mNextArg;    /** Data of current argument */    private String mCurArgData;    /** Running in verbose output mode? 1= verbose, 2=very verbose */    private int mVerbose;    /** Ignore any application crashes while running? */    private boolean mIgnoreCrashes;    /** Ignore any not responding timeouts while running? */    private boolean mIgnoreTimeouts;    /** Ignore security exceptions when launching activities */    /** (The activity launch still fails, but we keep pluggin' away) */    private boolean mIgnoreSecurityExceptions;    /** Monitor /data/tombstones and stop the monkey if new files appear. */    private boolean mMonitorNativeCrashes;    /** Ignore any native crashes while running? */    private boolean mIgnoreNativeCrashes;    /** Send no events. Use with long throttle-time to watch user operations */    private boolean mSendNoEvents;    /** This is set when we would like to abort the running of the monkey. */    private boolean mAbort;    /**     * Count each event as a cycle. Set to false for scripts so that each time     * through the script increments the count.     */    private boolean mCountEvents = true;    /**     * This is set by the ActivityController thread to request collection of ANR     * trace files     */    private boolean mRequestAnrTraces = false;    /**     * This is set by the ActivityController thread to request a     * "dumpsys meminfo"     */    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 a system watchdog report     */    private boolean mRequestWatchdogBugreport = false;    /**     * Synchronization for the ActivityController callback to block     * until we are done handling the reporting of the watchdog error.     */    private boolean mWatchdogWaiting = false;    /**     * This is set by the ActivityController thread to request a     * bugreport after java application crash     */    private boolean mRequestAppCrashBugreport = false;    /**Request the bugreport based on the mBugreportFrequency. */    private boolean mGetPeriodicBugreport = false;    /**     * Request the bugreport based on the mBugreportFrequency.     */    private boolean mRequestPeriodicBugreport = false;    /** Bugreport frequency. */    private long mBugreportFrequency = 10;    /** Failure process name */    private String mReportProcessName;    /**     * This is set by the ActivityController thread to request a "procrank"     */    private boolean mRequestProcRank = false;    /** Kill the process after a timeout or crash. */    private boolean mKillProcessAfterError;    /** Generate hprof reports before/after monkey runs */    private boolean mGenerateHprof;    /** Package blacklist file. */    private String mPkgBlacklistFile;    /** Package whitelist file. */    private String mPkgWhitelistFile;    /** Categories we are allowed to launch **/    private ArrayList<String> mMainCategories = new ArrayList<String>();    /** Applications we can switch to. */    private ArrayList<ComponentName> mMainApps = new ArrayList<ComponentName>();    /** The delay between event inputs **/    long mThrottle = 0;    /** Whether to randomize each throttle (0-mThrottle ms) inserted between events. */    boolean mRandomizeThrottle = false;    /** The number of iterations **/    int mCount = 1000;    /** The random number seed **/    long mSeed = 0;    /** The random number generator **/    Random mRandom = null;    /** Dropped-event statistics **/    long mDroppedKeyEvents = 0;    long mDroppedPointerEvents = 0;    long mDroppedTrackballEvents = 0;    long mDroppedFlipEvents = 0;    long mDroppedRotationEvents = 0;    /** The delay between user actions. This is for the scripted monkey. **/    long mProfileWaitTime = 5000;    /** Device idle time. This is for the scripted monkey. **/    long mDeviceSleepTime = 30000;    boolean mRandomizeScript = false;    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;    /** 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;    private static final File TOMBSTONES_PATH = new File("/data/tombstones");    private HashSet<String> mTombstones = null;    float[] mFactors = new float[MonkeySourceRandom.FACTORZ_COUNT];    MonkeyEventSource mEventSource;    private MonkeyNetworkMonitor mNetworkMonitor = new MonkeyNetworkMonitor();    private boolean mPermissionTargetSystem = false;    // information on the current activity.    public static Intent currentIntent;    public static String currentPackage;    /**     * Monitor operations happening in the system.     */    private class ActivityController extends IActivityController.Stub {        public boolean activityStarting(Intent intent, String pkg) {            boolean allow = MonkeyUtils.getPackageFilter().checkEnteringPackage(pkg)                    || (DEBUG_ALLOW_ANY_STARTS != 0);            if (mVerbose > 0) {                // StrictMode's disk checks end up catching this on                // userdebug/eng builds due to PrintStream going to a                // FileOutputStream in the end (perhaps only when                // redirected to a file?)  So we allow disk writes                // around this region for the monkey to minimize                // harmless dropbox uploads from monkeys.                StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();                System.out.println("    // " + (allow ? "Allowing" : "Rejecting") + " start of "                        + intent + " in package " + pkg);                StrictMode.setThreadPolicy(savedPolicy);            }            currentPackage = pkg;            currentIntent = intent;            return allow;        }        public boolean activityResuming(String pkg) {            StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();            System.out.println("    // activityResuming(" + pkg + ")");            boolean allow = MonkeyUtils.getPackageFilter().checkEnteringPackage(pkg)                    || (DEBUG_ALLOW_ANY_RESTARTS != 0);            if (!allow) {                if (mVerbose > 0) {                    System.out.println("    // " + (allow ? "Allowing" : "Rejecting")                            + " resume of package " + pkg);                }            }            currentPackage = pkg;            StrictMode.setThreadPolicy(savedPolicy);            return allow;        }        public boolean appCrashed(String processName, int pid,                String shortMsg, String longMsg,                long timeMillis, String stackTrace) {            StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();            System.err.println("// CRASH: " + processName + " (pid " + pid + ")");            System.err.println("// Short Msg: " + shortMsg);            System.err.println("// Long Msg: " + longMsg);            System.err.println("// Build Label: " + Build.FINGERPRINT);            System.err.println("// Build Changelist: " + Build.VERSION.INCREMENTAL);            System.err.println("// Build Time: " + Build.TIME);            System.err.println("// " + stackTrace.replace("\n", "\n// "));            StrictMode.setThreadPolicy(savedPolicy);            if (!mIgnoreCrashes || mRequestBugreport) {                synchronized (Monkey.this) {                    if (!mIgnoreCrashes) {                        mAbort = true;                    }                    if (mRequestBugreport){                        mRequestAppCrashBugreport = true;                        mReportProcessName = processName;                    }                }                return !mKillProcessAfterError;            }            return false;        }        public int appEarlyNotResponding(String processName, int pid, String annotation) {            return 0;        }        public int appNotResponding(String processName, int pid, String processStats) {            StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();            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) {                    mAbort = true;                }            }            return (mKillProcessAfterError) ? -1 : 1;        }        public int systemNotResponding(String message) {            StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();            System.err.println("// WATCHDOG: " + message);            StrictMode.setThreadPolicy(savedPolicy);            synchronized (Monkey.this) {                if (!mIgnoreCrashes) {                    mAbort = true;                }                if (mRequestBugreport) {                    mRequestWatchdogBugreport = true;                }                mWatchdogWaiting = true;            }            synchronized (Monkey.this) {                while (mWatchdogWaiting) {                    try {                        Monkey.this.wait();                    } catch (InterruptedException e) {                    }                }            }            return (mKillProcessAfterError) ? -1 : 1;        }    }    /**     * Run the procrank tool to insert system status information into the debug     * report.     */    private void reportProcRank() {        commandLineReport("procrank", "procrank");    }    /**     * Run "cat /data/anr/traces.txt". Wait about 5 seconds first, to let the     * asynchronous report writing complete.     */    private void reportAnrTraces() {        try {            Thread.sleep(5 * 1000);        } catch (InterruptedException e) {        }        commandLineReport("anr traces", "cat /data/anr/traces.txt");    }    /**     * Run "dumpsys meminfo"     * <p>     * NOTE: You cannot perform a dumpsys call from the ActivityController     * callback, as it will deadlock. This should only be called from the main     * loop of the monkey.     */    private void reportDumpsysMemInfo() {        commandLineReport("meminfo", "dumpsys meminfo");    }    /**     * Print report from a single command line.     * <p>     * TODO: Use ProcessBuilder & redirectErrorStream(true) to capture both     * streams (might be important for some command lines)     *     * @param reportName Simple tag that will print before the report and in     *            various annotations.     * @param command Command line to execute.     */    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                                .getLegacyExternalStorageDirectory(), 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) {                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());        }    }    // Write the numbe of iteration to the log    private void writeScriptLog(int count) {        // TO DO: Add the script file name to the log.        try {            Writer output = new BufferedWriter(new FileWriter(new File(                    Environment.getLegacyExternalStorageDirectory(), "scriptlog.txt"), true));            output.write("iteration: " + count + " time: "                    + MonkeyUtils.toCalendarTime(System.currentTimeMillis()) + "\n");            output.close();        } catch (IOException e) {            System.err.println(e.toString());        }    }    // 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.     *     * @param args The command-line arguments     */    public static void main(String[] args) {        // Set the process name showing in "ps" or "top"        Process.setArgV0("com.android.commands.monkey");        int resultCode = (new Monkey()).run(args);        System.exit(resultCode);    }    /**     * Run the command!     *     * @param args The command-line arguments     * @return Returns a posix-style result code. 0 for no error.     */    private int run(String[] args) {        // Super-early debugger wait        for (String s : args) {            if ("--wait-dbg".equals(s)) {                Debug.waitForDebugger();            }        }        // Default values for some command-line options        mVerbose = 0;        mCount = 1000;        mSeed = 0;        mThrottle = 0;        // prepare for command-line processing        mArgs = args;        mNextArg = 0;        // set a positive value, indicating none of the factors is provided yet        for (int i = 0; i < MonkeySourceRandom.FACTORZ_COUNT; i++) {            mFactors[i] = 1.0f;        }        if (!processOptions()) {            return -1;        }        if (!loadPackageLists()) {            return -1;        }        // now set up additional data in preparation for launch        if (mMainCategories.size() == 0) {            mMainCategories.add(Intent.CATEGORY_LAUNCHER);            mMainCategories.add(Intent.CATEGORY_MONKEY);        }        if (mSeed == 0) {            mSeed = System.currentTimeMillis() + System.identityHashCode(this);        }        if (mVerbose > 0) {            System.out.println(":Monkey: seed=" + mSeed + " count=" + mCount);            MonkeyUtils.getPackageFilter().dump();            if (mMainCategories.size() != 0) {                Iterator<String> it = mMainCategories.iterator();                while (it.hasNext()) {                    System.out.println(":IncludeCategory: " + it.next());                }            }        }        if (!checkInternalConfiguration()) {            return -2;        }        if (!getSystemInterfaces()) {            return -3;        }        if (!getMainApps()) {            return -4;        }        mRandom = new Random(mSeed);        if (mScriptFileNames != null && mScriptFileNames.size() == 1) {            // script mode, ignore other options            mEventSource = new MonkeySourceScript(mRandom, mScriptFileNames.get(0), mThrottle,                    mRandomizeThrottle, mProfileWaitTime, mDeviceSleepTime);            mEventSource.setVerbose(mVerbose);            mCountEvents = false;        } else if (mScriptFileNames != null && mScriptFileNames.size() > 1) {            if (mSetupFileName != null) {                mEventSource = new MonkeySourceRandomScript(mSetupFileName,                        mScriptFileNames, mThrottle, mRandomizeThrottle, mRandom,                        mProfileWaitTime, mDeviceSleepTime, mRandomizeScript);                mCount++;            } else {                mEventSource = new MonkeySourceRandomScript(mScriptFileNames,                        mThrottle, mRandomizeThrottle, mRandom,                        mProfileWaitTime, mDeviceSleepTime, mRandomizeScript);            }            mEventSource.setVerbose(mVerbose);            mCountEvents = false;        } else if (mServerPort != -1) {            try {                mEventSource = new MonkeySourceNetwork(mServerPort);            } catch (IOException e) {                System.out.println("Error binding to network socket.");                return -5;            }            mCount = Integer.MAX_VALUE;        } else {            // random source by default            if (mVerbose >= 2) { // check seeding performance                System.out.println("// Seeded: " + mSeed);            }            mEventSource = new MonkeySourceRandom(mRandom, mMainApps,                    mThrottle, mRandomizeThrottle, mPermissionTargetSystem);            mEventSource.setVerbose(mVerbose);            // set any of the factors that has been set            for (int i = 0; i < MonkeySourceRandom.FACTORZ_COUNT; i++) {                if (mFactors[i] <= 0.0f) {                    ((MonkeySourceRandom) mEventSource).setFactors(i, mFactors[i]);                }            }            // in random mode, we start with a random activity            ((MonkeySourceRandom) mEventSource).generateActivity();        }        // validate source generator        if (!mEventSource.validate()) {            return -5;        }        // If we're profiling, do it immediately before/after the main monkey        // loop        if (mGenerateHprof) {            signalPersistentProcesses();        }        mNetworkMonitor.start();        int crashedAtCycle = 0;        try {            crashedAtCycle = runMonkeyCycles();        } finally {            // Release the rotation lock if it's still held and restore the            // original orientation.            new MonkeyRotationEvent(Surface.ROTATION_0, false).injectEvent(                mWm, mAm, mVerbose);        }        mNetworkMonitor.stop();        synchronized (this) {            if (mRequestAnrTraces) {                reportAnrTraces();                mRequestAnrTraces = false;            }            if (mRequestAnrBugreport){                System.out.println("Print the anr report");                getBugreport("anr_" + mReportProcessName + "_");                mRequestAnrBugreport = false;            }            if (mRequestWatchdogBugreport) {                System.out.println("Print the watchdog report");                getBugreport("anr_watchdog_");                mRequestWatchdogBugreport = false;            }            if (mRequestAppCrashBugreport){                getBugreport("app_crash" + mReportProcessName + "_");                mRequestAppCrashBugreport = false;            }            if (mRequestDumpsysMemInfo) {                reportDumpsysMemInfo();                mRequestDumpsysMemInfo = false;            }            if (mRequestPeriodicBugreport){                getBugreport("Bugreport_");                mRequestPeriodicBugreport = false;            }            if (mWatchdogWaiting) {                mWatchdogWaiting = false;                notifyAll();            }        }        if (mGenerateHprof) {            signalPersistentProcesses();            if (mVerbose > 0) {                System.out.println("// Generated profiling reports in /data/misc");            }        }        try {            mAm.setActivityController(null);            mNetworkMonitor.unregister(mAm);        } catch (RemoteException e) {            // just in case this was latent (after mCount cycles), make sure            // we report it            if (crashedAtCycle >= mCount) {                crashedAtCycle = mCount - 1;            }        }        // report dropped event stats        if (mVerbose > 0) {            System.out.print(":Dropped: keys=");            System.out.print(mDroppedKeyEvents);            System.out.print(" pointers=");            System.out.print(mDroppedPointerEvents);            System.out.print(" trackballs=");            System.out.print(mDroppedTrackballEvents);            System.out.print(" flips=");            System.out.print(mDroppedFlipEvents);            System.out.print(" rotations=");            System.out.println(mDroppedRotationEvents);        }        // report network stats        mNetworkMonitor.dump();        if (crashedAtCycle < mCount - 1) {            System.err.println("** System appears to have crashed at event " + crashedAtCycle                    + " of " + mCount + " using seed " + mSeed);            return crashedAtCycle;        } else {            if (mVerbose > 0) {                System.out.println("// Monkey finished");            }            return 0;        }    }    /**     * Process the command-line options     *     * @return Returns true if options were parsed with no apparent errors.     */    private boolean processOptions() {        // quick (throwaway) check for unadorned command        if (mArgs.length < 1) {            showUsage();            return false;        }        try {            String opt;            Set<String> validPackages = new HashSet<>();            while ((opt = nextOption()) != null) {                if (opt.equals("-s")) {                    mSeed = nextOptionLong("Seed");                } else if (opt.equals("-p")) {                    validPackages.add(nextOptionData());                } else if (opt.equals("-c")) {                    mMainCategories.add(nextOptionData());                } else if (opt.equals("-v")) {                    mVerbose += 1;                } else if (opt.equals("--ignore-crashes")) {                    mIgnoreCrashes = true;                } else if (opt.equals("--ignore-timeouts")) {                    mIgnoreTimeouts = true;                } else if (opt.equals("--ignore-security-exceptions")) {                    mIgnoreSecurityExceptions = true;                } else if (opt.equals("--monitor-native-crashes")) {                    mMonitorNativeCrashes = true;                } else if (opt.equals("--ignore-native-crashes")) {                    mIgnoreNativeCrashes = true;                } else if (opt.equals("--kill-process-after-error")) {                    mKillProcessAfterError = true;                } else if (opt.equals("--hprof")) {                    mGenerateHprof = true;                } else if (opt.equals("--pct-touch")) {                    int i = MonkeySourceRandom.FACTOR_TOUCH;                    mFactors[i] = -nextOptionLong("touch events percentage");                } else if (opt.equals("--pct-motion")) {                    int i = MonkeySourceRandom.FACTOR_MOTION;                    mFactors[i] = -nextOptionLong("motion events percentage");                } else if (opt.equals("--pct-trackball")) {                    int i = MonkeySourceRandom.FACTOR_TRACKBALL;                    mFactors[i] = -nextOptionLong("trackball events percentage");                } else if (opt.equals("--pct-rotation")) {                    int i = MonkeySourceRandom.FACTOR_ROTATION;                    mFactors[i] = -nextOptionLong("screen rotation events percentage");                } else if (opt.equals("--pct-syskeys")) {                    int i = MonkeySourceRandom.FACTOR_SYSOPS;                    mFactors[i] = -nextOptionLong("system (key) operations percentage");                } else if (opt.equals("--pct-nav")) {                    int i = MonkeySourceRandom.FACTOR_NAV;                    mFactors[i] = -nextOptionLong("nav events percentage");                } else if (opt.equals("--pct-majornav")) {                    int i = MonkeySourceRandom.FACTOR_MAJORNAV;                    mFactors[i] = -nextOptionLong("major nav events percentage");                } else if (opt.equals("--pct-appswitch")) {                    int i = MonkeySourceRandom.FACTOR_APPSWITCH;                    mFactors[i] = -nextOptionLong("app switch events percentage");                } else if (opt.equals("--pct-flip")) {                    int i = MonkeySourceRandom.FACTOR_FLIP;                    mFactors[i] = -nextOptionLong("keyboard flip percentage");                } else if (opt.equals("--pct-anyevent")) {                    int i = MonkeySourceRandom.FACTOR_ANYTHING;                    mFactors[i] = -nextOptionLong("any events percentage");                } else if (opt.equals("--pct-pinchzoom")) {                    int i = MonkeySourceRandom.FACTOR_PINCHZOOM;                    mFactors[i] = -nextOptionLong("pinch zoom events percentage");                } else if (opt.equals("--pct-permission")) {                    int i = MonkeySourceRandom.FACTOR_PERMISSION;                    mFactors[i] = -nextOptionLong("runtime permission toggle events percentage");                } else if (opt.equals("--pkg-blacklist-file")) {                    mPkgBlacklistFile = nextOptionData();                } else if (opt.equals("--pkg-whitelist-file")) {                    mPkgWhitelistFile = nextOptionData();                } else if (opt.equals("--throttle")) {                    mThrottle = nextOptionLong("delay (in milliseconds) to wait between events");                } else if (opt.equals("--randomize-throttle")) {                    mRandomizeThrottle = true;                } else if (opt.equals("--wait-dbg")) {                    // do nothing - it's caught at the very start of run()                } else if (opt.equals("--dbg-no-events")) {                    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")) {                    mScriptFileNames.add(nextOptionData());                } else if (opt.equals("--profile-wait")) {                    mProfileWaitTime = nextOptionLong("Profile delay" +                                " (in milliseconds) to wait between user action");                } else if (opt.equals("--device-sleep-time")) {                    mDeviceSleepTime = nextOptionLong("Device sleep time" +                                                      "(in milliseconds)");                } else if (opt.equals("--randomize-script")) {                    mRandomizeScript = true;                } else if (opt.equals("--script-log")) {                    mScriptLog = true;                } else if (opt.equals("--bugreport")) {                    mRequestBugreport = true;                } else if (opt.equals("--periodic-bugreport")){                    mGetPeriodicBugreport = true;                    mBugreportFrequency = nextOptionLong("Number of iterations");                } else if (opt.equals("--permission-target-system")){                    mPermissionTargetSystem = true;                } else if (opt.equals("-h")) {                    showUsage();                    return false;                } else {                    System.err.println("** Error: Unknown option: " + opt);                    showUsage();                    return false;                }            }            MonkeyUtils.getPackageFilter().addValidPackages(validPackages);        } catch (RuntimeException ex) {            System.err.println("** Error: " + ex.toString());            showUsage();            return false;        }        // If a server port hasn't been specified, we need to specify        // a count        if (mServerPort == -1) {            String countStr = nextArg();            if (countStr == null) {                System.err.println("** Error: Count not specified");                showUsage();                return false;            }            try {                mCount = Integer.parseInt(countStr);            } catch (NumberFormatException e) {                System.err.println("** Error: Count is not a number");                showUsage();                return false;            }        }        return true;    }    /**     * Load a list of package names from a file.     *     * @param fileName The file name, with package names separated by new line.     * @param list The destination list.     * @return Returns false if any error occurs.     */    private static boolean loadPackageListFromFile(String fileName, Set<String> list) {        BufferedReader reader = null;        try {            reader = new BufferedReader(new FileReader(fileName));            String s;            while ((s = reader.readLine()) != null) {                s = s.trim();                if ((s.length() > 0) && (!s.startsWith("#"))) {                    list.add(s);                }            }        } catch (IOException ioe) {            System.err.println(ioe);            return false;        } finally {            if (reader != null) {                try {                    reader.close();                } catch (IOException ioe) {                    System.err.println(ioe);                }            }        }        return true;    }    /**     * Load package blacklist or whitelist (if specified).     *     * @return Returns false if any error occurs.     */    private boolean loadPackageLists() {        if (((mPkgWhitelistFile != null) || (MonkeyUtils.getPackageFilter().hasValidPackages()))                && (mPkgBlacklistFile != null)) {            System.err.println("** Error: you can not specify a package blacklist "                    + "together with a whitelist or individual packages (via -p).");            return false;        }        Set<String> validPackages = new HashSet<>();        if ((mPkgWhitelistFile != null)                && (!loadPackageListFromFile(mPkgWhitelistFile, validPackages))) {            return false;        }        MonkeyUtils.getPackageFilter().addValidPackages(validPackages);        Set<String> invalidPackages = new HashSet<>();        if ((mPkgBlacklistFile != null)                && (!loadPackageListFromFile(mPkgBlacklistFile, invalidPackages))) {            return false;        }        MonkeyUtils.getPackageFilter().addInvalidPackages(invalidPackages);        return true;    }    /**     * Check for any internal configuration (primarily build-time) errors.     *     * @return Returns true if ready to rock.     */    private boolean checkInternalConfiguration() {        return true;    }    /**     * Attach to the required system interfaces.     *     * @return Returns true if all system interfaces were available.     */    private boolean getSystemInterfaces() {        mAm = ActivityManagerNative.getDefault();        if (mAm == null) {            System.err.println("** Error: Unable to connect to activity manager; is the system "                    + "running?");            return false;        }        mWm = IWindowManager.Stub.asInterface(ServiceManager.getService("window"));        if (mWm == null) {            System.err.println("** Error: Unable to connect to window manager; is the system "                    + "running?");            return false;        }        mPm = IPackageManager.Stub.asInterface(ServiceManager.getService("package"));        if (mPm == null) {            System.err.println("** Error: Unable to connect to package manager; is the system "                    + "running?");            return false;        }        try {            mAm.setActivityController(new ActivityController());            mNetworkMonitor.register(mAm);        } catch (RemoteException e) {            System.err.println("** Failed talking with activity manager!");            return false;        }        return true;    }    /**     * Using the restrictions provided (categories & packages), generate a list     * of activities that we can actually switch to.     *     * @return Returns true if it could successfully build a list of target     *         activities     */    private boolean getMainApps() {        try {            final int N = mMainCategories.size();            for (int i = 0; i < N; i++) {                Intent intent = new Intent(Intent.ACTION_MAIN);                String category = mMainCategories.get(i);                if (category.length() > 0) {                    intent.addCategory(category);                }                List<ResolveInfo> mainApps = mPm.queryIntentActivities(intent, null, 0,                        UserHandle.myUserId());                if (mainApps == null || mainApps.size() == 0) {                    System.err.println("// Warning: no activities found for category " + category);                    continue;                }                if (mVerbose >= 2) { // very verbose                    System.out.println("// Selecting main activities from category " + category);                }                final int NA = mainApps.size();                for (int a = 0; a < NA; a++) {                    ResolveInfo r = mainApps.get(a);                    String packageName = r.activityInfo.applicationInfo.packageName;                    if (MonkeyUtils.getPackageFilter().checkEnteringPackage(packageName)) {                        if (mVerbose >= 2) { // very verbose                            System.out.println("//   + Using main activity " + r.activityInfo.name                                    + " (from package " + packageName + ")");                        }                        mMainApps.add(new ComponentName(packageName, r.activityInfo.name));                    } else {                        if (mVerbose >= 3) { // very very verbose                            System.out.println("//   - NOT USING main activity "                                    + r.activityInfo.name + " (from package " + packageName + ")");                        }                    }                }            }        } catch (RemoteException e) {            System.err.println("** Failed talking with package manager!");            return false;        }        if (mMainApps.size() == 0) {            System.out.println("** No activities found to run, monkey aborted.");            return false;        }        return true;    }    /**     * Run mCount cycles and see if we hit any crashers.     * <p>     * TODO: Meta state on keys     *     * @return Returns the last cycle which executed. If the value == mCount, no     *         errors detected.     */    private int runMonkeyCycles() {        int eventCounter = 0;        int cycleCounter = 0;        boolean shouldReportAnrTraces = false;        boolean shouldReportDumpsysMemInfo = false;        boolean shouldAbort = false;        boolean systemCrashed = false;        // TO DO : The count should apply to each of the script file.        while (!systemCrashed && cycleCounter < mCount) {            synchronized (this) {                if (mRequestProcRank) {                    reportProcRank();                    mRequestProcRank = false;                }                if (mRequestAnrTraces) {                    mRequestAnrTraces = false;                    shouldReportAnrTraces = true;                }                if (mRequestAnrBugreport){                    getBugreport("anr_" + mReportProcessName + "_");                    mRequestAnrBugreport = false;                }                if (mRequestWatchdogBugreport) {                    System.out.println("Print the watchdog report");                    getBugreport("anr_watchdog_");                    mRequestWatchdogBugreport = false;                }                if (mRequestAppCrashBugreport){                    getBugreport("app_crash" + mReportProcessName + "_");                    mRequestAppCrashBugreport = false;                }                if (mRequestPeriodicBugreport){                    getBugreport("Bugreport_");                    mRequestPeriodicBugreport = false;                }                if (mRequestDumpsysMemInfo) {                    mRequestDumpsysMemInfo = false;                    shouldReportDumpsysMemInfo = true;                }                if (mMonitorNativeCrashes) {                    // first time through, when eventCounter == 0, just set up                    // 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;                    }                }                if (mAbort) {                    shouldAbort = true;                }                if (mWatchdogWaiting) {                    mWatchdogWaiting = false;                    notifyAll();                }            }            // Report ANR, dumpsys after releasing lock on this.            // This ensures the availability of the lock to Activity controller's appNotResponding            if (shouldReportAnrTraces) {               shouldReportAnrTraces = false;               reportAnrTraces();            }            if (shouldReportDumpsysMemInfo) {               shouldReportDumpsysMemInfo = false;               reportDumpsysMemInfo();            }            if (shouldAbort) {               shouldAbort = false;               System.out.println("** Monkey aborted due to error.");               System.out.println("Events injected: " + eventCounter);               return eventCounter;            }            // In this debugging mode, we never send any events. This is            // primarily here so you can manually test the package or category            // limits, while manually exercising the system.            if (mSendNoEvents) {                eventCounter++;                cycleCounter++;                continue;            }            if ((mVerbose > 0) && (eventCounter % 100) == 0 && eventCounter != 0) {                String calendarTime = MonkeyUtils.toCalendarTime(System.currentTimeMillis());                long systemUpTime = SystemClock.elapsedRealtime();                System.out.println("    //[calendar_time:" + calendarTime + " system_uptime:"                                   + systemUpTime + "]");                System.out.println("    // Sending event #" + eventCounter);            }            MonkeyEvent ev = mEventSource.getNextEvent();            if (ev != null) {                int injectCode = ev.injectEvent(mWm, mAm, mVerbose);                if (injectCode == MonkeyEvent.INJECT_FAIL) {                    System.out.println("    // Injection Failed");                    if (ev instanceof MonkeyKeyEvent) {                        mDroppedKeyEvents++;                    } else if (ev instanceof MonkeyMotionEvent) {                        mDroppedPointerEvents++;                    } else if (ev instanceof MonkeyFlipEvent) {                        mDroppedFlipEvents++;                    } else if (ev instanceof MonkeyRotationEvent) {                        mDroppedRotationEvents++;                    }                } else if (injectCode == MonkeyEvent.INJECT_ERROR_REMOTE_EXCEPTION) {                    systemCrashed = true;                    System.err.println("** Error: RemoteException while injecting event.");                } else if (injectCode == MonkeyEvent.INJECT_ERROR_SECURITY_EXCEPTION) {                    systemCrashed = !mIgnoreSecurityExceptions;                    if (systemCrashed) {                        System.err.println("** Error: SecurityException while injecting event.");                    }                }                // Don't count throttling as an event.                if (!(ev instanceof MonkeyThrottleEvent)) {                    eventCounter++;                    if (mCountEvents) {                        cycleCounter++;                    }                }            } else {                if (!mCountEvents) {                    cycleCounter++;                    writeScriptLog(cycleCounter);                    //Capture the bugreport after n iteration                    if (mGetPeriodicBugreport) {                        if ((cycleCounter % mBugreportFrequency) == 0) {                            mRequestPeriodicBugreport = true;                        }                    }                } else {                    // Event Source has signaled that we have no more events to process                    break;                }            }        }        System.out.println("Events injected: " + eventCounter);        return eventCounter;    }    /**     * Send SIGNAL_USR1 to all processes. This will generate large (5mb)     * profiling reports in data/misc, so use with care.     */    private void signalPersistentProcesses() {        try {            mAm.signalPersistentProcesses(Process.SIGNAL_USR1);            synchronized (this) {                wait(2000);            }        } catch (RemoteException e) {            System.err.println("** Failed talking with activity manager!");        } catch (InterruptedException e) {        }    }    /**     * Watch for appearance of new tombstone files, which indicate native     * crashes.     *     * @return Returns true if new files have appeared in the list     */    private boolean checkNativeCrashes() {        String[] tombstones = TOMBSTONES_PATH.list();        // shortcut path for usually empty directory, so we don't waste even        // more objects        if ((tombstones == null) || (tombstones.length == 0)) {            mTombstones = null;            return false;        }        // use set logic to look for new files        HashSet<String> newStones = new HashSet<String>();        for (String x : tombstones) {            newStones.add(x);        }        boolean result = (mTombstones == null) || !mTombstones.containsAll(newStones);        // keep the new list for the next time        mTombstones = newStones;        return result;    }    /**     * Return the next command line option. This has a number of special cases     * which closely, but not exactly, follow the POSIX command line options     * patterns:     *     * <pre>     * -- means to stop processing additional options     * -z means option z     * -z ARGS means option z with (non-optional) arguments ARGS     * -zARGS means option z with (optional) arguments ARGS     * --zz means option zz     * --zz ARGS means option zz with (non-optional) arguments ARGS     * </pre>     *     * Note that you cannot combine single letter options; -abc != -a -b -c     *     * @return Returns the option string, or null if there are no more options.     */    private String nextOption() {        if (mNextArg >= mArgs.length) {            return null;        }        String arg = mArgs[mNextArg];        if (!arg.startsWith("-")) {            return null;        }        mNextArg++;        if (arg.equals("--")) {            return null;        }        if (arg.length() > 1 && arg.charAt(1) != '-') {            if (arg.length() > 2) {                mCurArgData = arg.substring(2);                return arg.substring(0, 2);            } else {                mCurArgData = null;                return arg;            }        }        mCurArgData = null;        return arg;    }    /**     * Return the next data associated with the current option.     *     * @return Returns the data string, or null of there are no more arguments.     */    private String nextOptionData() {        if (mCurArgData != null) {            return mCurArgData;        }        if (mNextArg >= mArgs.length) {            return null;        }        String data = mArgs[mNextArg];        mNextArg++;        return data;    }    /**     * Returns a long converted from the next data argument, with error handling     * if not available.     *     * @param opt The name of the option.     * @return Returns a long converted from the argument.     */    private long nextOptionLong(final String opt) {        long result;        try {            result = Long.parseLong(nextOptionData());        } catch (NumberFormatException e) {            System.err.println("** Error: " + opt + " is not a number");            throw e;        }        return result;    }    /**     * Return the next argument on the command line.     *     * @return Returns the argument string, or null if we have reached the end.     */    private String nextArg() {        if (mNextArg >= mArgs.length) {            return null;        }        String arg = mArgs[mNextArg];        mNextArg++;        return arg;    }    /**     * Print how to use this command.     */    private void showUsage() {        StringBuffer usage = new StringBuffer();        usage.append("usage: monkey [-p ALLOWED_PACKAGE [-p ALLOWED_PACKAGE] ...]\n");        usage.append("              [-c MAIN_CATEGORY [-c MAIN_CATEGORY] ...]\n");        usage.append("              [--ignore-crashes] [--ignore-timeouts]\n");        usage.append("              [--ignore-security-exceptions]\n");        usage.append("              [--monitor-native-crashes] [--ignore-native-crashes]\n");        usage.append("              [--kill-process-after-error] [--hprof]\n");        usage.append("              [--pct-touch PERCENT] [--pct-motion PERCENT]\n");        usage.append("              [--pct-trackball PERCENT] [--pct-syskeys PERCENT]\n");        usage.append("              [--pct-nav PERCENT] [--pct-majornav PERCENT]\n");        usage.append("              [--pct-appswitch PERCENT] [--pct-flip PERCENT]\n");        usage.append("              [--pct-anyevent PERCENT] [--pct-pinchzoom PERCENT]\n");        usage.append("              [--pct-permission PERCENT]\n");        usage.append("              [--pkg-blacklist-file PACKAGE_BLACKLIST_FILE]\n");        usage.append("              [--pkg-whitelist-file PACKAGE_WHITELIST_FILE]\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] ...]\n");        usage.append("              [--throttle MILLISEC] [--randomize-throttle]\n");        usage.append("              [--profile-wait MILLISEC]\n");        usage.append("              [--device-sleep-time MILLISEC]\n");        usage.append("              [--randomize-script]\n");        usage.append("              [--script-log]\n");        usage.append("              [--bugreport]\n");        usage.append("              [--periodic-bugreport]\n");        usage.append("              [--permission-target-system]\n");        usage.append("              COUNT\n");        System.err.println(usage.toString());    }}


源码部分说明

A.从run方法开始正式运行
private int run(String[] args) {
        ......
        //mMainCategories列表装载
        // now set up additional data in preparation for launch
        if (mMainCategories.size() == 0) {   //  ArrayList<String> mMainCategories
            mMainCategories.add(Intent.CATEGORY_LAUNCHER);
            mMainCategories.add(Intent.CATEGORY_MONKEY);
        }
        ......
        //打印mMainCategories列表
        if (mVerbose > 0) {
            System.out.println(":Monkey: seed=" + mSeed + " count=" + mCount);
            MonkeyUtils.getPackageFilter().dump();
            if (mMainCategories.size() != 0) {
                Iterator<String> it = mMainCategories.iterator();
                while (it.hasNext()) {
                    System.out.println(":IncludeCategory: " + it.next());
                }
            }
        }
        
        ......
}  

B.获取系统接口
 private boolean getSystemInterfaces() {
        mAm = ActivityManagerNative.getDefault();
        if (mAm == null) {
            System.err.println("** Error: Unable to connect to activity manager; is the system "
                    + "running?");
            return false;
        }

        mWm = IWindowManager.Stub.asInterface(ServiceManager.getService("window"));
        if (mWm == null) {
            System.err.println("** Error: Unable to connect to window manager; is the system "
                    + "running?");
            return false;
        }

        mPm = IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
        if (mPm == null) {
            System.err.println("** Error: Unable to connect to package manager; is the system "
                    + "running?");
            return false;
        }

        try {
            mAm.setActivityController(new ActivityController());
            mNetworkMonitor.register(mAm);
        } catch (RemoteException e) {
            System.err.println("** Failed talking with activity manager!");
            return false;
        }

        return true;
  }
 
C. 获取待测试的Activity列表
 private boolean getMainApps() {
        try {
            final int N = mMainCategories.size();
            for (int i = 0; i < N; i++) {
                Intent intent = new Intent(Intent.ACTION_MAIN);
                String category = mMainCategories.get(i);
                if (category.length() > 0) {
                    intent.addCategory(category);
                }
                List<ResolveInfo> mainApps = mPm.queryIntentActivities(intent, null, 0,
                        UserHandle.myUserId());

                if (mainApps == null || mainApps.size() == 0) {
                    System.err.println("// Warning: no activities found for category " + category);
                    continue;
                }
                if (mVerbose >= 2) { // very verbose
                    System.out.println("// Selecting main activities from category " + category);
                }
                final int NA = mainApps.size();
                for (int a = 0; a < NA; a++) {
                    ResolveInfo r = mainApps.get(a);
                    String packageName = r.activityInfo.applicationInfo.packageName;
                    if (MonkeyUtils.getPackageFilter().checkEnteringPackage(packageName)) {
                        if (mVerbose >= 2) { // very verbose
                            System.out.println("//   + Using main activity " + r.activityInfo.name
                                    + " (from package " + packageName + ")");
                        }
                        mMainApps.add(new ComponentName(packageName, r.activityInfo.name));
                    } else {
                        if (mVerbose >= 3) { // very very verbose
                            System.out.println("//   - NOT USING main activity "
                                    + r.activityInfo.name + " (from package " + packageName + ")");
                        }
                    }
                }
            }
        } catch (RemoteException e) {
            System.err.println("** Failed talking with package manager!");
            return false;
        }

        if (mMainApps.size() == 0) {
            System.out.println("** No activities found to run, monkey aborted.");
            return false;
        }

        return true;
  }


2. ActivityManagerService.java

    @Override
    public void setUserIsMonkey(boolean userIsMonkey) {
        synchronized (this) {
            synchronized (mPidsSelfLocked) {
                final int callingPid = Binder.getCallingPid();
                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
                if (precessRecord == null) {
                    throw new SecurityException("Unknown process: " + callingPid);
                }
                if (precessRecord.instrumentationUiAutomationConnection  == null) {
                    throw new SecurityException("Only an instrumentation process "
                            + "with a UiAutomation can call setUserIsMonkey");
                }
            }
            mUserIsMonkey = userIsMonkey;
        }
    }

    @Override
    public boolean isUserAMonkey() {
        synchronized (this) {
            // If there is a controller also implies the user is a monkey.
            return (mUserIsMonkey || mController != null);
        }
    }


判断当前是否处于monkey测试

使用这个方法:ActivityManager.isUserAMonkey()


运行monkey测试

adb shell回车,monkey  --ignore-crashes --ignore-timeouts --ignore-native-crashes --monitor-native-crashes --throttle 1000 -v -v -v -s 800  380000 2>/sdcard/error.txt 1>/sdcard/info.txt


Log

:Monkey: seed=800 count=380000:IncludeCategory: android.intent.category.LAUNCHER:IncludeCategory: android.intent.category.MONKEY// Selecting main activities from category android.intent.category.LAUNCHER//   + Using main activity com.android.browser.BrowserActivity (from package com.android.browser)//   + Using main activity com.android.calendar.AllInOneActivity (from package com.android.calendar)//   + Using main activity com.android.camera.CameraLauncher (from package com.android.camera3)//   + Using main activity com.android.contacts.activities.PeopleActivity (from package com.android.contacts)//   + Using main activity com.android.dialer.DialtactsActivity (from package com.android.contacts)//   + Using main activity com.android.deskclock.DeskClock (from package com.android.deskclock)//   + Using main activity com.android.email.activity.Welcome (from package com.android.email)//   + Using main activity com.android.mms.ui.ConversationList (from package com.android.mms)//   + Using main activity com.android.music.MusicBrowserActivity (from package com.android.music)//   + Using main activity com.android.music.VideoBrowserActivity (from package com.android.music)//   + Using main activity com.android.settings.Settings (from package com.android.settings)//   + Using main activity com.cmdc.phonekeeper.PhoneKeeperMainActivity (from package com.cmdc.phonekeeper)//   + Using main activity com.cyanogenmod.filemanager.activities.NavigationActivity (from package com.cyanogenmod.filemanager)//   + Using main activity com.android.gallery3d.app.GalleryActivity (from package org.codeaurora.gallery)//   + Using main activity com.android.calculator2.Calculator (from package com.android.calculator2)//   + Using main activity com.android.documentsui.LauncherActivity (from package com.android.documentsui)//   + Using main activity com.android.mplayer.VideoAlbumGrid (from package com.android.mplayer)//   + Using main activity com.android.quicksearchbox.SearchActivity (from package com.android.quicksearchbox)//   + Using main activity com.caf.fmradio.FMRadio (from package com.caf.fmradio)//   + Using main activity com.hmct.FileManager.Activity.ClassifyFileManager (from package com.hmct.FileManager.Activity)//   + Using main activity com.qti.csm.EnterSet (from package com.qti.csm)//   + Using main activity com.qualcomm.qti.carrierconfigure.ConfigurationActivity (from package com.qualcomm.qti.carrierconfigure)//   + Using main activity com.qualcomm.qti.logkit.cActivity (from package com.qualcomm.qti.logkit)//   + Using main activity com.qualcomm.qti.securemsm.mdtp.MdtpDemo.MainUserActivity (from package com.qualcomm.qti.securemsm.mdtp.MdtpDemo)//   + Using main activity com.qualcomm.qti.sensors.ui.qsensortest.TabControl (from package com.qualcomm.qti.sensors.qsensortest)//   + Using main activity com.quicinc.cne.settings.CneSettings (from package com.quicinc.cne.settings)//   + Using main activity com.quicinc.wipoweragent.WipowerAgentActivity (from package com.quicinc.wipoweragent)//   + Using main activity com.wingtech.countrycodeswitch.CountryCodeSwitchActivity (from package com.wingtech.countrycodeswitch)//   + Using main activity com.wingtech.note.list.NotesListActivity (from package com.wingtech.note)//   + Using main activity com.xxx.userservice.MainActivity (from package com.xxx.userservice)//   + Using main activity org.codeaurora.bluetooth.hidtestapp.HidTestApp (from package org.codeaurora.bluetooth.hidtestapp)//   + Using main activity com.android.anim.RecentsActivity (from package com.android.anim)//   + Using main activity com.example.android.multiwindow.LaunchingAdjacentActivity (from package com.example.android.multiwindow)//   + Using main activity com.example.navigationdrawer.MainActivity (from package com.example.navigationdrawer)// Selecting main activities from category android.intent.category.MONKEY//   + Using main activity com.android.launcher3.Launcher (from package com.android.launcher3)//   + Using main activity com.android.settings.Settings$RunningServicesActivity (from package com.android.settings)//   + Using main activity com.android.settings.Settings$StorageUseActivity (from package com.android.settings)// Seeded: 800// Event percentages://   0: 15.0%//   1: 10.0%//   2: 2.0%//   3: 15.0%//   4: -0.0%//   5: -0.0%//   6: 25.0%//   7: 15.0%//   8: 2.0%//   9: 2.0%//   10: 1.0%//   11: 13.0%:Switch: #Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.android.calendar/.AllInOneActivity;end    // Allowing start of Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.android.calendar/.AllInOneActivity } in package com.android.calendarSleeping for 1000 milliseconds:Sending Trackball (ACTION_MOVE): 0:(3.0,2.0):Sending Trackball (ACTION_MOVE): 0:(0.0,-3.0):Sending Trackball (ACTION_MOVE): 0:(1.0,3.0):Sending Trackball (ACTION_MOVE): 0:(0.0,-3.0):Sending Trackball (ACTION_MOVE): 0:(-2.0,-5.0):Sending Trackball (ACTION_MOVE): 0:(-4.0,-3.0):Sending Trackball (ACTION_MOVE): 0:(-1.0,2.0):Sending Trackball (ACTION_MOVE): 0:(-5.0,-4.0):Sending Trackball (ACTION_MOVE): 0:(-4.0,-4.0):Sending Trackball (ACTION_MOVE): 0:(1.0,-1.0):Sending Trackball (ACTION_MOVE): 0:(-1.0,-5.0):Sending Trackball (ACTION_MOVE): 0:(-1.0,0.0):Sending Trackball (ACTION_MOVE): 0:(-3.0,-3.0):Sending Trackball (ACTION_MOVE): 0:(1.0,-4.0):Sending Trackball (ACTION_MOVE): 0:(0.0,-3.0):Sending Trackball (ACTION_MOVE): 0:(-5.0,1.0):Sending Trackball (ACTION_MOVE): 0:(-3.0,0.0):Sending Trackball (ACTION_MOVE): 0:(-2.0,4.0):Sending Trackball (ACTION_MOVE): 0:(3.0,-4.0):Sending Trackball (ACTION_MOVE): 0:(0.0,2.0):Sending Key (ACTION_DOWN): 25    // KEYCODE_VOLUME_DOWN:Sending Key (ACTION_UP): 25    // KEYCODE_VOLUME_DOWNSleeping for 1000 milliseconds:Sending Touch (ACTION_DOWN): 0:(345.0,830.0):Sending Touch (ACTION_UP): 0:(334.6787,838.3302)Sleeping for 1000 milliseconds:Sending Key (ACTION_DOWN): 82    // KEYCODE_MENU:Sending Key (ACTION_UP): 82    // KEYCODE_MENUSleeping for 1000 milliseconds:Sending Key (ACTION_DOWN): 82    // KEYCODE_MENU:Sending Key (ACTION_UP): 82    // KEYCODE_MENUSleeping for 1000 milliseconds:Sending Touch (ACTION_DOWN): 0:(41.0,133.0):Sending Touch (ACTION_MOVE): 0:(49.90042,140.75574):Sending Touch (ACTION_MOVE): 0:(52.748535,158.99876):Sending Touch (ACTION_MOVE): 0:(56.985256,172.18214):Sending Touch (ACTION_UP): 0:(60.56301,173.46811)Sleeping for 1000 milliseconds

停止monke测试

$adb shell kill -9 `adb shell ps | grep "com.android.commands.monkey" | awk '{print $2}'`

原文地址:http://blog.csdn.net/yelangjueqi/article/details/58594383

0 0
原创粉丝点击