Android Native Service初期化ノート
これはずいぶん前に書いた文章で、コードがアンドロイドであることを忘れました.5でしょう.注意:最新のアンドロイドと比較して、また多くのものを追加して、私はまた最新のコードを整理するのがおっくうで、しかし大体の流れはOKで、必要な比較が見られます
1. mediaserver
XXX::instantiate()BinderServiceから継承されたテンプレートクラスは、最終的にsm->addservice()によってサービスを作成し(ここでは対応するクラスを構築します)、smに追加されます.
2. AudioFlinger init
注意BnAudioFlingerはRefBaseから継承され、IServiceManagement::addService()の2番目のパラメータは強い参照です.
AudioFlinger::instantiate(); --> ... -> AudioFlinger::AudioFlinger()しかし、その構造関数はいくつかの変数の初期化を行っただけです.では、ここで止まったのか、それともどこで続いたのか.
前述のaddService()の2番目のパラメータは強参照であるためonFirstRef()が呼び出され、ここでは初期化が継続され、void AudioFlinger::onFirstRef()を見ても内容はなく、mStandbyTimeInNsecsとmPatchPanelに値を割り当ててAudioFlingerの初期化が完了する
3. AudioPolicyService init
次に、AudioPolicyServices::instantiate();注意AudioPolicyServiceは、ユーザ構成(audio_policy.conf)に従ってAFローディングデバイスインタフェースを指示する
AudioPolicyService::AudioPolicyService()コンストラクション関数も実質的なことはしていません.
同様にAPSはRefBaseから継承され、onFirstRef()が呼び出されます.
次に思うのは、new AudioPolicyManager(clientInterface)とnew AudioPolicyEffects()のコンストラクション関数に何があるかを見ることです.
AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface*clientInterface)では、各モジュールの遍歴がポイントであり、多くのことがここで発生しています.以下、primaryのmoduleを例に分析します.先ほどのloadHwModule()はAPMで、次にもloadHwModule()がありますが、clientを通じて最終的にAFに調整されたloadHwModule()です.この2つは混同しないでください.機能的にAPM::loadHwModule()は解析audio_policy.confファイル、AF::loadHwModule()は、主にHAL対応のlibライブラリをロードし、対応する初期化を行います.
module処理が完了し,また2つのサブのforループにより,OutputProfilesとInputProfilesをそれぞれ処理する.
outputprofileの処理については、次の文に注意してください.
つまりdirect flagがあるのは省略しましたが、後ろのopenoutputが開いているのはprimaryとlowだけです.latencyおよびvoice_txのデバイス、voice_txという名前はおかしいですが、inputデバイスだと思いますが、なぜoutputに入れるのでしょうか.わかりません.そしてoutProfileに基づいてクラスnew AudioOutputDescriptor()を生成した.
outputprofileの処理が完了した後にまたInputProfileの過程も大体悪くなくて、具体的に見ません.そしてエラーの処理に対してupdateDevicesAndOutputs()を呼び出す.更新しても构造完了
APMの構造をまとめてやること:audioを解析するpolicy.conf解析したmoduleに基づいて、対応するlibをロードして解析結果のoutputprofileを処理し続け、inputprofile、ストリームを開き、対応するスレッドを作成する
1. mediaserver
main_mediaserver.cpp (frameworks\av\media\mediaserver)
int main(int argc __unused, char** argv)
{
...
if (doLog && (childPid = fork()) != 0) {
...
} else {
....
AudioFlinger::instantiate();
MediaPlayerService::instantiate();
CameraService::instantiate();
#ifdef AUDIO_LISTEN_ENABLED
ALOGI("ListenService instantiated");
ListenService::instantiate();
#endif
AudioPolicyService::instantiate();
.....
}
}
XXX::instantiate()BinderServiceから継承されたテンプレートクラスは、最終的にsm->addservice()によってサービスを作成し(ここでは対応するクラスを構築します)、smに追加されます.
static status_t publish(bool allowIsolated = false) {
sp sm(defaultServiceManager());
return sm->addService(
String16(SERVICE::getServiceName()),
new SERVICE(), allowIsolated);
}
......
static void instantiate() { publish(); }
2. AudioFlinger init
注意BnAudioFlingerはRefBaseから継承され、IServiceManagement::addService()の2番目のパラメータは強い参照です.
AudioFlinger::instantiate(); --> ... -> AudioFlinger::AudioFlinger()しかし、その構造関数はいくつかの変数の初期化を行っただけです.では、ここで止まったのか、それともどこで続いたのか.
前述のaddService()の2番目のパラメータは強参照であるためonFirstRef()が呼び出され、ここでは初期化が継続され、void AudioFlinger::onFirstRef()を見ても内容はなく、mStandbyTimeInNsecsとmPatchPanelに値を割り当ててAudioFlingerの初期化が完了する
3. AudioPolicyService init
次に、AudioPolicyServices::instantiate();注意AudioPolicyServiceは、ユーザ構成(audio_policy.conf)に従ってAFローディングデバイスインタフェースを指示する
AudioPolicyService::AudioPolicyService()コンストラクション関数も実質的なことはしていません.
同様にAPSはRefBaseから継承され、onFirstRef()が呼び出されます.
AudioPolicyService::onFirstRef()
+--> // start tone playback thread mTonePlaybackThread = new AudioCommandThread(String8("ApmTone"), this);
+ // start audio commands thread
+ // start output activity command thread
+ mAudioPolicyClient = new AudioPolicyClient(this); // this APClient mAudioPolicyService
+ mAudioPolicyManager = createAudioPolicyManager(mAudioPolicyClient); --> new AudioPolicyManager(clientInterface)
+ new // load audio processing modules, new AudioPolicyEffects();
+ APS onFirstRef 。
次に思うのは、new AudioPolicyManager(clientInterface)とnew AudioPolicyEffects()のコンストラクション関数に何があるかを見ることです.
AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface)
+ mForceUse[i] = AUDIO_POLICY_FORCE_NONE; //mForceUse
| mDefaultOutputDevice = new DeviceDescriptor(String8(""), AUDIO_DEVICE_OUT_SPEAKER); //
| loadAudioPolicyConfig() /vendor/etc /system/etc audio_policy.conf,
| +--> loadHwModules() audio config, , mHwModules, mOutputProfiles, mInputProfiles
| +--> loadGlobalConfig()
| initializeVolumeCurves(); // // , 。
| *** laudio_policy.conf, for , module output/input, , ***
+ 。
AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface*clientInterface)では、各モジュールの遍歴がポイントであり、多くのことがここで発生しています.以下、primaryのmoduleを例に分析します.先ほどのloadHwModule()はAPMで、次にもloadHwModule()がありますが、clientを通じて最終的にAFに調整されたloadHwModule()です.この2つは混同しないでください.機能的にAPM::loadHwModule()は解析audio_policy.confファイル、AF::loadHwModule()は、主にHAL対応のlibライブラリをロードし、対応する初期化を行います.
mHwModules[i]->mHandle = mpClientInterface->loadHwModule(mHwModules[i]->mName);
^ +--> mpClientInterface APS , AudioPolicyClientImpl.cpp
+ +-->... af->loadHwModule(name);
+ +-->.... binder AudioFlinger::loadHwModule()
+ +--> settingsAllowed()
+------------------ AudioFlinger::loadHwModule_l()
| +--> , mAudioHwDevs.keyAt(i)
| + load_audio_interface(name, &dev)
| | +--> hw_get_module_by_class() , , ID libxxx.so, AHAL
| | | audio_hw_device_open()
| | | +--> module->methods->open() module open
| | | +--> adev_open()
| | | +-->
| | | | voice_init()
| | | | platform_init() --> , xml acdb , , 。
| | | | audio_extn_listen_init()
| | | | audio_extn_sound_trigger_init()
| | | | offload
| | +--> +--> audio_extn_utils_update_streams_output_cfg_list() Android 5.0 , output config , 。
| + HAL master volume/mute, HAL master volue/mute
| + audio_module_handle_t handle = nextUniqueId();
| + mAudioHwDevs.add(handle, new AudioHwDevice(handle, name, dev, flags));
| + , new AudioHwDevice(), HAL dev, C++ C
| + handle mAudioHwDevs , handle AudioHwDevice() HAL
^ + handl HAL
+----------+--> return handle; module handle
module処理が完了し,また2つのサブのforループにより,OutputProfilesとInputProfilesをそれぞれ処理する.
outputprofileの処理については、次の文に注意してください.
if ((outProfile->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) != 0) {
continue;
}
つまりdirect flagがあるのは省略しましたが、後ろのopenoutputが開いているのはprimaryとlowだけです.latencyおよびvoice_txのデバイス、voice_txという名前はおかしいですが、inputデバイスだと思いますが、なぜoutputに入れるのでしょうか.わかりません.そしてoutProfileに基づいてクラスnew AudioOutputDescriptor()を生成した.
AudioPolicyManager.cpp
for mHwModules
for mHwModules[i]->mOutputProfiles
sp outputDesc = new AudioOutputDescriptor(outProfile);
openOutput()
audio_config_t config = AUDIO_CONFIG_INITIALIZER;
config.sample_rate = outputDesc->mSamplingRate;
config.channel_mask = outputDesc->mChannelMask;
config.format = outputDesc->mFormat;
audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
status_t status = mpClientInterface->openOutput(outProfile->mModule->mHandle,
+--> AudioPolicyClientImpl.cpp
+--> af->openOutput()
+--> sp thread = openOutput_l(module, output, config, *devices, address, flags); //
| ^ +--> findSuitableHwDev_l() AF module mAudioHwDevs
| | + audio_hw_device_t *hwDevHal = outHwDev->hwDevice(); HAL
| | + *output = nextUniqueId(); handler , ( )。
| | + hwDevHal->open_output_stream() AHAL open_output_stream()
| | + +--> adev_open_output_stream()
| | | +--> out, config
| | | | , out_ ,
| | | | ( module adev_ ), module/
| | | | adev_ , out_/in_ 。
| | | +--> , kernel , open_output_stream 。
| | + AudioStreamOut *outputStream = new AudioStreamOut(outHwDev, outStream, flags); strem hwdev, new , 。
| | + flag
| | + AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD => new OffloadThread()
| | + AUDIO_OUTPUT_FLAG_DIRECT => new DirectOutputThread()
| | + new MixerThread()
| | + ******** for direct flag ? MixerThread() *******
| | + thread 。
| ^ + mPlaybackThreads.add(*output, thread); handler thead ,
| +---+--> return thread;
+ // notify client processes of the new output creation
+ thread->audioConfigChanged(AudioSystem::OUTPUT_OPENED); IO , , 。
+--> mPrimaryHardwareDev->hwDevice()->set_mode(mPrimaryHardwareDev->hwDevice(), mMode); flags primary, 。
AUDIO_OUTPUT_FLAG_PRIMARY mPrimaryOutput = output;
addOutput(output, outputDesc); // output handler (AF::openOutput_l() )
setOutputDevice(); // , 。
outputprofileの処理が完了した後にまたInputProfileの過程も大体悪くなくて、具体的に見ません.そしてエラーの処理に対してupdateDevicesAndOutputs()を呼び出す.更新しても构造完了
APMの構造をまとめてやること:audioを解析するpolicy.conf解析したmoduleに基づいて、対応するlibをロードして解析結果のoutputprofileを処理し続け、inputprofile、ストリームを開き、対応するスレッドを作成する