Location服务分析

Location服务分析
===============================================
启动Location服务。
ServiceManager.addService(Context.LOCATION_SERVICE, new LocationManagerService(context));
new LocationManagerService
调用了  LocationManagerService类的 构造函数 LocationManagerService()
构造函数调用了
loadProviders();
LocationManagerService.java (frameworks/base/services/java/com/android/server):           
void loadProviders()
LocationManagerService.java (frameworks/base/services/java/com/android/server)
loadProvidersLocked()
LocationManagerService.java (frameworks/base/services/java/com/android/server)
_loadProvidersLocked()
LocationManagerService.java (frameworks/base/services/java/com/android/server)
private void _loadProvidersLocked() {
  // Attempt to load "real" providers first
  if (GpsLocationProvider.isSupported())
     return native_is_supported()
       native_is_supported本地调用:
       static jboolean android_location_GpsLocationProvider_is_supported(JNIEnv* env, jclass clazz)
         if (!sGpsInterface)
           sGpsInterface = gps_get_interface();
             gps_find_hardware() //获取gps接口
         return (sGpsInterface != NULL);
  {
    //创建一gpslocation provider
    mGpsLocationProvider = new GpsLocationProvider(mContext);
    LocationProviderImpl.addProvider(mGpsLocationProvider);
  }
  ...
  updateProvidersLocked();
    updateProviderListenersLocked(name,true)
      if (enabled)
        p.enable();
此处调用的是:
GpsLocationProvider.java (frameworks/base/location/java/com/android/internal/location)
中的 void enable()
  mEnabled = native_init();
    native_init 本地调用的是:
    static jboolean android_location_GpsLocationProvider_init(JNIEnv* env, jobject obj)
      if (!sGpsInterface)
        sGpsInterface = gps_get_interface();         
      return (sGpsInterface && sGpsInterface->init(&sGpsCallbacks) == 0);
      native_is_supported中调用了 gps_get_interface 所以此处的 sGpsInterface 不为NULL
  mEventThread = new GpsEventThread()
    run() //GpsLocationProvider.java (frameworks/base/location/java/com/android/internal/location)
      native_wait_for_event();
      native_wait_for_event 本地调用的是:
      void android_location_GpsLocationProvider_wait_for_event(JNIEnv* env, jobject obj)
        env->CallVoidMethod(obj, method_reportStatus, sGpsStatusCopy.status);

获取gps接口:
const GpsInterface* gps_get_interface()
{
    if (sGpsInterface == NULL)
         gps_find_hardware();
    return sGpsInterface;
}
static void gps_find_hardware( void )
{
#ifdef HAVE_QEMU_GPS_HARDWARE
    if (qemu_check()) {
        sGpsInterface = gps_get_qemu_interface();
        if (sGpsInterface) {
            LOGD("using QEMU GPS Hardware emulation/n");
            return;
        }
    }
#endif

#ifdef HAVE_GPS_HARDWARE
    sGpsInterface = gps_get_hardware_interface();
#endif
    if (!sGpsInterface)
        LOGD("no GPS hardware on this device/n");
}
因为  gps_find_hardware 没有实际的硬件,所以调用的是:
const GpsInterface* gps_get_qemu_interface()
{
    return &qemuGpsInterface;
}
因为有下面的定义:
static const GpsInterface  qemuGpsInterface = {
    qemu_gps_init,
    qemu_gps_start,
    qemu_gps_stop,
    qemu_gps_set_fix_frequency,
    qemu_gps_cleanup,
    qemu_gps_inject_time,
    qemu_gps_delete_aiding_data,
    qemu_gps_set_position_mode,
    qemu_gps_get_extension,
};
因为:
static jboolean android_location_GpsLocationProvider_init(JNIEnv* env, jobject obj)
{
    if (!sGpsInterface)
        sGpsInterface = gps_get_interface();
    return (sGpsInterface && sGpsInterface->init(&sGpsCallbacks) == 0);
}
此时执行了 :qemu_gps_init
Gps_qemu.c (hardware/libhardware_legacy/gps)
static int qemu_gps_init(GpsCallbacks* callbacks)
    GpsState*  s = _gps_state;
    if (!s->init)
        gps_state_init(s);
static void gps_state_init( GpsState*  state )
  if ( pthread_create( &state->thread, NULL, gps_state_thread, state ) != 0 )
    static void* gps_state_thread( void*  arg )
      ret = read( fd, &cmd, 1 );
      ...
      cmd == CMD_START
      nmea_reader_set_callback( reader, state->callbacks.location_cb );
因为有:
android_location_GpsLocationProvider.cpp (frameworks/base/core/jni):
GpsCallbacks sGpsCallbacks = {
    location_callback,
    status_callback,
    sv_status_callback,
};
所以  state->callbacks.location_cb 执行的是:
static void location_callback(GpsLocation* location)
{
    pthread_mutex_lock(&sEventMutex);
    //置sPendingCallbacks 标记为 kLocation
    sPendingCallbacks |= kLocation;
    memcpy(&sGpsLocation, location, sizeof(sGpsLocation));
    pthread_cond_signal(&sEventCond);
    pthread_mutex_unlock(&sEventMutex);
}

static pthread_mutex_t sEventMutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t sEventCond = PTHREAD_COND_INITIALIZER;
GpsLocationProvider.java (frameworks/base/location/java/com/android/internal/location):
因为线程  GpsEventThread 类的run函数循环调用了 native_wait_for_event,实际本地调用:
static void android_location_GpsLocationProvider_wait_for_event(JNIEnv* env, jobject obj)
{
    pthread_mutex_lock(&sEventMutex);
    //等待信号量 sEventCond 和 锁
    pthread_cond_wait(&sEventCond, &sEventMutex);
   
    //拷贝并且清除 sPendingCallbacks 表记,如果收到的信号量是由 location_callback 函数触发,
    //那么此时 sPendingCallbacks 为  kLocation
    int pendingCallbacks = sPendingCallbacks;
    sPendingCallbacks = 0;
  
    // copy everything and unlock the mutex before calling into Java code to avoid the possibility
    // of timeouts in the GPS engine.
    memcpy(&sGpsLocationCopy, &sGpsLocation, sizeof(sGpsLocationCopy));
    memcpy(&sGpsStatusCopy, &sGpsStatus, sizeof(sGpsStatusCopy));
    memcpy(&sGpsSvStatusCopy, &sGpsSvStatus, sizeof(sGpsSvStatusCopy));
    pthread_mutex_unlock(&sEventMutex); 

    //如果信号量由  location_callback 触发,那么执行 method_reportLocation 方法。
    if (pendingCallbacks & kLocation) {
        env->CallVoidMethod(obj, method_reportLocation, sGpsLocationCopy.flags,
                (jdouble)sGpsLocationCopy.latitude, (jdouble)sGpsLocationCopy.longitude,
                (jdouble)sGpsLocationCopy.altitude,
                (jfloat)sGpsLocationCopy.speed, (jfloat)sGpsLocationCopy.bearing,
                (jfloat)sGpsLocationCopy.accuracy, (jlong)sGpsLocationCopy.timestamp);
    }
    if (pendingCallbacks & kStatus) {
        env->CallVoidMethod(obj, method_reportStatus, sGpsStatusCopy.status);
    }
    if (pendingCallbacks & kSvStatus) {
        env->CallVoidMethod(obj, method_reportSvStatus);
    }
    if (pendingCallbacks & kXtraDownloadRequest) {  
        env->CallVoidMethod(obj, method_xtraDownloadRequest);
    }
    if (pendingCallbacks & kDisableRequest) {
        // don't need to do anything - we are just poking so wait_for_event will return.
    }
}

上面函数的:
env->CallVoidMethod(obj, method_reportLocation, sGpsLocationCopy.flags,
                (jdouble)sGpsLocationCopy.latitude, (jdouble)sGpsLocationCopy.longitude,
                (jdouble)sGpsLocationCopy.altitude,
                (jfloat)sGpsLocationCopy.speed, (jfloat)sGpsLocationCopy.bearing,
                (jfloat)sGpsLocationCopy.accuracy, (jlong)sGpsLocationCopy.timestamp);
由于  method_reportLocation = env->GetMethodID(clazz, "reportLocation", "(IDDDFFFJ)V");
所以实际上执行的是:
文件 GpsLocationProvider.java (frameworks/base/location/java/com/android/internal/location) 中的函数:
private void reportLocation(int flags, double latitude, double longitude, double altitude,
            float speed, float bearing, float accuracy, long timestamp)
{

}
private void reportStatus(int status)
{
  ...  
  //发送一个intent 通知 :GPS 已经被开启或者关闭。
  Intent intent = new Intent(GPS_ENABLED_CHANGE_ACTION);
  intent.putExtra(EXTRA_ENABLED, mNavigating);
  mContext.sendBroadcast(intent);
  ...
}
//called from native code to update SV info
private void reportSvStatus()
{
}

GpsLocationProvider.java (frameworks/base/location/java/com/android/internal/location)
GpsLocationProvider 类里面初始了 class_init_native
实际调用:
{"class_init_native", "()V", (void *)android_location_GpsLocationProvider_class_init_native},
static void android_location_GpsLocationProvider_class_init_native(JNIEnv* env, jclass clazz) {
    method_reportLocation = env->GetMethodID(clazz, "reportLocation", "(IDDDFFFJ)V");
    method_reportStatus = env->GetMethodID(clazz, "reportStatus", "(I)V");
    method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "()V");
    method_xtraDownloadRequest = env->GetMethodID(clazz, "xtraDownloadRequest", "()V");
}


