摘要: libaudioclient 除了支持 setAudioPortConfig() 调用,也支持 setMasterMute()、setStreamMute()、setParameters()、getParameters()、setMode() 等接口调用,满足各种开发测试需求。它让你不需要关注这些细枝末节的差别,一份代码可以不加修改地完美运行在不同芯片平台、不同 Android 版本上。尽管 IHalAdapterVendorExtension 被注册为 AIDL service,但这段代码没有通过 binder 去获取服务,而是通过链接 IHalAdapterVendorExtension 实现端的库,直接在代码里构造了 mHalAdapterVendorExtn 对象,以避免不必要的跨进程通信开销。 阅读全文
posted @ 2025-09-18 19:25 Qidi_Huang 阅读(29) 评论(0) 推荐(0)
摘要: Android 系统提供一款专有工具 procrank 用于查看各进程(包括 Java 进程)的内存占用情况。进程的 Pss 值可以较为准确地反映其真实占用的物理内存大小。 procrank 显示的是所有进程的内存占用概要情况。如果要查看某个特定进程的内存占用情况,可以使用 showmap 命令。 阅读全文
posted @ 2025-08-30 15:01 Qidi_Huang 阅读(74) 评论(0) 推荐(0)
摘要: 可以使用 Builder,通过 setChannelIndexMask() 方法来设置声道参数,达到多声道录音的目的。不过,由于前述 1.2节 中的限制,我们在构造 AudioRecord 对象时,不可以使用 getMinBufferSize() 来计算 bufferSize 参数值,而应该手动计算出合适的值。否则,APP 将抛出异常并中止运行。 阅读全文
posted @ 2025-08-07 18:02 Qidi_Huang 阅读(177) 评论(0) 推荐(0)
摘要: Android 14 会先构造好 AudioFlinger 和 AudioPolicyService 这两个实例,再调用 addService() 依次向 ServiceManager 注册服务。 从提交记录和代码注释看,做这个调整的目的是为了减少 TimeCheck 超时导致 audioserver 进程退出的问题。 修改了 AudioSystem::get_audio_flinger() 逻辑。当 AudioFlinger 调用方与 AudioFlinger 处于同一进程时,就直接返回 AudioSystem 中缓存的 gLocalAudioFlinger,而不再通过 ServiceManager 查询。 阅读全文
posted @ 2025-07-09 17:48 Qidi_Huang 阅读(104) 评论(0) 推荐(0)
摘要: 从 bootchart.png 图中我们可以看出以下信息: 各主要系统进程是否及时启动; CPU 和 磁盘 在开机过程中的整体负载情况; 某进程的启动时机是否晚于预期; 某进程启动时的 CPU 消耗、忙闲情况; 某进程在开机过程中是否存在崩溃、重启; 如果进程A的功能依赖于进程B,进程B是否及时启动; launcher 进程的启动时机(意味着用户可以触屏操作)。 使用 perfetto 分析过系统运行时性能问题的朋友,应该对这个画风比较熟悉。 阅读全文
posted @ 2025-06-26 18:30 Qidi_Huang 阅读(472) 评论(0) 推荐(0)
摘要: 很多时候我们都是执行 cd $OUT 命令来跳转到编译产物目录。然而这个命令既包含特殊字符,又要进行大小写切换,手敲起来费时且不方便,不如自己实现一个 cout 命令来提高效率。做法很简单,我们知道 croot 的实现代码在 /build/envsetup.sh 脚本中,所以我们只需要在其中相邻位置添加以下函数就行了。 阅读全文
posted @ 2025-06-17 18:06 Qidi_Huang 阅读(21) 评论(0) 推荐(0)
摘要: 抓取 DSP 整体性能/负载数据: sysMonAppQNX profiler --q6 adsp --duration 60 抓取各硬件线程性能/负载数据: sysMonAppQNX tlp --profile 1 --samplingPeriod 1 --q6 adsp --defaultSetEnable 3 --duration 60 需要将抓取到的数据,即 sysmon*.bin,转换成 HTML 页面,才能阅读。 工作中碰到个 “播放收音机的过程中频繁切换音效导致播放出现大量噪声” 的问题。由于收音机数据是 ADSP 直接从 Modem芯片 读取、再写入功放芯片,所以怀疑噪声是由于 ADSP 性能不足所致,与 CPU 调度无关。以此问题为例,对分析报告过程进行说明。 阅读全文
posted @ 2025-06-13 18:02 Qidi_Huang 阅读(648) 评论(0) 推荐(0)
摘要: MPPS 参数有两种用法: 一是用作评估 DSP 最大处理能力。 比如,DSP 主频 1.5GHz,运行其上的代码的平均 CPP 为 3,那么在此种情形下 DSP 能承载的最大 MPPS 就是 500。 二是用作评估代码对 DSP 带来的负载。 因为代码在编译后生成的指令数是固定的,相应地,其 Packet数量 和 CPP 也能预估出来,因而也能估算出代码所需的 MPPS 值。 根据 Qualcomm 建议,车机设备上所有用户场景带来的负载总和不应超过最大 MPPS 的 70%,以避免音频播放时出现噪声。 当 DSP/CPU 的空闲算力不小于所需理论算力的 1.3 倍时,我们才认为 DSP/CPU 能够满足算法模块的算力需求,这是因为需要给算法模块加载/销毁、I/O延迟等非理想情况留出余量。当 DSP/CPU 的空闲带宽不小于该理论带宽值的 1.3 倍时,我们才认为 DSP/CPU 能够满足算法模块的带宽需求。 类似 MPPS,MIPS 参数也常被用来评估 DSP 能力、代码所需负载。 阅读全文
posted @ 2025-06-10 18:11 Qidi_Huang 阅读(505) 评论(0) 推荐(0)
摘要: 高通对某些接口是停用了 QIIFA 检查的。由于我在 vendor 下新增的自定义 AIDL 接口与 AOSP 和 Qualcomm 完全无关,且当前开发阶段我们也没有对接口版本进行冻结的计划,所以我们也可以停用 QIIFA 对该自定义接口的检查,从而解决编译问题。 具体操作为,在 vendor/qcom/proprietary/commonsys-intf/QIIFA-cmd/aidl/qiifa_aidl_skipped_interfaces.json 的 ALL 字段中添加我们的自定义服务名。 阅读全文
posted @ 2025-06-04 17:26 Qidi_Huang 阅读(361) 评论(0) 推荐(0)
摘要: 通常我们会使用两种方法登录 Android 设备: 使用 USB 直接将电脑和 Android 设备相连,然后执行 adb shell 命令登录; 让电脑和 Android 设备连入同一个网络。检查 Android 设备 IP,然后执行 adb connect xxx.xxx.xxx.xxx 和 adb shell 命令登录。 不过这两种方法都存在以下局限性: 要明确知道 Android 设备存在; 要手动配置 Android 设备(连接 USB 线,或查询 IP)。 和我们处于同一局域网上的 Android 设备,只要开启了 USB调试 和 无线ADB连接 功能,我们都可以利用 mDNS 发现它。进而通过 adb 与其建立连接。 阅读全文
posted @ 2025-05-30 15:43 Qidi_Huang 阅读(381) 评论(0) 推荐(0)
摘要: 分析编译错误日志,可知 Stable AIDL 是通过比对 hash值 来判断接口变动。回忆在老 Android 版本上开发 HIDL 接口时,可以通过手动修改 hash值 来绕过检查,所以现在我们也尝试这样做来绕过 Stable AIDL 的编译检查。 阅读全文
posted @ 2025-05-29 18:25 Qidi_Huang 阅读(514) 评论(0) 推荐(0)
摘要: 车机环境下的音频使用场景,相较于原始 Android 的音频使用场景,存在这些特殊性: 使用专门的 aDSP 芯片进行音效处理; 需要播放/控制原始 Android 预设之外的音源(AudioUsage); 音源间交互行为更加复杂(AudioFocus); 需要响应更复杂的电源模式变化。 其中第一、二点会直接影响用户从 APP 层调节音量的方式,以及 AudioHAL 的实现。 阅读全文
posted @ 2023-12-13 15:20 Qidi_Huang 阅读(1486) 评论(0) 推荐(1)
摘要: 通过 RO 机制,我们就可以将自己编写的 Java 服务在系统启动时运行起来。 阅读全文
posted @ 2023-12-12 09:51 Qidi_Huang 阅读(530) 评论(0) 推荐(1)
摘要: 我们需要一种方式,在不进行界面操作或切换 USB Role 的情况下,也能启用 logcat 日志的本地存储 阅读全文
posted @ 2023-12-11 14:12 Qidi_Huang 阅读(2193) 评论(0) 推荐(1)
摘要: 理想的测试工具代码应该具备以下特点: + 测试流程代码和测试用例代码分离 + 与项目需求相关的代码位于测试用例代码中 + 与项目依赖相关的代码也位于测试用例代码中 + 测试函数接口稳定,函数名及参数不因项目不同而变化 + 测试用例代码可以方便地进行替换 阅读全文
posted @ 2023-10-16 01:27 Qidi_Huang 阅读(130) 评论(0) 推荐(0)
摘要: 为了摆脱 `va_start()` 对参数列表起始地址的依赖,我们可以把函数参数按照从左往右的顺序,依次存储于一个动态创建的链表中。 阅读全文
posted @ 2023-10-15 23:44 Qidi_Huang 阅读(46) 评论(0) 推荐(0)