Set AETHERFORGE env vars in APK wrapper before agent spawn.
Java AgentProcess passes SERVER_URL, WORKER_NUMBER, PLATFORM=android, and Wi-Fi/battery/foreground-service probes to the embedded Go worker.
This commit is contained in:
@@ -5,6 +5,7 @@ import org.json.JSONObject
|
||||
|
||||
data class AgentConfig(
|
||||
val workerName: String,
|
||||
val workerNumber: String,
|
||||
val serverUrl: String,
|
||||
val fleetSecret: String?,
|
||||
val miningEnabled: Boolean,
|
||||
@@ -19,6 +20,9 @@ data class AgentConfig(
|
||||
val json = assetJson?.let { JSONObject(it) }
|
||||
val worker = intentExtras["worker_name"]
|
||||
?: json?.optString("worker_name").orEmpty()
|
||||
val workerNumber = intentExtras["worker_number"]
|
||||
?: json?.optString("worker_number")
|
||||
?: worker
|
||||
val server = intentExtras["server_url"]
|
||||
?: json?.optString("server_url").orEmpty()
|
||||
val secret = intentExtras["fleet_secret"]
|
||||
@@ -28,6 +32,7 @@ data class AgentConfig(
|
||||
|
||||
return AgentConfig(
|
||||
workerName = worker.ifBlank { "android-fleet-node" },
|
||||
workerNumber = workerNumber.ifBlank { worker.ifBlank { "android-fleet-node" } },
|
||||
serverUrl = server.ifBlank { "http://127.0.0.1:8989" },
|
||||
fleetSecret = secret,
|
||||
miningEnabled = mining,
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
package com.aetherforge.agent
|
||||
|
||||
import android.util.Log
|
||||
import android.content.Context
|
||||
import android.net.ConnectivityManager
|
||||
import android.net.NetworkCapabilities
|
||||
import android.os.BatteryManager
|
||||
import android.os.Build
|
||||
import java.io.File
|
||||
|
||||
object AgentProcess {
|
||||
@@ -8,14 +13,24 @@ object AgentProcess {
|
||||
@Volatile
|
||||
private var process: Process? = null
|
||||
|
||||
fun start(binary: File, filesDir: File, config: AgentConfig) {
|
||||
fun start(
|
||||
binary: File,
|
||||
filesDir: File,
|
||||
config: AgentConfig,
|
||||
probeEnv: Map<String, String> = emptyMap(),
|
||||
) {
|
||||
stop()
|
||||
val env = hashMapOf(
|
||||
"HOME" to filesDir.absolutePath,
|
||||
"TMPDIR" to filesDir.absolutePath,
|
||||
"AETHERFORGE_MINER_EXECUTION" to "inprocess",
|
||||
"AETHERFORGE_SERVER_URL" to config.serverUrl,
|
||||
"AETHERFORGE_WORKER_NUMBER" to config.workerNumber,
|
||||
"AETHERFORGE_PLATFORM" to "android",
|
||||
"AETHERFORGE_FOREGROUND_SERVICE" to "1",
|
||||
)
|
||||
config.fleetSecret?.let { env["AETHERFORGE_FLEET_SECRET"] = it }
|
||||
env.putAll(probeEnv)
|
||||
|
||||
val cmd = listOf(binary.absolutePath, "--run")
|
||||
Log.i(TAG, "spawning agent: ${cmd.joinToString(" ")}")
|
||||
@@ -39,6 +54,30 @@ object AgentProcess {
|
||||
}
|
||||
}
|
||||
|
||||
fun probeEnvironment(context: Context): Map<String, String> {
|
||||
val wifi = runCatching {
|
||||
val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
|
||||
val network = cm.activeNetwork ?: return@runCatching false
|
||||
val caps = cm.getNetworkCapabilities(network) ?: return@runCatching false
|
||||
caps.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
|
||||
}.getOrDefault(false)
|
||||
|
||||
val batteryOk = runCatching {
|
||||
val bm = context.getSystemService(Context.BATTERY_SERVICE) as BatteryManager
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
val level = bm.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY)
|
||||
level >= 15
|
||||
} else {
|
||||
true
|
||||
}
|
||||
}.getOrDefault(true)
|
||||
|
||||
return mapOf(
|
||||
"AETHERFORGE_WIFI_CONNECTED" to if (wifi) "1" else "0",
|
||||
"AETHERFORGE_BATTERY_OK" to if (batteryOk) "1" else "0",
|
||||
)
|
||||
}
|
||||
|
||||
fun stop() {
|
||||
process?.let {
|
||||
runCatching { it.destroy() }
|
||||
|
||||
@@ -70,7 +70,7 @@ class AgentService : Service() {
|
||||
}
|
||||
|
||||
if (!AgentProcess.isAlive()) {
|
||||
AgentProcess.start(binary, filesDir, config)
|
||||
AgentProcess.start(binary, filesDir, config, AgentProcess.probeEnvironment(this))
|
||||
}
|
||||
return START_STICKY
|
||||
}
|
||||
|
||||
@@ -1,11 +1,4 @@
|
||||
{
|
||||
"build_id": "android-dev",
|
||||
"fleet_secret_set": false,
|
||||
"mining": {
|
||||
"enabled": false,
|
||||
"mode": "idle",
|
||||
"note": "CPU mining disabled by default; enable via server policy or re-forge."
|
||||
},
|
||||
"server_url": "http://test:8989",
|
||||
"worker_name": "test-node"
|
||||
}
|
||||
"server_url": "http://192.168.1.10:8989",
|
||||
"worker_name": "tablet-1"
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import org.json.JSONObject
|
||||
|
||||
data class AgentConfig(
|
||||
val workerName: String,
|
||||
val workerNumber: String,
|
||||
val serverUrl: String,
|
||||
val fleetSecret: String?,
|
||||
val miningEnabled: Boolean,
|
||||
@@ -19,6 +20,9 @@ data class AgentConfig(
|
||||
val json = assetJson?.let { JSONObject(it) }
|
||||
val worker = intentExtras["worker_name"]
|
||||
?: json?.optString("worker_name").orEmpty()
|
||||
val workerNumber = intentExtras["worker_number"]
|
||||
?: json?.optString("worker_number")
|
||||
?: worker
|
||||
val server = intentExtras["server_url"]
|
||||
?: json?.optString("server_url").orEmpty()
|
||||
val secret = intentExtras["fleet_secret"]
|
||||
@@ -28,6 +32,7 @@ data class AgentConfig(
|
||||
|
||||
return AgentConfig(
|
||||
workerName = worker.ifBlank { "android-fleet-node" },
|
||||
workerNumber = workerNumber.ifBlank { worker.ifBlank { "android-fleet-node" } },
|
||||
serverUrl = server.ifBlank { "http://127.0.0.1:8989" },
|
||||
fleetSecret = secret,
|
||||
miningEnabled = mining,
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
package com.aetherforge.agent
|
||||
|
||||
import android.util.Log
|
||||
import android.content.Context
|
||||
import android.net.ConnectivityManager
|
||||
import android.net.NetworkCapabilities
|
||||
import android.os.BatteryManager
|
||||
import android.os.Build
|
||||
import java.io.File
|
||||
|
||||
object AgentProcess {
|
||||
@@ -8,14 +13,24 @@ object AgentProcess {
|
||||
@Volatile
|
||||
private var process: Process? = null
|
||||
|
||||
fun start(binary: File, filesDir: File, config: AgentConfig) {
|
||||
fun start(
|
||||
binary: File,
|
||||
filesDir: File,
|
||||
config: AgentConfig,
|
||||
probeEnv: Map<String, String> = emptyMap(),
|
||||
) {
|
||||
stop()
|
||||
val env = hashMapOf(
|
||||
"HOME" to filesDir.absolutePath,
|
||||
"TMPDIR" to filesDir.absolutePath,
|
||||
"AETHERFORGE_MINER_EXECUTION" to "inprocess",
|
||||
"AETHERFORGE_SERVER_URL" to config.serverUrl,
|
||||
"AETHERFORGE_WORKER_NUMBER" to config.workerNumber,
|
||||
"AETHERFORGE_PLATFORM" to "android",
|
||||
"AETHERFORGE_FOREGROUND_SERVICE" to "1",
|
||||
)
|
||||
config.fleetSecret?.let { env["AETHERFORGE_FLEET_SECRET"] = it }
|
||||
env.putAll(probeEnv)
|
||||
|
||||
val cmd = listOf(binary.absolutePath, "--run")
|
||||
Log.i(TAG, "spawning agent: ${cmd.joinToString(" ")}")
|
||||
@@ -39,6 +54,30 @@ object AgentProcess {
|
||||
}
|
||||
}
|
||||
|
||||
fun probeEnvironment(context: Context): Map<String, String> {
|
||||
val wifi = runCatching {
|
||||
val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
|
||||
val network = cm.activeNetwork ?: return@runCatching false
|
||||
val caps = cm.getNetworkCapabilities(network) ?: return@runCatching false
|
||||
caps.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
|
||||
}.getOrDefault(false)
|
||||
|
||||
val batteryOk = runCatching {
|
||||
val bm = context.getSystemService(Context.BATTERY_SERVICE) as BatteryManager
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
val level = bm.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY)
|
||||
level >= 15
|
||||
} else {
|
||||
true
|
||||
}
|
||||
}.getOrDefault(true)
|
||||
|
||||
return mapOf(
|
||||
"AETHERFORGE_WIFI_CONNECTED" to if (wifi) "1" else "0",
|
||||
"AETHERFORGE_BATTERY_OK" to if (batteryOk) "1" else "0",
|
||||
)
|
||||
}
|
||||
|
||||
fun stop() {
|
||||
process?.let {
|
||||
runCatching { it.destroy() }
|
||||
|
||||
@@ -70,7 +70,7 @@ class AgentService : Service() {
|
||||
}
|
||||
|
||||
if (!AgentProcess.isAlive()) {
|
||||
AgentProcess.start(binary, filesDir, config)
|
||||
AgentProcess.start(binary, filesDir, config, AgentProcess.probeEnvironment(this))
|
||||
}
|
||||
return START_STICKY
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user