Initialize Meatbag SDUI platform
This commit is contained in:
79
research/sdui_and_haptics_research.md
Normal file
79
research/sdui_and_haptics_research.md
Normal file
@@ -0,0 +1,79 @@
|
||||
# Meatbag Research: SDUI Inflation, Wear OS Haptics, and Server Push
|
||||
|
||||
This document summarizes architectural research for the Meatbag platform, focusing on performance, latency, and platform-specific haptic patterns.
|
||||
|
||||
---
|
||||
|
||||
## 1. Server-Driven UI (SDUI) in Compose Multiplatform
|
||||
|
||||
### The Reflection-Free Pattern
|
||||
To meet performance constraints and avoid runtime performance degradation on lightweight clients (such as Wear OS watches), Meatbag implements a strictly typed, reflection-free Component Registry.
|
||||
|
||||
```kotlin
|
||||
@Composable
|
||||
fun ComponentRegistry(primitive: UiPrimitive, onAction: (ApprovalResponse) -> Unit) {
|
||||
when (primitive) {
|
||||
is ApprovalRequest -> ApprovalRequestCard(primitive, onAction)
|
||||
is ActionList -> ActionListContainer(primitive, onAction)
|
||||
is TextInput -> TextInputField(primitive, onAction)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
* **Advantage**: Compile-time safety. Polymorphic serialization (via `kotlinx.serialization` with custom class discriminators like `"type"`) ensures payloads map directly to Kotlin data types without dynamic inspection.
|
||||
* **State Management**: Adheres to Unidirectional Data Flow (UDF). Primitives are read-only configuration blueprints; interactive widgets emit state updates upward through explicit event callbacks (`onAction`), keeping clients entirely stateless.
|
||||
|
||||
---
|
||||
|
||||
## 2. Wear OS Haptic Feedback APIs
|
||||
|
||||
To minimize human response times, we utilize precise physical notifications based on the resolved `AttentionTier`.
|
||||
|
||||
### Android / Wear OS API Mapping
|
||||
For triggering haptics on physical Wear OS smartwatches, the system integrates with Android's hardware `Vibrator` API.
|
||||
|
||||
#### 1. Predefined Effects (Android SDK 29+)
|
||||
Modern Wear OS devices support the `VibrationEffect` API, which yields crisp, hardware-optimized clicks rather than fuzzy motor rumbling.
|
||||
* **`AttentionTier.SILENT_HAPTIC`**: Double short pulses to signal prompt urgency without making sound.
|
||||
```kotlin
|
||||
val vibrator = context.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
|
||||
val effect = VibrationEffect.startComposition()
|
||||
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1.0f)
|
||||
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1.0f, 150) // 150ms delay
|
||||
.compose()
|
||||
vibrator.vibrate(effect)
|
||||
```
|
||||
* **`AttentionTier.BACKGROUND_NOTIFICATION`**: A light tick effect.
|
||||
```kotlin
|
||||
vibrator.vibrate(VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK))
|
||||
```
|
||||
* **`AttentionTier.OVERRIDE_SCREEN`**: Repetitive pulsing alert composition.
|
||||
```kotlin
|
||||
val timings = longArrayOf(0, 200, 100, 200, 100, 500) // delay, vibe, pause, vibe...
|
||||
val amplitudes = intArrayOf(0, 255, 0, 255, 0, 255)
|
||||
vibrator.vibrate(VibrationEffect.createWaveform(timings, amplitudes, -1))
|
||||
```
|
||||
|
||||
#### 2. Legacy Fallbacks (Android SDK < 29)
|
||||
* For older Wear OS versions, fallback to deprecated pattern arrays:
|
||||
```kotlin
|
||||
vibrator.vibrate(longArrayOf(0, 80, 100, 80), -1)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Server Push Architecture: WebSockets vs. SSE
|
||||
|
||||
Smartwatches are subject to battery constraints and intermittent connectivity. The push transport layer must be responsive yet lightweight.
|
||||
|
||||
| Feature | WebSockets | Server-Sent Events (SSE) |
|
||||
| :--- | :--- | :--- |
|
||||
| **Protocol** | Bi-directional, custom framing | Uni-directional (Server -> Client), HTTP/1.1 or HTTP/2 |
|
||||
| **Connection Overhead** | Low (post-handshake) | Extremely low (standard HTTP connection) |
|
||||
| **Battery Impact** | Higher (constant connection maintenance) | Lower (leverages HTTP client connection pooling) |
|
||||
| **Firewall Traversal** | Can be blocked by strict proxy rules | Standard HTTP, easily passes through proxies |
|
||||
| **Meatbag MVP Selection** | **WebSockets** (Allows immediate client confirmation frames and bi-directional pings) | **Candidate for mobile clients** (Fallback for phone targets via standard APNS / FCM) |
|
||||
|
||||
### Recommended Hybrid Strategy
|
||||
1. **Wear OS Smartwatches**: Utilize persistent WebSockets with optimized ping-pong intervals (e.g. 30 seconds) when the app is active in the foreground.
|
||||
2. **Mobile Phones (iOS & Android)**: Fall back to native push notification systems (FCM/APNS) to wake up the client, which then opens a short-lived WebSocket or POST connection to render the SDUI primitive.
|
||||
Reference in New Issue
Block a user