LocationManageService.java中
- private void updateProviderListenersLocked(String provider, boolean enabled) {
- ... ...
- if (enabled) {
- p.enable();
- if (listeners > 0) {
- p.setMinTime(getMinTimeLocked(provider), mTmpWorkSource);
- p.enableLocationTracking(true);
- }
- } else {
- p.enableLocationTracking(false);
- p.disable();
- }
- }
接上, 我们研究完了p.enable函数。接下去 如果有listeners ,我们去调用 p.enableLocationTracking()函数。
enableLocationTracking 在GPSLocationProvider.java中。
- public void enableLocationTracking(boolean enable) {
- // FIXME - should set a flag here to avoid race conditions with single shot request
- synchronized (mHandler) {
- sendMessage(ENABLE_TRACKING, (enable ? 1 : 0), null);
- }
- }
- public void handleMessage(Message msg) {
- int message = msg.what;
- switch (message) {
- case ENABLE:
- if (msg.arg1 == 1) {
- handleEnable();
- } else {
- handleDisable();
- }
- break;
- case ENABLE_TRACKING:
- handleEnableLocationTracking(msg.arg1 == 1);
- break;
- private void handleEnableLocationTracking(boolean enable) {
- if (enable) {
- mTTFF = 0;
- mLastFixTime = 0;
- startNavigating(false);
- } else {
- if (!hasCapability(GPS_CAPABILITY_SCHEDULING)) {
- mAlarmManager.cancel(mWakeupIntent);
- mAlarmManager.cancel(mTimeoutIntent);
- }
- stopNavigating();
- }
- }
- private void startNavigating(boolean singleShot) {
- if (!mStarted) {
- if (DEBUG) Log.d(TAG, "startNavigating");
- mStarted = true;
- mSingleShot = singleShot;
- mPositionMode = GPS_POSITION_MODE_STANDALONE;
- if (Settings.Secure.getInt(mContext.getContentResolver(),
- Settings.Secure.ASSISTED_GPS_ENABLED, 1) != 0) {
- if (singleShot && hasCapability(GPS_CAPABILITY_MSA)) {
- mPositionMode = GPS_POSITION_MODE_MS_ASSISTED;
- } else if (hasCapability(GPS_CAPABILITY_MSB)) {
- mPositionMode = GPS_POSITION_MODE_MS_BASED;
- }
- }
- int interval = (hasCapability(GPS_CAPABILITY_SCHEDULING) ? mFixInterval : 1000);
- if (!native_set_position_mode(mPositionMode, GPS_POSITION_RECURRENCE_PERIODIC,
- interval, 0, 0)) {
- mStarted = false;
- Log.e(TAG, "set_position_mode failed in startNavigating()");
- return;
- }
- if (!native_start()) {
- mStarted = false;
- Log.e(TAG, "native_start failed in startNavigating()");
- return;
- }
- // reset SV count to zero
- updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, 0);
- mFixRequestTime = System.currentTimeMillis();
- if (!hasCapability(GPS_CAPABILITY_SCHEDULING)) {
- // set timer to give up if we do not receive a fix within NO_FIX_TIMEOUT
- // and our fix interval is not short
- if (mFixInterval >= NO_FIX_TIMEOUT) {
- mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
- SystemClock.elapsedRealtime() + NO_FIX_TIMEOUT, mTimeoutIntent);
- }
- }
- }
- }
这边我中主要关注两个native函数。native_set_position_mode 和native_start!
在com_android_server_location_GpslocationProvider.cpp中找到两个对应的函数。
首先是native_set_position_mode:
- 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)
- {
- const GpsInterface* interface = GetGpsInterface(env, obj);
- if (interface)
- return (interface->set_position_mode(mode, recurrence, min_interval, preferred_accuracy,
- preferred_time) == 0);
- else
- return false;
- }
这边调用了interface->set_position_mode。我们到gps_qemu.c当中去找其相关实现
- static int qemu_gps_set_position_mode(GpsPositionMode mode, int fix_frequency)
- {
- // FIXME - support fix_frequency
- return 0;
- }
显然其中没有相关的实现。
接下去我们看native_start函数。
- static jboolean android_location_GpsLocationProvider_start(JNIEnv* env, jobject obj)
- {
- const GpsInterface* interface = GetGpsInterface(env, obj);
- if (interface)
- return (interface->start() == 0);
- else
- return false;
- }
- static int qemu_gps_start()
- {
- GpsState* s = _gps_state;
- if (!s->init) {
- D("%s: called with uninitialized state !!", __FUNCTION__);
- return -1;
- }
- D("%s: called", __FUNCTION__);
- gps_state_start(s);
- return 0;
- }
通过向底层发送命令,CMD_START来启动gps。其实这个所谓的底层就是在enable/init函数中启动的等待数据的线程。
- static void
- gps_state_start( GpsState* s )
- {
- char cmd = CMD_START;
- int ret;
- do { ret=write( s->control[0], &cmd, 1 ); }
- while (ret < 0 && errno == EINTR);
- if (ret != 1)
- D("%s: could not send CMD_START command: ret=%d: %s",
- __FUNCTION__, ret, strerror(errno));
- }
数据监听线程
- /* this is the main thread, it waits for commands from gps_state_start/stop and,
- * when started, messages from the QEMU GPS daemon. these are simple NMEA sentences
- * that must be parsed to be converted into GPS fixes sent to the framework
- */
- static void*
- gps_state_thread( void* arg )
- {
- GpsState* state = (GpsState*) arg;
- NmeaReader reader[1];
- int epoll_fd = epoll_create(2);
- int started = 0;
- int gps_fd = state->fd;
- int control_fd = state->control[1];
- nmea_reader_init( reader );
- // register control file descriptors for polling
- epoll_register( epoll_fd, control_fd );
- epoll_register( epoll_fd, gps_fd );
- D("gps thread running");
- // now loop
- for (;;) {
- struct epoll_event events[2];
- int ne, nevents;
- nevents = epoll_wait( epoll_fd, events, 2, -1 );
- if (nevents < 0) {
- if (errno != EINTR)
- LOGE("epoll_wait() unexpected error: %s", strerror(errno));
- continue;
- }
- D("gps thread received %d events", nevents);
- for (ne = 0; ne < nevents; ne++) {
- if ((events[ne].events & (EPOLLERR|EPOLLHUP)) != 0) {
- LOGE("EPOLLERR or EPOLLHUP after epoll_wait() !?");
- goto Exit;
- }
- if ((events[ne].events & EPOLLIN) != 0) {
- int fd = events[ne].data.fd;
- if (fd == control_fd)
- {
- char cmd = 255;
- int ret;
- D("gps control fd event");
- do {
- ret = read( fd, &cmd, 1 );
- } while (ret < 0 && errno == EINTR);
- if (cmd == CMD_QUIT) {
- D("gps thread quitting on demand");
- goto Exit;
- }
- else if (cmd == CMD_START) {
- if (!started) {
- D("gps thread starting location_cb=%p", state->callbacks.location_cb);
- started = 1;
- nmea_reader_set_callback( reader, state->callbacks.location_cb );
- }
- }
- else if (cmd == CMD_STOP) {
- if (started) {
- D("gps thread stopping");
- started = 0;
- nmea_reader_set_callback( reader, NULL );
- }
- }
- }
- else if (fd == gps_fd)
- {
- char buff[32];
- D("gps fd event");
- for (;;) {
- int nn, ret;
- ret = read( fd, buff, sizeof(buff) );
- if (ret < 0) {
- if (errno == EINTR)
- continue;
- if (errno != EWOULDBLOCK)
- LOGE("error while reading from gps daemon socket: %s:", strerror(errno));
- break;
- }
- D("received %d bytes: %.*s", ret, ret, buff);
- for (nn = 0; nn < ret; nn++)
- nmea_reader_addc( reader, buff[nn] );
- }
- D("gps fd event end");
- }
- else
- {
- LOGE("epoll_wait() returned unkown fd %d ?", fd);
- }
- }
- }
- }
- Exit:
- return NULL;
- }
这个监听线程最主要的一个就是nmea_reader_set_callback( )函数
其实就是注册了一个回调函数,location_cb 这个回调函数就是对底层location数据上报的回调函数。
到此
enableLocationTracking函数完成了,
也就是LocationManageService.java中
updateProviderListenersLocked的完成
也就是updateProvidersLocked的完成,
也就是loadProviders函数的完成
也就是 initialize的完成,
也就是run的完成,
也就是systemReady的完成
所以完了
阅读(1572) | 评论(0) | 转发(0) |