Android4.4 GPS框架分析

GPS HAL層代碼在目錄trunk/Android/hardware/xxx/gps/skytraqskytraq_gsp.c,向下與硬件驅動通訊,向上提供接口
GPS JNI層層代碼在目錄trunk/Android/frameworks/base/services/jni/com_android_server_location_GpsLocationProvider.cpp  C與java轉換,給java層提供接口
GPS framework層代碼目錄Android/frameworks/base/services/java/com/android/server下,主要文件是location服務對內部的封裝並提供provider服務
Android/frameworks/base/location/java/com/android/internal/location這個是framework對location服務內部的實現

啓動GPS服務代碼流程如下
public static void main(String[] args)
	-->ServerThread thr = new ServerThread();
		-->location = new LocationManagerService(context); 
		-->ServiceManager.addService(Context.LOCATION_SERVICE, location);
		-->locationF.systemRunning()
			-->systemRunning()
				-->loadProvidersLocked();
					-->GpsLocationProvider gpsProvider = new GpsLocationProvider(mContext, this, mLocationHandler.getLooper());
						-->class_init_native();
							-->android_location_GpsLocationProvider_class_init_native(JNIEnv* env, jclass clazz) 
								-->err = module->methods->open(module, GPS_HARDWARE_MODULE_ID, &device);
									-->pen_gps(const struct hw_module_t *module, char const *name, struct hw_device_t **device)
								-->sGpsInterface = gps_device->get_gps_interface(gps_device);
									-->const GpsInterface *gps__get_gps_interface(struct gps_device_t *dev)
										-->return &skytraqGpsInterface;
					-->GpsLocationProvider.isSupported()
						-->native_is_supported()
							-->android_location_GpsLocationProvider_is_supported(JNIEnv* env, jclass clazz)
								-->return (sGpsInterface != NULL);
				-->updateProvidersLocked
					-->	updateProviderListenersLocked
						-->	applyRequirementsLocked(provider);
								--> p.setRequest(providerRequest, worksource);
									-->	public void setRequest(ProviderRequest request, WorkSource source) 
							    	--> sendMessage(SET_REQUEST, 0, new GpsRequest(request, source));
						    			-->public void handleMessage(Message msg)
						    				-->handleSetRequest(gpsRequest.request, gpsRequest.source);
						    					-->startNavigating(singleShot);
						    						-->native_set_position_mode(mPositionMode, GPS_POSITION_RECURRENCE_PERIODIC,interval, 0, 0)
						    						-->native_start()

Android系統運行的第一個進程就是init進程,在該進程中創建的第一個虛擬機就是zygote,zygote孵化的第一個虛擬機就是Dalvik,該進程就是SystemServer,
對於的SystemServer代碼是framework\base\services\java\com\android\server\SystemServer.java
該SystemServer對於的第一個運行函數就是main

