# High-Priority Sync Mode
## Problem Statement
WearOS aggressively manages power, which causes critical issues for mesh networking:
1. **Silent BLE scan termination** - Scans stop after ~5 minutes with no error callback
2. **Connection supervision timeouts** - Long delays before detecting peer disconnection
3. **Background service throttling** - Reduced CPU time for background operations
4. **WiFi/BLE coexistence issues** - Radio contention causes missed packets
For tactical/emergency use cases, reliable peer communication is more important than battery life.
---
## Solution: High-Priority Sync Mode
A configurable mode that trades battery life for communication reliability.
### Behavior Changes
| Scan restart interval | 2 minutes | 30 seconds |
| Keep-alive ping interval | 10 seconds | 3 seconds |
| Reconnection polling | 3 seconds | 1 second |
| Connection interval request | Default (~30ms) | Minimum (7.5ms) |
| Wake lock | None | Partial wake lock |
| Battery optimization | System default | Request exemption |
| Sync interval | 3 seconds | 1 second |
### Expected Battery Impact
- **Normal mode**: ~8-12 hours typical use
- **High-priority mode**: ~4-6 hours typical use (estimated 40-50% reduction)
---
## Systems Touched
### 1. peat-btle Library (`PeatBtle.kt`)
New configuration class:
```kotlin
data class PeatMeshConfig(
val highPriorityMode: Boolean = false,
val scanRestartIntervalMs: Long = if (highPriorityMode) 30000 else 120000,
val keepAliveIntervalMs: Long = if (highPriorityMode) 3000 else 10000,
val reconnectIntervalMs: Long = if (highPriorityMode) 1000 else 3000,
val syncIntervalMs: Long = if (highPriorityMode) 1000 else 3000,
val requestConnectionInterval: Int? = if (highPriorityMode) 6 else null, // 7.5ms units
val useWakeLock: Boolean = highPriorityMode,
val requestBatteryExemption: Boolean = highPriorityMode
)
```
New methods:
```kotlin
fun setHighPriorityMode(enabled: Boolean)
fun isHighPriorityMode(): Boolean
fun requestBatteryOptimizationExemption(activity: Activity)
```
### 2. WearTAK Service (`PeatBtleService.kt`)
- Acquire/release `PowerManager.PARTIAL_WAKE_LOCK` based on mode
- Update notification to indicate high-priority mode active
- Persist mode preference to SharedPreferences
### 3. WearTAK Repository (`PeatBtleRepository.kt`)
New state:
```kotlin
private val _highPriorityMode = MutableStateFlow(false)
val highPriorityMode: StateFlow<Boolean> = _highPriorityMode
fun setHighPriorityMode(enabled: Boolean)
```
### 4. WearTAK UI (`PeatMeshActivity.kt`)
Add toggle button at top of peer list:
```
+----------------------------------+
| Mesh Peers (2 connected) |
+----------------------------------+
| WEAROS-4059 -62dBm 100% [*] |
| WEAROS-3301 -55dBm 87% [*] |
+----------------------------------+
```
When enabled:
- Button shows "PRIORITY SYNC: ON" with warning color (orange/yellow)
- Optional: Show battery warning toast on first enable
### 5. Watchface Complication
Expose high-priority state for watchface display:
- Normal mode: Green mesh icon
- High-priority mode: Orange/yellow mesh icon with "!" indicator
- Tapping complication could toggle mode (optional)
---
## Implementation Steps
### Phase 1: Core Library Support
1. Add `PeatMeshConfig` data class to PeatBtle
2. Add configuration setters/getters
3. Implement dynamic interval updates (scan restart, sync, reconnect)
4. Add connection parameter request on connect
5. Add wake lock support (passed from app context)
### Phase 2: WearTAK Service Integration
1. Add SharedPreferences persistence for mode
2. Implement wake lock acquisition/release
3. Update foreground notification with mode indicator
4. Add battery optimization exemption request flow
### Phase 3: UI Integration
1. Add toggle button to PeatMeshActivity
2. Add confirmation dialog with battery warning
3. Update PeatBtleRepository with mode state
4. Add mode indicator to existing Peat icons
### Phase 4: Watchface Integration
1. Expose mode via complication data
2. Update icon color based on mode
3. Optional: Add tap-to-toggle functionality
---
## Android APIs Used
### Wake Lock
```kotlin
val powerManager = getSystemService(Context.POWER_SERVICE) as PowerManager
val wakeLock = powerManager.newWakeLock(
PowerManager.PARTIAL_WAKE_LOCK,
"WearTAK::PeatMeshWakeLock"
)
wakeLock.acquire() // On enable
wakeLock.release() // On disable
```
### Battery Optimization Exemption
```kotlin
val intent = Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS)
intent.data = Uri.parse("package:$packageName")
startActivity(intent)
```
### BLE Connection Parameters
```kotlin
// Request faster connection interval after connecting
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
gatt.requestConnectionPriority(BluetoothGatt.CONNECTION_PRIORITY_HIGH)
}
```
### Foreground Service Type
```kotlin
// In AndroidManifest.xml
<service
android:name=".service.PeatBtleService"
android:foregroundServiceType="connectedDevice|location" />
```
---
## Risk Mitigation
1. **Battery drain warning** - Show clear warning when enabling
2. **Auto-disable after timeout** - Optionally disable after 1-2 hours
3. **Charging detection** - Could auto-enable when charging
4. **Visual indicators** - Always show when mode is active
5. **Easy toggle** - Make it simple to turn off quickly
---
## Design Decisions
1. **Auto-disable timeout** - Configurable option (default: 1 hour, options: off, 30min, 1hr, 2hr)
2. **Auto-enable on emergency** - YES, automatically enable when any peer enters SOS/emergency state
3. **Watchface tap confirmation** - YES, show confirmation dialog before toggling
4. **Battery estimate** - Future consideration, not in initial implementation
---
## Configuration Options
```kotlin
data class HighPriorityConfig(
val enabled: Boolean = false,
val autoDisableAfterMs: Long? = 3600000, // 1 hour, null = never
val autoEnableOnEmergency: Boolean = true,
val showBatteryWarning: Boolean = true
)
```
### Auto-Disable Options
- Off (manual only)
- 30 minutes
- 1 hour (default)
- 2 hours
### Emergency Auto-Enable Behavior
When any mesh peer enters emergency/SOS state:
1. Automatically enable high-priority mode
2. Show notification: "Priority sync enabled - peer emergency detected"
3. Reset auto-disable timer
4. Stays enabled until:
- Emergency is cleared AND auto-disable timeout reached, OR
- User manually disables
---
*Document created: 2026-02-05*
*Updated: 2026-02-05 - Added design decisions*