11package com.chimerapps.discovery.device.adb
22
3- import com.chimerapps.discovery.utils.Platform
4- import com.chimerapps.discovery.utils.currentPlatform
5- import com.chimerapps.discovery.utils.debug
6- import com.chimerapps.discovery.utils.info
7- import com.chimerapps.discovery.utils.logger
8- import com.chimerapps.discovery.utils.warn
9- import se.vidstige.jadb.JadbConnection
10- import java.io.File
11- import java.util.ArrayList
12- import java.util.HashSet
13- import java.util.concurrent.TimeUnit
3+ import com.chimerapps.discovery.device.debugbridge.DebugBridgeBootstrap
4+ import com.chimerapps.discovery.device.sdb.SDBDevice
145
156/* *
167 * @author Nicola Verbeeck
178 */
18- class ADBBootstrap (private val sdkPathGuesses : Collection <String >, private val adbPathProvider : (() -> String? )? = null ) {
19-
20- companion object {
21- private val log = logger<ADBBootstrap >()
22- private const val DEFAULT_ADB_TIMEOUT_S = 4L
23- private val platformExt: String by lazy { if (currentPlatform == Platform .WINDOWS ) " .exe" else " " }
24-
25- private fun determineExecutablePath (name : String ): String? {
26- val foundPath = System .getenv(" PATH" ).split(File .pathSeparator).find {
27- val file = File (it, name)
28- file.exists() && file.canExecute()
29- }
30- if (foundPath != null )
31- return " $foundPath${File .separator}$name "
32- return null
33- }
34-
35- private fun findADB (sdkPathGuesses : Collection <String >): String? {
36- findAndroidSdkDirs(sdkPathGuesses).forEach {
37- val file = hasValidAdb(it)
38- if (file != null )
39- return file.absolutePath
40- }
41- log.info(" Failed to find android sdk dir, searching path" )
42-
43- return determineExecutablePath(" adb$platformExt " )
44- }
45-
46- private fun hasValidAdb (sdkDir : String ): File ? {
47- log.debug(" Found android sdk at $sdkDir " )
48- val adbFile = File (" $sdkDir${File .separator} platform-tools${File .separator} adb$platformExt " )
49- if (adbFile.exists() && adbFile.canExecute())
50- return adbFile
51-
52- log.warn(" Could not find adb at $adbFile -> Exist: ${adbFile.exists()} , Can execute: ${adbFile.canExecute()} " )
53- return null
54- }
55-
56- private fun findAndroidSdkDirs (sdkPathGuesses : Collection <String >): Collection <String > {
57- val list = HashSet <String >(sdkPathGuesses)
58- val env = System .getenv(" ANDROID_HOME" )
59- if (env != null ) {
60- log.info(" Got android sdk dir from env variable: $env " )
61- list + = env
62- }
63- return list
64- }
65-
66- }
67-
68- val pathToAdb: String?
69- get() = adbPathProvider?.invoke() ? : findADB(sdkPathGuesses)
70- private var hasBootStrap = false
71-
72- fun bootStrap (): ADBInterface {
73- val pathToAdb = pathToAdb
74- if (! hasBootStrap && pathToAdb != null && File (pathToAdb).let { it.exists() && it.canExecute() }) {
75- try {
76- executeADBCommand(" start-server" )
77- hasBootStrap = true
78- } catch (e: Throwable ) {
79- }
80- }
81- if (pathToAdb == null || ! File (pathToAdb).let { it.exists() && it.canExecute() })
82- return ADBInterface (connection = null , bootstrap = this )
83- return ADBInterface (connection = JadbConnection (), bootstrap = this )
84- }
85-
86- fun executeADBCommand (vararg commands : String ) = executeADBCommand(DEFAULT_ADB_TIMEOUT_S , * commands)
87-
88- fun executeADBCommand (timeoutInSeconds : Long , vararg commands : String ): String? {
89- return (adbPathProvider?.invoke() ? : pathToAdb)?.let {
90- val builder = ProcessBuilder (it.prepend(commands))
91- val process = builder.start()
92- val success = process.waitFor(timeoutInSeconds, TimeUnit .SECONDS )
93- val response = if (success) {
94- val response = process.inputStream.bufferedReader().readText().trim()
95- val error = process.errorStream.bufferedReader().readText()
96- if (error.isNotBlank())
97- System .err.println (error)
98- response
99- } else
100- null
101- try {
102- if (! success)
103- process.destroy()
104- } catch (e: Throwable ) {
105- e.printStackTrace()
106- }
107-
108- response
109- }
110- }
111-
112- }
113-
114- private fun String.prepend (list : Array <out String >): List <String > {
115- val newList = ArrayList <String >(list.size + 1 )
116- newList + = this
117- newList + = list
118- return newList
119- }
9+ class ADBBootstrap (
10+ sdkPathGuesses : Collection <String >,
11+ adbPathProvider : (() -> String? )? = null ,
12+ ) : DebugBridgeBootstrap(
13+ toolExecutableName = " adb" ,
14+ toolName = " android" ,
15+ sdkPathEnvironmentVariable = " ANDROID_HOME" ,
16+ sdkPathGuesses = sdkPathGuesses,
17+ debugBridgePathProvider = adbPathProvider,
18+ deviceBridgeServerPort = 5037 ,
19+ deviceCreator = { device, bootstrap -> SDBDevice (device, bootstrap) },
20+ sdkToolSubDirectory = " platform-tools" ,
21+ )
0 commit comments