1. 程式人生 > >android 原始碼分析開啟mic

android 原始碼分析開啟mic

1、demo

  AudioManager  audioManager  =  (AudioManager)getSystemService("audio");
  audioManager.setMode(AudioManager.STREAM_MUSIC);//設定聲音模式
  audioManager.setMicrophoneMute(true); //開啟麥克風

  許可權:<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />

2、java層

    <1>frameworks/base/media/java/android/media/AudioManager.java

     public void setMicrophoneMute(boolean on){             

     IAudioService service = getService();   
     service.setMicrophoneMute(on, mContext.getOpPackageName()); }

  <2>frameworks/base/media/java/android/media/AudioSystem.java

        public static native int muteMicrophone(boolean on);

3、Native層

  <1>frameworks/base/core/jni/android_media_AudioSystem.cpp

       (1)static JNINativeMethodgMethods[] ={

       {"muteMicrophone", "(Z)I", (void *)android_media_AudioSystem_muteMicrophone},};

      (2)static jint android_media_AudioSystem_muteMicrophone(JNIEnv *env, jobject thiz, jboolean on)   {                                                                     return (jint) check_AudioSystem_Command(AudioSystem::muteMicrophone(on));  

         }

  <2>frameworks/av/media/libmedia/AudioSystem.cpp

        status_t AudioSystem::muteMicrophone(bool state)  {                                                                                                                                                     const sp<IAudioFlinger>&af = AudioSystem::get_audio_flinger();
          return af->setMicMute(state);  }

  <3>Binder的Client端Bp層,真正實現的部分在服務端的Bn層

       frameworks/av/media/libmedia/IaudioFlinger.cpp

       class BpAudioFlinger : public BpInterface<IAudioFlinger>{

         virtual status_t setMicMute(bool state)  {     
           Parcel data, reply;   
          data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());                       
          data.writeInt32(state);  
          remote()->transact(SET_MIC_MUTE, data, &reply);       
          return reply.readInt32();  
         }

       };

      IMPLEMENT_META_INTERFACE(AudioFlinger, "android.media.IAudioFlinger");

     status_t BnAudioFlinger::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags){
      case SET_MIC_MUTE: {
            CHECK_INTERFACE(IAudioFlinger, data, reply);
            reply->writeInt32( setMicMute(state) ); //傳送給Bn服務端
            return NO_ERROR;}
            break;

}

   <4>Binder服務端的Bn層,真正實現的部分

       frameworks/av/services/audioflinger/AudioFlinger.cpp

       AudioFlinger::AudioFlinger() :BnAudioFlinger(){//建構函式

       }
     status_t AudioFlinger::setMicMute(bool state){
       status_t result = dev->set_mic_mute(dev, state);//呼叫HAL層
     }

4、HAL層

    hardware/rockchip/audio/tinyalsa_hal/audio_hw.c

    <1>static int adev_open(const hw_module_t* module, const char* name, hw_device_t** device)
    {
        struct audio_device *adev;
        adev->hw_device.set_mic_mute = adev_set_mic_mute;
    }

    static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
    {                                                                                                                                                                                                           
       struct audio_device *adev = (struct audio_device *)dev;
       adev->mic_mute = state;
       return 0;
   }

   <2>開啟audio裝置節點操作

         external/tinyalsa/pcm.c

         struct pcm *pcm_open(unsigned int card, unsigned int device, unsigned int flags, struct pcm_config *config)

        {                                                                                                                                
          snprintf(fn, sizeof(fn), "/dev/snd/pcmC%uD%u%c", card, device, flags & PCM_IN ? 'c' : 'p');

          pcm->fd =open(fn, O_RDWR);               
       }

5、Kernel層

     kernel/sound/soc/rockchip/rk30_fpga192k.c

     static int rk30_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params)
    {
       snd_soc_dai_set_sysclk(cpu_dai, 0, pll_out, 1);  
       snd_soc_dai_set_clkdiv(cpu_dai, ROCKCHIP_DIV_BCLK,div_bclk);
       snd_soc_dai_set_clkdiv(cpu_dai, ROCKCHIP_DIV_MCLK, div_mclk);
   }