93 lines
4.1 KiB
Markdown
93 lines
4.1 KiB
Markdown
setup:
|
|
|
|
(If a log error "VisualQueryDetector is only available if multiple detectors are allowed" , set target_sdk_version: "10000" in Android.bp for now.)
|
|
1. Set the KEYPHRASE constant in SampleVoiceInteractionService.java to something the device's
|
|
default assistant supports.
|
|
2. m -j SampleVoiceInteractor
|
|
4. adb root; adb remount
|
|
5. adb push development/samples/VoiceInteractionService/com.example.android.voiceinteractor.xml /system/etc/permissions/com.example.android.voiceinteractor.xml
|
|
6. adb shell mkdir /system/priv-app/SampleVoiceInteractor
|
|
7. adb push out/target/product/$TARGET_PRODUCT/system/priv-app/SampleVoiceInteractor/SampleVoiceInteractor.apk /system/priv-app/SampleVoiceInteractor/
|
|
8. adb reboot
|
|
9. Go to the sample app info/settings.
|
|
10. Tap on Permissions and grant Mic access.
|
|
11. Reboot.
|
|
12. Set the "Digital assistant app" to "Sample Voice Interactor" in the Android settings
|
|
13. Check for this in the logs to make sure it worked:
|
|
com.example.android.voiceinteractor I/VIS: onAvailabilityChanged: 2
|
|
14. If it didn't, check if the pregrant worked:
|
|
adb shell dumpsys package com.example.android.voiceinteractor | grep CAPTURE_AUDIO_HOTWORD
|
|
|
|
Iterating:
|
|
* adb install like usual
|
|
* If syncing changes to the system image, either first copy the permissions file into
|
|
out/target/product/system/etc/permissions/ or push it again after syncing. Sometimes you might
|
|
need to uninstall the app (go to the sample app info/settings -> 3 dots menu -> uninstall
|
|
updates).
|
|
|
|
to test:
|
|
1. Say "1,2,Ok Poodle,3,4.."
|
|
2. Check the logs for the app and wait till it finishes recording.
|
|
3. Either check the logs for the sampled bytes to match, e.g. "sample=[95, 2, 97, ...]" should
|
|
appear twice; or open the sample app activity and click the button to play back the recorded
|
|
audio.
|
|
Tap directRecord to simulate the non-DSP case (must be done after a dsp trigger since it
|
|
reuses the previous data).
|
|
|
|
Debugging:
|
|
* Set DEBUG to true in AlwaysOnHotwordDetector
|
|
* uncomment LOG_NDEBUG lines at the top in AudioFlinger.cpp, Threads.cpp, Tracks.cpp,
|
|
AudioPolicyInterfaceImpl.cpp, AudioPolicyService.cpp
|
|
* Use this logcat filter:
|
|
com.example.android.voiceinteractor|AlwaysOnHotword|SoundTrigger|RecordingActivityMonitor|soundtrigger|AudioPolicyManager|AudioFlinger|AudioPolicyIntefaceImpl|AudioPolicyService|VIS|SHotwordDetectionSrvc|Hotword-AudioUtils
|
|
|
|
Collecting trace events: \
|
|
Trace events are used throughout the test app to measure the time it takes to read the AudioRecord
|
|
data in both the VoiceInteractionService and the trusted HotwordDetectionService. This section can
|
|
be used as a guide to collect and observe this trace data.
|
|
|
|
* Trace events:
|
|
* 'VIS.onDetected' and 'HDS.onDetected'
|
|
* 'VIS.createAudioRecord' and 'HDS.createAudioRecord'
|
|
* 'VIS.startRecording' and 'HDS.startRecording'
|
|
* 'AudioUtils.read' and 'AudioRecord.read'
|
|
* 'AudioUtils.bytesRead'
|
|
* Counter trace value increasing as the AudioUtils.read call progresses. This value is reset after each new call.
|
|
|
|
* How to capture a trace:
|
|
* Follow this guide or a similar one: https://developer.android.com/topic/performance/tracing/on-device
|
|
* Open https://perfetto.dev/#/running.md and upload a trace report
|
|
* Search for the events manually or run the below example SQL query to pull out the events.
|
|
|
|
* Perfetto trace SQL query
|
|
* How to run a SQL query: https://perfetto.dev/docs/quickstart/trace-analysis
|
|
* Covers both command line and HTML implementations
|
|
```
|
|
WITH
|
|
audio_events AS (
|
|
SELECT
|
|
ts,
|
|
(dur / 1000000) as dur_ms,
|
|
name
|
|
FROM
|
|
slice
|
|
WHERE
|
|
(name LIKE "%AudioUtils.read%"
|
|
OR name LIKE "%AudioRecord.read%"
|
|
OR name LIKE "%onDetected%"
|
|
OR name LIKE "%startRecording%"
|
|
OR name LIKE "%createAudioRecord%")
|
|
),
|
|
audio_counters AS (
|
|
SELECT ts, name, value
|
|
FROM counter
|
|
INNER JOIN track ON counter.track_id = track.id
|
|
WHERE name LIKE "%AudioUtils.bytesRead%"
|
|
)
|
|
SELECT ts, 'event' as type, name, dur_ms as value
|
|
FROM audio_events
|
|
UNION ALL
|
|
SELECT ts, 'counter' as type, name, value
|
|
FROM audio_counters
|
|
ORDER BY ts
|
|
``` |