上面的  reportStatus 发送了一个 GPS_ENABLED_CHANGE_ACTION 的 intent
mContext.sendBroadcast(intent) 实际上调用的是:
ApplicationContext.java (frameworks/base/core/java/android/app) 文件中的:
void sendBroadcast(Intent intent)
  ActivityManagerNative.getDefault().broadcastIntent(mMainThread.getApplicationThread(), intent,...)
因为有:
public abstract class ActivityManagerNative extends Binder implements IActivityManager
public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor
所以 broadcastIntent 最终执行的是文件:ActivityManagerService.java (frameworks/base/services/java/com/android/server/am)
中类  ActivityManagerService 的 broadcastIntent 函数
int broadcastIntent(IApplicationThread caller,
            Intent intent, String resolvedType, IIntentReceiver resultTo,
            int resultCode, String resultData, Bundle map,
            String requiredPermission, boolean serialized, boolean sticky)
调用:int res = broadcastIntentLocked(callerApp,callerApp != null ? callerApp.info.packageName : null,
                    intent, resolvedType, resultTo,
                    resultCode, resultData, map, requiredPermission, serialized,
                    sticky, callingPid, callingUid);
接着调用:
broadcastIntentLocked
  scheduleBroadcastsLocked()
    mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
以上完成发送一个消息。
============
以下为消息接收流程:
ActivityManagerService.java (frameworks/base/services/java/com/android/server/am)
void handleMessage(Message msg)
  case BROADCAST_INTENT_MSG:
    processNextBroadcast(true);
      BroadcastRecord r;
      ...
      BroadcastFilter filter = (BroadcastFilter)nextReceiver;
      deliverToRegisteredReceiver(r, filter, r.ordered);
        performReceive(filter.receiverList.app, filter.receiverList.receiver,new Intent(r.intent), r.resultCode,
                    r.resultData, r.resultExtras, r.ordered);
          if (app != null && app.thread != null)
            app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,data, extras, ordered);
            
          else
            receiver.performReceive(intent, resultCode, data, extras, ordered);
