diff --git a/android/app/src/main/java/com/thisux/droidclaw/model/Protocol.kt b/android/app/src/main/java/com/thisux/droidclaw/model/Protocol.kt index 53a2422..df6f5e8 100644 --- a/android/app/src/main/java/com/thisux/droidclaw/model/Protocol.kt +++ b/android/app/src/main/java/com/thisux/droidclaw/model/Protocol.kt @@ -13,9 +13,12 @@ data class AuthMessage( @Serializable data class DeviceInfoMsg( val model: String, + val manufacturer: String, val androidVersion: String, val screenWidth: Int, - val screenHeight: Int + val screenHeight: Int, + val batteryLevel: Int, + val isCharging: Boolean ) @Serializable @@ -48,6 +51,13 @@ data class PongMessage( val type: String = "pong" ) +@Serializable +data class HeartbeatMessage( + val type: String = "heartbeat", + val batteryLevel: Int, + val isCharging: Boolean +) + @Serializable data class ServerMessage( val type: String, diff --git a/android/app/src/main/java/com/thisux/droidclaw/util/DeviceInfo.kt b/android/app/src/main/java/com/thisux/droidclaw/util/DeviceInfo.kt index 5e51171..cc549b8 100644 --- a/android/app/src/main/java/com/thisux/droidclaw/util/DeviceInfo.kt +++ b/android/app/src/main/java/com/thisux/droidclaw/util/DeviceInfo.kt @@ -1,6 +1,9 @@ package com.thisux.droidclaw.util import android.content.Context +import android.content.Intent +import android.content.IntentFilter +import android.os.BatteryManager import android.util.DisplayMetrics import android.view.WindowManager import com.thisux.droidclaw.model.DeviceInfoMsg @@ -11,11 +14,30 @@ object DeviceInfoHelper { val metrics = DisplayMetrics() @Suppress("DEPRECATION") wm.defaultDisplay.getRealMetrics(metrics) + + val batteryIntent = context.registerReceiver(null, IntentFilter(Intent.ACTION_BATTERY_CHANGED)) + val level = batteryIntent?.getIntExtra(BatteryManager.EXTRA_LEVEL, -1) ?: -1 + val scale = batteryIntent?.getIntExtra(BatteryManager.EXTRA_SCALE, -1) ?: -1 + val batteryPct = if (level >= 0 && scale > 0) (level * 100 / scale) else -1 + val plugged = batteryIntent?.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0) ?: 0 + return DeviceInfoMsg( model = android.os.Build.MODEL, + manufacturer = android.os.Build.MANUFACTURER.replaceFirstChar { it.uppercase() }, androidVersion = android.os.Build.VERSION.RELEASE, screenWidth = metrics.widthPixels, - screenHeight = metrics.heightPixels + screenHeight = metrics.heightPixels, + batteryLevel = batteryPct, + isCharging = plugged != 0 ) } + + fun getBattery(context: Context): Pair { + val batteryIntent = context.registerReceiver(null, IntentFilter(Intent.ACTION_BATTERY_CHANGED)) + val level = batteryIntent?.getIntExtra(BatteryManager.EXTRA_LEVEL, -1) ?: -1 + val scale = batteryIntent?.getIntExtra(BatteryManager.EXTRA_SCALE, -1) ?: -1 + val batteryPct = if (level >= 0 && scale > 0) (level * 100 / scale) else -1 + val plugged = batteryIntent?.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0) ?: 0 + return Pair(batteryPct, plugged != 0) + } } diff --git a/packages/shared/src/protocol.ts b/packages/shared/src/protocol.ts index 420cd56..9a7998f 100644 --- a/packages/shared/src/protocol.ts +++ b/packages/shared/src/protocol.ts @@ -5,7 +5,8 @@ export type DeviceMessage = | { type: "screen"; requestId: string; elements: UIElement[]; screenshot?: string; packageName?: string } | { type: "result"; requestId: string; success: boolean; error?: string; data?: string } | { type: "goal"; text: string } - | { type: "pong" }; + | { type: "pong" } + | { type: "heartbeat"; batteryLevel: number; isCharging: boolean }; export type ServerToDeviceMessage = | { type: "auth_ok"; deviceId: string } @@ -38,4 +39,5 @@ export type DashboardMessage = | { type: "device_offline"; deviceId: string } | { type: "step"; sessionId: string; step: number; action: Record; reasoning: string; screenHash: string } | { type: "goal_started"; sessionId: string; goal: string; deviceId: string } - | { type: "goal_completed"; sessionId: string; success: boolean; stepsUsed: number }; + | { type: "goal_completed"; sessionId: string; success: boolean; stepsUsed: number } + | { type: "device_status"; deviceId: string; batteryLevel: number; isCharging: boolean }; diff --git a/packages/shared/src/types.ts b/packages/shared/src/types.ts index 11b7863..fb994a0 100644 --- a/packages/shared/src/types.ts +++ b/packages/shared/src/types.ts @@ -53,9 +53,12 @@ export interface ActionResult { export interface DeviceInfo { model: string; + manufacturer: string; androidVersion: string; screenWidth: number; screenHeight: number; + batteryLevel: number; + isCharging: boolean; } export interface ScreenState {