6.6 KiB
6.6 KiB
语音协议广播测试脚本
adb shell am broadcast 形式的联调脚本集合,覆盖 可行性评估文档 §6.1 中定义的统一协议(action=com.pukka.jiecheng.action.VOICE_COMMAND),用于在没有第三方语音 App 时手工驱动 voice 模块。
适用范围:
bash(Git Bash 即可)。脚本里所有路径用 Unix 风格。
1. 目录结构
test/voice_helper/
├── lib/
│ └── common.sh # 公共函数:payload 构造 / 广播发送 / 应用级操作
├── jump_film.sh # 单片跳转 JUMP/FILM
├── jump_category.sh # 分类跳转 JUMP/CATEGORY
├── search.sh # 语音搜索 SEARCH
├── control.sh # 播放控制 CONTROL/<action>
├── cold_start.sh # 冷启动单片跳转(force-stop + 投递 + 拉起)
├── throttle_test.sh # 2 秒内连续投递同类命令(验证节流)
├── security_test.sh # 非白名单 sourceApp 投递(验证签名校验)
├── listen_callback.sh # 反向广播回调监听(adb logcat)
├── run_all.sh # 顺序执行全部用例
└── README.md
2. 协议约定(与文档 §6.1 一致)
action: com.pukka.jiecheng.action.VOICE_COMMAND
permission: com.pukka.jiecheng.permission.VOICE_COMMAND
component: com.pukka.jiecheng/.voice.receiver.VoiceCommandReceiver
extras:
requestId string 第三方生成的请求 ID,回传时带回
sourceApp string 第三方包名
sourcePlatform string 第三方平台标识(用于选择 VendorAParser/BParser)
commandType string JUMP / SEARCH / CONTROL
payload string JSON,业务字段
callbackAction string 反向广播 action,由第三方传入
timestamp long 毫秒
payload 按 commandType 分支:
| commandType | payload 字段 |
|---|---|
JUMP |
jumpType (FILM/CATEGORY/ACTOR/DIRECTOR) + 对应 *Id/*Name,可带 autoPlay |
SEARCH |
filmName / actorName / directorName / category / unionStyle / region / releaseDate |
CONTROL |
action (PLAY/PAUSE/FULLSCREEN_ENTER/FULLSCREEN_EXIT/SEEK_FORWARD/SEEK_BACKWARD/SEEK_TO/PREV/NEXT/SELECT_INDEX/PAGE_NEXT/PAGE_PREV/GOTO_PAGE) + seconds / index / page |
3. 快速开始
# 设备已连接 adb 后:
cd test/voice_helper
# 单片跳转(默认 filmId=film-demo-001 / autoPlay=true)
./jump_film.sh
# 自定义参数
./jump_film.sh film-12345 "我的影片" true
# 分类跳转
./jump_category.sh cat-action "动作片"
# 语音搜索
./search.sh "流浪地球"
./search.sh "流浪地球" "吴京"
# 播放控制
./control.sh PAUSE
./control.sh SEEK_FORWARD seconds=10
./control.sh SEEK_TO seconds=300
./control.sh SELECT_INDEX index=3
./control.sh GOTO_PAGE page=2
# 冷启动(force-stop → 投递 → 拉起 MainActivity)
./cold_start.sh
# 2 秒内连续 5 次 PAUSE,验证节流
./throttle_test.sh PAUSE 5
# 非白名单 sourceApp 投递(验证拦截)
./security_test.sh com.attacker.malicious
# 反向广播监听(需 voice 模块按 tag 打印回调日志,tag 默认 VoiceCommand)
./listen_callback.sh # 监听全部
./listen_callback.sh vt-1756000000-12345 # 只过滤指定 requestId
# 一键全量
./run_all.sh
4. 环境变量
| 变量 | 默认值 | 说明 |
|---|---|---|
ACTION_VOICE_COMMAND |
com.pukka.jiecheng.action.VOICE_COMMAND |
广播 action |
PERMISSION_VOICE |
com.pukka.jiecheng.permission.VOICE_COMMAND |
协议权限 |
RECEIVER_COMPONENT |
com.pukka.jiecheng/.voice.receiver.VoiceCommandReceiver |
显式组件 |
MAIN_ACTIVITY_COMPONENT |
com.pukka.jiecheng/.MainActivity |
冷启动入口 |
TEST_APP_PKG |
com.pukka.jiecheng |
应用包名 |
DEFAULT_SOURCE_APP |
com.test.voicehelper |
模拟第三方包名 |
DEFAULT_PLATFORM |
vendorA |
模拟平台 |
DEFAULT_CALLBACK_ACTION |
com.test.voicehelper.action.VOICE_CALLBACK |
反向广播 action |
TEST_REQUEST_PREFIX |
vt- |
requestId 前缀 |
SKIP_PERMISSION_CHECK |
0 |
开发期临时绕开 signature-level permission 校验时置 1 |
LOG_TAG |
VoiceCommand |
listen_callback.sh 监听的 logcat tag |
示例:自定义第三方包名
TEST_REQUEST_PREFIX=demo- DEFAULT_SOURCE_APP=com.xiaomi.voice ./jump_film.sh
5. 关于 signature-level permission
文档 §6.2 规定 Receiver 使用自定义 signature-level permission(com.pukka.jiecheng.permission.VOICE_COMMAND)。adb shell 默认以 shell 用户身份投递,不持有第三方签名权限,广播会被系统直接丢弃。
联调期三种处理方式:
- 临时降级(推荐):在
app/build.gradle给debugflavor 注入manifestPlaceholder:然后在debug { manifestPlaceholders = [voiceProtectionLevel: "normal"] } release { manifestPlaceholders = [voiceProtectionLevel: "signature"] }AndroidManifest.xml:<permission android:name="com.pukka.jiecheng.permission.VOICE_COMMAND" android:protectionLevel="${voiceProtectionLevel}" /> - 拷贝脚本到端内:在应用内临时放一个
BroadcastSenderActivity 直接发广播,绕过 shell 权限。 - 改 adb 用户:通过
adb root切到 root 身份,仅在 userdebug 镜像生效。
脚本本身不强制任何一种处理,遇到权限拦截请按上面方式放开。
6. 验证 checklist(对应文档 §12)
联调完成后逐项打勾:
- 应用未启动时第三方冷启动并执行命令(
cold_start.sh) - 应用未激活时被守卫拦截,回传
DEVICE_NOT_ACTIVATED - 正在播放时收到搜索 / 分类命令先退出再跳转
- 2 秒内连续多次控制命令只保留最后一条(
throttle_test.sh) - 第三方收到成功 / 失败回传(
listen_callback.sh配合 logcat) SELECT_INDEX/GOTO_PAGE在播放页列表中正确选中- 白名单外的
sourceApp被拦截、不回传(security_test.sh)
7. 调试技巧
# 查看应用包内注册的 Receiver
adb shell dumpsys package com.pukka.jiecheng | grep -i receiver
# 查看设备上所有待发广播
adb shell dumpsys activity broadcasts
# 查看最近一次 am broadcast 的返回结果(带 requestId 过滤)
adb shell am broadcast -a com.pukka.jiecheng.action.VOICE_COMMAND -n ... --es requestId probe
# 实时过滤 voice 模块日志
adb logcat -v threadtime VoiceCommand:V VoiceCommandLogger:V "*:S"