@@ -4,11 +4,11 @@ import java.io.File
4
4
import java.util.*
5
5
import java.util.concurrent.TimeUnit
6
6
7
- class Deployer {
7
+ class Deployer ( private val adbDeviceName : String? ) {
8
8
9
9
private val soName = " libcoverage_instrumenting_agent.so"
10
10
11
- fun deploy (packageName : String , adbDeviceName : String? ) {
11
+ fun deploy (packageName : String ) {
12
12
println (" Instrumenting app $packageName with coverage agent." )
13
13
// Get the architecture of the device.
14
14
val architecture = getDeviceArchitecture(adbDeviceName)
@@ -18,11 +18,11 @@ class Deployer {
18
18
val library = File (" runtime_cpp/build/intermediates/merged_native_libs/debug/out/lib/${architecture} /${soName} " )
19
19
println (" [i] Using library: ${library.absolutePath} " )
20
20
21
- runAdbCommand(adbDeviceName, " push" , library.absolutePath, " /data/local/tmp/" )
21
+ runAdbCommand(" push" , library.absolutePath, " /data/local/tmp/" )
22
22
println (" [+] Pushed library to /data/local/tmp/${soName} " )
23
23
24
24
println (" [i] Trying to use run-as to copy to startup_agents" )
25
- val copyDestinationWithRunAs = tryToCopyLibraryWithRunAs(packageName, adbDeviceName )
25
+ val copyDestinationWithRunAs = tryToCopyLibraryWithRunAs(packageName)
26
26
if (copyDestinationWithRunAs.isPresent) {
27
27
println (" [+] Library copied to ${copyDestinationWithRunAs.get()} " )
28
28
return
@@ -31,7 +31,7 @@ class Deployer {
31
31
println (" [x] run-as failed, using su permissions instead." )
32
32
33
33
// Use dumpsys package to figure out the data directory and user id of the application.
34
- val dumpSysOutput = runAdbCommand(adbDeviceName, " shell" , " dumpsys" , " package" , packageName)
34
+ val dumpSysOutput = runAdbCommand(" shell" , " dumpsys" , " package" , packageName)
35
35
36
36
var dataDir: String? = null
37
37
var userId: String? = null
@@ -46,33 +46,33 @@ class Deployer {
46
46
}
47
47
println (" [i] Grabbed app's dataDir=$dataDir and userId=$userId " )
48
48
49
- runAdbCommand(adbDeviceName,
49
+ runAdbCommand(
50
50
" shell" , " su" , userId, " \" mkdir -p $dataDir /code_cache/startup_agents/\" " )
51
- runAdbCommand(adbDeviceName,
51
+ runAdbCommand(
52
52
" shell" , " su" , userId, " \" cp /data/local/tmp/${soName} $dataDir /code_cache/startup_agents/\" " )
53
53
println (" [+] Library copied to $dataDir /code_cache/startup_agents/" )
54
54
}
55
55
56
56
private fun getDeviceArchitecture (adbDeviceName : String? ): String {
57
- return runAdbCommand(adbDeviceName, " shell" , " getprop" , " ro.product.cpu.abi" ).trim()
57
+ return runAdbCommand(" shell" , " getprop" , " ro.product.cpu.abi" ).trim()
58
58
}
59
59
60
- private fun tryToCopyLibraryWithRunAs (packageName : String , adbDeviceName : String? ): Optional <String > {
60
+ private fun tryToCopyLibraryWithRunAs (packageName : String ): Optional <String > {
61
61
return try {
62
- runAdbCommand(adbDeviceName, " shell" , " run-as" , packageName, " mkdir -p code_cache/startup_agents/" )
63
- runAdbCommand(adbDeviceName, " shell" , " run-as" , packageName, " cp /data/local/tmp/${soName} code_cache/startup_agents/" )
62
+ runAdbCommand(" shell" , " run-as" , packageName, " mkdir -p code_cache/startup_agents/" )
63
+ runAdbCommand(" shell" , " run-as" , packageName, " cp /data/local/tmp/${soName} code_cache/startup_agents/" )
64
64
65
- Optional .of(runAdbCommand(adbDeviceName, " shell" , " run-as" , packageName, " pwd" ))
65
+ Optional .of(runAdbCommand(" shell" , " run-as" , packageName, " pwd" ))
66
66
} catch (e: RuntimeException ) {
67
67
Optional .empty()
68
68
}
69
69
}
70
70
71
- private fun runAdbCommand (adbDeviceName : String? , vararg command : String ): String {
71
+ fun runAdbCommand (vararg command : String ): String {
72
72
val adbCommand = mutableListOf (" adb" )
73
- if (adbDeviceName != null ) {
73
+ if (this . adbDeviceName != null ) {
74
74
adbCommand.add(" -s" )
75
- adbCommand.add(adbDeviceName)
75
+ adbCommand.add(this . adbDeviceName)
76
76
}
77
77
adbCommand.addAll(command)
78
78
return runCommandAndGetOutput(adbCommand)
@@ -100,9 +100,16 @@ class Deployer {
100
100
101
101
fun main (args : Array <String >) {
102
102
if (args.isEmpty()) {
103
- println (" Usage: Deployer <android-package-name> [adb-device-name]" )
103
+ println (" Usage: Deployer <android-package-name> [--device= adb-device-name] [--force-debuggable ]" )
104
104
return
105
105
}
106
106
107
- Deployer ().deploy(packageName = args[0 ], adbDeviceName = args.getOrNull(1 ))
107
+ val deviceName = args.filter { it.startsWith(" --device=" ) }.map { it.replace(" --device=" , " " ) }.firstOrNull()
108
+
109
+ val deployer = Deployer (deviceName)
110
+ if (" --force-debuggable" in args) {
111
+ ForceAppDebuggable (deployer).makeDebuggable(packageName = args[0 ])
112
+ }
113
+
114
+ deployer.deploy(packageName = args[0 ])
108
115
}
0 commit comments