Commit a68566a7 authored by liuyang's avatar liuyang

APK图片抓取识别及轮播流地址抓取,ftp上传处理

#BYLSERVER-1438
parent 661cd827
......@@ -12,6 +12,7 @@
<application
android:allowBackup="true"
android:name=".DlbRobotApp"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
......
......@@ -5,7 +5,7 @@
"launchDelay": "15",
"captureDelay": "15",
"channelKeyEvent": "down",
"channelCount": "10",
"channelCount": "2",
"mediaExt": "m3u8|.mp4",
"menuKeyEvent": "ok"
}
\ No newline at end of file
package com.duolebo.blyrobot
import android.app.Application
import net.gotev.uploadservice.UploadService
import net.gotev.uploadservice.okhttp.OkHttpStack
import okhttp3.OkHttpClient
class DlbRobotApp: Application() {
override fun onCreate() {
super.onCreate()
UploadService.NAMESPACE = BuildConfig.APPLICATION_ID
UploadService.NAMESPACE = this.packageName
val client = OkHttpClient()
UploadService.HTTP_STACK = OkHttpStack(client)
}
}
\ No newline at end of file
......@@ -10,8 +10,12 @@ import com.duolebo.blyrobot.protocol.ApkReportProtocol
import com.duolebo.blyrobot.util.AdbUtil
import com.duolebo.blyrobot.util.AppUtil
import com.duolebo.blyrobot.util.Config
import net.gotev.uploadservice.ServerResponse
import net.gotev.uploadservice.UploadInfo
import net.gotev.uploadservice.UploadNotificationConfig
import net.gotev.uploadservice.UploadStatusDelegate
import net.gotev.uploadservice.ftp.FTPUploadRequest
import net.gotev.uploadservice.ftp.UnixPermissions
import org.json.JSONObject
import java.io.File
import java.text.SimpleDateFormat
......@@ -30,6 +34,8 @@ class Task : IAppBaseCallback {
private var capturePath = Environment
.getExternalStorageDirectory().absolutePath + "/capture.txt"
private var uploadImages = ArrayList<String>()
private var channelIndex = 0
private var reportProtocol: ApkReportProtocol
......@@ -50,7 +56,7 @@ class Task : IAppBaseCallback {
this.apkInfo = apkInfo
// this.imagePath = this.context.cacheDir.absolutePath + "/" + apkInfo.packageName
this.imagePath = Environment
.getExternalStorageDirectory().absolutePath + "/" + apkInfo.packageName
.getExternalStorageDirectory().absolutePath + "/upload/" + apkInfo.packageName
val dir = File(this.imagePath)
if (!dir.exists())
dir.mkdirs()
......@@ -82,29 +88,34 @@ class Task : IAppBaseCallback {
}
AdbUtil.launchApp("${this.apkInfo.packageName}/${this.apkInfo.launcher}")
Thread.sleep(2 * 1000L)
// 启动2s开始抓取,避免第一个频道没有抓到
capture(this.apkInfo.launchDelay + this.apkInfo.captureDelay)
Thread.sleep(this.apkInfo.launchDelay * 1000L)
}
private fun processChannels() {
Log.i(TAG, "processChannels")
step()
for (i in 1..this.apkInfo.channelCount) {
for (i in 1 until this.apkInfo.channelCount) {
// 模拟按键事件. 切换频道进行抓取
this.channelIndex = i
capture(apkInfo.captureDelay)
AdbUtil.sendMultiKey(this.apkInfo.channelKeyEvent)
step()
}
}
private fun step() {
capture()
// 截图保存
val screenShots = saveScreenShot()
if (screenShots.size > 0)
uploadImages.addAll(screenShots)
val playUrlItems = analysisCapture()
}
// 抓包处理
private fun capture() {
private fun capture(delay: Int) {
Log.i(TAG, "capture")
val file = File(this.capturePath)
if (file.exists())
......@@ -112,8 +123,8 @@ class Task : IAppBaseCallback {
Thread(Runnable {
proc = AdbUtil.tcpCapture(this.capturePath)
}).start()
Log.i(TAG, "capture sleep ${this.apkInfo.captureDelay} seconds")
Thread.sleep(this.apkInfo.captureDelay * 1000L)
Log.i(TAG, "capture sleep $delay seconds")
Thread.sleep(delay * 1000L)
proc?.destroy()
AdbUtil.killTcpdump()
Thread.sleep(2000L)
......@@ -122,8 +133,10 @@ class Task : IAppBaseCallback {
// 分析http抓包文件
private fun analysisCapture(): ArrayList<PlayInfo> {
val playUrlItems = ArrayList<PlayInfo>()
val file = File(Environment
.getExternalStorageDirectory().absolutePath + "/capture.txt")
val file = File(this.capturePath)
if (!file.exists())
return playUrlItems
val lines = file.readLines()
var partUrl = ""
......@@ -206,24 +219,62 @@ class Task : IAppBaseCallback {
AppUtil.pngToJpg(pngPath, jpgPath)
}
private fun uploadComplete(errorCount: Int) {
report()
}
private fun uploadImageCallback(): UploadStatusDelegate {
val totalUpload = this.uploadImages.size
var uploadCount = 0
return object: UploadStatusDelegate {
override fun onCancelled(context: Context?, uploadInfo: UploadInfo?) {
}
override fun onProgress(context: Context?, uploadInfo: UploadInfo?) {
}
override fun onError(context: Context?, uploadInfo: UploadInfo?, serverResponse: ServerResponse?, exception: java.lang.Exception?) {
Log.i(TAG, "upload error " + uploadInfo?.toString())
uploadCount++
if (uploadCount == totalUpload) {
uploadComplete(uploadCount - uploadInfo?.successfullyUploadedFiles!!.size)
}
}
override fun onCompleted(context: Context?, uploadInfo: UploadInfo?, serverResponse: ServerResponse?) {
uploadCount++
if (uploadCount == totalUpload) {
uploadComplete(uploadCount - uploadInfo?.successfullyUploadedFiles!!.size)
}
}
}
}
private fun uploadImage() {
try {
val uploadRequest = FTPUploadRequest(context, "ftp.duolebo.com", 21)
.setUsernameAndPassword("user", "password")
val uploadRequest = FTPUploadRequest(context, Config.instance.getFtpServer(), 21)
.setUsernameAndPassword(Config.instance.getFtpUserName(), Config.instance.getFtpPassword())
.setNotificationConfig(UploadNotificationConfig())
.setCreatedDirectoriesPermissions(UnixPermissions("777"))
.setSocketTimeout(5000)
.setConnectTimeout(5000)
.setDelegate(uploadImageCallback())
.setMaxRetries(4)
val dir = File(imagePath)
dir.listFiles().forEach {
uploadRequest.addFileToUpload(it.absolutePath, "/remote/path")
this.uploadImages.forEach {
val uploadFile = File(it)
if (uploadFile.exists()) {
uploadRequest.addFileToUpload(it, Config.instance.getFtpRemotePath())
}
}
val uploadId = uploadRequest.startUpload()
Log.i(TAG, "upload id $uploadId")
} catch (exc: Exception) {
Log.e("AndroidUploadService", exc.message, exc)
Log.e(TAG, exc.message, exc)
}
}
private fun report() {
......
......@@ -55,7 +55,9 @@ class TaskManager {
}
fun stop() {
this.tasks.clear()
this.tasks.forEach {
}
this.isRunning = false
}
......
......@@ -210,6 +210,7 @@ object AdbUtil {
try {
dos = DataOutputStream(proc!!.outputStream)
dos.write(captureCmd.toByteArray())
dos.writeBytes(LINE_BREAK)
dos.flush()
val result = proc.waitFor()
......@@ -292,6 +293,18 @@ object AdbUtil {
}
}
fun isAppActive(packageName: String): Boolean {
val result = exeCmdEcho("dumpsys activity | grep mFocusedActivity", true)
if (result.status == 0) {
for (line in result.successLines) {
if (line.contains(packageName))
return true
}
}
return false
}
fun resetApp(packageName: String) {
exeCmdEcho("pm clear $packageName", true)
}
......
......@@ -25,6 +25,22 @@ class Config: IProtocolConfig {
return "http://test.duolebo.com/staging/apkReport/report.do"
}
fun getFtpServer(): String {
return "192.168.2.195"
}
fun getFtpUserName(): String {
return "mateng"
}
fun getFtpPassword(): String {
return "qwertasdfg"
}
fun getFtpRemotePath(): String {
return "/upload"
}
companion object {
val instance = Config()
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment