# Script to start "monkey" on the device, which has a very rudimentary # shell. # base=/system export CLASSPATH=$base/framework/monkey.jar trap "" HUP for a in "$@"; do echo " bash arg:" $a done exec app_process $base/bin com.android.commands.monkey.Monkey "$@"
publicstaticvoidmain(String[] args){ // Set the process name showing in "ps" or "top" Process.setArgV0("com.android.commands.monkey"); // 运行Monkey int resultCode = (new Monkey()).run(args); // 退出 System.exit(resultCode); }
// 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; } // 解析Monkey参数并逐一赋值 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 (mVerbose > 0) { System.out.println(":Monkey: seed=" + mSeed + " count=" + mCount); if (mValidPackages.size() > 0) { Iterator<String> it = mValidPackages.iterator(); while (it.hasNext()) { System.out.println(":AllowPackage: " + it.next()); } } if (mInvalidPackages.size() > 0) { Iterator<String> it = mInvalidPackages.iterator(); while (it.hasNext()) { System.out.println(":DisallowPackage: " + it.next()); } } if (mMainCategories.size() != 0) { Iterator<String> it = mMainCategories.iterator(); while (it.hasNext()) { System.out.println(":IncludeCategory: " + it.next()); } } }
if (!checkInternalConfiguration()) { return -2; } // 以上获取到了ActivityManager,WindowManager,PackageManager三大系统资源 // 通过ActivityManager调用setActivityController()方法对测试生命周期进行监控 // 通过WindowManager的方法将事件注入到应用中,实现事件操作 // 通过PackageManager获取Intent中应用列表,方便多应用之间切换 if (!getSystemInterfaces()) { return -3; }
if (!getMainApps()) { return -4; }
mRandom = new SecureRandom(); mRandom.setSeed((mSeed == 0) ? -1 : mSeed); // 脚本事件源:带-f参数且脚本数等于1 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; // 脚本事件源:带-f参数且脚本数大于1 } elseif (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; // 远程调用事件源:带--port参数 } elseif (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); 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(); // 开始执行Monkey int crashedAtCycle = runMonkeyCycles(); mNetworkMonitor.stop(); // 打印ANR,Crash报告 synchronized (this) { if (mRequestAnrTraces) { reportAnrTraces(); mRequestAnrTraces = false; } if (mRequestAnrBugreport){ System.out.println("Print the anr report"); getBugreport("anr_" + mReportProcessName + "_"); mRequestAnrBugreport = false; } if (mRequestAppCrashBugreport){ getBugreport("app_crash" + mReportProcessName + "_"); mRequestAppCrashBugreport = false; } if (mRequestDumpsysMemInfo) { reportDumpsysMemInfo(); mRequestDumpsysMemInfo = false; } if (mRequestPeriodicBugreport){ getBugreport("Bugreport_"); mRequestPeriodicBugreport = false; } }
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; } }