FM打开fmOn()过程

来源:互联网 发布:windows 10 v1703 编辑:程序博客网 时间:2024/05/02 04:42
FM打开fmOn()过程


FMPlay.java
private RadioServiceStub mService;
private Thread createOpenThread() {
        return new Thread(new Runnable() {
            public void run() {
                Log.d(LOGTAG, "tring open fm");
                mOver = false;
                mHandler.sendMessage(mHandler.obtainMessage(MSG_PROGRESS));
                mOpenResult = mService.fmOn();
                Log.d(LOGTAG, "tring open fm result = " + mOpenResult);
                mOver = true;
            }
       });
    }




RadioServiceStub.java
 private IRadioService mService;
 public boolean fmOn() {
        boolean value = false;
        if (mService != null) {
            try {
                value = mService.fmOn();
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }


        return value;
    }
此处aidl实现,在IRadioService.java中


FMplayService.java
具体实现fmOn()的地方
static class ServiceStub extends IRadioService.Stub {
        WeakReference<FMplayService> mService;


        public ServiceStub(FMplayService service) {
            mService = new WeakReference<FMplayService>(service);
        }


        public boolean fmOn() throws RemoteException {
            if(mService != null){
                if(mService.get() != null){
                    return mService.get().fmOn();
                }
            }
            return false;
        }
}


FMplayService.java
具体实现fmOn()的地方
private FmReceiver mReceiver = null;
private static final String RADIO_DEVICE = "/dev/radio0";
public boolean fmOn() {
        mNeedShutdown = false;
        mCanStopNotification = true;


        boolean value = false;
        if (mReceiver == null) {
            try {
                Log.d(LOGTAG, "create FmReceiver instance");
                mReceiver = new FmReceiver(RADIO_DEVICE, null); -------------------- important1
            } catch (InstantiationException e) {
                Log.e(LOGTAG, "exception when creating FmReceiver instance");
                e.printStackTrace();
            }


            if (mReceiver != null) {
                Log.d(LOGTAG, "FmReceiver enable");
                value = mReceiver.enable(null);  -------------------- important2
                if (!value) {
                    Log.i(LOGTAG, "mReceiver enable failed");
                }
            }


            if (value) {
                startNotification();
                Log.d(LOGTAG, "turn on radio " + value);


                // fix bug 126872 start
                // no effective station is set after fm is enabled so noise comes out
                setFreq(savedFreq);
                // fix bug 126872 end
            }
        } else {
            value = true;
            if (mPausedByAudioFocus) {
                mPausedByAudioFocus = false;
                unMute();
            }
        }


        if (value) {
            value = routeAudio(mAudioDevice);
        }


        if (!value || mNeedShutdown) {
            Log.d(LOGTAG, "close fm because mNeedShutdown = " + mNeedShutdown + " value "+value);
            fmOff();
            value = false;
        }


        return value;
    }


=======================================AIDL upper==============================================
FmReceiver.java
public FmReceiver(String devicePath,
                     FmRxEvCallbacksAdaptor callback) throws InstantiationException {
      mControl = new FmRxControls();
      mRxEvents = new FmRxEventListener();


      if ( !acquire(devicePath))
        throw new InstantiationException("Unable to open device descriptor");


      mDevice = devicePath;
      
      registerClient(callback);
      mRdsData = new FmRxRdsData(sFd);
   }


FmRxControls.java
/*
    * Turn on FM Rx/Tx.      ---------------------1
    * Rx = 1 and Tx = 2
    */  //fd = -1
   public void fmOn(int fd, int device) {      -------------------- important3
      FmReceiverJNI.setControlNative(fd, V4L2_CID_PRIVATE_TAVARUA_STATE, 1); 
   }


FmRxEventListener.java


FmRxRdsData.java




FmTransceiver.java
protected static final int FM_RX    =1;                     //com.android.music.musicservicecommand.pause
public boolean enable (FmConfig configSettings){
      boolean status;


      /* Enable the Transceiver common for both
         receiver and transmitter
         */
      status = super.enable(configSettings, FmTransceiver.FM_RX);


      return status;
   }


FmTransceiver.java
 public boolean enable (FmConfig configSettings, int device){




      Log.d(TAG, "turning on %d" + device);
      mControl.fmOn(sFd, device);


      Log.d(TAG, "Calling fmConfigure");
      return FmConfig.fmConfigure (sFd, configSettings);


   }
 
FmRxControls.java    sFd=-1
mControl.fmOn(sFd, device);    -> 1


FmReceiverJNI.java
public synchronized static native int setControlNative (int fd, int id, int value);


android_hardware_fm.cpp
/*
 * JNI registration.
 */
static JNINativeMethod gMethods[] = {
        /* name, signature, funcPtr */
................
{ "setControlNative", "(III)I",
            (void*)android_hardware_fmradio_FmReceiverJNI_setControlNative},
................
}


static jint android_hardware_fmradio_FmReceiverJNI_setControlNative
    (JNIEnv * env, jobject thiz, jint fd, jint id, jint value)     //fd=-1 id=V4L2_CID_PRIVATE_TAVARUA_STATE value=1
{
    fm_device_t* device = (fm_device_t *)fd;
    int err = device->setControl(device,id,value);    //device ?
    LOGE("(setControl)operation=%x value=%d result=%d errno=%d", id, value, err, errno);
    if (err < 0) {
        return FM_JNI_FAILURE;
    }


    return FM_JNI_SUCCESS;
}


====================================JNI upper============================================
libfm-brcm_hw.cpp
static int
setControl(struct fm_device_t* dev,int id, int value)
{
    int err = -1;
    struct bcm4330_fm_device_t *device = (struct bcm4330_fm_device_t *)dev;
    int status = FM_SUCCESS;


    LOGD("%s, %d\n", __FUNCTION__, id );


    switch(id) {
        case V4L2_CID_PRIVATE_TAVARUA_STATE:
        {
         value ? enableNative(FUNC_REGION_NA): disableNative(false);


         if(gMutex.wait(0, 3))
         {
             status = FM_FAILURE;
 }
 else
         {
                      if(gfm_params.chnl_info.status == BTA_FM_OK)
                      {
                 status = FM_SUCCESS;
                      }
                      else
                      {
                 status = FM_FAILURE;
                      }
 }
        }
        break;


        case V4L2_CID_AUDIO_VOLUME:
        {
                  if( value < 0 )
                  {
                      gVolume = 0;
                  }
                  else if( value > 15 )
                  {
                      gVolume = 256;
                  }
                  else
                      gVolume = volumeTbl[value];




                  LOGD("Set Volume : %d, %d\n", value, gVolume);


         setFMVolumeNative( gVolume );


         if(gMutex.wait(0, 3))
         {
      status = FM_FAILURE;
                  }
 else
                  {
     if(gfm_params.chnl_info.status == BTA_FM_OK)
                      {
                  status = FM_SUCCESS;
                      }
                      else
                      {
                  status = FM_FAILURE;
                      }
 }
        }
        break;


        case V4L2_CID_AUDIO_MUTE:
        {
          muteNative(value);


                   if(gMutex.wait(0, 3))
          {
       status = FM_FAILURE;
                   }
                   else
          {
              if(gfm_params.chnl_info.status == BTA_FM_OK)
                       {
                   status = FM_SUCCESS;
                       }
                       else
                       {
                   status = FM_FAILURE;
                       }
  }
        }
        break;
    }


    LOGE("(setControl)operation=%x value=%d status=%d", id, value, status);
    
    return status;
}




=================================others below============================
android_hardware_fm.cpp
int register_android_hardware_fm_fmradio(JNIEnv* env)
{
return AndroidRuntime::registerNativeMethods(env, "android/hardware/fmradio/FmReceiverJNI", gMethods, NELEM(gMethods));
}


AndroidRuntime.cpp
/*
 * Register native methods using JNI.
 */
/*static*/ int AndroidRuntime::registerNativeMethods(JNIEnv* env,
    const char* className, const JNINativeMethod* gMethods, int numMethods)
{
    return jniRegisterNativeMethods(env, className, gMethods, numMethods);
}


static const RegJNIRec gRegJNI[] = {
.....................
    REG_JNI(register_android_hardware_fm_fmradio),
.....................
}


/*
 * Register android native functions with the VM.
 */
/*static*/ int AndroidRuntime::startReg(JNIEnv* env)
{
    /*
     * This hook causes all future threads created in this process to be
     * attached to the JavaVM.  (This needs to go away in favor of JNI
     * Attach calls.)
     */
    androidSetCreateThreadFunc((android_create_thread_fn) javaCreateThreadEtc);


    LOGV("--- registering native functions ---\n");


    /*
     * Every "register" function calls one or more things that return
     * a local reference (e.g. FindClass).  Because we haven't really
     * started the VM yet, they're all getting stored in the base frame
     * and never released.  Use Push/Pop to manage the storage.
     */
    env->PushLocalFrame(200);


    if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {
        env->PopLocalFrame(NULL);
        return -1;
    }
    env->PopLocalFrame(NULL);


    //createJavaThread("fubar", quickTest, (void*) "hello");


    return 0;
}
原创粉丝点击