Audio java部分代码流程(4.1.2 version):

在frameworks/base/media/java/android/media中:
IAudioService.aidl提供了所有对外的接口函数,如下:
[cpp] view plain copy
  1. interfaceIAudioService{
  2. voidadjustVolume(intdirection,intflags);
  3. voidadjustSuggestedStreamVolume(intdirection,intsuggestedStreamType,intflags);
  4. voidadjustStreamVolume(intstreamType,intdirection,intflags);
  5. voidsetStreamVolume(intstreamType,intindex,intflags);
  6. voidsetStreamSolo(intstreamType,booleanstate,IBindercb);
  7. voidsetStreamMute(intstreamType,booleanstate,IBindercb);
  8. booleanisStreamMute(intstreamType);
  9. intgetStreamVolume(intstreamType);
  10. intgetStreamMaxVolume(intstreamType);
  11. intgetLastAudibleStreamVolume(intstreamType);
  12. voidsetRingerMode(intringerMode);
  13. .......................
  14. }
这些函数的实现在服务AudioService.java中:
[cpp] view plain copy
  1. publicclassAudioServiceextendsIAudioService.Stub{
  2. ........
  3. }
该服务在services/java/com/android/server/SystemServer.java中注册进servicemanager中:
[cpp] view plain copy
  1. 492try{
  2. 493Slog.i(TAG,"AudioService");
  3. 494ServiceManager.addService(Context.AUDIO_SERVICE,newAudioService(context));
  4. 495}catch(Throwablee){
  5. 496reportWtf("startingAudioService",e);
  6. 497}
这样在frameworks中可以通过ServiceManager.getService(Context.AUDIO_SERVICE)来获得该服务。
而AudioManager.java则实现这些函数了对外应用的接口,比如:
[cpp] view plain copy
  1. 496publicvoidadjustVolume(intdirection,intflags){
  2. 497IAudioServiceservice=getService();//
  3. 498try{
  4. 499service.adjustVolume(direction,flags);
  5. 500}catch(RemoteExceptione){
  6. 501Log.e(TAG,"DeadobjectinadjustVolume",e);
  7. 502}
  8. 503}
这里的getService()获得的是前面的AudioService,如下:
[cpp] view plain copy
  1. 365privatestaticIAudioServicegetService()
  2. 366{
  3. 367if(sService!=null){
  4. 368returnsService;
  5. 369}
  6. 370IBinderb=ServiceManager.getService(Context.AUDIO_SERVICE);
  7. 371sService=IAudioService.Stub.asInterface(b);
  8. 372returnsService;
  9. 373}
要把AudioManager.java中的对外公开,则要在 core/java/android/app/ContextImpl.java中注册:
[cpp] view plain copy
  1. 281registerService(AUDIO_SERVICE,newServiceFetcher(){
  2. 282publicObjectcreateService(ContextImplctx){
  3. 283returnnewAudioManager(ctx);
  4. 284}});
而且,还要把这些函数变量等在api/current.txt中声明:
[cpp] view plain copy
  1. 10353publicclassAudioManager{
  2. 10354methodpublicintabandonAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener);
  3. 10355methodpublicvoidadjustStreamVolume(int,int,int);
  4. 10356methodpublicvoidadjustSuggestedStreamVolume(int,int,int);
  5. 10357methodpublicvoidadjustVolume(int,int);
  6. 10358methodpublicintgetMode();
  7. 10359methodpublicjava.lang.StringgetParameters(java.lang.String);
  8. 10360methodpublicintgetRingerMode();
  9. 10361methodpublicdeprecatedintgetRouting(int);
  10. 10362methodpublicintgetStreamMaxVolume(int);
  11. 10363methodpublicintgetStreamVolume(int);
  12. 10364methodpublicintgetVibrateSetting(int);
  13. 10365methodpublicbooleanisBluetoothA2dpOn();
这样在应用中用(AudioManager) getSystemService(Context.AUDIO_SERVICE);即可获得服务,从而使用AudioManager.java中的方法 然后看看比如setStreamVolume是如何从java调用到底层的:
1、应用调用比如mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, progress, 0);
2、AudioManager.java调用public void setStreamVolume(int streamType, int index, int flags){};
3、AudioService.java调用public void setStreamVolume(int streamType, int index, int flags){},在该函数中调用
 setStreamVolumeInt(mStreamVolumeAlias[streamType],                                                                                            831                                    index,       832                                    device,       833                                    false,       834                                    true);  --------->      1002                 sendMsg(mAudioHandler,      1003                         MSG_PERSIST_VOLUME,      1004                         SENDMSG_QUEUE,      1005                         PERSIST_LAST_AUDIBLE,      1006                         device,      1007                         streamState,      1008                         PERSIST_DELAY);  


