# AC-Powered Kiosk Display - Final Changes Summary

## Device Type: Android LED Displays (AC-Powered, Not Battery)

### Key Understanding
These are **permanent display installations**, always plugged into power. The issue is **NOT** about battery drain, but about Android OS treating long-running apps as "idle" and killing them even when on AC power.

---

## What Was Fixed

### ✅ 1. Accurate Uptime Tracking
**Problem:** Previous code calculated time since midnight, not actual app runtime
**Solution:** Now tracks real app start time

**Before:**
```
Health check performed - App uptime: 6 hours  ← WRONG (should be 14h)
```

**After:**
```
Health check performed - App uptime: 14h 23m (started: 2026-02-26 20:00:00)  ← CORRECT
```

---

### ✅ 2. Kiosk Display Mode (Native Android)
**Problem:** App treated as regular app, killed after 14 hours of "inactivity"
**Solution:** Added window flags to prevent Android from sleeping/killing app

```kotlin
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED)
window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON)
window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD)
window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN)
```

**Result:** App stays in foreground, Android can't kill it for being "idle"

---

### ✅ 3. Connection Health Monitoring
**Problem:** SignalR connection could die silently, no recovery
**Solution:** 
- Health check every 5 minutes
- Track consecutive failures
- Auto-restart connection after 3 failures

```dart
if (healthCheckFailures >= 3) {
    await queuingViewModel.stopHubConnection();
    await Future.delayed(const Duration(seconds: 2));
    await queuingViewModel.startHubConnection();
}
```

---

### ✅ 4. Lifecycle Event Tracking
**Problem:** No visibility when app goes to background or gets killed
**Solution:** Log all lifecycle events with actual uptime

**Now you'll see:**
```
[onAppPaused] - App uptime: 14h - WARNING: App going to background!
[onAppDetached] - App uptime: 14h - CRITICAL: App being killed!
```

If app stays alive correctly, you should **NEVER** see these logs.

---

### ✅ 5. Clinic Prefix Validation
**Added:** `isClinicPrefixAdded(String ticketNo)` method
**Returns true only for:** `"XXX W-XX"` format (3 letters + space + W-)

---

## Files Changed

1. `lib/view_models/screen_config_view_model.dart` - Fixed uptime, health checks, lifecycle
2. `lib/models/global_config_model.dart` - Clinic prefix feature
3. `lib/repositories/signalR_repo.dart` - Connection improvements
4. `android/app/src/main/kotlin/.../MainActivity.kt` - Kiosk display mode
5. `android/app/src/main/AndroidManifest.xml` - Activity flags

---

## Why App Was Dying (Root Cause)

Android has **App Standby Buckets** (Android 9+) and **Doze Mode** (Android 6+):
- Even on AC power, Android monitors app activity
- No user interaction = app considered "idle"
- After ~12-24 hours, Android kills "idle" apps to free memory
- **This happens even on plugged-in devices!**

**Our Fix:** Window flags tell Android "this is a kiosk display, keep it alive"

---

## Deployment Steps

### 1. Build
```bash
cd /Volumes/Data/Projects/Flutter/HMG_QLine
flutter clean
flutter build apk --release
```

### 2. Deploy
```bash
adb install -r build/app/outputs/flutter-apk/app-release.apk
```

### 3. Verify
**No user action needed** - app auto-configures for kiosk mode

**Check logs for:**
```
MainActivity created - Kiosk display mode active
Health check performed - App uptime: 0h 5m (started: 2026-03-01 10:54:37)
```

---

## Expected Behavior After Fix

| Time | Expected Log |
|------|-------------|
| **0-5 min** | `Health check performed - App uptime: 0h 5m` |
| **1 hour** | `Health check performed - App uptime: 1h 0m` |
| **14 hours** | `Health check performed - App uptime: 14h 0m` ← CRITICAL (previously died here) |
| **24 hours** | `Health check performed - App uptime: 24h 0m` |
| **48 hours** | `Health check performed - App uptime: 48h 0m` |
| **60+ hours** | `WARNING: App running for 60+ hours - scheduling proactive restart` |

---

## What You Should NOT See

If fix works correctly:
- ❌ No `[onAppPaused]` logs (means going to background)
- ❌ No `[onAppDetached]` logs (means being killed)
- ❌ No gaps in health check logs (every 5 minutes without fail)

---

## If App Still Dies

### Scenario 1: Manufacturer-Specific Restrictions
Some Android devices (Xiaomi, Oppo, Vivo, Realme) have **additional** task killers:

**Solution:**
1. Go to device Settings > Apps > QLine
2. Enable "Auto-start"
3. Set Battery to "No restrictions" (even though it's AC powered)
4. Disable "Battery optimization"

### Scenario 2: Android Doze Override Needed
```bash
# Whitelist app from doze restrictions
adb shell dumpsys deviceidle whitelist +com.example.hmg_qline.hmg_qline

# Verify
adb shell dumpsys deviceidle whitelist | grep hmg_qline
```

### Scenario 3: Full Kiosk Mode Required
If above doesn't work, may need **Device Owner Mode**:
```bash
adb shell dpm set-device-owner com.example.hmg_qline/.DeviceAdminReceiver
```
This gives app full control over device - cannot be killed by OS.

---

## Testing Checklist

- [ ] Deploy new APK to test device
- [ ] Check log: "MainActivity created - Kiosk display mode active"
- [ ] Verify health checks appear every 5 minutes
- [ ] Confirm uptime increments correctly (0h 5m → 0h 10m → 0h 15m)
- [ ] Wait 14 hours - verify no `[onAppPaused]` or `[onAppDetached]` logs
- [ ] Wait 24 hours - verify app still running
- [ ] Disconnect network for 15 min - verify auto-reconnection
- [ ] Check SignalR connection recovers automatically

---

## Success Metrics

✅ Health check logs every 5 minutes without gaps
✅ Uptime shows continuously (no resets except midnight restart)
✅ Hub connection stays alive
✅ App runs past 14-hour checkpoint
✅ App runs 48+ hours continuously
✅ No lifecycle events (paused/detached) in logs

---

## Emergency Commands

### Check if app is running:
```bash
adb shell ps | grep hmg_qline
```

### Check device idle state:
```bash
adb shell dumpsys deviceidle
```

### Force prevent app kill:
```bash
adb shell cmd appops set com.example.hmg_qline.hmg_qline RUN_IN_BACKGROUND allow
```

### View last 100 logs:
```bash
adb logcat -t 100 | grep MainActivity
```

---

## Contact for Issues

If app still dies after these changes, provide:
1. Last 200 lines of logs before app stopped
2. Android version and device model
3. Screenshot of Apps > QLine > Battery settings
4. Output of: `adb shell dumpsys deviceidle whitelist`

