From 1adcb0fb3beb7c2a4f32ad47374e6705ce854ee2 Mon Sep 17 00:00:00 2001 From: KremeCN <3265494849@qq.com> Date: Fri, 28 Aug 2026 10:38:47 +0800 Subject: [PATCH] docs: reorganize project documentation --- README.md | 133 ++ docs/README.md | 22 + docs/architecture.md | 209 ++- docs/device-control-compose-ui-change-log.md | 195 --- docs/device-list-compose-ui-pr-description.md | 133 -- docs/examples/LoginAsyncTaskDemo.java | 92 -- docs/examples/activity_main_login.xml | 33 - docs/project-overview.md | 90 ++ docs/project_plan.md | 590 -------- docs/protocol/absdk-0630.md | 2 +- docs/requirement_spec.md | 20 - .../plans/2026-08-24-infrared-control.md | 1300 ----------------- .../plans/2026-08-24-infrared-remote-ui.md | 589 -------- ...26-08-24-lan-absdk-and-local-experience.md | 1059 -------------- .../2026-08-24-infrared-control-design.md | 606 -------- .../2026-08-24-infrared-remote-ui-design.md | 115 -- ...4-lan-absdk-and-local-experience-design.md | 238 --- docs/testing/device-data-capability-matrix.md | 60 +- docs/testing/infrared-hardware-validation.md | 112 +- .../release-lan-hardware-validation.md | 99 +- docs/{ => vendor}/ABSDK接口部分_0630.md | 0 docs/{ => vendor}/ABSDK接口部分_0630.xls | Bin 22 files changed, 495 insertions(+), 5202 deletions(-) create mode 100644 README.md create mode 100644 docs/README.md delete mode 100644 docs/device-control-compose-ui-change-log.md delete mode 100644 docs/device-list-compose-ui-pr-description.md delete mode 100644 docs/examples/LoginAsyncTaskDemo.java delete mode 100644 docs/examples/activity_main_login.xml create mode 100644 docs/project-overview.md delete mode 100644 docs/project_plan.md delete mode 100644 docs/requirement_spec.md delete mode 100644 docs/superpowers/plans/2026-08-24-infrared-control.md delete mode 100644 docs/superpowers/plans/2026-08-24-infrared-remote-ui.md delete mode 100644 docs/superpowers/plans/2026-08-24-lan-absdk-and-local-experience.md delete mode 100644 docs/superpowers/specs/2026-08-24-infrared-control-design.md delete mode 100644 docs/superpowers/specs/2026-08-24-infrared-remote-ui-design.md delete mode 100644 docs/superpowers/specs/2026-08-24-lan-absdk-and-local-experience-design.md rename docs/{ => vendor}/ABSDK接口部分_0630.md (100%) rename docs/{ => vendor}/ABSDK接口部分_0630.xls (100%) diff --git a/README.md b/README.md new file mode 100644 index 0000000..0154a4f --- /dev/null +++ b/README.md @@ -0,0 +1,133 @@ +

+ ABox Manager logo +

+ +

ABox Manager

+ +

+ 面向 Android 手机和平板的 ABox 智能家居管理应用 +

