优化开关与渐变的无缝衔接,消除‘先黑一下再变亮’突变

问题:关灯渐变进行中途点击开灯,会出现先熄灭再从0渐变的突变。

方案(A+B+C):
A. ‘开灯’打断‘关灯渐变’时,沿用当前渐变中的即时亮度作为起点,反向渐变到目标(不再强制从0起步)。
B. 渐变任务收尾保护:关灯渐变完成前若已被开灯抢占,跳过PWM关断收尾,避免黑场。
C. 取消逻辑加固:取消当前渐变时清除 is_fading/is_closing_fade/fade_completed,避免旧渐变回调误关灯。

实现点:
- set_light:记录 was_closing_fade 与当前即时亮度;开灯时根据 was_closing_fade 决定起点(即时亮度或0)。
- fade_task:在关灯完成分支检查 g_device_control.on,已被开灯抢占则不关断,交由开灯渐变接管。
- cancel_current_light_fade:补充状态清理,防止回调残留。

验证:亮→关(渐变中)→开、末尾抢占、快速连点关/开、单色↔双色切换夹杂开关,均无‘黑一下’突变。
This commit is contained in:
2025-11-17 07:27:44 +08:00
parent cb1ef39108
commit 53ba39e35d
17 changed files with 328 additions and 19 deletions

View File