因为有:    
class ApplicationThreadProxy implements IApplicationThread
public abstract class ApplicationThreadNative extends Binder implements IApplicationThread
private final class ApplicationThread extends ApplicationThreadNative
所以调用的是  ActivityThread.java (frameworks/base/core/java/android/app)
ApplicationThread  类中的
void schedulePauseActivity(IBinder token, boolean finished,boolean userLeaving, int configChanges)
  receiver.performReceive(intent, resultCode, dataStr, extras, ordered);
因为有:
final static class InnerReceiver extends IIntentReceiver.Stub
void performReceive(Intent intent, int resultCode,String data, Bundle extras, boolean ordered)
  rd.performReceive(intent, resultCode, data, extras, ordered);
最终执行的是:ReceiverDispatcher 类中的  performReceive 函数
performReceive 调用了 mActivityThread.post(args)
  Args args = new Args();
  args.mCurIntent = intent;
  args.mCurCode = resultCode;
  args.mCurData = data;
  args.mCurMap = extras;
  args.mCurOrdered = ordered;
  if (!mActivityThread.post(args))
  ...
因为有 final class Args implements Runnable
  执行 Args 的run 函数,在run函数里面执行 :receiver.onReceive(mContext, intent);
 这里的 onReceive



======================================


分析文件:
hardware/libhardware_legacy/gps/Android.mk
===============================
# Use hardware GPS implementation if available.
#
ifneq ($(BOARD_GPS_LIBRARIES),)
  LOCAL_CFLAGS           += -DHAVE_GPS_HARDWARE
  LOCAL_SHARED_LIBRARIES += $(BOARD_GPS_LIBRARIES)
