未完成!!!
语音助手包括ASR(auto speech recognition),Sound trigger和TTS(text to speech);下面是Android car中的相关Code。
1. Code
1.1 frameworks and car
- frameworks/base/core/java/android/speech/
- frameworks/base/core/java/android/speech/tts/
- frameworks/base/core/java/android/service/voice/
- frameworks/base/services/voiceinteraction/
- packages/apps/Car/libs/car-assist-client-lib
- packages/apps/Car/libs/car-assist-lib
1.2 Test code and CTS code
Test code and CTS code can help you to understand the design.
- frameworks/base/tests/SoundTriggerTestApp
- frameworks/base/tests/VoiceInteraction
- frameworks/base/tests/VoiceEnrollment
- frameworks/base/tests/TtsTests
- frameworks/base/tests/Assist/AssistInteractionSessionService
- cts/tests/tests/voiceinteraction
- cts/tests/tests/voicesettings
- cts/tests/tests/assist
有service端,有client端(test app), 还有test code
1.3 Sample code
- development/samples/VoiceRecognitionService
2. Voice interaction
VoiceInteractionService, RecognitionService都是需要server端实现的。前者用来接入Sound triger, 后者可以连接第三方的引擎。 SpeechRecognizer,showAssist@Activity,VoiceInteractionManagerService, SoundTriggerManager, TextToSpeech, VoiceInteractionSessionService 都是可以供Client端使用的。
2.1 System 相关
VoiceInteractionManagerService的findAvailInteractor(…)方法会找到所有AndroidManifest文件中配置了下面intent-filter的service,并根据它的meta-data去解析interaction相关配置。
<intent-filter>
<action android:name="android.service.voice.VoiceInteractionService" />
</intent-filter>
Activity 可以获取VoiceInteractor
public VoiceInteractor getVoiceInteractor() {
return mVoiceInteractor;
}
这里的mVoiceInteractor从何而来呢? 是ActivityThread创建Activity时传入的,而后者的VoiceInteractor来源之一是 handleLocalVoiceInteractionStarted(…) 方法。
2.2 获取Assist data
如果想获取assist data,在show session的时候要加上SHOW_WITH_ASSIST,如果要截图,要加上SHOW_WITH_SCREENSHOT。 如果你调用的接口会调用到VoiceInteractionManagerService的showSessionForActiveService(…) 方法,那么上面两个flag会被加上,否则还得自己添加。另外能否获取到assist data还要看设备策略中是否允许获取screen信息(DevicePolicyCacheImpl),AssistContent的获取条件是window没有这是secure属性。
VoiceInteractionSession中的setDisabledShowContext()方法会影响assist data的抓取。该方法的参数是VoiceinteractionSession中的SHOW_****,比如SHOW_WITH_ASSIST。如果你使用了SHOW_WITH_ASSIST,那么将无法抓取assist data.
VoiceInteractionSession的 onHandleAssist(@NonNull AssistState state) 方法中的AssistState中包含三个部分,如下表:
数据类型 | 填充方法 |
---|
Bundle data | Activity中的onProvideAssistData(Bundle data) 或通过application的dispatchOnProvideAssistData(Bundle data)方法 | AssistContent | Activity中的onProvideAssistContent()方法 | AssistStructure | 重要内容在ActivityTaskManagerService的reportAssistContextExtras方法中进行填充 |
3. Sound trigger
以下是基于Android R上的调查,仅供参考!!
要使用自己的热词唤醒,要满足以下条件:
- App要是privilege的。
- Application要声明 Manifest.permission.MANAGE_VOICE_KEYPHRASES 权限, 这点可能影响比较大,因为其他进程想启动activity或者start/bind Service都会受这个权限的影响。
- 要有声明一个Service组件,可以通过 “com.android.intent.action.MANAGE_VOICE_KEYPHRASES” 来启动;这个service组件应该是用来更新 KeyphraseSoundModel 。
- 构造自己的KeyphraseSoundModel。
3.1 Key enrollment
VoiceInteractionService 在onReady的时候会创建一个KeyphraseEnrollmentInfo对象。 这个对象的构造方法里会去查询并提取设置的keyphrase,并存储在一个数组中。 一个应用的配置要满足以下条件才能被解析:
- App要是privilege的。
- Application要声明 Manifest.permission.MANAGE_VOICE_KEYPHRASES 权限
- 要有声明一个Service组件,可以通过 “com.android.intent.action.MANAGE_VOICE_KEYPHRASES” 来启动;这个service组件应该是用来更新 KeyphraseSoundModel 。
当AlwaysOnHotwordDetector构造管理key phrase相关的intent时会用到这个数组中的值,比如当调用AlwaysOnHotwordDetector 的createReEnrollIntent方法时便会使用到,下面是调用流程:
MyVoiceInteractionService
AlwaysOnHotwordDetector
KeyphraseEnrollmentInfo
createEnrollIntent()
getManageIntentLocked(...)
getManageIntentLocked(...)
getManageKeyphraseIntent(...)
getKeyphraseMetadata(...)
MyVoiceInteractionService
AlwaysOnHotwordDetector
KeyphraseEnrollmentInfo
如果获取不到值,那么Intent就构造失败。
Keyphrase enrollment流程图:
3.2 Sound trigger(KeyphrashSoundModel)流程图
另外,还可以直接通过调用SoundTriggerManager(会调用SoundTriggerService)的接口来更新SoundModel和发起监听。
4. Text to speech
TextToSpeechService 是留给server端实现的,一般来说会在这里连接第三方引擎。
5. Settings
adb shell settings get secure assistant
adb shell settings get secure voice_recognition_service
adb shell settings get secure voice_interaction_service
6. Others
KeyEvent.KEYCODE_VOICE_ASSIST CarInputService
|