+ +## 项目介绍 + +ABox Manager 使用 ABSDK 连接局域网中的 ABox 网关,为智能插座、温湿度传感器和红外控制器提供统一的设备管理体验。应用同时包含不依赖账号、网络或真实硬件的本地体验模式,可用于浏览界面和验证主要操作流程。 + +当前正式版本为 **1.0.0**,由 **Flagship** 团队开发。 + +## 主要功能 + +- ABox 登录、自动登录、加密凭据与会话失效处理; +- 智能插座状态查询、开关控制和命令后状态确认; +- 温度与湿度读取,以及无数据、错误和离线状态展示; +- 预置红外码库下载,以及自定义遥控器按键学习; +- 遥控器布局、按钮、硬件槽位和顺序管理; +- 手动指令与基于时间、温度、湿度和设备状态的自动指令; +- 插座、红外、延迟和系统通知动作; +- 按 profile 隔离并持久化的活动记录; +- 浅色、深色、动态颜色、强调色与界面缩放; +- 英文和简体中文本地化; +- 独立且确定性的本地体验环境。 + +## 技术栈 + +- Kotlin 2.4 +- Jetpack Compose 与 Material +- Navigation Compose +- Hilt +- Coroutines 与 StateFlow +- Room +- DataStore 与 Android Keystore +- WorkManager +- 多模块 Gradle 工程 + +核心模块: + +```text +domain/ 领域模型、端口和用例 +absdk-bridge/ ABSDK 0630 防腐层 +runtime/simulation/ 本地体验模拟运行时 +testing/fakes/ 测试专用 Fake +android/core/ 设计系统、偏好、设备目录和会话 +android/feature/infrared/ 红外遥控器功能 +android/feature/automation/ 情景、自动化和活动记录 +android/app/ 应用组合根、导航和设备界面 +``` + +完整依赖方向和数据边界见 [架构文档](docs/architecture.md)。 + +## 开发环境 + +- JDK 17 +- Android SDK 37 +- Android Studio,或能够运行 Gradle Wrapper 的 Android 开发环境 +- Windows、macOS 或 Linux + +项目最低支持 Android 8.0(API 26),目标 SDK 为 36。 + +克隆仓库后,确保 Android SDK 路径已由 Android Studio 写入本机 `local.properties`,然后构建调试 APK: + +```powershell +.\gradlew.bat :android:app:assembleDebug +``` + +macOS 或 Linux: + +```bash +./gradlew :android:app:assembleDebug +``` + +APK 输出位置: + +```text +android/app/build/outputs/apk/debug/app-debug.apk +``` + +连接模拟器或 Android 设备后可以安装: + +```bash +adb install -r android/app/build/outputs/apk/debug/app-debug.apk +``` + +## 使用方式 + +### ABox + +设备需要与 ABox 网关处于可用的局域网环境,并使用有效账号登录。ABSDK 通过设备名称匹配网关设备;App 中的设备名称必须与网关实际名称一致。 + +首次初始化 ABox profile 时,App 会按设备类型补充以下默认记录: + +- `智能插座` +- `温湿度传感器` +- `红外控制器` + +已有同类型设备不会被迁移、重命名或覆盖。 + +### 本地体验 + +本地体验无需账号和网络,使用独立模拟数据。它适合浏览产品和验证界面流程,但不能作为真实 ABox、网络或硬件验收结果。 + +## 文档 + +- [项目概览](docs/project-overview.md) +- [架构说明](docs/architecture.md) +- [ABSDK 0630 已确认事实与边界](docs/protocol/absdk-0630.md) +- [设备数据能力矩阵](docs/testing/device-data-capability-matrix.md) +- [红外硬件验证](docs/testing/infrared-hardware-validation.md) +- [正式版局域网硬件验收](docs/testing/release-lan-hardware-validation.md) +- [完整文档索引](docs/README.md) + +## 安全边界 + +厂商 ABSDK JAR 使用明文 HTTP,并依赖外部局域网环境完成域名到网关的访问。真实 ABox 功能只能在已授权、受控的局域网中使用。 + +不得在日志、截图、问题报告或测试记录中提交密码、Token、完整网关地址、完整硬件标识、原始红外码值或未脱敏 SDK 响应。 + +## 贡献流程 + +`main` 是受保护分支。所有修改必须从最新 `main` 创建专用分支,通过 Pull Request 合并,不得直接在 `main` 上开发或推送。详细规则见 [AGENTS.md](AGENTS.md)。 + +## 第三方资料 + +内置的部分红外预置来源于 Flipper-IRDB,并按照 CC0 1.0 提供。来源、转换范围和归属信息见 [Flipper-IRDB attribution](docs/third-party/flipper-irdb.md)。 + +仓库中的厂商 SDK、接口资料和第三方内容分别受其自身许可或授权条件约束;本仓库当前未声明覆盖整个项目的统一开源许可证。 diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..b52e475 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,22 @@ +# ABox Manager 文档 + +本目录只保留需要长期维护的产品、架构、协议、验证和第三方归属资料。功能分支计划、Pull Request 描述、临时 UI 方案和一次性实施记录不进入长期文档。 + +## 文档索引 + +- [`project-overview.md`](project-overview.md):正式版产品范围、关键行为和团队职责。 +- [`architecture.md`](architecture.md):当前模块、依赖方向、数据边界和运行时架构。 +- [`protocol/absdk-0630.md`](protocol/absdk-0630.md):ABSDK 0630 已确认事实、实现约束和待确认事项。 +- [`vendor/ABSDK接口部分_0630.md`](vendor/ABSDK接口部分_0630.md):厂商接口资料的可搜索 Markdown 版本。 +- [`vendor/ABSDK接口部分_0630.xls`](vendor/ABSDK接口部分_0630.xls):厂商原始接口表格。 +- [`testing/device-data-capability-matrix.md`](testing/device-data-capability-matrix.md):可在界面与自动化中使用的真实数据能力。 +- [`testing/infrared-hardware-validation.md`](testing/infrared-hardware-validation.md):红外控制器真机验证流程。 +- [`testing/release-lan-hardware-validation.md`](testing/release-lan-hardware-validation.md):正式版局域网端到端验收流程。 +- [`third-party/flipper-irdb.md`](third-party/flipper-irdb.md):内置开源红外码库的来源与许可说明。 + +## 维护规则 + +- 文档描述当前 `main` 的行为,不描述尚未合并的分支状态。 +- SDK 推测必须标为待确认;已确认事实应给出代码、JAR、厂商资料或真机观测依据。 +- 不记录密码、Token、完整网关地址、完整设备标识、原始红外码值或未脱敏 SDK 响应。 +- 代码行为发生变化时,同一 Pull Request 应更新受影响的长期文档。 diff --git a/docs/architecture.md b/docs/architecture.md index 256062d..4a03ec7 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -1,166 +1,129 @@ -# ABox Manager 架构基线 +# ABox Manager 架构 -## 1. 文档范围 +## 总体结构 -本文记录已建立的模块边界、依赖方向、提供方路由和并行开发接口,覆盖 ABox(局域网 ABSDK)与本地体验两条连接路径。ABSDK 0630 的初始化、签名细节和会话清理等未确认内容不在本文中固化,协议观测证据见 `docs/protocol/absdk-0630.md`。 - -产品范围和固定分工以 `docs/project_plan.md` 为准,原始简要需求继续保留在 `docs/requirement_spec.md`。 - -## 2. 当前模块 +ABox Manager 是单 Activity 的 Kotlin/Compose Android 应用。业务能力通过纯 Kotlin 领域端口表达,Android 模块负责持久化、系统集成、依赖注入和 UI,厂商 SDK 被限制在独立防腐层中。 ```text abox-mgr/ -├── android/ -│ ├── app/ # Android 应用、提供方路由与依赖注入组合根 -│ └── core/ -│ ├── designsystem/ # Compose Material 3 设计系统基础 -│ └── session/ # 提供方 profile、凭据 Keystore 持久化 -├── domain/ # 纯 Kotlin 领域模型和公共端口 -├── absdk-bridge/ # ABSDK 0630 防腐层(生产) -├── runtime/simulation/ # 本地体验模拟运行时(生产) -├── testing/fakes/ # 测试专用 Fake(仅测试依赖) -├── docs/ -└── samples/ # 历史示例,仅供参考 +├── domain/ # 领域模型、端口、用例与执行器 +├── absdk-bridge/ # ABSDK 0630 防腐层 +├── runtime/simulation/ # 本地体验生产模拟运行时 +├── testing/fakes/ # 测试专用 Fake +└── android/ + ├── core/ + │ ├── designsystem/ # Compose 主题、组件和设计令牌 + │ ├── preferences/ # 界面偏好 DataStore + │ ├── devicecatalog/ # ABox 本地设备目录与 Provider 路由 + │ └── session/ # Profile、会话偏好和加密凭据 + ├── feature/ + │ ├── infrared/ # 遥控器、按键、码库与学习流程 + │ └── automation/ # 情景、自动化、通知和活动记录 + └── app/ # 应用组合根、导航和设备页面 ``` -依赖方向: +依赖遵循以下方向: ```text -android/app ────────────────┬──> android/core/designsystem - ├──> android/core/session ──> domain - ├──> domain - ├──> absdk-bridge ──> domain - └──> runtime/simulation ──> domain - -android/core/designsystem ─────> Compose Material 3 -testing/fakes(仅测试)────────> domain -domain ────────────────────────> Kotlin 与 Coroutines +android/app ──> android/core/*, android/feature/*, domain +android/feature/* ──> domain +android/core/* ──> domain +absdk-bridge ──> domain +runtime/simulation ──> domain +testing/fakes ──> domain +domain ──> Kotlin 与 Coroutines ``` -`domain` 不依赖 Android、Compose、Room、ABSDK 或具体网络实现。业务 UI 只依赖领域端口和类型化结果。 +`domain` 不依赖 Android、Compose、Room、DataStore 或 ABSDK。UI 不直接调用厂商 SDK。 -## 3. 提供方与数据隔离 +## Provider 与会话 -认证前应用只提供两种入口,两者在所有构建变体中始终可用: +应用支持 `ABOX` 和本地体验两种 Provider。`ProviderProfileId` 是所有会话、目录、遥控器、情景、自动化状态和活动记录的数据隔离键。 -1. **ABox**:通过进程内唯一的真实 `AbsdkBridge` 连接当前局域网中的智能家居网关,登录成功后进入应用; -2. **本地体验**:由 `:runtime:simulation` 直接建立模拟会话并进入应用,不请求凭据、不访问网络、不调用 ABSDK。 +- 任一时刻只有一个活动 Provider; +- 切换 Provider 前结束当前会话; +- ABox 会话由进程内唯一 `AbsdkBridge` 维护; +- 本地体验由 `runtime/simulation` 建立无凭据会话; +- 自动登录凭据使用 Android Keystore 的 AES-256-GCM 加密,profile id 作为 AAD; +- ABSDK 没有 logout 和 Token setter,退出只清理 App/Bridge 本地会话,重新登录覆盖 SDK Token。 -每个提供方 profile 由 `ProviderProfileId` 标识,所有会话、设备目录和设备操作都显式携带该标识。 +## 领域端口 -约束: +主要公共端口包括: -- 任一时刻只启用一个提供方; -- 切换提供方前必须退出当前会话; -- 不同提供方的数据、凭据和设备状态不得互相混用; -- 本地体验不调用 ABSDK,也不启动本地 HTTP 服务; -- Release 不是特殊情况:debug 与 release 暴露相同的提供方和路由行为。 +- `SessionGateway`、`LocalSessionGateway`; +- `ProviderProfileStore`、`CredentialStore`; +- `DeviceCatalog`; +- `SocketGateway`、`TemperatureHumidityGateway`、`InfraredGateway`; +- `VirtualRemoteRepository`、`InfraredKeyRepository`; +- `SceneRepository`、`SceneExecutor`、`NotificationGateway`; +- `ActivityRepository`。 -## 4. 公共领域端口 +所有设备与会话操作返回 `DomainResult`。错误通过 `DomainError` 分类,必要时保留脱敏的厂商错误码;`ABRet`、原始 `Map` 和厂商对象不得越过 Bridge。 -`domain` 当前提供以下最小端口: +## 设备目录与默认内容 -- `SessionGateway`:登录、观察会话、验证会话和退出; -- `LocalSessionGateway`:无凭据本地会话的标记端口,继承 `SessionGateway`; -- `ProviderProfileStore`:提供方 profile、活动 profile 和登录偏好持久化; -- `CredentialStore`:自动登录凭据的加密存取; -- `DeviceCatalog`:按提供方观察设备目录; -- `SocketGateway`:查询和设置插座状态; -- `TemperatureHumidityGateway`:读取温度和湿度; -- `InfraredGateway`:发送、学习和下载红外码。 +ABSDK 0630 没有设备发现或列表接口。ABox 设备目录由 `android/core/devicecatalog` 使用 Room 按 profile 持久化,设备操作最终使用 `DeviceName` 调用网关。 -端口只覆盖需求和 ABSDK 0630 文档已经确认的行为。`DeviceId` 是 App 本地目录中的稳定记录标识;设备操作必须使用 ABSDK 0630 实际接受的 `DeviceName`。同一提供方配置和设备类型内,`DeviceName` 必须唯一,设备目录在添加、编辑和导入时负责强制该约束。设备目录的增删改与二维码导入、遥控器布局、情景动作和持久化模型将在对应模块提出后增量加入,不在公共层提前假定。 +ABox profile 首次初始化时,如果某一设备类型尚不存在,App 补充以下默认记录: -## 5. 结果与错误边界 +- `智能插座`; +- `温湿度传感器`; +- `红外控制器`。 -所有端口返回 `DomainResult`: +初始化按设备类型判断,不迁移或重命名已有记录。用户修改设备名后,名称必须与网关实际设备名一致。 -- `Success` 携带类型化领域值; -- `Failure` 携带 `DomainError`; -- `DomainError.externalCode` 可以保留外部 SDK 错误码用于诊断; -- UI 不接触 `ABRet`、原始 `Map`、HTTP 表单或任何服务端数据库模型。 +同一初始化流程会为 `红外控制器` 添加两个未学习的自定义遥控器:自定义电视遥控器和自定义面板遥控器。 -ABSDK 防腐层已在 `:absdk-bridge` 中完成同步阻塞调用的后台串行化、返回解析和错误映射。 +## 设备操作 -## 6. Fake 边界 +`android/app` 中的路由网关根据活动 Provider 分发操作: -`testing/fakes` 提供会话、设备目录、插座、温湿度和红外 Fake。它们: +- ABox 调用共享 `AbsdkBridge`; +- 本地体验调用确定性的模拟实现。 -- 不使用网络、Android API、真实时间或随机数; -- 支持成功、失败、无数据、离线和 Token 无效场景; -- 对插座状态和设备目录按 `ProviderProfileId` 隔离; -- 记录红外学习、发送和下载调用; -- 可直接用于其他模块的 ViewModel 与 UI 测试。 +插座控制不会把期望值直接当成真实状态。命令成功后必须回读;回读失败时 UI 保持“等待确认”或错误状态。温湿度允许单字段缺失,只有两个字段都不存在时才进入无数据状态。设备离线通过领域错误显式传递到 UI。 -Fake 只用于开发和测试,不能作为真实 ABox 或真实硬件验收证据。`:testing:fakes` 是测试专用模块,不得加入应用生产依赖。 +## 红外 -ABSDK 不提供设备目录发现能力。生产 ABox 设备目录由 `:android:core:devicecatalog` 按当前 profile 持久化,来源是用户明确配置或导入的真实 `DeviceName`;它不从本地体验目录复制数据,也不把测试 Fake 绑定到生产组合根。Local profile 仍由 `SimulationDeviceCatalog` 提供独立的确定性目录。 +`android/feature/infrared` 使用独立 Room 数据库保存虚拟遥控器、按钮布局、学习状态和硬件槽位信息。 -## 7. 本地体验模拟运行时 +- 预置遥控器从内置码库下载,不提供学习入口; +- 自定义遥控器通过硬件学习建立按键; +- 按键状态区分未学习、学习中、失败和可发送; +- 学习任务由应用级协调器执行,页面离开后可继续; +- 进程中断遗留的学习状态在恢复时保守标记为失败; +- 开源码库来源和转换约束见 `docs/third-party/flipper-irdb.md`。 -`:runtime:simulation` 是生产 Kotlin/JVM 模块,为本地体验提供确定性实现: +## 情景、自动化与活动记录 -- `SimulationSessionGateway`:直接建立无凭据的本地会话; -- `SimulationDeviceCatalog`:内置的本地体验设备目录; -- `SimulationSocketGateway`、`SimulationTemperatureHumidityGateway`、`SimulationInfraredGateway`:固定行为的模拟设备操作。 +`android/feature/automation` 使用 Room 保存情景文档、触发器匹配状态、定时 occurrence claim 和活动记录。 -模拟实现不暴露脚本化失败注入、调用记录或断言辅助;这些能力只存在于 `:testing:fakes`。 +手动指令直接执行。自动指令由 WorkManager 调度和 `AutomationEngine` 评估: -## 8. Android 组合根与提供方路由 +1. 收集相关温湿度与插座状态快照; +2. 对每个启用的自动指令评估多个触发器; +3. 状态型触发器只在不匹配到匹配的转换上产生新触发; +4. 时间触发器通过 occurrence key 去重; +5. 任一新触发出现后,再要求全部条件满足; +6. 按情景配置执行动作并记录结果。 -`android/app` 是单 Activity Compose 应用,负责: +触发器支持时间、温度、湿度和插座状态;条件支持温度、湿度、插座状态和时间范围;动作支持插座、虚拟遥控器、红外按键、延迟和通知。 -- `ABoxManagerApplication` 与 Hilt 组合根; -- `MainActivity`; -- 根 `NavHost` 与提供方选择、登录、认证后路由; -- 默认英文和简体中文资源; -- 使用 `android/core/designsystem` 的主题和基础组件。 +活动记录按 profile 保存设备命令、状态确认、传感器刷新、红外发送/学习、情景及动作结果。记录只保存领域层允许的信息,不保存凭据、原始响应或红外码值。 -组合根按端口绑定生产实现: +## 界面偏好 -```text -SessionGateway -> AbsdkBridge(进程内单例) -LocalSessionGateway -> SimulationSessionGateway -SocketGateway -> RoutingSocketGateway -TemperatureHumidityGateway -> RoutingTemperatureHumidityGateway -InfraredGateway -> RoutingInfraredGateway -``` +`android/core/preferences` 使用 DataStore 保存主题模式、动态颜色、强调色、色彩风格、色彩规范、界面缩放和触觉反馈偏好。当前生产界面保持 Material 渲染;未采用的渲染器值保留兼容数据,但不作为正式功能承诺。预测性返回默认关闭,且不向用户显示设置入口。 -`AbsdkBridge` 以 Hilt 单例提供并在所有构建变体中相同:会话与插座/温湿度/红外操作共享同一个 Bridge 实例,使互斥锁和 Bridge 本地会话与厂商 SDK 单例状态保持一致。三个 Routing 网关读取活动 profile 并按提供方分发——ABox 转发到共享的 AbsdkBridge 实现,本地体验转发到模拟实现。任何功能 UI 都不直接选择真实或 Fake 实现。 +## ABSDK 边界 -设备目录导航、插座与温湿度页面、红外页面和情景页面由固定模块负责人实现,不放入工程基础层。 +`absdk-bridge` 是厂商 JAR 的唯一生产接入点: -## 9. ABSDK Bridge +- 全部同步 SDK 调用转移到后台并串行执行; +- 进程内共享同一个 SDK/Bridge 实例; +- 不调用语义未确认的 `setHostInfo`; +- 使用 `@CleartextAbsdkTransport` 显式标记明文传输风险; +- App 仅因厂商 JAR 的历史行为允许明文流量,不把该策略扩展到其他网络功能。 -`:absdk-bridge` 是纯 Kotlin/JVM 防腐层,依赖 `domain` 并实现会话、插座、温湿度和红外 Gateway。该模块: - -- 只在 `VendorAbsdkClient` 中接触 `ABSDK`、`ABRet` 和 `IrInfo`; -- 将所有同步调用移到后台并串行进入全局 SDK; -- 将返回值和错误码转换为 `DomainResult` 和领域模型; -- 不调用未确认的 `setHostInfo`; -- logout 只清除 Bridge 本地会话,因为 JAR 没有公开 logout 或 Token setter; -- 生产工厂始终返回进程内同一个 Bridge,使互斥锁和本地会话与厂商单例保持一致; -- 真实工厂标记为 `@CleartextAbsdkTransport`,调用方必须显式 opt-in 承认厂商 JAR 的硬编码 HTTP 风险; -- 当前直接引用归档 Sample 目录中的唯一一份 JAR,不复制厂商二进制; -- ABSDK 0630 没有设备目录能力,Bridge 因此也不提供设备目录或设备发现。 - -App 组合根已通过 Hilt 单例绑定该 Bridge,绑定处以 `@CleartextAbsdkTransport` 显式 opt-in 承认厂商 JAR 的硬编码明文 HTTP 风险;App 同时声明 `INTERNET` 权限并允许明文传输(`usesCleartextTraffic`),这是项目所有者对当前局域网集成约束的明确风险接受,不代表传输具备机密性或完整性。协议证据与限制记录在 `docs/protocol/absdk-0630.md`。 - -## 10. Provider Session - -`:android:core:session` 负责提供方登录的持久化与 Android 安全边界: - -- `ProviderProfileStore` 使用 DataStore 保存 profile、当前活动 profile、记住用户名和自动登录开关;已移除的提供方类型(如历史兼容后端值)被忽略,不会成为活动 profile; -- `CredentialStore` 使用 Android Keystore 中的 AES-256-GCM 密钥加密自动登录凭据,DataStore 只保存带随机 IV 的密文; -- `ProviderProfileId` 作为 GCM AAD,防止不同 profile 的密文互换; -- 本地体验的会话由 `:runtime:simulation` 的 `SimulationSessionGateway` 提供,不调用 HTTP 或 ABSDK。 - -纯 Kotlin `SessionCoordinator` 统一处理启动恢复、提供方选择、登录偏好、自动登录、Token 失效重登、退出和切换提供方。ABox 登录成功必须来自注入的真实 Bridge 返回 `DomainResult.Success`;无效凭据和网络错误停留在登录页并显示本地化错误。ABox 远端退出清除密码和 Session,但保留 profile 与记住的用户名以便再次显示登录页;本地体验退出清除本地会话和活动 profile,回到提供方选择。 - -两个提供方在所有构建变体中始终可用,不存在按 debug/release 区分的可用性开关。 - -登录完成后进入 `authenticated` 协作路由。设备中心、详情、红外、情景、自动化和活动记录由对应 Android 模块提供,并通过当前 profile 路由到真实或本地体验端口。 - -## 11. 后续边界 - -Room 与设备业务 DataStore 的具体 schema/key 只在对应数据所有权明确后创建。生产 ABox 设备目录由设备目录模块维护,不能回退到 `FakeDeviceCatalog`。历史示例中的 AsyncTask、明文密码存储和散落 SDK 调用不得进入正式架构;ABSDK 厂商 JAR 的明文局域网传输风险已明确记录并由所有构建变体共同承担。 +协议事实、端点、签名边界和待确认事项见 `docs/protocol/absdk-0630.md`。 diff --git a/docs/device-control-compose-ui-change-log.md b/docs/device-control-compose-ui-change-log.md deleted file mode 100644 index 9cc1428..0000000 --- a/docs/device-control-compose-ui-change-log.md +++ /dev/null @@ -1,195 +0,0 @@ -# Device List Compose UI Change Log - -Branch: `feature/device-control-compose-ui` - -## Summary - -This branch adds only the Kotlin Jetpack Compose device list page owned by this feature area. - -The implementation provides a reusable Compose screen that displays the ABox terminal device categories: - -- Smart socket -- Temperature/humidity sensor -- Infrared controller - -This branch intentionally does not modify the app entry point or app shell routing. The app shell, login flow, and detail-feature routing are owned by other feature branches. - -## Added Files - -### `android/app/src/main/kotlin/com/flagship/abox/manager/ui/devicecontrollist/DeviceListScreen.kt` - -Adds the device list page. - -The page displays entries for: - -- Smart socket -- Temperature/humidity sensor -- Infrared controller - -Current scope: - -- Display the device categories as list entry UI. -- Keep the UI in Kotlin Compose. -- Expose click callbacks for each device category. -- Avoid adding app-shell routing, detail routes, or detail control pages in this branch. - -Integration API: - -```kotlin -DeviceListScreen( - onSocketClick = { /* route to socket module later */ }, - onTemperatureHumidityClick = { /* route to temperature/humidity module later */ }, - onInfraredClick = { /* route to infrared controller module later */ }, -) -``` - -Future integration point: - -- The app shell or feature owner responsible for routing can host this screen and connect these callbacks to their own routes/modules later. - -## Architecture Notes - -This branch follows the current repository direction: - -- Kotlin instead of Java -- Jetpack Compose instead of XML layouts -- Single-Activity UI instead of multiple Activities -- Navigation Compose compatibility through external callbacks -- Existing design-system wrappers where practical - -This branch intentionally does not copy the previous Java/XML experiment module into the team repository. - -## Scope Intentionally Not Included - -This branch does not include: - -- App entry point changes -- App shell or login routing changes -- A device-control navigation graph file -- Socket control screen implementation -- Temperature/humidity status screen implementation -- Infrared controller screen implementation -- Shared detail-control component scaffolding -- Direct ABSDK calls from Compose UI -- New Java Activity classes -- XML layout files -- A separate Android module copied from the experiment project -- Full session/login integration for device gateway calls -- Persistent infrared key storage - -These should be added by the corresponding feature owners in later branches or follow-up commits after team architecture review. - -## Verification - -- Built and ran `android.app` from Android Studio successfully during local validation. -- `:android:app:assembleDebug` completed successfully after trimming the feature scope. - -## Files Intended for Commit - -The intended commit scope is limited to: - -```text -android/app/src/main/kotlin/com/flagship/abox/manager/ui/devicecontrollist/DeviceListScreen.kt -docs/device-control-compose-ui-change-log.md -``` - -`settings.gradle.kts` is intentionally excluded from this feature commit. Local Gradle/JDK/toolchain setup should be handled on the developer machine and should not modify the team-provided project configuration in this branch. - ---- - -# 设备列表 Compose UI 修改说明(中文) - -分支:`feature/device-control-compose-ui` - -## 概要 - -本分支只新增当前分工负责的 Kotlin Jetpack Compose 设备列表页面。 - -设备列表展示的设备类别包括: - -- 智能插座 -- 温湿度传感器 -- 红外控制器 - -本分支故意不修改 App 入口或应用壳路由。程序入口、登录流程和各设备详情模块路由由其他功能分支负责。 - -## 新增文件 - -### `android/app/src/main/kotlin/com/flagship/abox/manager/ui/devicecontrollist/DeviceListScreen.kt` - -新增设备列表页面。 - -页面展示三个设备入口: - -- 智能插座 -- 温湿度传感器 -- 红外控制器 - -当前实现范围: - -- 展示设备类别入口 UI。 -- 保持 Kotlin Compose 实现。 -- 为每个设备类别暴露点击回调。 -- 不在本分支实现 App 入口接入、设备详情 route 或设备控制页面。 - -对接 API: - -```kotlin -DeviceListScreen( - onSocketClick = { /* 后续跳转到智能插座模块 */ }, - onTemperatureHumidityClick = { /* 后续跳转到温湿度模块 */ }, - onInfraredClick = { /* 后续跳转到红外控制器模块 */ }, -) -``` - -后续接入点: - -- 由负责 App shell 或对应设备模块的同学,在各自分支中挂载这个页面,并把这些回调连接到他们自己的详情路由或功能模块。 - -## 架构说明 - -本分支遵循当前小组仓库的技术方向: - -- 使用 Kotlin,而不是 Java。 -- 使用 Jetpack Compose,而不是 XML layout。 -- 使用单 Activity 架构,而不是多个 Activity 跳转。 -- 通过外部回调保持与 Navigation Compose 的兼容性。 -- 尽量复用已有 design system 中的组件封装。 - -本分支没有把之前个人实验项目中的 Java/XML 模块直接复制进团队仓库。 - -## 本分支未包含的内容 - -本分支暂不包含: - -- App 入口修改。 -- App shell 或登录路由修改。 -- 设备控制 navigation graph 文件。 -- 智能插座控制页面。 -- 温湿度状态页面。 -- 红外控制器操作页面。 -- 设备详情控制页面共用组件。 -- Compose UI 中直接调用 ABSDK。 -- 新增 Java Activity。 -- 新增 XML layout。 -- 从个人实验项目复制独立 Android 模块。 -- 完整登录/session 与设备 gateway 的联动。 -- 红外学习按键的持久化存储。 - -这些内容建议由对应模块负责人在后续 branch 或后续 commit 中继续实现。 - -## 验证 - -- 本地验证过程中已从 Android Studio 成功 build/run `android.app`。 -- 修剪职责范围后,`:android:app:assembleDebug` 构建成功。 - -## 预期提交范围 - -本次提交范围应限制在: - -```text -android/app/src/main/kotlin/com/flagship/abox/manager/ui/devicecontrollist/DeviceListScreen.kt -docs/device-control-compose-ui-change-log.md -``` - -`settings.gradle.kts` 当前不属于本次设备列表 UI 功能提交范围。本地 Gradle/JDK/toolchain 配置应在开发者本机处理,不应修改团队提供的项目配置文件。 diff --git a/docs/device-list-compose-ui-pr-description.md b/docs/device-list-compose-ui-pr-description.md deleted file mode 100644 index 28d50e7..0000000 --- a/docs/device-list-compose-ui-pr-description.md +++ /dev/null @@ -1,133 +0,0 @@ -# WIP: Add device list Compose screen - -## Summary - -This MR adds only the reusable Kotlin Jetpack Compose device list screen for my assigned scope. - -The screen displays the three ABox device categories: - -- Smart socket -- Temperature/humidity sensor -- Infrared controller - -This MR intentionally does not modify the app entry point, login flow, app shell routing, or any device detail/control screen. Those parts are handled by other feature branches. - -## Changes - -- Add `DeviceListScreen`. -- Expose click callbacks for each device category: - - `onSocketClick` - - `onTemperatureHumidityClick` - - `onInfraredClick` -- Update the device-list change log document. -- Remove the earlier out-of-scope temporary device control screens from this branch. - -## Scope - -Included: - -- Device list Compose UI component -- Device category entry UI -- Callback API for future route integration - -Not included: - -- App entry point changes -- Login flow changes -- Device control navigation graph -- Smart socket control screen -- Temperature/humidity status screen -- Infrared controller screen -- Direct ABSDK calls -- Java Activity classes -- XML layout files - -## Integration Notes - -The screen is designed to be hosted by the app shell or routing owner later: - -```kotlin -DeviceListScreen( - onSocketClick = { /* route to socket module */ }, - onTemperatureHumidityClick = { /* route to temperature/humidity module */ }, - onInfraredClick = { /* route to infrared controller module */ }, -) -``` - -The current branch keeps these callbacks external so other feature owners can connect their modules without this MR taking ownership of routing. - -## Verification - -- Built and ran `android.app` locally from Android Studio. -- `:android:app:assembleDebug` completed successfully after trimming this branch to the device-list component scope. - -## Notes - -`settings.gradle.kts` is intentionally not part of this MR. Local Gradle/JDK/toolchain setup is handled on the developer machine and should not modify the team-provided project configuration. - ---- - -# WIP: 新增设备列表 Compose 页面 - -## 概要 - -本 MR 只新增我当前分工负责的 Kotlin Jetpack Compose 设备列表页面组件。 - -设备列表展示三类 ABox 设备入口: - -- 智能插座 -- 温湿度传感器 -- 红外控制器 - -本 MR 故意不修改 App 入口、登录流程、应用壳路由,也不实现任何设备详情/控制页面。这些部分由其他功能分支负责。 - -## 修改内容 - -- 新增 `DeviceListScreen`。 -- 为三类设备入口暴露点击回调: - - `onSocketClick` - - `onTemperatureHumidityClick` - - `onInfraredClick` -- 更新设备列表变更说明文档。 -- 从本分支中移除早期临时加入、但不属于当前分工范围的设备控制页面。 - -## 本 MR 包含 - -- 设备列表 Compose UI 组件 -- 设备类别入口 UI -- 后续路由接入所需的 callback API - -## 本 MR 不包含 - -- App 入口修改 -- 登录流程修改 -- 设备控制 navigation graph -- 智能插座控制页面 -- 温湿度状态页面 -- 红外控制器页面 -- Compose UI 中直接调用 ABSDK -- Java Activity -- XML layout - -## 对接说明 - -该页面后续可以由 App shell 或路由负责人挂载: - -```kotlin -DeviceListScreen( - onSocketClick = { /* 后续跳转到智能插座模块 */ }, - onTemperatureHumidityClick = { /* 后续跳转到温湿度模块 */ }, - onInfraredClick = { /* 后续跳转到红外控制器模块 */ }, -) -``` - -当前分支只提供页面和回调 API,不负责具体跳转目标,以便其他模块负责人对接自己的功能页面。 - -## 验证 - -- 已在本地通过 Android Studio 成功 build/run `android.app`。 -- 修剪为设备列表组件范围后,`:android:app:assembleDebug` 构建成功。 - -## 备注 - -`settings.gradle.kts` 不属于本 MR 范围。本地 Gradle/JDK/toolchain 配置在开发者本机处理,不修改团队提供的项目配置文件。 diff --git a/docs/examples/LoginAsyncTaskDemo.java b/docs/examples/LoginAsyncTaskDemo.java deleted file mode 100644 index b0c8d9a..0000000 --- a/docs/examples/LoginAsyncTaskDemo.java +++ /dev/null @@ -1,92 +0,0 @@ -// AsyncTask用法的Demo -package tr.dhee.abox.demo.ui.login; - -import android.os.AsyncTask; -import android.os.Bundle; -import android.os.Process; -import android.view.View; -import android.widget.Button; - -import androidx.activity.ComponentActivity; -import androidx.activity.EdgeToEdge; -import androidx.appcompat.app.AppCompatActivity; -import androidx.core.graphics.Insets; -import androidx.core.view.ViewCompat; -import androidx.core.view.WindowInsetsCompat; - -import com.dhc.absdk.ABRet; -import com.dhc.absdk.ABSDK; - -import java.lang.reflect.Parameter; - -import tr.dhee.abox.demo.R; - -public class MainActivity extends AppCompatActivity { - - Button buttonLoginABox; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - EdgeToEdge.enable(this); - setContentView(R.layout.activity_main); - ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> { - Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()); - v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom); - return insets; - }); - - buttonLoginABox = findViewById(R.id.buttonLoginAbox); - - buttonLoginABox.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - //使用aboxSDK里面的芳芳 - ABRet abRet = ABSDK.getInstance().loginWithUsername("a", "a"); - -//替换成如下写法 - String[] userArray = {"", ""}; - - LoginAsyncTask loginAsyncTask = new LoginAsyncTask(); - loginAsyncTask.execute(userArray); - } - }); - - - } - - class LoginAsyncTask extends AsyncTask { - @Override - protected ABRet doInBackground(String... params) { - return ABSDK.getInstance().loginWithUsername(params[0], params[1]); - } - - @Override - protected void onPostExecute(ABRet abRet) { - super.onPostExecute(abRet); - if (abRet.getCode().equals("00000")) { - - //跳转到设备列表页面 - } - } - } - - -} - - - - - - - - - - - - - - - - - diff --git a/docs/examples/activity_main_login.xml b/docs/examples/activity_main_login.xml deleted file mode 100644 index 45bed0e..0000000 --- a/docs/examples/activity_main_login.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - -