feat: extend DeviceInfo with battery, manufacturer, heartbeat

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Sanju Sivalingam
2026-02-17 20:55:42 +05:30
parent 0c0efe9b1e
commit a7738936f2
4 changed files with 41 additions and 4 deletions

View File

@@ -13,9 +13,12 @@ data class AuthMessage(
@Serializable @Serializable
data class DeviceInfoMsg( data class DeviceInfoMsg(
val model: String, val model: String,
val manufacturer: String,
val androidVersion: String, val androidVersion: String,
val screenWidth: Int, val screenWidth: Int,
val screenHeight: Int val screenHeight: Int,
val batteryLevel: Int,
val isCharging: Boolean
) )
@Serializable @Serializable
@@ -48,6 +51,13 @@ data class PongMessage(
val type: String = "pong" val type: String = "pong"
) )
@Serializable
data class HeartbeatMessage(
val type: String = "heartbeat",
val batteryLevel: Int,
val isCharging: Boolean
)
@Serializable @Serializable
data class ServerMessage( data class ServerMessage(
val type: String, val type: String,

View File

@@ -1,6 +1,9 @@
package com.thisux.droidclaw.util package com.thisux.droidclaw.util
import android.content.Context import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.BatteryManager
import android.util.DisplayMetrics import android.util.DisplayMetrics
import android.view.WindowManager import android.view.WindowManager
import com.thisux.droidclaw.model.DeviceInfoMsg import com.thisux.droidclaw.model.DeviceInfoMsg
@@ -11,11 +14,30 @@ object DeviceInfoHelper {
val metrics = DisplayMetrics() val metrics = DisplayMetrics()
@Suppress("DEPRECATION") @Suppress("DEPRECATION")
wm.defaultDisplay.getRealMetrics(metrics) 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( return DeviceInfoMsg(
model = android.os.Build.MODEL, model = android.os.Build.MODEL,
manufacturer = android.os.Build.MANUFACTURER.replaceFirstChar { it.uppercase() },
androidVersion = android.os.Build.VERSION.RELEASE, androidVersion = android.os.Build.VERSION.RELEASE,
screenWidth = metrics.widthPixels, screenWidth = metrics.widthPixels,
screenHeight = metrics.heightPixels screenHeight = metrics.heightPixels,
batteryLevel = batteryPct,
isCharging = plugged != 0
) )
} }
fun getBattery(context: Context): Pair<Int, Boolean> {
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)
}
} }

View File

@@ -5,7 +5,8 @@ export type DeviceMessage =
| { type: "screen"; requestId: string; elements: UIElement[]; screenshot?: string; packageName?: string } | { type: "screen"; requestId: string; elements: UIElement[]; screenshot?: string; packageName?: string }
| { type: "result"; requestId: string; success: boolean; error?: string; data?: string } | { type: "result"; requestId: string; success: boolean; error?: string; data?: string }
| { type: "goal"; text: string } | { type: "goal"; text: string }
| { type: "pong" }; | { type: "pong" }
| { type: "heartbeat"; batteryLevel: number; isCharging: boolean };
export type ServerToDeviceMessage = export type ServerToDeviceMessage =
| { type: "auth_ok"; deviceId: string } | { type: "auth_ok"; deviceId: string }
@@ -38,4 +39,5 @@ export type DashboardMessage =
| { type: "device_offline"; deviceId: string } | { type: "device_offline"; deviceId: string }
| { type: "step"; sessionId: string; step: number; action: Record<string, unknown>; reasoning: string; screenHash: string } | { type: "step"; sessionId: string; step: number; action: Record<string, unknown>; reasoning: string; screenHash: string }
| { type: "goal_started"; sessionId: string; goal: string; deviceId: 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 };

View File

@@ -53,9 +53,12 @@ export interface ActionResult {
export interface DeviceInfo { export interface DeviceInfo {
model: string; model: string;
manufacturer: string;
androidVersion: string; androidVersion: string;
screenWidth: number; screenWidth: number;
screenHeight: number; screenHeight: number;
batteryLevel: number;
isCharging: boolean;
} }
export interface ScreenState { export interface ScreenState {