public static void main(String[] args) //SystemServer運行的第一個函數
	ServerThread thr = new ServerThread(); //初始化一個server線程 
		class ServerThread 
		{
			 public void initAndLoop() 
			 {
				   if (!disableLocation) //開始的時候這裏的 disableLocation = false
				   { 
             try{
                     Slog.i(TAG, "Location Manager");
 <1>                 location = new LocationManagerService(context); //實例化一個LocationManagerService服務,該服務主要用來管理GPS地理位置的變化
                     ServiceManager.addService(Context.LOCATION_SERVICE, location); //將這個service添加到SystemManager中
             } 
             catch (Throwable e) 
             {
                reportWtf("starting Location Manager", e);
             }

             try {
                    Slog.i(TAG, "Country Detector");
                    countryDetector = new CountryDetectorService(context);//實例化一個CountryDetectorService服務,用來探測不同國家,也就是不同地區和時區 
                    ServiceManager.addService(Context.COUNTRY_DETECTOR, countryDetector);
             } catch (Throwable e) {
                    reportWtf("starting Country Detector", e);
             }
          }
          
        ActivityManagerService.self().systemReady(new Runnable() 
        {
        	public void run() 
        	{
        		try 
        		{
<2>             if (locationF != null) locationF.systemRunning();//在<1>的位置已給locationF賦值,在這裏調用LocationManagerService的systemRunning()函數
            } 
            catch(Throwable e) 
            {
               reportWtf("Notifying Location Service running", e);
            }
        	}
        }
             
			}	
		}

接下來分析LocationManagerService(context)
/**framework\base\services\java\com\android\server\LocationManagerService.java**/
public class LocationManagerService extends ILocationManager.Stub
{
	public void systemRunning() //該函數有<2>處調用
	{
		synchronized (mLock)
		{
		/*GPS啓動到運行及監聽都在這兩個函數裏*/
<3>			loadProvidersLocked(); //在這裏加載各種provider
<4>			updateProvidersLocked(); //加載後更新
		}	
	}
}

/**framework\base\services\java\com\android\server\LocationManagerService.java**/
private void loadProvidersLocked()
{
 // create a passive location provider, which is always enabled
    PassiveProvider passiveProvider = new PassiveProvider(this);
    addProviderLocked(passiveProvider);
    mEnabledProviders.add(passiveProvider.getName());
    mPassiveProvider = passiveProvider;
    // Create a gps location provider
<5> GpsLocationProvider gpsProvider = new GpsLocationProvider(mContext, this,
            mLocationHandler.getLooper());

<6> if (GpsLocationProvider.isSupported()) //這裏調用JNI的函數接口 
    {
        mGpsStatusProvider = gpsProvider.getGpsStatusProvider(); //獲取gps狀態provider
        mNetInitiatedListener = gpsProvider.getNetInitiatedListener(); //初始網絡監聽 
        addProviderLocked(gpsProvider); //將gpsProvider添加到mProviders中
        mRealProviders.put(LocationManager.GPS_PROVIDER, gpsProvider);
    }	
}

/**分析  <5>  ***/
public class GpsLocationProvider implements LocationProviderInterface 
{
	static { class_init_native(); } //在這裏調用JNI的android_location_GpsLocationProvider_class_init_native函數
}

static void android_location_GpsLocationProvider_class_init_native(JNIEnv* env, jclass clazz) 
{
	err = module->methods->open(module, GPS_HARDWARE_MODULE_ID, &device);//打開GPS設備文件,對應trunk/Android/hardware/xxx/gps/skytraq/skytraq_gps.c
				-->static int open_gps(const struct hw_module_t *module, char const *name, struct hw_device_t **device)
				
	//獲取gpsInterface接口,該函數接口在trunk/Android/hardware/xxx/gps/skytraq/skytraq_gps.c中,對應的函數是gps__get_gps_interface
	sGpsInterface = gps_device->get_gps_interface(gps_device);
}

const GpsInterface *gps__get_gps_interface(struct gps_device_t *dev)
{
    return &skytraqGpsInterface;
}

/**分析 <6>  **/
public static boolean GpsLocationProvider.isSupported()
{
	return native_is_supported(); //該函數對應JNI的函數如下
}

static jboolean android_location_GpsLocationProvider_is_supported(JNIEnv* env, jclass clazz) 
{
    return (sGpsInterface != NULL);
}
GpsLocationProvider.isSupported()返回true,所以會走if{}裏面的。在網上查閱資料,都是基於2.3的系統,2.3的系統裏是直接在isSupported()函數裏來獲取接口,沒有在GpsLocationProvider類中實現調用class_init_native()來獲取接口

/**分析 <4> **/
/**framework\base\services\java\com\android\server\LocationManagerService.java**/
private void updateProvidersLocked() 
{
	for (int i = mProviders.size() - 1; i >= 0; i--)
	{
		boolean isEnabled = p.isEnabled(); //開始的時候返回false
		boolean shouldBeEnabled = isAllowedByCurrentUserSettingsLocked(name); //在loadProvidersLocked()函數就說了,一直是enabled
		所以會走else
		else if (!isEnabled && shouldBeEnabled)
		 {
<7>      updateProviderListenersLocked(name, true, mCurrentUserId);
         changesMade = true;
     }
	}
	/*發送廣播,app和framework都可以接受該廣播*/
	if (changesMade) {
            mContext.sendBroadcastAsUser(new Intent(LocationManager.PROVIDERS_CHANGED_ACTION),
                    UserHandle.ALL);
            mContext.sendBroadcastAsUser(new Intent(LocationManager.MODE_CHANGED_ACTION),
                    UserHandle.ALL);
  }
}

/**分析 <7>   framework\base\services\java\com\android\server\locationManagerService.java **/
private void updateProviderListenersLocked(String provider, boolean enabled, int userId) 
{
	if (records != null)
	{
		//這裏主要是從UserHandle裏解析UserId 是否等於 mCurrentUserId,如果是則發送notification給receiver  
	} 
	if (enabled) //這裏的 enabled == true
	{
<8>  p.enable();
     if (listeners > 0) 
     {
<9>       applyRequirementsLocked(provider);
     }
  }
	 else 
	 {
     p.disable();
   }
   
}

/**分析 <8>   framework\base\services\java\com\android\server\location\gpsLocationProvider.java**/
public void enable() 
{
	synchronized (mLock) 
	{
   	if (mEnabled) return;//開始的時候這裏是false
   	mEnabled = true;     
	}
<10>  sendMessage(ENABLE, 1, null);//發送消息
}
/**分析  <10>     base\services\java\com\android\server\location\gpsLocationProvider.java**/
private void sendMessage(int message, int arg, Object obj) 
{
        // hold a wake lock until this message is delivered
        // note that this assumes the message will not be removed from the queue before
        // it is handled (otherwise the wake lock would be leaked).
        mWakeLock.acquire();
<11>    mHandler.obtainMessage(message, arg, 1, obj).sendToTarget(); //通過handler機制來發送消息
}

/**分析  <11>     base\services\java\com\android\server\location\gpsLocationProvider.java**/
private final class ProviderHandler extends Handler 
{
	public void handleMessage(Message msg) 
	{
		switch (message) 
		{
    	case ENABLE:  //有<10>可知,message == ENABLE , msg.arg1 == 1
        if (msg.arg1 == 1) {   
<12>        handleEnable(); //所以會調用這個函數
        } else {
            handleDisable();
        }
        break;
    .....
    }
	}
}

/**分析  <12>     framework\base\services\java\com\android\server\location\gpsLocationProvider.java**/
private void handleEnable() 
{
<13>	boolean enabled = native_init(); //調用JNI中的 static jboolean android_location_GpsLocationProvider_init(JNIEnv* env, jobject obj)
  if (enabled) 
  {
      mSupportsXtra = native_supports_xtra(); //native_supports_xtra()直接返回true,在class_init_native()已經賦值

      if (mSuplServerHost != null) 
      {
      	/*這裏沒做任何事,因爲sAGpsInterface爲空,代碼流程如下*/
          native_set_agps_server(AGPS_TYPE_SUPL, mSuplServerHost, mSuplServerPort);
          	-->static void android_location_GpsLocationProvider_set_agps_server(JNIEnv* env, jobject obj, jint type, jstring hostname, jint port)
          		-->if (!sAGpsInterface) return;
          	-->sAGpsInterface = (const AGpsInterface*)sGpsInterface->get_extension(AGPS_INTERFACE);
          		-->static const void *skytraq_gps_get_extension(const char* name)
								{
    							ALOGD("%s: called", __FUNCTION__);
    							return NULL;
								}
				
      }
      if (mC2KServerHost != null) { //同理這裏也直接返回了
          native_set_agps_server(AGPS_TYPE_C2K, mC2KServerHost, mC2KServerPort);
      }
  }else{
      synchronized (mLock) {
          mEnabled = false;
      }
      Log.w(TAG, "Failed to enable location provider");
  }
    
}

/**分析  <13>  framework\base\services\jni\com_android_server_location_GpsLocationProvider.cpp **/
static jboolean android_location_GpsLocationProvider_init(JNIEnv* env, jobject obj)
{
<14>	if (!sGpsInterface || sGpsInterface->init(&sGpsCallbacks) != 0)//sGpsInterface不爲null,在一開始的就已賦值,所以會調用init函數
			return false;
			.....
}

/**分析  <14>   hardware\xxx\gps\skytraq\Skytraq_gps.c **/
static int skytraq_gps_init(GpsCallbacks* callbacks) //callbacks回調函數時有JNI傳下來的,在JNI中實現的
{
	GpsState*  s = &_gps_state; //該結構圖數組初始化的時候都爲0
	if (!s->init)
<15>		gps_state_init(s, callbacks);
}

/**分析  <15>   hardware\xxx\gps\skytraq\Skytraq_gps.c **/
static void gps_state_init( GpsState*  state, GpsCallbacks* callbacks )
{
	state->fd = gps_channel_open(GPS_CHANNEL_NAME);
			--> fd = open("/dev/skytraq_gps_ipc", O_RDWR |  O_SYNC); //打開串口
	int ret = ioctl(state->fd, GPS_IPC_SET, &gps_connect_info); //調用驅動函數ioctl設置gps
	state->thread = callbacks->create_thread_cb( "gps_state_thread", gps_state_thread, state );//創建線程,用來監聽發送的命令和監聽數據上報,
}


/**分析<9> frwmework\base\services\java\com\android\server\LocationManagerService.java
private void applyRequirementsLocked(String provider)
{
	//設置worksource和providerRequest
	.....
<16>	p.setRequest(providerRequest, worksource); //location provider 發送請求
}
 

/**分析<16> frwmework\base\services\java\com\android\server\location\GpsLocationProvider.java**/
public void setRequest(ProviderRequest request, WorkSource source) 
{
<17>   sendMessage(SET_REQUEST, 0, new GpsRequest(request, source)); //發送消息,SET_REQUEST == 3
}

/**分析<17> frwmework\base\services\java\com\android\server\location\GpsLocationProvider.java**/
public void handleMessage(Message msg)
{
	...
	case SET_REQUEST:
       GpsRequest gpsRequest = (GpsRequest) msg.obj;
<18>   handleSetRequest(gpsRequest.request, gpsRequest.source);
       break;
}

/**分析<18> frwmework\base\services\java\com\android\server\location\GpsLocationProvider.java**/
private void handleSetRequest(ProviderRequest request, WorkSource source) 
{
	...
<19>	startNavigating(singleShot);//開始導航
}

/**分析<19> frwmework\base\services\java\com\android\server\location\GpsLocationProvider.java**/
private void startNavigating(boolean singleShot)
{
<20>	native_set_position_mode(mPositionMode, GPS_POSITION_RECURRENCE_PERIODIC, interval, 0, 0)//該函數在HAL層直接返回了,沒做任何事
<21>	native_start()
} 

/**分析<20> framework\base\services\jni\com_android_server_location_GpsLocationProvider.cpp**/
static jboolean android_location_GpsLocationProvider_set_position_mode(JNIEnv* env, jobject obj,
        jint mode, jint recurrence, jint min_interval, jint preferred_accuracy, jint preferred_time)
{
	if (sGpsInterface)
<22>        return (sGpsInterface->set_position_mode(mode, recurrence, min_interval, preferred_accuracy, 
                preferred_time) == 0); //調用HAL層接口
}

/**分析<22> xxx\gps\skytraq\skytraq.gps.c**/
static int skytraq_gps_set_position_mode(GpsPositionMode mode,
                                      GpsPositionRecurrence recurrence,
                                      uint32_t min_interval,
                                      uint32_t preferred_accuracy,
                                      uint32_t preferred_time)
{
    ALOGD("%s: called", __FUNCTION__);
    return 0;
}
/**分析<21> framework\base\services\jni\com_android_server_location_GpsLocationProvider.cpp**/
static jboolean android_location_GpsLocationProvider_start(JNIEnv* env, jobject obj)
{
	if (sGpsInterface)
<23>		return (sGpsInterface->start() == 0); //調用HAL 層的static int skytraq_gps_start()
}

/**分析<23> xxx\gps\skytraq\skytraq.gps.c**/
static int skytraq_gps_start()
{
	gps_state_start(s);
		-->s->status = CMD_START; 
  /*在<15>線程函數gps_state_thread()中while(1)中等該命令,進入獲取數據*/
}
此時GPS就已運行
爲了保密,只好用xxx來代替
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章