# 02 — 交互流程与导航设计

> **核心原则**：间接启动（语音/手势）不进入全屏 APP，而是以悬浮覆盖层呈现  
> **关联文档**：[01-voice-assistant-system.md](01-voice-assistant-system.md)

---

## 1. 启动来源 → 界面模式 映射表

```
┌──────────────────────────────────────────────────────────┐
│                    启动来源                              │
├───────────────────────┬──────────────────────────────────┤
│   直接启动 (Explicit) │     间接启动 (Implicit)          │
├───────────────────────┼──────────────────────────────────┤
│ · 桌面图标            │ · 语音唤醒 ("昔涟")              │
│ · 最近任务列表         │ · 长按 Home 键                  │
│ · 通知栏点击           │ · 底部两角向内滑动               │
│ · Deep Link           │ · 长按电源键 (配置后)            │
│                       │ · 耳机按键 (单击/长按)           │
│                       │ · 锁屏右滑助手                    │
├───────────────────────┼──────────────────────────────────┤
│         ▼             │              ▼                   │
│  全屏 Activity        │  VoiceInteractionSession         │
│  (MainActivity)       │  (全屏悬浮覆盖层)                 │
│  · 完整导航栏          │  · 无导航栏                      │
│  · Tab 切换            │  · 仅对话卡片                    │
│  · 设置/IoT 面板       │  · 半透明遮罩透出底层             │
│  · 压入返回栈          │  · 不压入返回栈                  │
└───────────────────────┴──────────────────────────────────┘
```

## 2. 全屏 Activity 模式

### 2.1 导航结构

```
MainActivity
├── BottomNavigation
│   ├── Tab 1: 对话 (ChatScreen)           ← 默认页
│   ├── Tab 2: IoT 面板 (IoTScreen)
│   └── Tab 3: 我的 (ProfileScreen)
├── TopAppBar
│   ├── 昔涟状态指示器 (在线/思考中/离线)
│   └── 快捷操作 (设置、通知)
└── 子页面 (通过 NavHost 导航)
    ├── SettingsScreen
    ├── MemoryScreen (记忆查看)
    ├── KnowledgeScreen (知识库)
    ├── AutomationScreen (自动化规则)
    ├── ReminderScreen (提醒列表)
    └── LoginScreen
```

### 2.2 导航图 (NavGraph)

```
LoginScreen ──(登录成功)──► MainScreen (带 BottomNav)
                                 │
                    ┌────────────┼────────────┐
                    ▼            ▼            ▼
                ChatScreen   IoTScreen   ProfileScreen
                    │                            │
                    ▼                            ▼
              MemoryScreen               SettingsScreen
              KnowledgeScreen               ├─ Account
              AutomationScreen              ├─ Appearance (主题)
              ReminderScreen                ├─ Voice (唤醒词/语音)
                                            ├─ IoT Config
                                            └─ About
```

### 2.3 登录流程

```
APP 首次启动
    → 检查本地 Token
        ├─ 有效 → 直接进入 MainScreen
        └─ 无效 → LoginScreen
            ├─ 输入 Gateway 地址 + 账号密码
            ├─ POST /api/v1/auth/login
            ├─ 保存 Token 到 DataStore
            └─ 进入 MainScreen
```

## 3. 悬浮覆盖层模式 (VoiceInteractionSession)

### 3.1 视觉层级

```
┌──────────────────────────────────────┐
│           底层 APP (半透明可见)        │
│   ┌──────────────────────────────┐   │
│   │   半透明黑色遮罩 (80% 不透明度)  │   │
│   │                              │   │
│   │   ┌──────────────────────┐   │   │
│   │   │                      │   │   │
│   │   │   对话卡片区域        │   │   │
│   │   │   (圆角顶部 28dp)     │   │   │
│   │   │                      │   │   │
│   │   │   · 昔涟状态条        │   │   │
│   │   │   · 对话消息流        │   │   │
│   │   │   · 文本输入框        │   │   │
│   │   │   · 语音输入按钮      │   │   │
│   │   │                      │   │   │
│   │   └──────────────────────┘   │   │
│   │                              │   │
│   └──────────────────────────────┘   │
└──────────────────────────────────────┘
```