endif

# Use emulator GPS implementation if QEMU_HARDWARE is set.
#
USE_QEMU_GPS_HARDWARE := $(QEMU_HARDWARE)

ifeq ($(USE_QEMU_GPS_HARDWARE),true)
    LOCAL_CFLAGS    += -DHAVE_QEMU_GPS_HARDWARE
    LOCAL_SRC_FILES += gps/gps_qemu.c
endif

LOCAL_SRC_FILES += gps/gps.cpp
===============================
因为文件 hardware/libhardware_legacy/Android.mk 中有:
ifneq ($(TARGET_SIMULATOR),true)
  LOCAL_CFLAGS  += -DQEMU_HARDWARE
  QEMU_HARDWARE := true
endif
当编译的是模拟器版本的时候 QEMU_HARDWARE 为true,所以使用的是模拟的gps调用。
如果编译相关的硬件版本,那么必须给 BOARD_GPS_LIBRARIES 赋值,因为从语句:
LOCAL_SHARED_LIBRARIES += $(BOARD_GPS_LIBRARIES) 可以看出,变量
BOARD_GPS_LIBRARIES 指定的应该是一个库的名称,通常为 libgps,也可以自定义
对于变量 BOARD_GPS_LIBRARIES 我们可以在文件:
vendor/marvell/littleton/BoardConfig.mk
或者
vendor/htc/dream-open/BoardConfig.mk
里面进行指定。
BOARD_GPS_LIBRARIES := libgps librpc
BOARD_GPS_LIBRARIES := libgps
指定变量 BOARD_GPS_LIBRARIES 表明我们依赖的是外部库 libgps.so,所以我们还必须
准备一个libgps.so 库,由它完成实际的gps调用。http://koudai.360.cn/
========================
libgps.so 是gps接口:
./hardware/libhardware_legacy/include/hardware_legacy/gps.h
的实现,所以根据不同的硬件,libgps.so的实现方式是不一样的,但是接口一致。
关于怎样添加一个 gps 库,可以参考文档:
http://www.netmite.com/android/mydroid/cupcake/development/pdk/docs/gps.html
========================
http://linux.die.net/man/3/libgps
参考文档:
BOARD_GPS_LIBRARIES := libgps
BOARD_GPS_LIBRARIES := libgps librpc
--- freedroid.orig/vendor/htc/dream/BoardConfig.mk
+++ freedroid/vendor/htc/dream/BoardConfig.mk
@@ -13,7 +13,8 @@ HAVE_CUSTOM_WIFI_DRIVER_2 := true
http://groups.fsf.org/wiki/Hardware/Replicant
补充信息:
target thumb C: libgps <= hardware/bbk/libgps/MyGpsLibrary.c
target thumb C: librpc <= hardware/bbk/librpc/svc.c
target SharedLib: libgps (out/target/product/littleton/obj/SHARED_LIBRARIES/libgps_intermediates/LINKED/libgps.so)
target StaticLib: librpc (out/target/product/littleton/obj/STATIC_LIBRARIES/librpc_intermediates/librpc.a)
target SharedLib: librpc (out/target/product/littleton/obj/SHARED_LIBRARIES/librpc_intermediates/LINKED/librpc.so)
target Prelink: libgps (out/target/product/littleton/symbols/system/lib/libgps.so)
target Prelink: librpc (out/target/product/littleton/symbols/system/lib/librpc.so)
target Strip: librpc (out/target/product/littleton/obj/lib/librpc.so)
target Strip: libgps (out/target/product/littleton/obj/lib/libgps.so)
Install: out/target/product/littleton/system/lib/librpc.so
target SharedLib: libhardware_legacy (out/target/product/littleton/obj/SHARED_LIBRARIES/libhardware_legacy_intermediates/LINKED/libhardware_legacy.so)
Install: out/target/product/littleton/system/lib/libgps.so

===============================

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蜡台

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值