前回のエントリで見た位置情報関連クラスは以下の通りです。
- Address
- Criteria
- Geocoder
- GpsSatelite
- GpsStatus
- Location
- LocationManager
- LocationProvider
さて、この中で真っ先に取得するのは、LocationManager [ frameworks/base/location/java/android/location/LocationManager.java ]
でした。LocationManagerは、Binderを使ってSystem Location Service(LocationManagerService)へアクセスするためのクラスのようです。
実体は、ContextImplクラスのstaticブロックで生成・登録されています。
[src] frameworks/base/core/java/android/app/ContextImpl.java
registerService(LOCATION_SERVICE, new StaticServiceFetcher() {
public Object createStaticService() {
IBinder b = ServiceManager.getService(LOCATION_SERVICE);
return new LocationManager(ILocationManager.Stub.asInterface(b));
}});
というわけで、ここでPF部として目を付けなくてはならないのは、LocationManagerServiceですね。で、このLocationManagerServiceが生成されているのは何処か?というと、いつか何処かでみた場所なんですね。この辺りはPF部でも発表してますし、さらっと呼び出しだけ見ておきましょう。
SystemServer::init2()
ServerThread::start()
ServerThread::run() [frameworks/base/services/java/com/android/server/SystemServer.java]
location = new LocationManagerService(context);
ServiceManager.addService(Context.LOCATION_SERVICE, location);
final LocationManagerService locationF = location;
locationF.systemReady(); [frameworks/base/services/java/com/android/server/LocationManagerService.java]
Thread thread = new Thread(null, this, "LocationManagerService");
thread.start();
注: 例によって上記はC++チックなメソッド名の表記をしているだけです。
init周りを追いかけた時にでてきたSystemServerのServerThread中で生成され、LocationManagerServiceスレッドがstartされています。
public void LocationManagerService::run()
{
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
Looper.prepare();
mLocationHandler = new LocationWorkerHandler();
initialize();
Looper.loop();
}
Runされると、initialize処理を行った後、Looperでまわしています。このLocationManagerService::initialize()の中で、呼んでいるLocationManagerSerivce::loadProviders()でAndroid共通のProviderの生成と登録、Geocoderの生成が行われています。
LocationManagerService::loadProviders()
LocationManagerService::loadProvidersLocked()
LocationManagerService::_loadProvidersLocked()
{
if (GpsLocationProvider.isSupported()) {
GpsLocationProvider gpsProvider = new GpsLocationProvider(mContext, this);
mGpsStatusProvider = gpsProvider.getGpsStatusProvider();
mNetInitiatedListener = gpsProvider.getNetInitiatedListener();
addProvider(gpsProvider);
mGpsLocationProvider = gpsProvider;
}
PassiveProvider passiveProvider = new PassiveProvider(this);
addProvider(passiveProvider);
mEnabledProviders.add(passiveProvider.getName());
PackageManager pm = mContext.getPackageManager();
if (mNetworkLocationProviderPackageName != null &&
pm.resolveService(new Intent(mNetworkLocationProviderPackageName), 0) != null) {
mNetworkLocationProvider =
new LocationProviderProxy(mContext, LocationManager.NETWORK_PROVIDER,
mNetworkLocationProviderPackageName, mLocationHandler);
addProvider(mNetworkLocationProvider);
}
if (mGeocodeProviderPackageName != null &&
pm.resolveService(new Intent(mGeocodeProviderPackageName), 0) != null) {
mGeocodeProvider = new GeocoderProxy(mContext, mGeocodeProviderPackageName);
}
updateProvidersLocked();
}
生成/AddされているProviderは、3つ
- public class GpsLocationProvider implements LocationProviderInterface
- public class PassiveProvider implements LocationProviderInterface
- public class LocationProviderProxy implements LocationProviderInterface
GeocodeProviderとしては
- public class GeocoderProxy
が生成されています。
またこのうちPassiveProviderは、mNetworkLocationProviderPackageNameのパッケージがある場合に生成されています。これは、リソース中のcom.android.internal.R.string.config_networkLocationProvider の文字列になります。
また、GeocodeProxyについても、mGeocodeProviderPackageNameのパッケージがある場合にのみ生成されており、こちらは、com.android.internal.R.string.config_geocodeProvider の文字列になります。
4.0のソースコードに含まれるtunaのconfig設定 [
device/samsung/tuna/overlay/frameworks/base/core/res/res/values/config.xml] ですと
<string name="config_networkLocationProvider">com.google.android.location.NetworkLocationProvider</string>
<string name="config_geocodeProvider">com.google.android.location.GeocodeProvider</string>
となっています。
ちなみに、GplLocationProvider classには
static { class_init_native(); }
となっています。ですので、最初のif文の時にこの関数が呼び出されます。
こちらは、nativeコードで実装されており、実際には
android_location_GpsLocationProvider_class_init_native()
static { class_init_native(); }
となっています。ですので、最初のif文の時にこの関数が呼び出されます。
こちらは、nativeコードで実装されており、実際には
android_location_GpsLocationProvider_class_init_native()
で、その中でhw_get_module("gps",....)が呼び出されます。この辺りはHALの実装の周りの部分でして、必要になるライブラリを探して行きます。4.0のコードでは以下の順にライブラリを探し見つかったものをdlopenを使ってZygoteとリンクします。
さて、とりあえずここまでで見た限りは、LocationManagerはLocation情報を管理しているわけではなく、LocationProviderの管理をしていると見るのが自然なようです。
というわけで、次回は、LocationProviderについて、Gpsを中心にもう少し調べてみたいなと思います。
- /vendor/lib/hw/gps.<ro.hardware>.so
- /system/lib/hw/gps.<ro.hardware>.so
- /vendor/lib/hw/gps.<ro.product.board>.so
- /system/lib/hw/gps.<ro.product.board>.so
- /vendor/lib/hw/gps.<ro.board.platform>.so
- /system/lib/hw/gps.<ro.board.platform>.so
- /vendor/lib/hw/gps.<ro.arch>.so
- /system/lib/hw/gps.<ro.arch>.so
- /system/lib/hw/gps.default.so
以前は、libがついていた気がするんですけどね。最近はlibがつかないのかな。
ついでにいうと、implements LocationProviderInterfaceなclassは他にもあって
- public class MockProvider implements LocationProviderInterface
というのがあります。こちらは、LocationManager::addTestProviderを行った時に内部でaddProviderされるProviderのようです。CTS等のテスト時に使われるようですね。
さて、とりあえずここまでで見た限りは、LocationManagerはLocation情報を管理しているわけではなく、LocationProviderの管理をしていると見るのが自然なようです。
というわけで、次回は、LocationProviderについて、Gpsを中心にもう少し調べてみたいなと思います。
0 件のコメント:
コメントを投稿