而mAudioHandler = new AudioHandler(),看看这个AudioHandler类:private class AudioHandler extends Handler {};-------->
所以调用该类重写的handleMessage方法--------->
[cpp] view plain copy
  1. 2940@Override
  2. 2941publicvoidhandleMessage(Messagemsg){
  3. 2942
  4. 2943switch(msg.what){
  5. 2944
  6. 2945caseMSG_SET_DEVICE_VOLUME:
  7. 2946setDeviceVolume((VolumeStreamState)msg.obj,msg.arg1);
  8. 2947break;

setDeviceVolume---------> mStreamStates[streamType].applyDeviceVolume(getDeviceForStream(streamType));---------->AudioSystem.setStreamVolumeIndex--------->

setStreamVolumeIndex的定义在AudioSystem.java中-------->public static native int setStreamVolumeIndex(int stream, int index, int device);

setStreamVolumeIndex的JNI实现在base/core/jni/android_media_AudioSystem.cpp中---------->
[cpp] view plain copy
  1. 178staticint
  2. 179android_media_AudioSystem_setStreamVolumeIndex(JNIEnv*env,
  3. 180jobjectthiz,
  4. 181jintstream,
  5. 182jintindex,
  6. 183jintdevice)
  7. 184{
  8. 185returncheck_AudioSystem_Command(
  9. 186AudioSystem::setStreamVolumeIndex(static_cast<audio_stream_type_t>(stream),
  10. 187index,
  11. 188(audio_devices_t)device));
  12. 189}
AudioSystem类在av/media/libmedia/AudioSystem.cpp中--------->
[cpp] view plain copy
  1. 666status_tAudioSystem::setStreamVolumeIndex(audio_stream_type_tstream,
  2. 667intindex,
  3. 668audio_devices_tdevice)
  4. 669{
  5. 670constsp<IAudioPolicyService>&aps=AudioSystem::get_audio_policy_service();
  6. 671if(aps==0)returnPERMISSION_DENIED;
  7. 672returnaps->setStreamVolumeIndex(stream,index,device);
  8. 673}
到这里就要涉及到进程间通讯binder的使用了,我们看AudioSystem::get_audio_policy_service()的实现:
[cpp] view plain copy
  1. 514constsp<IAudioPolicyService>&AudioSystem::get_audio_policy_service()
  2. 515{
  3. 516gLock.lock();
  4. 517if(gAudioPolicyService==0){
  5. 518sp<IServiceManager>sm=defaultServiceManager();//取得BpServiceManager,通过这个代理可以调用BnServiceManager::onTransact,最后和ServiceManager通讯
  6. 519sp<IBinder>binder;
  7. 520do{
  8. 521binder=sm->getService(String16("media.audio_policy"));//从ServiceManager获得远程AudioPolicyService的句柄
  9. 522if(binder!=0)
  10. 523break;
  11. 524ALOGW("AudioPolicyServicenotpublished,waiting...");
  12. 525usleep(500000);//0.5s
  13. 526}while(true);
  14. 527if(gAudioPolicyServiceClient==NULL){
  15. 528gAudioPolicyServiceClient=newAudioPolicyServiceClient();
  16. 529}
  17. 530binder->linkToDeath(gAudioPolicyServiceClient);
  18. 531gAudioPolicyService=interface_cast<IAudioPolicyService>(binder);
  19. 532gLock.unlock();
  20. 533}else{
  21. 534gLock.unlock();
  22. 535}
  23. 536returngAudioPolicyService;
  24. 537}
上面531行interface_cast<IAudioPolicyService>(binder),interface_cast是一个模版,在frameworks/native/include/binder/IInterface.h中定义如下:
[cpp] view plain copy
  1. 42inlinesp<INTERFACE>interface_cast(constsp<IBinder>&obj)
  2. 43{
  3. 44returnINTERFACE::asInterface(obj);
  4. 45}
展开后是IAudioPolicyService::asInterface(obj);而IAudioPolicyService::asInterface的实现在frameworks/av/include/media/IAudioPolicyService.h中,通过宏
[cpp] view plain copy
  1. DECLARE_META_INTERFACE(AudioPolicyService)展开后得到的,DECLARE_META_INTERFACE定义在IInterface.h中:
  2. 74#defineDECLARE_META_INTERFACE(INTERFACE)\
  3. 75staticconstandroid::String16descriptor;\
  4. 76staticandroid::sp<I##INTERFACE>asInterface(\
  5. 77constandroid::sp<android::IBinder>&obj);\
  6. 78virtualconstandroid::String16&getInterfaceDescriptor()const;\
  7. 79I##INTERFACE();\
  8. 80virtual~I##INTERFACE();
76行展开即可得到IAudioPolicyService::asInterface的定义,而这个定义的实现也是在IInterface.h,通过宏来定义的:
[cpp] view plain copy
  1. #defineIMPLEMENT_META_INTERFACE(INTERFACE,NAME)
  2. ........................
  3. 89android::sp<I##INTERFACE>I##INTERFACE::asInterface(\
  4. 90constandroid::sp<android::IBinder>&obj)\
  5. 91{\
  6. 92android::sp<I##INTERFACE>intr;\
  7. 93if(obj!=NULL){\
  8. 94intr=static_cast<I##INTERFACE*>(\
  9. 95obj->queryLocalInterface(\
  10. 96I##INTERFACE::descriptor).get());\
  11. 97if(intr==NULL){\
  12. 98intr=newBp##INTERFACE(obj);\
  13. 99}\
  14. 100}\
  15. 101returnintr;\
  16. 102}

展开后最终是生成调用new BpAudioPolicyService(new BpBinder(handle)),这里的handle是一个句柄;这样我们最终得到了AudioPolicyService的代理BpAudioPolicyService,通过它就可以和 AudioPolicyService的本地接口BnAudioPolicyService通讯了。
回到前面的AudioSystem.cpp,取得代理BpAudioPolicyService后调用aps->setStreamVolumeIndex,所以进入IAudioPolicyService.cpp:
class BpAudioPolicyService : public BpInterface<IAudioPolicyService>:
[cpp] view plain copy
  1. 233virtualstatus_tsetStreamVolumeIndex(audio_stream_type_tstream,
  2. 234intindex,
  3. 235audio_devices_tdevice)
  4. 236{
  5. 237Parceldata,reply;
  6. 238data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
  7. 239data.writeInt32(static_cast<uint32_t>(stream));
  8. 240data.writeInt32(index);
  9. 241data.writeInt32(static_cast<uint32_t>(device));
  10. 242remote()->transact(SET_STREAM_VOLUME,data,&reply);
  11. 243returnstatic_cast<status_t>(reply.readInt32());
  12. 244}
242行的remote是通过继承关系BpAudioPolicyService -> BpInterface -> BpRefBase,在类BpRefBase中定义的:
[cpp] view plain copy
  1. inlineIBinder*remote(){returnmRemote;}
  2. IBinder*constmRemote;
这里mRemote声明为const,可见它是静态不变,只赋值一次,它是在前面获取远程服务AudioPolicyService时候创建的BpBinder对象(主要是打开了binder驱动,获得FD描述符,并且内 存映射了空间),所以调用BpBinder.cpp的transact函数:
[cpp] view plain copy
  1. 159status_tBpBinder::transact(
  2. 160uint32_tcode,constParcel&data,Parcel*reply,uint32_tflags)
  3. 161{
  4. 162//Onceabinderhasdied,itwillnevercomebacktolife.
  5. 163if(mAlive){
  6. 164status_tstatus=IPCThreadState::self()->transact(
  7. 165mHandle,code,data,reply,flags);
  8. 166if(status==DEAD_OBJECT)mAlive=0;
  9. 167returnstatus;
  10. 168}
  11. 169
  12. 170returnDEAD_OBJECT;
  13. 171}
从164行,调用IPCThreadState.cpp的transact,这里就是最终和binder驱动打交道的地方了,165行通过mHandle,底层binder驱动知道了传输数据的目标地址为mediaserver进 程,binder驱动将数据拷贝到service的内存共享空间,并告诉service这个内核空间相对用户空间的偏移,远程服务端就可以不用再次拷贝数据,直接从用户空间就可以读取数据了, 这样remote()->transact(SET_STREAM_VOLUME, data, &reply)就通过binder传递到BnAudioPolicyService中了,这样就调用IAudioPolicyService.cpp的 BnAudioPolicyService::onTransact函数来处理该请求(但由于继承关系最终是派发到Bn的派生类AudioPolicyService::onTransact来处理,不过我们后面也会发现派生类又调回Bn类 的onTransact去处理,很有意思啊),我们看看BnAudioPolicyService是如何获得remote()->transact(SET_STREAM_VOLUME, data, &reply)的请求的,这样要从 AudioPolicyService是如何将自己的服务添加到servicemanager中的说起,在frameworks/av/media/mediaserver/main_mediaserver.cpp中:
[cpp] view plain copy
  1. 34intmain(intargc,char**argv)
  2. 35{
  3. 36sp<ProcessState>proc(ProcessState::self());
  4. 37sp<IServiceManager>sm=defaultServiceManager();
  5. 38ALOGI("ServiceManager:%p",sm.get());
  6. 39AudioFlinger::instantiate();
  7. 40MediaPlayerService::instantiate();
  8. 41CameraService::instantiate();
  9. 42AudioPolicyService::instantiate();
  10. 43ProcessState::self()->startThreadPool();
  11. 44IPCThreadState::self()->joinThreadPool();
  12. 45}
36行,由于main_mediaserver.cpp是编译成一个可执行文件,就是它的启动是作为服务在一个独立的进程中运行了,Main_MediaServer主函数由init.rc在启动时调用,先明白这点, 然后看:
frameworks/native/libs/binder/ProcessState.cpp:
[cpp] view plain copy
  1. 74sp<ProcessState>ProcessState::self()
  2. 75{
  3. 76Mutex::Autolock_l(gProcessMutex);
  4. 77if(gProcess!=NULL){
  5. 78returngProcess;
  6. 79}
  7. 80gProcess=newProcessState;
  8. 81returngProcess;
  9. 82}
从77行可知,这是一个单例模式,在这个进程中以后再调用这个函数的话,就直接返回78行,这里我们第一次进来,所以跑到80行,进入ProcessState构造函数:
[cpp] view plain copy
  1. 335ProcessState::ProcessState()
  2. 336:mDriverFD(open_driver())
  3. 337,mVMStart(MAP_FAILED)
  4. 338,mManagesContexts(false)
  5. 339,mBinderContextCheckFunc(NULL)
  6. 340,mBinderContextUserData(NULL)
  7. 341,mThreadPoolStarted(false)
  8. 342,mThreadPoolSeq(1)
  9. 343{
  10. 344if(mDriverFD>=0){
  11. 345//XXXIdeally,thereshouldbeaspecificdefineforwhetherwe
  12. 346//havemmap(orwhetherwecouldpossiblyhavethekernelmodule
  13. 347//availabla).
  14. 348#if!defined(HAVE_WIN32_IPC)
  15. 349//mmapthebinder,providingachunkofvirtualaddressspacetoreceivetransactions.
  16. 350mVMStart=mmap(0,BINDER_VM_SIZE,PROT_READ,MAP_PRIVATE|MAP_NORESERVE,mDriverFD,0);
  17. .................................
  18. }
336行打开Binder设备文件/dev/binder,并将打开设备文件描述符保存在成员变量mDriverFD中;350行mmap来把设备文件/dev/binder映射到内存中,这样我们就有了一块共享内存。
回到main_mediaserver.cpp,37行defaultServiceManager(),在frameworks/native/libs/binder/IServiceManager.cpp中:
[cpp] view plain copy
  1. 34sp<IServiceManager>defaultServiceManager()
  2. 35{
  3. 36if(gDefaultServiceManager!=NULL)returngDefaultServiceManager;
  4. 37
  5. 38{
  6. 39AutoMutex_l(gDefaultServiceManagerLock);
  7. 40if(gDefaultServiceManager==NULL){
  8. 41gDefaultServiceManager=interface_cast<IServiceManager>(
  9. 42ProcessState::self()->getContextObject(NULL));
  10. 43}
  11. 44}
  12. 45
  13. 46returngDefaultServiceManager;
  14. 47}
和前面一样,也是一个单例模式,第一次进来肯定为NULL,所以进入41行,ProcessState::self()前面已经运行过一次,直接调用getContextObject(NULL),注意传进来的是NULL 参数,表示和ServiceManager通讯:
[cpp] view plain copy
  1. 89sp<IBinder>ProcessState::getContextObject(constsp<IBinder>&caller)
  2. 90{
  3. 91returngetStrongProxyForHandle(0);
  4. 92}
getStrongProxyForHandle(0)最终会调用new BpBinder(0),这样我们就得到了ServiceManager的代理BpBinder,回到IServiceManager.cpp的41行,就变成了 interface_cast<IServiceManager>(new BpBinder(0)),interface_cast在前面已经分析过,所以最后变成new BpServiceManager(new BpBinder(0))。 接着进入main_mediaserver.cpp42行AudioPolicyService::instantiate(),先看看frameworks/av/services/audioflinger/AudioPolicyService.h中的继承关系:
[cpp] view plain copy
  1. 37classAudioPolicyService:
  2. 38publicBinderService<AudioPolicyService>,
  3. 39publicBnAudioPolicyService,
  4. 40//publicAudioPolicyClientInterface,
  5. 41publicIBinder::DeathRecipient
AudioPolicyService并没有实现instantiate方法,而是继承BinderService得到的,该类在frameworks/native/include/binder/BinderService.h中:
[cpp] view plain copy
  1. 33template<typenameSERVICE>
  2. 34classBinderService
  3. 35{
  4. 36public:
  5. 37staticstatus_tpublish(boolallowIsolated=false){
  6. 38sp<IServiceManager>sm(defaultServiceManager());
  7. 39returnsm->addService(String16(SERVICE::getServiceName()),newSERVICE(),allowIsolated);
  8. 40}
  9. 41
  10. 42staticvoidpublishAndJoinThreadPool(boolallowIsolated=false){
  11. 43sp<IServiceManager>sm(defaultServiceManager());
  12. 44sm->addService(String16(SERVICE::getServiceName()),newSERVICE(),allowIsolated);
  13. 45ProcessState::self()->startThreadPool();
  14. 46IPCThreadState::self()->joinThreadPool();
  15. 47}
  16. 48
  17. 49staticvoidinstantiate(){publish();}
  18. 50
  19. 51staticstatus_tshutdown(){
  20. 52returnNO_ERROR;
  21. 53}
  22. 54};
这是一个类模版,最终调用39行,得到sm->addService(String16(AudioPolicyService::getServiceName()), new AudioPolicyService(), false)即:
BpServiceManager(new BpBinder(0))->addService(String16("media.audio_policy", new AudioPolicyService(), false),进入BpServiceManger::addService的实现,这个 函数实现在frameworks/native/libs/binder/IServiceManager.cpp:
[cpp] view plain copy
  1. 154virtualstatus_taddService(constString16&name,constsp<IBinder>&service,boolallowIsolated)
  2. 156{
  3. 157Parceldata,reply;
  4. 158data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
  5. 159data.writeString16(name);
  6. 160data.writeStrongBinder(service);
  7. 161data.writeInt32(allowIsolated?1:0);
  8. 162status_terr=remote()->transact(ADD_SERVICE_TRANSACTION,data,&reply);
  9. 163returnerr==NO_ERROR?reply.readExceptionCode():err;
  10. 164}
这里162行remote流程和前面分析的差不多,最终调用IPCThreadState.cpp的transact,这里就是最终和binder驱动打交道的地方了,binder即为前面main_mediaserver.cpp中36行 ProcessState::ProcessState打开的驱动,用这块共享内存和servicemanager打交道,在底层的内核空间binder驱动会根据传进来的mHandle值判断目标服务地址,这里的 mHandle为0,所以调整servermanager的buffer指向本地内存共享空间,接着往下看main_mediaserver.cpp的43行ProcessState::self()- >startThreadPool(), 在frameworks/native/libs/binder/ProcessState.cpp中:
[cpp] view plain copy
  1. 136voidProcessState::startThreadPool()
  2. 137{
  3. 138AutoMutex_l(mLock);
  4. 139if(!mThreadPoolStarted){
  5. 140mThreadPoolStarted=true;
  6. 141spawnPooledThread(true);
  7. 142}
  8. 143}
看141行:
[cpp] view plain copy
  1. 286voidProcessState::spawnPooledThread(boolisMain)
  2. 287{
  3. 288if(mThreadPoolStarted){
  4. 289int32_ts=android_atomic_add(1,&mThreadPoolSeq);
  5. 290charbuf[16];
  6. 291snprintf(buf,sizeof(buf),"Binder_%X",s);
  7. 292ALOGV("Spawningnewpooledthread,name=%s\n",buf);
  8. 293sp<Thread>t=newPoolThread(isMain);
  9. 294t->run(buf);
  10. 295}
  11. 296}
293行创建了线程,PoolThread类继承列thread类,ProcessState.cpp中::
[cpp] view plain copy
  1. 56classPoolThread:publicThread
  2. 57{
  3. 58public:
  4. 59PoolThread(boolisMain)
  5. 60:mIsMain(isMain)
  6. 61{
  7. 62}
  8. 63
  9. 64protected:
  10. 65virtualboolthreadLoop()
  11. 66{
  12. 67IPCThreadState::self()->joinThreadPool(mIsMain);
  13. 68returnfalse;
  14. 69}
  15. 70
  16. 71constboolmIsMain;
  17. 72};
294行执行线程,thread在frameworks/native/libs/utils/Threads.cpp中,这样run函数最终调用子类的threadLoop函数,看67行,调用的和main_mediaserver.cpp的44行一样, 进入IPCThreadState.cpp中,result =talkWithDriver()等待client请求,最终会调用 executeCommand(cmd)函数来处理请求,而在executeCommand函数 中,最终会调用BBinder::transact来真正处理Client的请求,接下来再看一下BBinder::transact的实现,frameworks/native/libs/binder/Binder.cpp中:
[cpp] view plain copy
  1. 97status_tBBinder::transact(
  2. 98uint32_tcode,constParcel&data,Parcel*reply,uint32_tflags)
  3. 99{
  4. 100data.setDataPosition(0);
  5. 101
  6. 102status_terr=NO_ERROR;
  7. 103switch(code){
  8. 104casePING_TRANSACTION:
  9. 105reply->writeInt32(pingBinder());
  10. 106break;
  11. 107default:
  12. 108err=onTransact(code,data,reply,flags);
  13. 109break;
  14. 110}
  15. 111
  16. 112if(reply!=NULL){
  17. 113reply->setDataPosition(0);
  18. 114}
  19. 115
  20. 116returnerr;
  21. 117}
108行,调用onTransact方法,由于这里的继承关系,在前面分析main_mediaserver.cpp的42行AudioPolicyService::instantiate()就知道,这里创建的是AudioPolicyService类, 这样由于虚函数onTransact的继承关系,最终调用了AudioPolicyService的onTransact方法,AudioPolicyService.cpp中:
[cpp] view plain copy
  1. 610status_tAudioPolicyService::onTransact(uint32_tcode,constParcel&data,Parcel*reply,uint32_tflags)
  2. 612{
  3. 613returnBnAudioPolicyService::onTransact(code,data,reply,flags);
  4. 614}
613行调用的还是基类BnAudioPolicyService的方法.
到这里BpAudioPolicyService和BnAudioPolicyService的binder通讯关系就完成了,回到前面IAudioPolicyService.cpp中的242行 remote()->transact(SET_STREAM_VOLUME, data, &reply);这里传进来的是SET_STREAM_VOLUME,所以调用BnAudioPolicyService::onTransact:
[cpp] view plain copy
  1. 512caseSET_STREAM_VOLUME:{
  2. 513CHECK_INTERFACE(IAudioPolicyService,data,reply);
  3. 514audio_stream_type_tstream=
  4. 515static_cast<audio_stream_type_t>(data.readInt32());
  5. 516intindex=data.readInt32();
  6. 517audio_devices_tdevice=static_cast<audio_devices_t>(data.readInt32());
  7. 518reply->writeInt32(static_cast<uint32_t>(setStreamVolumeIndex(stream,
  8. 519index,
  9. 520device)));
  10. 521returnNO_ERROR;
  11. 522}break;
518行AudioPolicyService覆盖了BpAudioPolicyService的setStreamVolumeIndex方法,所以最终调用了AudioPolicyService.cpp的setStreamVolumeIndex方法:
[cpp] view plain copy
  1. 380status_tAudioPolicyService::setStreamVolumeIndex(audio_stream_type_tstream,
  2. 381intindex,
  3. 382audio_devices_tdevice)
  4. 383{
  5. 384if(mpAudioPolicy==NULL){
  6. 385returnNO_INIT;
  7. 386}
  8. 387if(!settingsAllowed()){
  9. 388returnPERMISSION_DENIED;
  10. 389}
  11. 390if(uint32_t(stream)>=AUDIO_STREAM_CNT){
  12. 391returnBAD_VALUE;
  13. 392}
  14. 393
  15. 394if(mpAudioPolicy->set_stream_volume_index_for_device){
  16. 395returnmpAudioPolicy->set_stream_volume_index_for_device(mpAudioPolicy,
  17. 396stream,
  18. 397index,
  19. 398device);
  20. 399}else{
  21. 400returnmpAudioPolicy->set_stream_volume_index(mpAudioPolicy,stream,index);
  22. 401}
  23. 402}
总结上面binder的通讯机制,理解了类之间的继承派生关系,也就能把来龙去脉弄清楚,主要还是熟悉C++才行,还有要理解binder通讯的设计原理,即每个服务或者想要获得服务的进程都会打开binder节点,并且内存映射有一块空间,传送数据时候,binder驱动根据client传进来的数据大小、位置和目标service(在驱动中用target_proc来表示),用binder_alloc_buf函数在目标service之前mmap时候分配的内核空间中申请空间,然后用copy_from_user将数据从用户空间拷贝到内核的这块空间中来,又因为service端之前mmap申请内核空间的时候已经记录了这块空间在内核中和用户空间的偏移量,从而计算binder_alloc_buf分配得到的内核空间对应用户空间的地址,最后将该地址拷贝到service的用户空间,service端就可以得到数据了,通过这样的浅拷贝即可实现进程间传输数据只用拷贝一次即可的原理。继续从AudioPolicyService.cpp往下走。先看它的构造函数:
[cpp] view plain copy
  1. 58AudioPolicyService::AudioPolicyService()
  2. 59:BnAudioPolicyService(),mpAudioPolicyDev(NULL),mpAudioPolicy(NULL)
  3. 60{
  4. 61charvalue[PROPERTY_VALUE_MAX];
  5. 62conststructhw_module_t*module;
  6. 63intforced_val;
  7. 64intrc;
  8. 65
  9. 66Mutex::Autolock_l(mLock);
  10. 67
  11. 68//starttoneplaybackthread
  12. 69mTonePlaybackThread=newAudioCommandThread(String8(""));
  13. 70//startaudiocommandsthread
  14. 71mAudioCommandThread=newAudioCommandThread(String8("ApmCommand"));
  15. 72
  16. 73/*instantiatetheaudiopolicymanager*/
  17. 74rc=hw_get_module(AUDIO_POLICY_HARDWARE_MODULE_ID,&module);
  18. 75if(rc)
  19. 76return;
  20. 77
  21. 78rc=audio_policy_dev_open(module,&mpAudioPolicyDev);
  22. 79ALOGE_IF(rc,"couldn'topenaudiopolicydevice(%s)",strerror(-rc));
  23. 80if(rc)
  24. 81return;
  25. 82
  26. 83rc=mpAudioPolicyDev->create_audio_policy(mpAudioPolicyDev,&aps_ops,this,
  27. 84&mpAudioPolicy);
  28. 85ALOGE_IF(rc,"couldn'tcreateaudiopolicy(%s)",strerror(-rc));
  29. 86if(rc)
  30. 87return;
  31. 88
  32. 89rc=mpAudioPolicy->init_check(mpAudioPolicy);
  33. 90ALOGE_IF(rc,"couldn'tinit_checktheaudiopolicy(%s)",strerror(-rc));
  34. 91if(rc)
  35. 92return;
  36. .......................
  37. }
74行AUDIO_POLICY_HARDWARE_MODULE_ID定义在libhardware/include/hardware/audio_policy.h中,
#define AUDIO_POLICY_HARDWARE_MODULE_ID "audio_policy"
根据hw_get_module的判断关系,看hardware/libhardware_legacy/audio/Android.mk可知,最终调用的是audio_policy.default.so,通过hw_get_module函数的 load(class_id, path, module)打开audio_policy.default.so并返回句柄,接着78行audio_policy_dev_open,在libhardware/include/hardware/audio_policy.h
[cpp] view plain copy
  1. 424staticinlineintaudio_policy_dev_open(consthw_module_t*module,
  2. 425structaudio_policy_device**device)
  3. 426{
  4. 427returnmodule->methods->open(module,AUDIO_POLICY_INTERFACE,
  5. 428(hw_device_t**)device);
  6. 429}
这样就调用了hardware/libhardware_legacy/audio/audio_policy_hal.cpp的open方法:
[cpp] view plain copy
  1. 406staticintlegacy_ap_dev_open(consthw_module_t*module,constchar*name,hw_device_t**device)
  2. 408{
  3. 409structlegacy_ap_device*dev;
  4. 411if(strcmp(name,AUDIO_POLICY_INTERFACE)!=0)
  5. 412return-EINVAL;
  6. 414dev=(structlegacy_ap_device*)calloc(1,sizeof(*dev));
  7. 415if(!dev)
  8. 416return-ENOMEM;
  9. 418dev->device.common.tag=HARDWARE_DEVICE_TAG;
  10. 419dev->device.common.version=0;
  11. 420dev->device.common.module=const_cast<hw_module_t*>(module);
  12. 421dev->device.common.close=legacy_ap_dev_close;
  13. 422dev->device.create_audio_policy=create_legacy_ap;
  14. 423dev->device.destroy_audio_policy=destroy_legacy_ap;
  15. 425*device=&dev->device.common;
  16. 427return0;
  17. 428}
结构体legacy_ap_device定义:
[cpp] view plain copy
  1. 40structlegacy_ap_device{
  2. 41structaudio_policy_devicedevice;
  3. 42};
结构体audio_policy_device定义:
[cpp] view plain copy
  1. 410structaudio_policy_device{
  2. 411structhw_device_tcommon;
  3. 412
  4. 413int(*create_audio_policy)(conststructaudio_policy_device*device,
  5. 414structaudio_policy_service_ops*aps_ops,
  6. 415void*service,
  7. 416structaudio_policy**ap);
  8. 417
  9. 418int(*destroy_audio_policy)(conststructaudio_policy_device*device,
  10. 419structaudio_policy*ap);
  11. 420};
所以这里open的425行*device = &dev->device.common赋值的虽然是结构体audio_policy_device的成员common的地址,但是common位于结构体首地址,也就是相当于返回了 audio_policy_device结构体的地址。所以接着AudioPolicyService.cpp的83行调用的是audio_policy_device的create_audio_policy,它指向create_legacy_ap函数:
[cpp] view plain copy
  1. 311staticintcreate_legacy_ap(conststructaudio_policy_device*device,
  2. 312structaudio_policy_service_ops*aps_ops,
  3. 313void*service,
  4. 314structaudio_policy**ap)
  5. 315{
  6. 316structlegacy_audio_policy*lap;
  7. 317intret;
  8. 318
  9. 319if(!service||!aps_ops)
  10. 320return-EINVAL;
  11. 321
  12. 322lap=(structlegacy_audio_policy*)calloc(1,sizeof(*lap));
  13. 323if(!lap)
  14. 324return-ENOMEM;
  15. 325
  16. 326lap->policy.set_device_connection_state=ap_set_device_connection_state;
  17. 327lap->policy.get_device_connection_state=ap_get_device_connection_state;
  18. 328lap->policy.set_phone_state=ap_set_phone_state;
  19. 329lap->policy.set_ringer_mode=ap_set_ringer_mode;
  20. 330lap->policy.set_force_use=ap_set_force_use;
  21. 331lap->policy.get_force_use=ap_get_force_use;
  22. 332lap->policy.set_can_mute_enforced_audible=ap_set_can_mute_enforced_audible;
  23. 334lap->policy.init_check=ap_init_check;
  24. 335lap->policy.get_output=ap_get_output;
  25. 336lap->policy.start_output=ap_start_output;
  26. 337lap->policy.stop_output=ap_stop_output;
  27. 338lap->policy.release_output=ap_release_output;
  28. 339lap->policy.get_input=ap_get_input;
  29. 340lap->policy.start_input=ap_start_input;
  30. 341lap->policy.stop_input=ap_stop_input;
  31. 342lap->policy.release_input=ap_release_input;
  32. 343lap->policy.init_stream_volume=ap_init_stream_volume;
  33. 344lap->policy.set_stream_volume_index=ap_set_stream_volume_index;
  34. 345lap->policy.get_stream_volume_index=ap_get_stream_volume_index;
  35. 346lap->policy.set_stream_volume_index_for_device=ap_set_stream_volume_index_for_device;
  36. 347lap->policy.get_stream_volume_index_for_device=ap_get_stream_volume_index_for_device;
  37. 348lap->policy.get_strategy_for_stream=ap_get_strategy_for_stream;
  38. 349lap->policy.get_devices_for_stream=ap_get_devices_for_stream;
  39. 350lap->policy.get_output_for_effect=ap_get_output_for_effect;
  40. 351lap->policy.register_effect=ap_register_effect;
  41. 352lap->policy.unregister_effect=ap_unregister_effect;
  42. 353lap->policy.set_effect_enabled=ap_set_effect_enabled;
  43. 354lap->policy.is_stream_active=ap_is_stream_active;
  44. 355lap->policy.dump=ap_dump;
  45. 356
  46. 357lap->service=service;
  47. 358lap->aps_ops=aps_ops;
  48. 359lap->service_client=
  49. 360newAudioPolicyCompatClient(aps_ops,service);
  50. 361if(!lap->service_client){
  51. 362ret=-ENOMEM;
  52. 363gotoerr_new_compat_client;
  53. 364}
  54. 365
  55. 366lap->apm=createAudioPolicyManager(lap->service_client);
  56. 367if(!lap->apm){
  57. 368ret=-ENOMEM;
  58. 369gotoerr_create_apm;
  59. 370}
  60. 371
  61. 372*ap=&lap->policy;
  62. 373return0;
  63. 374
  64. 375err_create_apm:
  65. 376deletelap->service_client;
  66. 377err_new_compat_client:
  67. 378free(lap);
  68. 379*ap=NULL;
  69. 380returnret;
  70. 381}
372行可知,这样mpAudioPolicy指针就指向了lap->policy方法。回到前面AudioPolicyService::setStreamVolumeIndex的394行调用audio_policy_hal.cpp方法:
[cpp] view plain copy
  1. 232staticintap_set_stream_volume_index_for_device(structaudio_policy*pol,
  2. 233audio_stream_type_tstream,
  3. 234intindex,
  4. 235audio_devices_tdevice)
  5. 236{
  6. 237structlegacy_audio_policy*lap=to_lap(pol);
  7. 238returnlap->apm->setStreamVolumeIndex((AudioSystem::stream_type)stream,
  8. 239index,
  9. 240device);
  10. 241}
237行结构体legacy_audio_policy定义:
[cpp] view plain copy
  1. 44structlegacy_audio_policy{
  2. 45structaudio_policypolicy;//即为mpAudioPolicy
  3. 46
  4. 47void*service;
  5. 48structaudio_policy_service_ops*aps_ops;
  6. 49AudioPolicyCompatClient*service_client;
  7. 50AudioPolicyInterface*apm;
  8. 51};
lap->apm的赋值在前面create_legacy_ap函数的366行,看createAudioPolicyManager,hardware/libhardware_legacy/audio/AudioPolicyManagerDefault.cpp中:
[cpp] view plain copy
  1. 24extern"C"AudioPolicyInterface*createAudioPolicyManager(AudioPolicyClientInterface*clientInterface)
  2. 25{
  3. 26returnnewAudioPolicyManagerDefault(clientInterface);
  4. 27}
----->hardware/libhardware_legacy/audio/AudioPolicyManagerDefault.h:
[cpp] view plain copy
  1. 25classAudioPolicyManagerDefault:publicAudioPolicyManagerBase
  2. 26{
  3. 28public:
  4. 29AudioPolicyManagerDefault(AudioPolicyClientInterface*clientInterface)
  5. 30:AudioPolicyManagerBase(clientInterface){}
  6. 31
  7. 32virtual~AudioPolicyManagerDefault(){}
  8. 33
  9. 34};
看基类AudioPolicyManagerBase,hardware/libhardware_legacy/include/hardware_legacy/AudioPolicyManagerBase.h的定义,终于找到了setStreamVolumeIndex方法,
在AudioPolicyManagerBase.cpp中:
953 status_t AudioPolicyManagerBase::setStreamVolumeIndex(AudioSystem::stream_type stream, int index, audio_devices_t device)956 {  958     if ((index < mStreams[stream].mIndexMin) || (index > mStreams[stream].mIndexMax)) {  959         return BAD_VALUE;  960     }  961     if (!audio_is_output_device(device)) {  962         return BAD_VALUE;  963     }  965     // Force max volume if stream cannot be muted  966     if (!mStreams[stream].mCanBeMuted) index = mStreams[stream].mIndexMax;  971     // if device is AUDIO_DEVICE_OUT_DEFAULT set default value and  972     // clear all device specific values  973     if (device == AUDIO_DEVICE_OUT_DEFAULT) {  974         mStreams[stream].mIndexCur.clear();  975     }  976     mStreams[stream].mIndexCur.add(device, index);  978     // compute and apply stream volume on all outputs according to connected device  979     status_t status = NO_ERROR;  980     for (size_t i = 0; i < mOutputs.size(); i++) {  981         audio_devices_t curDevice =  982                 getDeviceForVolume((audio_devices_t)mOutputs.valueAt(i)->device());  983         if (device == curDevice) {  984             status_t volStatus = checkAndSetVolume(stream, index, mOutputs.keyAt(i), curDevice);  985             if (volStatus != NO_ERROR) {  986                 status = volStatus;  987             }  988         }  989     }  990     return status;  991 }  


看984行checkAndSetVolume函数:
[cpp] view plain copy
  1. 2683status_tAudioPolicyManagerBase::checkAndSetVolume(intstream,
  2. 2684intindex,
  3. 2685audio_io_handle_toutput,
  4. 2686audio_devices_tdevice,
  5. 2687intdelayMs,
  6. 2688boolforce)
  7. 2689{
  8. ....................
  9. 2722if(stream==AudioSystem::BLUETOOTH_SCO){
  10. 2723mpClientInterface->setStreamVolume(AudioSystem::VOICE_CALL,volume,output,delayMs);
  11. 2724}
  12. 2725}
  13. 2726
  14. 2727mpClientInterface->setStreamVolume((AudioSystem::stream_type)stream,volume,output,delayMs);
  15. ...................
  16. 2747}
这里mpClientInterface是在AudioPolicyManagerBase构造函数中赋值的,就是create_legacy_ap函数360行AudioPolicyCompatClient,方法在AudioPolicyCompatClient.cpp:
[cpp] view plain copy
  1. 120status_tAudioPolicyCompatClient::setStreamVolume(
  2. 121AudioSystem::stream_typestream,
  3. 122floatvolume,
  4. 123audio_io_handle_toutput,
  5. 124intdelayMs)
  6. 125{
  7. 126returnmServiceOps->set_stream_volume(mService,(audio_stream_type_t)stream,
  8. 127volume,output,delayMs);
  9. 128}
这里是在构造函数中赋值的,看AudioPolicyCompatClient.h:
[cpp] view plain copy
  1. 32classAudioPolicyCompatClient:publicAudioPolicyClientInterface{
  2. 33public:
  3. 34AudioPolicyCompatClient(structaudio_policy_service_ops*serviceOps,
  4. 35void*service):
  5. 36mServiceOps(serviceOps),
  6. mService(service){}
从36行可知,构造时候就已经赋值了,所以调用的是create_legacy_ap函数312行传进来的的型参aps_ops的set_stream_volume,它的赋值在 frameworks/av/services/audioflinger/AudioPolicyService.cpp中:
[cpp] view plain copy
  1. 1538structaudio_policy_service_opsaps_ops={
  2. 1539open_output:aps_open_output,
  3. 1540open_duplicate_output:aps_open_dup_output,
  4. 1541close_output:aps_close_output,
  5. 1542suspend_output:aps_suspend_output,
  6. 1543restore_output:aps_restore_output,
  7. 1544open_input:aps_open_input,
  8. 1545close_input:aps_close_input,
  9. 1546set_stream_volume:aps_set_stream_volume,
  10. 1547set_stream_output:aps_set_stream_output,
  11. 1548set_parameters:aps_set_parameters,
  12. 1549get_parameters:aps_get_parameters,
  13. 1550start_tone:aps_start_tone,
  14. 1551stop_tone:aps_stop_tone,
  15. 1552set_voice_volume:aps_set_voice_volume,
  16. 1553move_effects:aps_move_effects,
  17. 1554load_hw_module:aps_load_hw_module,
  18. 1555open_output_on_module:aps_open_output_on_module,
  19. 1556open_input_on_module:aps_open_input_on_module,
  20. 1557};
------------>
[cpp] view plain copy
  1. 1503staticintaps_set_stream_volume(void*service,audio_stream_type_tstream,
  2. 1504floatvolume,audio_io_handle_toutput,
  3. 1505intdelay_ms)
  4. 1506{
  5. 1507AudioPolicyService*audioPolicyService=(AudioPolicyService*)service;
  6. 1508
  7. 1509returnaudioPolicyService->setStreamVolume(stream,volume,output,
  8. 1510delay_ms);
  9. 1511}
这里1507行的service即create_legacy_ap 360行传进来的service,也就是AudioPolicyService.cpp构造函数中83行的this指针,饶了半天居然还是调用了AudioPolicyService.cpp 的setStreamVolume, setStreamVolume的实现:
[cpp] view plain copy
  1. 1006intAudioPolicyService::setStreamVolume(audio_stream_type_tstream,
  2. 1007floatvolume,
  3. 1008audio_io_handle_toutput,
  4. 1009intdelayMs)
  5. 1010{
  6. 1011return(int)mAudioCommandThread->volumeCommand(stream,volume,
  7. 1012output,delayMs);
  8. 1013}
一看就知道是个线程之类的东西了,AudioCommandThread继承了Thread类,看看volumeCommand的实现:
[cpp] view plain copy
  1. 800status_tAudioPolicyService::AudioCommandThread::volumeCommand(audio_stream_type_tstream,
  2. 801floatvolume,
  3. 802audio_io_handle_toutput,
  4. 803intdelayMs)
  5. 804{
  6. 805status_tstatus=NO_ERROR;
  7. 806
  8. 807AudioCommand*command=newAudioCommand();
  9. 808command->mCommand=SET_VOLUME;
  10. 809VolumeData*data=newVolumeData();
  11. 810data->mStream=stream;
  12. 811data->mVolume=volume;
  13. 812data->mIO=output;
  14. 813command->mParam=data;
  15. 814if(delayMs==0){
  16. 815command->mWaitStatus=true;
  17. 816}else{
  18. 817command->mWaitStatus=false;
  19. 818}
  20. 819Mutex::Autolock_l(mLock);
  21. 820insertCommand_l(command,delayMs);
  22. 821ALOGV("AudioCommandThread()addingsetvolumestream%d,volume%f,output%d",
  23. 822stream,volume,output);
  24. 823mWaitWorkCV.signal();
  25. 824if(command->mWaitStatus){
  26. 825command->mCond.wait(mLock);
  27. 826status=command->mStatus;
  28. 827mWaitWorkCV.signal();
  29. 828}
  30. 829returnstatus;
  31. 830}
820行insertCommand_l,加入线程队列中,看看线程的执行函数threadLoop:
[cpp] view plain copy
  1. boolAudioPolicyService::AudioCommandThread::threadLoop()
  2. {
  3. 681caseSET_VOLUME:{
  4. 682VolumeData*data=(VolumeData*)command->mParam;
  5. 683ALOGV("AudioCommandThread()processingsetvolumestream%d,\
  6. 684volume%f,output%d",data->mStream,data->mVolume,data->mIO);
  7. 685command->mStatus=AudioSystem::setStreamVolume(data->mStream,
  8. 686data->mVolume,
  9. 687data->mIO);
  10. 688if(command->mWaitStatus){
  11. 689command->mCond.signal();
  12. 690mWaitWorkCV.wait(mLock);
  13. 691}
  14. 692deletedata;
  15. 693}break;
  16. }
685行,我们又回到AudioSystem.cpp中来啦:
[cpp] view plain copy
  1. 123status_tAudioSystem::setStreamVolume(audio_stream_type_tstream,floatvalue,
  2. 124audio_io_handle_toutput)
  3. 125{
  4. 126if(uint32_t(stream)>=AUDIO_STREAM_CNT)returnBAD_VALUE;
  5. 127constsp<IAudioFlinger>&af=AudioSystem::get_audio_flinger();
  6. 128if(af==0)returnPERMISSION_DENIED;
  7. 129af->setStreamVolume(stream,value,output);
  8. 130returnNO_ERROR;
  9. 131}
129行,我们终于要进入AudioFlinger.cpp中啦,先看126行,get_audio_flinger:
[cpp] view plain copy
  1. 49constsp<IAudioFlinger>&AudioSystem::get_audio_flinger()
  2. 50{
  3. 51Mutex::Autolock_l(gLock);
  4. 52if(gAudioFlinger==0){
  5. 53sp<IServiceManager>sm=defaultServiceManager();
  6. 54sp<IBinder>binder;
  7. 55do{
  8. 56binder=sm->getService(String16("media.audio_flinger"));
  9. 57if(binder!=0)
  10. 58break;
  11. 59ALOGW("AudioFlingernotpublished,waiting...");
  12. 60usleep(500000);//0.5s
  13. 61}while(true);
  14. 62if(gAudioFlingerClient==NULL){
  15. 63gAudioFlingerClient=newAudioFlingerClient();
  16. 64}else{
  17. 65if(gAudioErrorCallback){
  18. 66gAudioErrorCallback(NO_ERROR);
  19. 67}
  20. 68}
  21. 69binder->linkToDeath(gAudioFlingerClient);
  22. 70gAudioFlinger=interface_cast<IAudioFlinger>(binder);
  23. 71gAudioFlinger->registerClient(gAudioFlingerClient);
  24. 72}
  25. 73ALOGE_IF(gAudioFlinger==0,"noAudioFlinger!?");
  26. 74
  27. 75returngAudioFlinger;
  28. 76}
分析完前面的binder通讯,再看这个函数的代码,太简单了!70行最终得到一个BpAudioFlinger代理,以便和BnAudioFlinger通讯,他们在IAudioFlinger.cpp中:
[cpp] view plain copy
  1. 255virtualstatus_tsetStreamVolume(audio_stream_type_tstream,floatvalue,
  2. 256audio_io_handle_toutput)
  3. 257{
  4. 258Parceldata,reply;
  5. 259data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
  6. 260data.writeInt32((int32_t)stream);
  7. 261data.writeFloat(value);
  8. 262data.writeInt32((int32_t)output);
  9. 263remote()->transact(SET_STREAM_VOLUME,data,&reply);
  10. 264returnreply.readInt32();
  11. 265}
263行,,类型为SET_STREAM_VOLUME,由于AudioFlinger继承BnAudioFlinger,调用AudioFlinger的onTransact,但该函数还是回调BnAudioFlinger的onTransact,进入
BnAudioFlinger::onTransact函数:
[cpp] view plain copy
  1. 780caseSET_STREAM_VOLUME:{
  2. 781CHECK_INTERFACE(IAudioFlinger,data,reply);
  3. 782intstream=data.readInt32();
  4. 783floatvolume=data.readFloat();
  5. 784audio_io_handle_toutput=(audio_io_handle_t)data.readInt32();
  6. 785reply->writeInt32(setStreamVolume((audio_stream_type_t)stream,volume,output));
  7. 786returnNO_ERROR;
785行,进入AudioFlinger.cpp:
[cpp] view plain copy
  1. 761status_tAudioFlinger::setStreamVolume(audio_stream_type_tstream,floatvalue,
  2. 762audio_io_handle_toutput)
  3. 763{
  4. 764//checkcallingpermissions
  5. 765if(!settingsAllowed()){
  6. 766returnPERMISSION_DENIED;
  7. 767}
  8. 769if(uint32_t(stream)>=AUDIO_STREAM_CNT){//定义在system/core/include/system/audio.h
  9. 771returnBAD_VALUE;
  10. 772}
  11. 774AutoMutexlock(mLock);
  12. 775PlaybackThread*thread=NULL;
  13. 776if(output){
  14. 777thread=checkPlaybackThread_l(output);
  15. 778if(thread==NULL){
  16. 779returnBAD_VALUE;
  17. 780}
  18. 781}
  19. 783mStreamTypes[stream].volume=value;
  20. 785if(thread==NULL){
  21. 786for(size_ti=0;i<mPlaybackThreads.size();i++){
  22. 787mPlaybackThreads.valueAt(i)->setStreamVolume(stream,value);
  23. 788}
  24. 789}else{
  25. 790thread->setStreamVolume(stream,value);
  26. 791}
  27. 793returnNO_ERROR;
  28. 794}
audioflinger的原理看另外一篇文章。

更多相关文章

  1. C语言函数的递归(上)
  2. Android(安卓)分辨率适配方法
  3. LocalBroadcastManager原理解析
  4. 自定义Dialog UI
  5. 安卓AIDL跨进程间通信
  6. Android(安卓)studio 点击按钮跳转到新的Activity
  7. 15个Android很有用的代码片段
  8. 修改版本号
  9. Android应用程序组件Content Provider在应用程序之间共享数据的

随机推荐

  1. Android(安卓)的演变【信息图】
  2. 基于mina的的android即时通信app
  3. android软键盘上添加一个按钮
  4. 最全面的AndroidStudio配置指南总结-包括
  5. 移动端键盘弹起引起的fixed定位问题
  6. Android(安卓)ViewDragHelper实现窗帘效
  7. 微软:Android(安卓)智能手机正在被僵尸网
  8. Android(安卓)Pay,能冲破第三方支付围堵
  9. Android内存泄漏检测及修复(转载)
  10. iOS 开发者的 Android(安卓)第一课