Android4.4 GPS框架分析
2015-06-28 22:02
483 查看
GPS HAL层代码在目录trunk/Android/hardware/sunplus/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/sunplus/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/sunplus/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\sunplus\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\sunplus\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> sunplus\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> sunplus\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就已运行
相关文章推荐
- Android下资源使用的方式-android学习之旅(五十三)
- Android下资源使用的方式-android学习之旅(五十三)
- Android下资源使用的方式-android学习之旅(五十三)
- android开发之蓝牙配对连接的方法
- Android的Init进程简析
- Android 中保存全局变量
- android的PowerManager和PowerManager.WakeLock
- android程序入门
- android fragment+ FragmentTabHost+viewpager 切换状态不保存的问题
- android fragment+ FragmentTabHost+viewpager 切换状态不保存的问题
- android fragment+ FragmentTabHost+viewpager 切换状态不保存的问题
- android fragment+ FragmentTabHost+viewpager 切换状态不保存的问题
- android fragment+ FragmentTabHost+viewpager 切换状态不保存的问题
- android fragment+ FragmentTabHost+viewpager 切换状态不保存的问题
- Android滚动截屏,ScrollView截屏
- Android开发资源列表
- Android Studio 使用笔记
- Android中ListView相关属性
- Android OpenGL ES(八)----纹理编程框架
- android 制作倒计时遇到的问题小结