@@ -254,14 +254,20 @@ static void *fade_task(const char *arg)
fade_ctx.fade_completed = false; fade_ctx.fade_completed = false;
if (fade_ctx.is_closing_fade) { if (fade_ctx.is_closing_fade) {
// 关灯渐变完成不更新g_device_control.brightness_local保持原有目标亮度 // 若在收尾时已被“开灯”抢占,则跳过关断动作,避免“先黑一下”的突变
fade_ctx.is_closing_fade = false; if (g_device_control.on) {
update_pwm_output(false, 0, 0); e_printf("[fade_task] Close-fade preempted by OPEN, skip turning off\r\n");
g_device_control.duty_cw = 0; fade_ctx.is_closing_fade = false;
g_device_control.duty_ww = 0; // 保持当前PWM与占空后续由OPEN流程接管渐变
// 注意:这里不更新 g_device_control.brightness_local保持之前的亮度值 } else {
e_printf("[fade_task] Close light fade completed, PWM turned off, brightness_local preserved: %d\r\n", // 关灯渐变完成不更新g_device_control.brightness_local保持原有目标亮度
g_device_control.brightness_local); fade_ctx.is_closing_fade = false;
update_pwm_output(false, 0, 0);
g_device_control.duty_cw = 0;
g_device_control.duty_ww = 0;
e_printf("[fade_task] Close light fade completed, PWM turned off, brightness_local preserved: %d\r\n",
g_device_control.brightness_local);
}
} else { } else {
// 正常渐变完成:正常更新所有值 // 正常渐变完成:正常更新所有值
g_device_control.duty_ww = device_control.duty_ww; g_device_control.duty_ww = device_control.duty_ww;
@@ -667,10 +673,10 @@ static void cancel_current_light_fade(void)
// 竞态保护:先拉低标志再停计时器,避免回调自重启 // 竞态保护:先拉低标志再停计时器,避免回调自重启
fade_ctx.timer_active = false; fade_ctx.timer_active = false;
uapi_timer_stop(fade_ctx.timer_handle); uapi_timer_stop(fade_ctx.timer_handle);
// 如果我打断了渐变,则将当前值更新到目标值不然下次计算会异常 // 标记为非渐变态,清除“关灯渐变”标记与完成态,避免旧渐变在回调里误触发收尾关断
// g_device_control.cct_local = fade_ctx.current_cct; fade_ctx.is_fading = false;
// g_device_control.brightness_local = fade_ctx.current_brightness; fade_ctx.is_closing_fade = false;
// memset(&fade_ctx, 0, FADE_CTRL_DATA_SIZE(fade_ctx)); fade_ctx.fade_completed = false;
} }
// 计算校验和 // 计算校验和
@@ -939,12 +945,16 @@ int set_light(light_ctrl_source_e source,
int32_t brightness_local_target, int32_t cct_local_target) int32_t brightness_local_target, int32_t cct_local_target)
{ {
bool was_on = g_device_control.on; bool was_on = g_device_control.on;
// 记录调用前是否处于“关灯渐变中”,用于开灯时做无缝反向
bool was_closing_fade = (fade_ctx.is_fading && fade_ctx.is_closing_fade);
int32_t curr_brightness_before_cancel = fade_ctx.current_brightness;
int32_t curr_cct_before_cancel = fade_ctx.current_cct;
struct fade_ctx_t tmp_fade_ctx = {0}; struct fade_ctx_t tmp_fade_ctx = {0};
if (fade_ctx.is_fading) { if (fade_ctx.is_fading) {
bool closing_fade_active = fade_ctx.is_closing_fade;
bool suppress_cancel = false; bool suppress_cancel = false;
// 在关灯渐变过程中,属性/模式变更不应打断关灯过程 // 在关灯渐变过程中,属性/模式变更不应打断关灯过程
if (closing_fade_active) { if (fade_ctx.is_closing_fade) {
if (source == APP_CHANGE_LIGHT_BRIGHTNESS_CCT || source == APP_CHANGE_LIGHT_MODE || source == APP_CLOSE_LIGHT) { if (source == APP_CHANGE_LIGHT_BRIGHTNESS_CCT || source == APP_CHANGE_LIGHT_MODE || source == APP_CLOSE_LIGHT) {
suppress_cancel = true; // 允许继续关灯渐变;再次关灯请求可复用或稍后重启 suppress_cancel = true; // 允许继续关灯渐变;再次关灯请求可复用或稍后重启
} }
@@ -958,11 +968,20 @@ int set_light(light_ctrl_source_e source,
g_device_control.on = true; g_device_control.on = true;
if (DEV_POWER_ON == source || (APP_OPEN_LIGHT == source && !was_on)) { if (DEV_POWER_ON == source || (APP_OPEN_LIGHT == source && !was_on)) {
// 开机或关灯→开灯从0开始渐变 // 若之前处于关灯渐变中,被“开灯”打断,则沿用渐变中的即时亮度作为起点,实现无缝反向
fade_ctx.current_brightness = 0; if (was_closing_fade) {
fade_ctx.current_cct = g_device_control.cct_local; // 色温保持目标值 fade_ctx.current_brightness = curr_brightness_before_cancel;
e_printf("[set_light] 开灯渐变设置: brightness=0->%d, cct=%d\n", fade_ctx.current_cct = g_device_control.cct_local; // 使用当前目标色温
g_device_control.brightness_local, fade_ctx.current_cct); fade_ctx.is_closing_fade = false;
e_printf("[set_light] 开灯打断关灯渐变: brightness=%d->%d, cct=%d\n",
fade_ctx.current_brightness, g_device_control.brightness_local, fade_ctx.current_cct);
} else {
// 真正的关→开或上电开灯从0开始渐变
fade_ctx.current_brightness = 0;
fade_ctx.current_cct = g_device_control.cct_local; // 色温保持目标值
e_printf("[set_light] 开灯渐变设置: brightness=0->%d, cct=%d\n",
g_device_control.brightness_local, fade_ctx.current_cct);
}
} }
brightness_local_target = g_device_control.brightness_local; brightness_local_target = g_device_control.brightness_local;

View File

@@ -0,0 +1,290 @@
# 调试模式WiFi Console + HTTP OTA需求与设计说明
- 文档版本v1.1
- 更新时间2025-10-26
- 适用机型/平台WS63LiteOS/Harmony 适配),本仓库版本 SR_Light_Hilink_14.2.1.312_20250714
- 文档目的:沉淀“仅 WiFi、按需开启”的远程 Debug 能力TCP Console + HTTP OTA在不影响现网业务下实现快速问题定位与在线升级。本文给出明确的需求、行为规格、接口契约、资源预算、测试与风控。
---
## 1. 背景与目标
设备组装后无物理串口;现场需要远程获取日志与执行命令,并可在线推送固件进行升级。现有工程具备 SOC_LOG、DIAG、UPG 能力,本文在不改动业务使用打印宏与模块的前提下,定义一套“仅 WiFi、调试模式下启用”的远程调试与 OTA 方案。
目标:
- 纯 WiFi仅用 TCP Console 与 HTTP OTA不使用 BLE/USB/AP/mDNS。
- 调试模式准入:仅当扫描到 SSID=`EK_HF_DEBUG` 时进入;平时不暴露任何端口与广播。
- 类串口体验:双向交互(收发),支持历史日志回溯与实时回显。
- OTA 直装:写入并校验通过后立即安装(可重启)。
- 低侵入:常态仅维护内存日志环形缓冲;调试行为可在高负载期延后;禁止 AP 模式。
不做:
- 不开启 UDP syslog不做 mDNS/DNSSD不引入 HTTPS/TLS 与口令认证。
## 2. 术语与缩写
- Debug 模式:本文所述仅在现场触发后短时开放的“调试窗口”。
- TCP Console类串口的 TCP 字节流服务。
- HTTP OTA通过 HTTP 推送固件包分片并安装。
- Ring Buffer内存日志环形缓冲常态写入调试时可读取。
## 3. 需求清单(用户决策映射)
1) 仅启用 TCP Console 与 HTTP OTAUDP 日志不启用,且所有 Debug 功能只在 Debug 模式开启时可用。
2) 常态始终维护日志 Ring Buffer仅内存不外发用于 Debug 时回溯。
3) 不做服务发现mDNS/DNSSD
4) 唯一入口=扫描到 SSID `EK_HF_DEBUG`
- 若设备当前“未连接任何 WiFi”STA 未关联),则直接连接该热点(开放式,无密码),以确保与调试主机处于同一网段后进入 Debug 模式。
- 若设备已连接 WiFi则不切换网络仅把“扫描命中”视作触发信号而进入 Debug 模式,避免打断云业务。
- 禁止开启 AP 模式。
5) 不需要共享口令、不做 SSID 校验后缀,入口完全开放(按风险提示执行)。
6) 多设备场景:进入 Debug 模式后,设备以 UDP 广播帧周期发布自身识别信息(复用 HiLink 设备信息字段)以便工具端筛选目标设备。
7) Debug 窗口:若进入后的 5 分钟内“从未有主机连接”Console 或 OTA 任一)则退出 Debug 模式并关闭端口与广播。
8) 端口由本方案指定(见 §6
9) 不启用 IP 白名单/黑名单。
10) 背景扫描允许在“高流量周期”暂停/延后。
## 4. 总体架构与模块
组件划分(逻辑):
- DebugManager状态机
- 维护状态 Closed/Debug、计时器、端口启停与广播调度。
- WifiScanner被动扫描或等效
- 周期扫描,命中 SSID 触发 Debug在高负载时延后。
- TcpConsoleServer2323/tcp
- 行缓冲命令模式 + RAW 透传模式;与 DIAG 虚拟 shell 对接;镜像实时日志。
- HttpOtaServer8070/tcp
- `prepare`/`chunk`/`commit`/`status` 路由;调用 UPG uapicommit 通过即安装。
- LogRingBuffer内存环形常态写入
- 通过 DIAG 通道 TX hook 或用户打印注册接口镜像日志到环形缓冲Debug 时提供 tail/dump 出口。
- UdpAnnouncer37501/udp 广播,仅 Debug
- 发布设备识别信息did/model/sn/ip/fw 等)。
- LoadMonitor高负载守门
- 采样 CPU/LWIP 队列/吞吐量,给扫描与广播提供延后/降频依据。
## 5. 状态机与时序
状态:
- Closed默认
- TcpConsole/HttpOta/Announcer 均关闭Ring Buffer 持续写入。
- WifiScanner 以固定周期被动扫描 SSID。
- Debug触发进入
- 立即开启 2323/tcp 与 8070/tcp并启动 37501/udp 广播。
- 启动“5 分钟首联计时器”。若 5 分钟内从未有主机建立 Console 或 OTA 连接,则自动回到 Closed。
- 一旦出现首个连接首联计时器停止Debug 模式默认保持,直至手工 `debug off` 或设备重启(可选:实现“断开后闲置 5 分钟退出”的拓展策略,默认关闭)。
触发(唯一):
- WifiScanner 扫描结果出现 SSID = `EK_HF_DEBUG`
- 若未联网:尝试连接该 SSID无密码DHCP 成功后进入 Debug。
- 若已联网:不切换,仅作为信号进入 Debug。
扫描策略:
- 周期:默认 120 s/次;优先采用被动扫描。目标是整个扫描总时长 ≤1.5 s具体信道驻留时长受驱动能力限制可按平台实际尽量控制。
- 高负载抑制CPU>60% 或 LWIP 队列>80% 或近 10 s 吞吐>阈值 → 跳过本轮并记录;连续跳过 3 次后强制进行“快速扫描”(仅当前信道与相邻)。若无法直接获取上述指标,可退化为基于 I/O 速率与任务执行时长的启发式延后/降频。
## 6. 端口与协议
- TCP Console`2323/tcp`
- 单连接优先。并发连接时:保持首个连接为“前台会话”,后续连接返回“忙碌”并断开。
- 编码UTF8行终止 CR/LF单行上限 512 字节(可配)。
- 模式:默认命令模式;支持 `raw on/off` 切换透传模式(不解析 CR/LF
- 历史日志:提供 `log tail N` / `log dump S` 指令(见 §7
- HTTP OTA`8070/tcp`
- `POST /ota/prepare` ContentType: application/json
- 入参:`{"length": <uint32>, "sha256": "<可选hex>"}`
- 行为:调用 `uapi_upg_prepare()`;返回 200/错误码。
- `PUT /ota/chunk?offset=<uint32>` ContentType: application/octet-stream
- 要求 4 字节对齐;`offset + len <= length`
- 行为:`uapi_upg_write_package_sync(offset, buf, len)`;返回 200/错误码。
- `POST /ota/commit`
- 行为:`uapi_upg_verify_file()` → 成功则 `uapi_upg_request_upgrade(reset=true)` 立刻安装并重启;返回 200可能随即断开
- `GET /ota/status`
- 返回:`{"status":"NONE|UPDATING|SUCC|FAIL", "progress":<0-100 可选>}`
- `status` 源自 `uapi_upg_get_status()` 的聚合状态。
- 若编译开启并注册 `uapi_upg_register_progress_callback()`,则返回 `progress`;否则仅返回状态。
- 设备广播(仅 Debug`37501/udp`(广播地址/子网广播)
- 间隔:进入 Debug 后前 10 秒每秒 1 次;之后每 30 秒 1 次,直至 Debug 结束。
- 载荷JSON 示例):
```json
{"t":"ekhf.debug.presence.v1","pid":"<productId>","did":"<deviceId>","model":"<model>",
"sn":"<sn>","mac":"<xx:xx:xx:xx:xx:xx>","ip":"<a.b.c.d>","fw":"<version>",
"uptime":12345,"ports":{"console":2323,"ota":8070},"window_sec_left":270}
```
实现备注:
- Console/HTTP 服务需基于 lwIP socket/netconn 自行实现最小可用服务器(单连接 Console、最小路由 HTTP
- 端口共存与冲突:若系统中已启用如 `hfnet_start_assis(ASSIS_PORT)` 等服务,需确保与 2323/8070 端口不冲突;必要时在 Debug 模式启用时暂时关闭或改口。
## 7. 日志 Ring Buffer常态写入仅 Debug 可读)
- 源:通过 DIAG 通道 TX hook 或用户打印注册接口,对 `SOC_LOG` 与 `osal_printk/print_str` 输出进行镜像,写入环形缓冲(生产者无阻塞拷贝)。
- 容量:建议 128 KB可调 128512 KB
- 条目时间戳ms、等级、模块、线程/CPU 与文本;按行存储,超过行长进行切分。
- 读取Console 指令):
- `log tail <N>`:输出最近 N 行;
- `log dump <S>`:输出最近 S 秒内日志;
- `log level <ERR|WARN|INFO|DBG>`:调节“实时镜像到 Console”的等级不影响 ring 的写入)。
- 限速Console 推送上限 100 KB/s可配
## 8. 资源与负载策略
- 扫描预算≤1.5 s/120 s高负载时延后连续跳过 3 次后进行快速扫描。
- Console 与 OTA非阻塞 socket后台任务优先级低于业务任务拥塞时降速/丢弃输出,不反压业务。
- 广播预算:仅 Debug 模式广播;高负载时自动将间隔提升至 60 s。
- 负载指标退化:若无法采集 CPU%/LWIP 队列等指标,允许使用基于 I/O 速率和任务运行时长的启发式降频/延后策略。
## 9. 安全与合规
- 入口完全开放(按照用户要求):
- 无密码 SSIDConsole/HTTP 无鉴权;无 IP 白名单/黑名单。
- 风险:同网段任何人可在 Debug 窗口内接入;因此 Debug 模式仅在现场触发、短时使用,且 5 分钟内无人接入即退出。
- 数据OTA 包整体仍由 UPG 在本地执行完整性校验(头/整包/镜像哈希与签名链,具体以现有 UPG 配置为准)。
## 10. 配置项(默认值)
| 项目 | 键名(建议) | 默认 |
|---|---|---|
| 扫描周期 | `DBG_SCAN_PERIOD_S` | 120 |
| 信道驻留 | `DBG_SCAN_DWELL_MS` | 100 |
| 高负载 CPU 阈值 | `DBG_CPU_BUSY_PCT` | 60 |
| 高负载 LWIP 队列阈值 | `DBG_LWIP_Q_BUSY_PCT` | 80 |
| Console 端口 | `DBG_CONSOLE_PORT` | 2323 |
| OTA 端口 | `DBG_OTA_PORT` | 8070 |
| 广播端口 | `DBG_BROADCAST_PORT` | 37501 |
| Ring 容量KB | `DBG_RING_KB` | 128 |
| Console 实时流上限KB/s | `DBG_CONSOLE_RATE_KBPS` | 100 |
| 首联超时s | `DBG_FIRST_CONN_TIMEOUT_S` | 300 |
> 注:以上均为实现时的可配置参数,本文档不强制其持久化方式(编译宏 / NV
## 11. 与现有代码的对接点(不改变业务调用)
0) 前置依赖与初始化:
- Kconfig启用升级模块`MIDDLEWARE_SUPPORT_UPDATE=y`)。
- 启动阶段调用 `ws63_upg_init()` 完成 `uapi_upg_init()` 初始化(见 `middleware/chips/ws63/update/common/upg_common_porting.c`)。
- Console/HTTP 服务需新增(基于 lwIP socket/netconn
1) Console 入站命令执行:
- 入口:`diag_debug_cmd_proc(uint8_t *data, uint32_t len)`
- 参考:`middleware/chips/ws63/dfx/dfx_system_init.c` 中 `cmd_shell_proc()` 用法。
2) 日志输出镜像与 Ring 写入:
- 通过 DIAG 通道 TX hook 做 tee先走原 UART 输出,再写入 Ring Buffer或使用平台暴露的用户打印注册入口实现镜像
- 保持原 UART 输出不变,同时镜像一份至 Console 与 Ring Buffer。
3) OTA 调用序列HTTP 路由对应):
- `prepare` → `uapi_upg_prepare(upg_prepare_info_t*)`
- `chunk` → `uapi_upg_write_package_sync(offset, buf, len)`
- `commit` → `uapi_upg_verify_file()` → `uapi_upg_request_upgrade(reset=true)`(立即安装与重启);
- `status` → `uapi_upg_get_status()`
- 参考:`middleware/utils/update/storage/upg_storage.c`、`middleware/utils/update/common/upg_verify.c`、`middleware/utils/update/local_update/upg_process.c`。
4) Wifi 扫描/连接:
- 复用现有 WiFi 管理接口(参照 `application/samples/wifi/*` 示例)实现被动扫描(或等效)与条件连接;不得影响现有 STA 工作。
5) 端口共存:
- 若使用 `hfnet_start_assis(ASSIS_PORT)` 等调试服务,需在 Debug 模式启用时避免与 2323/8070 端口冲突(可在进入 Debug 时停止该服务或调整端口)。
## 12. 错误码与返回(建议)
Console
- `BUSY`(已占用,拒绝并断开)
- `ERR_BAD_CMD` / `ERR_ARGS` / `ERR_TOO_LONG`
HTTP OTA
- 400 `ERR_INVALID_ARGS`length/offset/对齐错误)
- 409 `ERR_STATE`(未 prepare 先 chunk重复 commit 等)
- 413 `ERR_TOO_LARGE`(包长超出 FOTA 区)
- 416 `ERR_RANGE`offset 越界)
- 422 `ERR_VERIFY_FAILED`(校验失败)
- 500 `ERR_INTERNAL`
## 13. 典型交互示例
1) Console
```
$ nc <dev-ip> 2323
> help\r\n
< ...(回显各命令)
> log tail 200\r\n
< 最近200行历史日志...
> raw on\r\n (进入透传)
```
2) OTA
```
# 1) 准备
curl -sS -X POST http://<dev-ip>:8070/ota/prepare \
-H 'Content-Type: application/json' -d '{"length": 1048576}'
# 2) 分片写入(举例 4KB 步进)
offset=0; while read -r -d '' -n 4096 chunk; do \
curl -sS -X PUT "http://<dev-ip>:8070/ota/chunk?offset=${offset}" \
--data-binary @<(printf "%s" "$chunk"); \
offset=$((offset+4096)); done < <(dd if=fw.bin bs=4096 status=none)
# 3) 提交并安装(设备可能立即断开并重启)
curl -sS -X POST http://<dev-ip>:8070/ota/commit
```
3) 广播(工具侧监听):
```
tcpdump -n -vv -s0 udp port 37501
```
## 14. 测试计划(验收标准)
触发:
- 未联网→现场开启 `EK_HF_DEBUG` 热点:设备自动连接并进入 Debug5 分钟内无连接则退出。
- 已联网→现场开启同名热点:设备不切换,仅进入 Debug5 分钟内无连接则退出。
Console
- 命令回显正常;`log tail 200`、`log dump 60` 正确输出;`raw on` 8KB 循环透传校验正确;并发第二连接被拒绝。
OTA
- `prepare→chunk→commit` 正常commit 后立即安装/重启;重启后版本信息与日志中可见升级结果;错误 offset/越界/校验失败分别返回 400/416/422。
- `GET /ota/status`:在未初始化/未 prepare/写入中/完成/失败各阶段返回符合 `NONE|UPDATING|SUCC|FAIL` 映射;启用进度回调时返回合理 `progress`。
稳定性:
- 高负载下扫描延后生效广播间隔自动增大Console/OTA 不阻塞业务(无明显时延抖动)。
端口与并发:
- 与 `ASSIS_PORT` 等服务共存/冲突验证Console 并发连接第二路返回 `BUSY` 并断开。
限速:
- Console 实时推送限速 100KB/s 验证(长流量压测下不反压业务)。
回归:
- Debug 退出后端口与广播确实关闭;常态 Ring Buffer 持续工作且占用符合预算。
## 15. 风险与缓解
- 开放式入口风险:同网段内任意主机可接入 Debug。缓解仅在现场触发5 分钟无人连即退出;记录接入来源到 Ring可后续加“口令开关”。
- 扫描扰动:被动扫描+高负载抑制;扫描时间受限;必要时频率可进一步降低。
- OTA 失败风险UPG 既有校验链与回退策略AB/整包/差分由现配置决定);失败保留当前运行分区。
## 16. 交付与实施建议(不改变业务逻辑)
开发任务拆解(建议):
1) DebugManager/LoadMonitor/状态机与计时器骨架。
2) WifiScanner被动扫描与条件连接高负载抑制策略。
3) TcpConsoleServer需新增基于 lwIP 单连接、行缓冲/RAW 模式、命令桥接、实时日志镜像、历史日志指令。
4) HttpOtaServer需新增最小路由 `/ota/prepare|chunk|commit|status` 与 UPG uapi 串接、错误码与进度上报。
5) LogRingBuffer通过 DIAG TX hook/用户打印注册入口做日志 tee读口限速。
6) UdpAnnouncerJSON 载荷、节流与停止逻辑。
7) 集成与测试:按 §14 验收标准逐项打勾。
端口冲突处理:
- 若存在既有调试/辅助服务占用端口,进入 Debug 模式时进行协调(停服或改口),退出时恢复。
## 17. 变更记录
- 2025-10-26v1.1 调整为可落地实现版本:
- 明确 Console/HTTP 需基于 lwIP 实现;新增端口冲突与共存说明。
- 日志镜像改为 DIAG TX hook/用户打印注册入口Ring 默认容量建议为 128KB。
- `GET /ota/status` 状态与进度对齐 `uapi_upg_get_status` 与进度回调。
- 扫描策略放宽为目标约束,并提供负载指标不可用时的启发式退化方案。
- 2025-10-26初版按“纯 WiFi + SSID 触发 + 无认证 + 5 分钟首联退出 + 无 AP/mDNS/UDP syslog”的决策输出

BIN
logs/after_color.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

BIN
logs/after_tap.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

BIN
logs/before_tap.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

BIN
logs/device_after.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

BIN
logs/device_after2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

BIN
logs/device_after3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

BIN
logs/device_after4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

BIN
logs/device_after5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

BIN
logs/device_screenshot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

BIN
logs/device_screenshot2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

BIN
logs/screen.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

BIN
logs/screen2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

BIN
logs/tap1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

BIN
logs/tap2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

BIN
logs/tap3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB