android gps機制分析--之二
1,概述
在android系統中,GPS對應的系統服務為LocationManagerService,本文主要論述LocationManagerService服務的啟動以及初始化過程。
SystemServer.java的startOtherServices方法中新增LocationManagerService方法的程式碼如下,
location = new LocationManagerService(context);
ServiceManager.addService(Context.LOCATION_SERVICE, location);
apk中獲取gps服務代理的程式碼如下,
mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
當然, LocationManager只是系統服務的一個代理。
新增gps服務到系統之後, SystemServer.java的startOtherServices方法中
locationF.systemRunning();
呼叫LocationManagerService的systemRunning方法,完成LocationManagerService服務的初始化。
2, 回撥方法的實現
當然在呼叫systemRunning之前,在新增到系統過程中,會呼叫LocationManagerService的構造方法,構造方法如下,
mContext = context; //傳入系統服務程式上下文
systemRunning方法中會呼叫loadProvidersLocked方法,
loadProvidersLocked();
updateProvidersLocked();
loadProvidersLocked方法主要是新增裝置上支援的GPS定位Provider,
if (GpsLocationProvider.isSupported()) {
// Create a gps location provider
GpsLocationProvider gpsProvider = new GpsLocationProvider(mContext, this,
mLocationHandler.getLooper());
mGpsStatusProvider = gpsProvider.getGpsStatusProvider();
mNetInitiatedListener = gpsProvider.getNetInitiatedListener();
addProviderLocked(gpsProvider);
mRealProviders.put(LocationManager.GPS_PROVIDER, gpsProvider);
mGpsMeasurementsProvider = gpsProvider.getGpsMeasurementsProvider();
mGpsNavigationMessageProvider = gpsProvider.getGpsNavigationMessageProvider();
mGpsGeofenceProxy = gpsProvider.getGpsGeofenceProxy();
}
裝置如果支援GpsLocationProvider,就會新建GpsLocationProvider物件,然後新增到mProviders和mProvidersByName等list中。
在這裡分為3個步驟,
1, isSupported方法的判斷。
2, updateProvidersLocked方法。
在這個章節,主要論述回撥方法的實現以及isSupported方法,下個章節論述updateProvidersLocked方法。在GpsLocationProvider的構造方法和isSupported之前,會呼叫class_init_native方法,
static { class_init_native(); }
該方法是一個native方法,
private static native void class_init_native();
GpsLocationProvider.java對應的C/C++檔案為com_android_server_location_GpsLocationProvider.cpp。
2.1 Framework呼叫JNI層方法
GpsLocationProvider.java中呼叫的native方法較多,部分如下,
com_android_server_location_GpsLocationProvider.cpp的sMethods中詳細的列舉了對應的native方法,部分如下,
{"class_init_native", "()V", (void *)android_location_GpsLocationProvider_class_init_native},
{"native_is_supported", "()Z", (void*)android_location_GpsLocationProvider_is_supported},
{"native_is_agps_ril_supported", "()Z", (void*)android_location_GpsLocationProvider_is_agps_ril_supported},
•••
這樣Java上層就可以通過JNI呼叫natvie的方法了。
2.2 JNI層呼叫Framework方法
com_android_server_location_GpsLocationProvider還定義著對GpsLocationProvide.java的回撥方法。部分定義如下,
static jmethodID method_reportLocation;
static jmethodID method_reportStatus;
static jmethodID method_reportSvStatus;
•••
這些回撥方法都在android_location_GpsLocationProvider_class_init_native方法中進行賦值,部分程式碼如下,
method_reportLocation = env->GetMethodID(clazz, "reportLocation", "(IDDDFFFJ)V");
method_reportStatus = env->GetMethodID(clazz, "reportStatus", "(I)V");
method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "()V");
•••
因此,method_reportLocation 對應GpsLocationProvide.java的reportLocation方法。
這樣com_android_server_location_GpsLocationProvider就可以回撥Java方法了。
2.3 JNI層呼叫gps庫方法
com_android_server_location_GpsLocationProvider的class_init_native方法中獲取gps.so庫中的sGpsInterface結構程式碼如下,
hw_module_t* module;
err = hw_get_module(GPS_HARDWARE_MODULE_ID, (hw_module_t const**)&module);
if (err == 0) {
hw_device_t* device;
err = module->methods->open(module, GPS_HARDWARE_MODULE_ID, &device);
if (err == 0) {
gps_device_t* gps_device = (gps_device_t *)device;
sGpsInterface = gps_device->get_gps_interface(gps_device);
}
}
首先呼叫hw_get_module方法載入gps相關的so庫,獲取hw_module_t結構體。
然後利用該結構體開啟so庫,獲取hw_device_t結構體,
最後利用hw_device_t結構體獲取GpsInterface結構體。
這樣,com_android_server_location_GpsLocationProvider就可以通過GpsInterface結構體呼叫so庫中的方法了。
根據 HAL 載入so文章分析,
GpsInterface結構體指向hardware\qcom\gps\loc_api\libloc_api_50001中loc.cpp的sLocEngInterface。
除了GpsInterface結構體之外,so庫中還定義了其他大量的結構體(包含回撥方法以及變數供上層呼叫),
因此com_android_server_location_GpsLocationProvider還需要獲取,
static const GpsInterface* sGpsInterface = NULL;
static const GpsXtraInterface* sGpsXtraInterface = NULL;
static const AGpsInterface* sAGpsInterface = NULL;
static const GpsNiInterface* sGpsNiInterface = NULL;
static const GpsDebugInterface* sGpsDebugInterface = NULL;
static const AGpsRilInterface* sAGpsRilInterface = NULL;
static const GpsGeofencingInterface* sGpsGeofencingInterface = NULL;
static const GpsMeasurementInterface* sGpsMeasurementInterface = NULL;
static const GpsNavigationMessageInterface* sGpsNavigationMessageInterface = NULL;
static const GnssConfigurationInterface* sGnssConfigurationInterface = NULL;
這些結構體都通過GpsInterface的get_extension方法獲取,不同方法只是以字元區分,
sGpsXtraInterface = (const GpsXtraInterface*)sGpsInterface->get_extension(GPS_XTRA_INTERFACE);
•••
這些字元都定義在gps.h檔案中,
#define GPS_XTRA_INTERFACE "gps-xtra"
#define GPS_DEBUG_INTERFACE "gps-debug"
#define AGPS_INTERFACE "agps"
•••
loc.cpp的loc_get_extension方法如下,
const void* loc_get_extension(const char* name)
{
ENTRY_LOG();
const void* ret_val = NULL;
LOC_LOGD("%s:%d] For Interface = %s\n",__func__, __LINE__, name);
if (strcmp(name, GPS_XTRA_INTERFACE) == 0)
{
ret_val = &sLocEngXTRAInterface;
}
else if (strcmp(name, AGPS_INTERFACE) == 0)
{
ret_val = &sLocEngAGpsInterface;
}
•••
EXIT_LOG(%p, ret_val);
return ret_val;
}
根據不同的字元返回不同的結構體。
這些結構體和GpsInterface完全一樣,在gps.h檔案中定義,然後在loc.cpp中實現。
這樣, com_android_server_location_GpsLocationProvider就可以通過這些結構體呼叫so庫中的方法了。
2.4 gps庫呼叫JNI層方法
com_android_server_location_GpsLocationProvider.cpp中定義了一些gps庫調回撥的結構體,
例如sGpsCallbacks,主要是gps庫中上傳資料的資訊,定義如下,
GpsCallbacks sGpsCallbacks = {
sizeof(GpsCallbacks),
location_callback,
status_callback,
sv_status_callback,
nmea_callback,
set_capabilities_callback,
acquire_wakelock_callback,
release_wakelock_callback,
create_thread_callback,
request_utc_time_callback,
};
這些結構體在gps庫中也都有對應的結構體,相當於JNI到so庫中的一個轉換。
都是通過android_location_GpsLocationProvider_init方法中呼叫gps庫中sGpsInterface/ sGpsXtraInterface
等結構體的init方法傳遞到so庫中。部分程式碼如下,
if (!sGpsInterface || sGpsInterface->init(&sGpsCallbacks) != 0)
return JNI_FALSE;
if (sGpsXtraInterface && sGpsXtraInterface->init(&sGpsXtraCallbacks) != 0)
sGpsXtraInterface = NULL;
if (sAGpsInterface)
sAGpsInterface->init(&sAGpsCallbacks);
•••
gps庫中gps.h對應的GpsCallbacks定義如下,
typedef struct {
/** set to sizeof(GpsCallbacks) */
size_t size;
gps_location_callback location_cb;
gps_status_callback status_cb;
gps_sv_status_callback sv_status_cb;
gps_nmea_callback nmea_cb;
gps_set_capabilities set_capabilities_cb;
gps_acquire_wakelock acquire_wakelock_cb;
gps_release_wakelock release_wakelock_cb;
gps_create_thread create_thread_cb;
gps_request_utc_time request_utc_time_cb;
} GpsCallbacks;
因此,gps庫中呼叫location_cb方法就是相當於呼叫JNI的location_callback方法,其他的結構體方法也完全相同,都是一一對應。
這樣,gps庫就可以回撥JNI層的方法了。
最後,GpsLocationProvider的isSupported也是一個native方法,
public static boolean isSupported() {
return native_is_supported();
}
JNI中的android_location_GpsLocationProvider_is_supported方法如下,
static jboolean android_location_GpsLocationProvider_is_supported(
JNIEnv* /* env */, jclass /* clazz */)
{
return (sGpsInterface != NULL) ? JNI_TRUE : JNI_FALSE;
}
如果可以開啟so庫,獲取sGpsInterface結構體就說明支援GPS,否則就不支援。
其實, com_android_server_location_GpsLocationProvide只是Framework和HAL之間的一個橋樑。
相關文章
- android gps機制分析--定位資料HAL處理Android
- Android IPC 機制分析Android
- 【MySQL】InnoDB鎖機制之二MySql
- Android 原始碼分析(二)handler 機制Android原始碼
- Android Handler機制使用,原始碼分析Android原始碼
- Android訊息機制原始碼分析Android原始碼
- android 4.0 藍芽分析之二Android藍芽
- android的TouchEvent派發機制的分析Android
- 【Android原始碼】Handler 機制原始碼分析Android原始碼
- Android 的 Handler 機制實現原理分析Android
- android的視窗機制分析------ViewRoot類AndroidView
- 原始碼分析:Android訊息處理機制原始碼Android
- android的視窗機制分析------事件處理Android事件
- 【Android原始碼】Binder機制和AIDL分析Android原始碼AI
- Android後臺殺死系列之二:ActivityManagerService與App現場恢復機制AndroidAPP
- Handler 機制分析
- 基於原始碼分析 Android View 繪製機制原始碼AndroidView
- android的視窗機制分析------UI管理系統AndroidUI
- Android 原始碼分析之旅3 1 訊息機制原始碼分析Android原始碼
- Android的GPS定位Android
- web安全機制問題詳解之二:CSRFWeb
- Android混淆機制Android
- Android 事件機制Android事件
- Android 安全機制Android
- 基於原始碼分析 Android View 事件分發機制原始碼AndroidView事件
- 「Android」分析EventBus原始碼擴充套件Weex事件機制Android原始碼套件事件
- View事件機制分析View事件
- Mysql鎖機制分析MySql
- 開啟android的gpsAndroid
- Java 虛擬機器之二:Java語言的執行機制Java虛擬機
- android中反射機制Android反射
- Android Classloader機制Android
- Android包管理機制Android
- Android簽名機制Android
- Android Framework : Alarm 機制AndroidFramework
- Android Handler機制理解Android
- android: 廣播機制Android
- 理解Android安全機制Android