Android-Monkey解析(二)

Android-Monkey详细分解

1. Monkey核心变量

Monkey.mAm:使用AMS系统服务提供的功能(跨进程调用)

Monkey.mWm:使用WMS系统服务提供的功能(跨进程调用)

Monkey.mPm:使用PMS系统服务提供的功能(跨进程调用)

Monkey.mEventSource:存放待执行随机事件

graph TD
  Monkey.mAm --> android.app.IActivityManager[依赖 Android.app.IActivityManager]
    Monkey.mWm --> android.view.IWindowManager[依赖 Android.view.IWindowManager]
    Monkey.mPm --> android.content.pm.IPackageManager[依赖 Android.content.pm.IPackageManager]
    Monkey.mEventSource --> MonkeyEventSource
    mNetworkMonitor --> MonkeyNetworkMonitor
    MonkeyNetworkMonitor --> android.content.IIntentReceiver[依赖 Android.content.IIntentReceiver]

2. Monkey四种事件源

  1. 随机种子+随机数生成器随机生成事件:MonkeySourceRandom
  2. 单个Monkey脚本中的事件:MonkeySourceScript
  3. N个Monkey脚本中的随机事件:MonkeySourceRandomScript
  4. 云端获取Monkey事件:MonkeySourceNetwork
graph TD
  MonkeyEventSource --> MonkeySourceRandom
  MonkeyEventSource --> MonkeySourceScript
    MonkeyEventSource --> MonkeySourceRandomScript
    MonkeyEventSource --> MonkeySourceNetwork

2. Monkey.java核心流程解析

Monkey run的主流程:

  1. 解析所有命令行输入参数
  2. 依次判断如下输入参数
    • 判断是否带有–wait-dbg参数:延迟执行、或立即执行
    • 判断是否带有-c参数:加载指定类别、或默认类别
    • 判断是否带有-s参数:指定随机种子、或默认自动生成新的随机种子
  3. 获取测试环境
    • 加载正确被测Package名:基于黑白名单加载被测Package
    • 获取所有可获取的系统接口,即系统服务的初始化:AMS、PMS、WMS
    • 获取(受限)被测activity列表:-p、-s
  4. 基于不同模式执行Monkey动作
    • 单一脚本模式执行:-setup
    • 多脚本模式执行:–randomize-script -f
    • 获取云上脚本执行:–port
    • 本地随机生成事件执行:默认
  5. 监控并生成分析报告
    • 监控crash并统计
    • 执行前、后生成分析报告:–hprof
graph TD    
  Monkey.main[入口 main] --> Android.os.Process.setArgV0(依赖 Android.os.Process)
  Android.os.Process.setArgV0 --> Monkey.run[运行 run]
  Monkey.run --> Monkey.args_debug[是否含有debug参数]
  Monkey.args_debug --true--> Android.os.Debug[依赖 Android.os.Debug]
  Monkey.args_debug --false--> Monkey.processOptions[是否正确解析参数 processOptions]
  Android.os.Debug --> Monkey.processOptions
  Monkey.processOptions --true--> Monkey.loadPackageLists[是否加载正确包列表 loadPackageLists]
  Monkey.processOptions --false--> Monkey.Return[Monkey.Return:-1,-2,-3,-4]
  Monkey.loadPackageLists --true--> Monkey.mMainCategories_0[是否指定类别 mMainCategories==0]
  Monkey.loadPackageLists --false--> Monkey.Return
  Monkey.mMainCategories_0 --true--> Monkey.mSeed_0[是否指定随机种子 Monkey.mSeed==0]
  Monkey.mMainCategories_0 --false--> Monkey.mMainCategories.add[加载默认类别 Monkey.mMainCategories.add]
  Monkey.mMainCategories.add --> Monkey.mSeed_0
  Monkey.mSeed_0 --true--> System.currentTimeMillis[依赖Java原生库生成随机种子 System.currentTimeMillis]
  Monkey.mSeed_0 --false--> Monkey.getSystemInterfaces
  checkInternalConfiguration[待分析 checkInternalConfiguration]
  checkInternalConfiguration --false--> Monkey.Return
  System.currentTimeMillis --> Monkey.getSystemInterfaces[获取系统所有接口 Monkey.getSystemInterfaces]
  Monkey.getSystemInterfaces --false--> Monkey.Return
  Monkey.getSystemInterfaces --true--> Monkey.getMainApps[是否获得被测APPs Monkey.getMainApps]
  Monkey.getMainApps --true--> java.util.Random[依靠java原生库创建随机数生成器 java.util.Random]
  Monkey.getMainApps --false--> Monkey.Return
  java.util.Random --> mScriptFileNames_size_1[是否输入单一脚本 mScriptFileNames.size == 1]
  mScriptFileNames_size_1 --true--> MonkeySourceScript[事件序列为单个脚本 MonkeySourceScript]
  mScriptFileNames_size_1 --false--> Monkey.mScriptFileNames_size_n[是否输入多个脚本 Monkey.mScriptFileNames.size > 1]
  Monkey.mScriptFileNames_size_n --true--> MonkeySourceRandomScript[事件序列为随机的输入脚本 MonkeySourceRandomScript]
  Monkey.mScriptFileNames_size_n --false--> Monkey.mServerPort[是否指定联网获取事件序列 mServerPort != -1]
  Monkey.mServerPort --true--> MonkeySourceNetwork[事件序列为从云上中获取的脚本 MonkeySourceNetwork]
  Monkey.mServerPort --false--> MonkeySourceRandom[事件序列为本地随机生成 MonkeySourceRandom]
  MonkeySourceRandom --> mEventSource.validate[验证随机生成事件序列是否有效 mEventSource.validate]
  MonkeySourceNetwork --> mEventSource.validate
  MonkeySourceRandomScript --> mEventSource.validate
  MonkeySourceScript --> mEventSource.validate
  mEventSource.validate --> mGenerateHprof[是否生成分析报告 mGenerateHprof]
  mGenerateHprof --true--> Monkey.mAm.signalPersistentProcesses[应用报告同步打印 Monkey.mAm.signalPersistentProcesses]
  Monkey.mAm.signalPersistentProcesses --> MonkeyNetworkMonitor.mNetworkMonitor.start[启动监控器用于监控执行过程 mNetworkMonitor.start]
  mGenerateHprof --false--> MonkeyNetworkMonitor.mNetworkMonitor.start
  MonkeyNetworkMonitor.mNetworkMonitor.start --> runMonkeyCycles[循环注入事件 runMonkeyCycles]
  runMonkeyCycles --> MonkeyNetworkMonitor.mNetworkMonitor.stop[停止监控器 mNetworkMonitor.stop]
  MonkeyNetworkMonitor.mNetworkMonitor.stop --> mGenerateHprof
  MonkeyNetworkMonitor.mNetworkMonitor.stop --> clean_env[最后检查,收集日志,AMS解锁,事件状态dump,网络状态dump]