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来代替