2.3
在SystemServer.java的init2函数中启动了一个线程来注册Android的诸多服务,如:Bluetooth Service,NetworkManagement Service,Notification Manager等,当然也包括Location Service。
systemServer.java [framework/base/services/java/com/android/server]
- public static final void init2() {
- Slog.i(TAG, "Entered the Android system server!");
- Thread thr = new ServerThread();
- thr.setName("android.server.ServerThread");
- thr.start();
- }
在ServerThread线程的run函数中LocationManager服务的代码段如下:
- try {
- Slog.i(TAG, "Location Manager");
- location = new LocationManagerService(context);
- ServiceManager.addService(Context.LOCATION_SERVICE, location);
- } catch (Throwable e) {
- Slog.e(TAG, "Failure starting Location Manager", e);
- }
在run函数的后半部分,是服务对系统的反馈,就是systemReady()函数。 LocationManager服务的反馈函数如下:
- final LocationManagerService locationF = location;
其中的locationF 是LocationManagerService的final类型,就是一旦赋值,不能更改。
- if (locationF != null) locationF.systemReady();
下面我们来看看2.3的 LocationManagerService 构造函数。
- /**
- * @param context the context that the LocationManagerService runs in
- */
- public LocationManagerService(Context context) {
- super();
- mContext = context;
- Resources resources = context.getResources();
- mNetworkLocationProviderPackageName = resources.getString(
- com.android.internal.R.string.config_networkLocationProvider);
- mGeocodeProviderPackageName = resources.getString(
- com.android.internal.R.string.config_geocodeProvider);
- mPackageMonitor.register(context, true);
- if (LOCAL_LOGV) {
- Slog.v(TAG, "Constructed LocationManager Service");
- }
- }
以下为2.2
- public LocationManagerService(Context context) {
- super();
- mContext = context;
- if (LOCAL_LOGV) {
- Slog.v(TAG, "Constructed LocationManager Service");
- }
- }
然后我们再看SystemReady()
- void systemReady() {
- // we defer starting up the service until the system is ready
- Thread thread = new Thread(null, this, "LocationManagerService");
- thread.start();
- }
在这个函数当中,我们创建了一个新线程。然后start之。
因此我们的视线也随之跟随到run函数里面。
- public void run()
- {
- Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
- Looper.prepare();
- mLocationHandler = new LocationWorkerHandler();
- initialize();
- Looper.loop();
- }
在run函数中,又调用了initialize 函数
- private void initialize() {
- // Create a wake lock, needs to be done before calling loadProviders() below
- PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
- mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_KEY);
- // Load providers
- loadProviders();
- // Register for Network (Wifi or Mobile) updates
- IntentFilter intentFilter = new IntentFilter();
- intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
- // Register for Package Manager updates
- intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
- intentFilter.addAction(Intent.ACTION_PACKAGE_RESTARTED);
- intentFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
- mContext.registerReceiver(mBroadcastReceiver, intentFilter);
- IntentFilter sdFilter = new IntentFilter(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
- mContext.registerReceiver(mBroadcastReceiver, sdFilter);
- // listen for settings changes
- ContentResolver resolver = mContext.getContentResolver();
- Cursor settingsCursor = resolver.query(Settings.Secure.CONTENT_URI, null,
- "(" + Settings.System.NAME + "=?)",
- new String[]{Settings.Secure.LOCATION_PROVIDERS_ALLOWED},
- null);
- mSettings = new ContentQueryMap(settingsCursor, Settings.System.NAME, true, mLocationHandler);
- SettingsObserver settingsObserver = new SettingsObserver();
- mSettings.addObserver(settingsObserver);
- }
初始化函数中,最重要的便是 loadProviders()函数。
- private void loadProviders() {
- synchronized (mLock) {
- if (sProvidersLoaded) {
- return;
- }
- // Load providers
- loadProvidersLocked();
- sProvidersLoaded = true;
- }
- }
loadProvidersLocked函数
- private void loadProvidersLocked() {
- try {
- _loadProvidersLocked();
- } catch (Exception e) {
- Slog.e(TAG, "Exception loading providers:", e);
- }
- }
_loadProvidersLocked函数
- private void _loadProvidersLocked() {
- // Attempt to load "real" providers first
- if (GpsLocationProvider.isSupported()) {
- // Create a gps location provider
- GpsLocationProvider gpsProvider = new GpsLocationProvider(mContext, this);
- mGpsStatusProvider = gpsProvider.getGpsStatusProvider();
- mNetInitiatedListener = gpsProvider.getNetInitiatedListener();
- addProvider(gpsProvider);
- mGpsLocationProvider = gpsProvider;
- }
- ...
- ...
- updateProvidersLocked();
- }
首先,我们看GpsLocationProvider.isSupported 这个函数, 这个函数很重要,我们跟进这个函数可以看到, 因为在这个语句中得到了HAL层的GPS接口GpsInterface。就是通过调用GpsLocationProvider的isSupported()函数才调用到gps.cpp[hardware/libhardware_legacy/gps]中的gps_get_interface()。这个isSupported函数才是第一个吃螃蟹的人。(而不是JNI层的init函数,这个下面会提到)。
- public static boolean isSupported() {
- return native_is_supported();
- }
函数中只有一句话, 这调用了native方法,既Jni层定义的方法。native_is_supported对应在
framework/base/services/jni/com_android_server_location_GpsLocationProvider.cpp文件中的android_location_GpsLocationProvider_is_supported方法。
- static jboolean android_location_GpsLocationProvider_is_supported(JNIEnv* env, jclass clazz) {
- return (sGpsInterface != NULL || get_gps_interface() != NULL);
- }
这里的get_gps_interface指的是本文件中
- static const GpsInterface* get_gps_interface() {
- int err;
- hw_module_t* module;
- const GpsInterface* interface = NULL;
- 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;
- interface = gps_device->get_gps_interface(gps_device);
- }
- }
- return interface;
- }
而在该get_gps_interface中,去打开模组,之后打开设备,然后通过设备区调用HAL层中的get_gps_interface(gps_device)。
在gps.c(hardware/qcom/gps/loc_api/libloc_api)文件中实现的gps__get_gps_interface调用了loc_eng.cpp里面的 get_gps_interface 接口。
- extern "C" const GpsInterface* get_gps_interface()
- {
- return &sLocEngInterface;
- }
- static const GpsInterface sLocEngInterface =
- {
- sizeof(GpsInterface),
- loc_eng_init,
- loc_eng_start,
- loc_eng_stop,
- loc_eng_cleanup,
- loc_eng_inject_time,
- loc_eng_inject_location,
- loc_eng_delete_aiding_data,
- loc_eng_set_position_mode,
- loc_eng_get_extension,
- };
到这里为止, 一句简单的isSupported()执行的内容终于告一段落了。 我们获取到了GPS 的接口。在上面的LocationManagerService.java中, 如果找到gps硬件,并获取了接口则我们据悉执行isSupported()的下一句。
- GpsLocationProvider gpsProvider = new GpsLocationProvider(mContext, this);
注意GpsLocationProvider构造函数里面的两个参数:mContext, this。下面来看看GpsLocationProvider的构造函数的前面几句:
- public GpsLocationProvider(Context context, ILocationManager locationManager) {
- mContext = context;
- mLocationManager = locationManager;
- mNIHandler = new GpsNetInitiatedHandler(context, this);
- ...
- }
接着看_loadProvidersLocked函数。
- private void _loadProvidersLocked() {
- // Attempt to load "real" providers first
- if (GpsLocationProvider.isSupported()) {
- // Create a gps location provider
- GpsLocationProvider gpsProvider = new GpsLocationProvider(mContext, this);
- mGpsStatusProvider = gpsProvider.getGpsStatusProvider();
- mNetInitiatedListener = gpsProvider.getNetInitiatedListener();
- addProvider(gpsProvider);
- mGpsLocationProvider = gpsProvider;
- }
- // create a passive location provider, which is always enabled
- PassiveProvider passiveProvider = new PassiveProvider(this);
- addProvider(passiveProvider);
- mEnabledProviders.add(passiveProvider.getName());
- // initialize external network location and geocoder services
- if (mNetworkLocationProviderPackageName != null) {
- mNetworkLocationProvider =
- new LocationProviderProxy(mContext, LocationManager.NETWORK_PROVIDER,
- mNetworkLocationProviderPackageName, mLocationHandler);
- addProvider(mNetworkLocationProvider);
- }
- if (mGeocodeProviderPackageName != null) {
- mGeocodeProvider = new GeocoderProxy(mContext, mGeocodeProviderPackageName);
- }
- updateProvidersLocked();
- }
在构造完GpsLocationProvider之后将其add到全局变量ArrayList<LocationProviderInterface> mProviders中,备以后调用。
PassiveProvider暂时未了解到其用意。
然后启动了nerwork location和geocoder 两个service。但是可惜的是这两个服务都无法启动,因为他们是通过配置文件conifg.xml [framework/base/core/res/res/values]得到服务的名字,然后启动服务的。但是在这个配置文件中,两个服务的名字都是null。
conifg.xml [framework/base/core/res/res/values]
<!-- Component name of the service providing network location support. --> |
其实这也导致了,在调用GetFromLocationName和GetFromLocation两个函数时提示“Service not Available”,这个是google Android 2.2中就存在的bug。
_loadProvidersLocked函数的最后一句是调用updateProvidersLocked函数,仍然在LocationManagerServic.java文件中。
2.3:
- private void updateProvidersLocked() {
- boolean changesMade = false;
- for (int i = mProviders.size() - 1; i >= 0; i--) {
- LocationProviderInterface p = mProviders.get(i);
- boolean isEnabled = p.isEnabled();
- String name = p.getName();
- boolean shouldBeEnabled = isAllowedBySettingsLocked(name);
- if (isEnabled && !shouldBeEnabled) {
- updateProviderListenersLocked(name, false);
- changesMade = true;
- } else if (!isEnabled && shouldBeEnabled) {
- updateProviderListenersLocked(name, true);
- changesMade = true;
- }
- }
- if (changesMade) {
- mContext.sendBroadcast(new Intent(LocationManager.PROVIDERS_CHANGED_ACTION));
- }
- }
依靠前面的代码我们可以推测在mProviders里面应该存在一个gpsProvider 和PassiveProvider,而gpsProvider是未被enable的。而passiveProvider是enable的。
这边我们对gpsProvider进行讨论,他执行的是updateProviderListenersLocked(name,true) 然后当有发生改变,就是changesMade=true时,它发送了广播,内容是告诉大家LocationManager发生了变化,让需要的接收者自己接收。
下面我们跟进updateProviderListenersLocked(name,true)函数。
在LocationManagerService.java文件中
- private void updateProviderListenersLocked(String provider, boolean enabled) {
- int listeners = 0;
- LocationProviderInterface p = mProvidersByName.get(provider);
- if (p == null) {
- return;
- }
- ArrayList<Receiver> deadReceivers = null;
- ArrayList<UpdateRecord> records = mRecordsByProvider.get(provider);
- if (records != null) {
- final int N = records.size();
- for (int i=0; i<N; i++) {
- UpdateRecord record = records.get(i);
- // Sends a notification message to the receiver
- if (!record.mReceiver.callProviderEnabledLocked(provider, enabled)) {
- if (deadReceivers == null) {
- deadReceivers = new ArrayList<Receiver>();
- }
- deadReceivers.add(record.mReceiver);
- }
- listeners++;
- }
- }
- if (deadReceivers != null) {
- for (int i=deadReceivers.size()-1; i>=0; i--) {
- removeUpdatesLocked(deadReceivers.get(i));
- }
- }
- if (enabled) {
- p.enable();
- if (listeners > 0) {
- p.setMinTime(getMinTimeLocked(provider), mTmpWorkSource);
- p.enableLocationTracking(true);
- }
- } else {
- p.enableLocationTracking(false);
- p.disable();
- }
- }
这边我们看if(enable)内的主题部分。 enable为真, 则启动了GPS服务。然后执行p.enable()函数。
enable()函数在GPSLocationProvider.java中
- /**
- * Enables this provider. When enabled, calls to getStatus()
- * must be handled. Hardware may be started up
- * when the provider is enabled.
- */
- public void enable() {
- synchronized (mHandler) {
- sendMessage(ENABLE, 1, null);
- }
- }
- private void sendMessage(int message, int arg, Object obj) {
- // hold a wake lock while messages are pending
- synchronized (mWakeLock) {
- mPendingMessageBits |= (1 << message);
- mWakeLock.acquire();
- mHandler.removeMessages(message);
- Message m = Message.obtain(mHandler, message);
- m.arg1 = arg;
- m.obj = obj;
- mHandler.sendMessage(m);
- }
- }
我们看到enable函数中只是调用了sendMessage。 跟进函数,可看到sendMessage函数,首先做的是把相关的消息标志位给设置位。而后获取mWakeLock ?这边有点疑问,之前进入本段代码的时候不是获取了mWakeLock了? 然后将上一次的相关消息删除,重新构造心的消息,让后发送给mHandler。
收到消息后,Hnadler会自动去调用handleMessage去处理收到的消息。
- public void handleMessage(Message msg) {
- int message = msg.what;
- switch (message) {
- case ENABLE:
- if (msg.arg1 == 1) {
- handleEnable();
- } else {
- handleDisable();
- }
- break;
- ...
根据构造的消息,我们将执行hanleEnable()。
- private void handleEnable() {
- if (DEBUG) Log.d(TAG, "handleEnable");
- if (mEnabled) return;
- mEnabled = native_init();
- if (mEnabled) {
- mSupportsXtra = native_supports_xtra();
- if (mSuplServerHost != null) {
- native_set_agps_server(AGPS_TYPE_SUPL, mSuplServerHost, mSuplServerPort);
- }
- if (mC2KServerHost != null) {
- native_set_agps_server(AGPS_TYPE_C2K, mC2KServerHost, mC2KServerPort);
- }
- } else {
- Log.w(TAG, "Failed to enable location provider");
- }
- }
这边handleEnable函数主要做了两件事。
1.调用JNI层的native_init()方法去初始化GPS。
2.试图启动agps服务。
我们先看第一件事。在com_android_server_location_GPSLocationProvider.cpp可以找到JNI层的相关实现
- static jboolean android_location_GpsLocationProvider_init(JNIEnv* env, jobject obj)
- {
- const GpsInterface* interface = GetGpsInterface(env, obj);
- if (!interface)
- return false;
- if (!sGpsDebugInterface)
- sGpsDebugInterface = (const GpsDebugInterface*)interface->get_extension(GPS_DEBUG_INTERFACE);
- return true;
- }
这边调用了GetGpsInterface去获取接口并初始化GPS。 后半部分试图去调用其相关的扩展接口。
- static const GpsInterface* GetGpsInterface(JNIEnv* env, jobject obj) {
- // this must be set before calling into the HAL library
- if (!mCallbacksObj)
- mCallbacksObj = env->NewGlobalRef(obj);
- if (!sGpsInterface) {
- sGpsInterface = get_gps_interface();
- if (!sGpsInterface || sGpsInterface->init(&sGpsCallbacks) != 0) {
- sGpsInterface = NULL;
- return NULL;
- }
- }
- return sGpsInterface;
- }
GetGpsInterface里面也去调用了get_gps_interface(),而这个函数前面也有提到,最早的地方便是isSupported()的这个函数。在获取了这个接口之后,使用sGpsInterface->init函数进行了初始化。
在gps_qemu.c中(模拟器中)
- static int
- qemu_gps_init(GpsCallbacks* callbacks)
- {
- GpsState* s = _gps_state;
- if (!s->init)
- gps_state_init(s);
- if (s->fd < 0)
- return -1;
- s->callbacks = *callbacks;
- return 0;
- }
这边qemu_gps_init函数即是sGpsInterface->init函数,其中里面做了gps_state_init初始化,并注册了callbacks回调函数,而这个函数也是在JNI层实现的,而且有JNI层传下来的函数。
- static void
- gps_state_init( GpsState* state )
- {
- state->init = 1;
- state->control[0] = -1;
- state->control[1] = -1;
- state->fd = -1;
- state->fd = qemud_channel_open(QEMU_CHANNEL_NAME);
- if (state->fd < 0) {
- D("no gps emulation detected");
- return;
- }
- D("gps emulation will read from '%s' qemud channel", QEMU_CHANNEL_NAME );
- if ( socketpair( AF_LOCAL, SOCK_STREAM, 0, state->control ) < 0 ) {
- LOGE("could not create thread control socket pair: %s", strerror(errno));
- goto Fail;
- }
- if ( pthread_create( &state->thread, NULL, gps_state_thread, state ) != 0 ) {
- LOGE("could not create gps thread: %s", strerror(errno));
- goto Fail;
- }
- D("gps state initialized");
- return;
- Fail:
- gps_state_done( state );
- }
在这个gps_state_init函数中,首先打开串口,然后建立socket通信,然后建立线程监听底层数据上报,分别对应于代码中黄低部分。
我们顺便看到qemu_gps_get_extension 函数,
- static const void*
- qemu_gps_get_extension(const char* name)
- {
- // no extensions supported
- return NULL;
- }
这是一个空函数,说明初始化的时候调用的相关扩展接口是没有用的。
在Android2.2中,handleEnable还做了一件事情,就是创建了一个监听线程 。
而android2.3中,在GPSlocationProvider构造的时候就创建了一个线程。
- public GpsLocationProvider(Context context, ILocationManager locationManager) {
- ... ...
- // wait until we are fully initialized before returning
- mThread = new GpsLocationProviderThread();
- mThread.start();
- while (true) {
- try {
- mInitializedLatch.await();
- break;
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- }
- }
- }
查看run函数相关内容:
- public void run() {
- Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
- initialize();
- Looper.prepare();
- mHandler = new ProviderHandler();
- // signal when we are initialized and ready to go
- mInitializedLatch.countDown();
- Looper.loop();
- }
run函数去调用了 initialize初始化函数,然后新建一个looper,新建一个providerHandler 用于处理该线程的消息。然后看是否初始化完成。然后进入消息循环,准备收发,处理消息。
- private void initialize() {
- // register our receiver on our thread rather than the main thread
- IntentFilter intentFilter = new IntentFilter();
- intentFilter.addAction(ALARM_WAKEUP);
- intentFilter.addAction(ALARM_TIMEOUT);
- mContext.registerReceiver(mBroadcastReciever, intentFilter);
- }
初始化主要是将线程的接收者注册到我们的线程上,而不是注册到主线程上。
到这边为止我们完成了 p.enable()函数的分析。