### 3.2 覆盖层生命周期

```
Trigger (唤醒词/手势/按键)
    │
    ▼
VoiceInteractionSession.onCreateContentView()
    │
    ▼
onShow() → 设置窗口属性 → 播放出现动画（底部滑入）
    │
    ▼
OverlayScreen Compose 渲染
    │
    ├→ 用户说话 → STT → 显示识别文本 → 发送到 AI-Core
    │                                         │
    │                                         ▼
    │                                   SSE 流式响应
    │                                         │
    ├← TTS 语音播放 ←── 流式合成 ←────────────┘
    │
    ├→ 用户打字输入 → WebSocket 发送 → 显示回复气泡
    │
    ▼
对话结束
    ├→ 用户主动关闭 (说"再见"/点击遮罩/下滑)
    └→ 超时自动关闭 (静默 10 秒)
        │
        ▼
    onHide() → 播放消失动画（底部滑出）
        │
        ▼
    finish() → 返回触发前界面
```

### 3.3 覆盖层状态机

```
           ┌──────────┐
           │  IDLE    │  (覆盖层不可见)
           └────┬─────┘
                │ 触发
                ▼
           ┌──────────┐
           │LISTENING │  (等待语音输入，波形动画)
           └────┬─────┘
                │ 检测到语音 / 用户开始打字
                ▼
           ┌──────────┐
           │PROCESSING│  (STT 识别中 / LLM 思考中)
           └────┬─────┘
                │ 收到回复
                ▼
           ┌──────────┐
           │SPEAKING  │  (TTS 播放中)
           └────┬─────┘
                │ 播放完毕，等待下一轮
                ▼
           ┌──────────┐
           │ WAITING  │  (等待用户继续或关闭)
           └────┬─────┘
                │
        ┌───────┼───────┐
        │               │
    用户继续说话     10s 静默
        │               │
        ▼               ▼
    LISTENING          IDLE
                    (覆盖层关闭)
```

### 3.4 与全屏 Activity 的切换

```
悬浮窗中用户点击 "打开完整 APP"
    → finish() 关闭悬浮窗
    → startActivity(MainActivity)
    → 用户在全屏模式下继续操作

全屏 APP 中用户按 Home 返回桌面
    → onStop() → 进入后台
    → WebSocket 保持连接
    → 推送/FCM 通知到达时，点击通知 → 恢复 MainActivity
```

## 4. 锁屏交互

### 4.1 锁屏唤醒

```
设备锁屏 + 息屏
    │
    ├→ 说出唤醒词 "昔涟"
    │   └→ onLaunchVoiceAssistFromKeyguard()
    │       └→ 简化版覆盖层 (仅对话，无 IoT / 敏感操作)
    │
    └→ 长按电源键
        └→ 同理
```

### 4.2 锁屏安全策略

| 操作 | 锁屏状态 | 行为 |
|------|---------|------|
| 查询天气/时间 | 允许 | 直接回复 |
| 简单闲聊 | 允许 | 直接回复 |
| IoT 查询（状态） | 允许 | 回复设备状态 |
| IoT 控制（开关） | **禁止** | 提示"请先解锁设备" |
| 查看记忆 | **禁止** | 提示"请先解锁设备" |
| 修改设置 | **禁止** | 提示"请先解锁设备" |
| 宿主命令 | **禁止** | 提示"请先解锁设备" |

## 5. 多窗口与分屏

- **分屏模式**：悬浮窗模式下不支持（本身已是覆盖层）；全屏 Activity 支持分屏
- **画中画**：语音通话场景支持画中画（PIP），显示昔涟头像 + 波形动画

## 6. 手势交互

| 手势 | 悬浮窗模式 | 全屏 Activity |
|------|-----------|---------------|
| 下滑覆盖层 | 关闭悬浮窗 | — |
| 点击遮罩区域 | 关闭悬浮窗 | — |
| 长按消息 | 复制/分享菜单 | 复制/分享/删除 |
| 左滑消息 | — | 查看消息详情/时间戳 |
| 双击昔涟头像 | 切换输入模式（语音↔文字） | 同左 |
