Android LocationManagerService启动(三)
接着上一篇文章
Android LocationManagerService启动(二)
GnssLocationProvider 是Java层的逻辑,大部分逻辑是Framework层的JNI代码完成的。
GnssProvider和HAL层交互的接口是native jni方法。在GnssProvider中,对应的是native_xxx的这些方法。但是,大家看源码就会发现,这些native方法的注册不在这个类里面。
GnssLocationProvider的静态代码块只有一个操作
static {
class_init_native();
}
我们知道,jni方法的注册有两种方式,一种是静态注册,就是通过java native函数签名,生成一个包含报名的c++函数名;另一种是动态注册,通过重写JNI_OnLoad方法来实现。
Android Framework中,将核心service的jni方法,都放到了一起统一加载。
入口文件:services/core/jni/onload.cpp
using namespace android;
extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
{
JNIEnv* env = NULL;
jint result = -1;
if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
ALOGE("GetEnv failed!");
return result;
}
ALOG_ASSERT(env, "Could not retrieve the env!");
register_android_server_broadcastradio_BroadcastRadioService(env);
register_android_server_broadcastradio_Tuner(vm, env);
register_android_server_PowerManagerService(env);
register_android_server_SerialService(env);
register_android_server_InputApplicationHandle(env);
register_android_server_InputWindowHandle(env);
register_android_server_InputManager(env);
register_android_server_LightsService(env);
register_android_server_AlarmManagerService(env);
register_android_server_UsbDeviceManager(env);
register_android_server_UsbMidiDevice(env);
register_android_server_UsbAlsaJackDetector(env);
register_android_server_UsbHostManager(env);
register_android_server_vr_VrManagerService(env);
register_android_server_VibratorService(env);
register_android_server_SystemServer(env);
register_android_server_location_GnssLocationProvider(env);
register_android_server_connectivity_Vpn(env);
register_android_server_connectivity_tethering_OffloadHardwareInterface(env);
register_android_server_devicepolicy_CryptoTestHelper(env);
register_android_server_ConsumerIrService(env);
register_android_server_BatteryStatsService(env);
register_android_server_hdmi_HdmiCecController(env);
register_android_server_tv_TvUinputBridge(env);
register_android_server_tv_TvInputHal(env);
register_android_server_PersistentDataBlockService(env);
register_android_server_HardwarePropertiesManagerService(env);
register_android_server_storage_AppFuse(env);
register_android_server_SyntheticPasswordManager(env);
register_android_server_GraphicsStatsService(env);
register_android_hardware_display_DisplayViewport(env);
register_android_server_net_NetworkStatsService(env);
#ifdef USE_ARC
register_android_server_ArcVideoService();
#endif
return JNI_VERSION_1_4;
}
从上面的代码可以看出,所有android server的jni方法,都是在这里注册的,GnssLocatoinProvider的jni方法,就是通过register_android_server_location_GnssLocationProvider(env);方法注册的。
找到这个函数的文件:services/core/jni/com_android_server_location_GnssLocationProvider.cpp
实现代码如下:
int register_android_server_location_GnssLocationProvider(JNIEnv* env) {
jniRegisterNativeMethods(
env,
"com/android/server/location/GnssBatchingProvider",
sMethodsBatching,
NELEM(sMethodsBatching));
jniRegisterNativeMethods(
env,
"com/android/server/location/GnssGeofenceProvider",
sGeofenceMethods,
NELEM(sGeofenceMethods));
jniRegisterNativeMethods(
env,
"com/android/server/location/GnssMeasurementsProvider",
sMeasurementMethods,
NELEM(sMeasurementMethods));
jniRegisterNativeMethods(
env,
"com/android/server/location/GnssNavigationMessageProvider",
sNavigationMessageMethods,
NELEM(sNavigationMessageMethods));
return jniRegisterNativeMethods(
env,
"com/android/server/location/GnssLocationProvider",
sMethods,
NELEM(sMethods));
}
上面的代码,就是jni放的注册入口了。
还记得上面提到的静态代码块里面的class_init_native方法吗?
具体的实现如下:
static void android_location_GnssLocationProvider_class_init_native(JNIEnv* env, jclass clazz) {
gnssHal_V1_1 = IGnss_V1_1::getService();
if (gnssHal_V1_1 == nullptr) {
ALOGD("gnssHal 1.1 was null, trying 1.0");
gnssHal = IGnss_V1_0::getService();
} else {
gnssHal = gnssHal_V1_1;
}
}
这里我们看到了非常重要的操作:获取绑定HAL层的service
这里为了兼容,会先去获取V1_1版本的服务,如果找不到,就去获取V1_0的服务。
完成了上面的这个操作,才会有下面的init等操作。这里有两个init函数
一个是native_init_once();一个是native_init();从名字可以看出,第一个是只执行一次,第二个是可能多次执行的。
native_init_once(): 服务启动时候会调用一次,有两种情况:1. 系统启动时候会调用一次;2. HAL层服务重启了,会调用一次
分别是在
private void handleInitialize() {
native_init_once();
/////...../////
}
和
private void reportGnssServiceDied() {
if (DEBUG) Log.d(TAG, "reportGnssServiceDied");
mHandler.post(() -> {
class_init_native();
native_init_once();
if (isEnabled()) {
// re-calls native_init() and other setup.
handleEnable();
// resend configuration into the restarted HAL service.
reloadGpsProperties(mContext, mProperties);
}
});
}
native_init():除了native_init_once()函数之后会执行,enable时候也会执行。
private void handleEnable() {
if (DEBUG) Log.d(TAG, "handleEnable");
boolean enabled = native_init();
//////......////////
}
native_init_once() 做了什么事情呢?主要有以下几个部分:
- 通过jni env,获取到相关的java函数指针(reportxxx)
- 保存一个静态jvm变量
- 向hal服务注册一个DeathRecipient Observer,用于监听HAL服务的状态,如果服务异常了,jni/java层会做出相应的处理。
- gnss相关feature的配置,比如agps,debug,navigation等等
static void android_location_GnssLocationProvider_init_once(JNIEnv* env, jclass clazz) {
method_reportLocation = env->GetMethodID(clazz, "reportLocation",
"(ZLandroid/location/Location;)V");
method_reportStatus = env->GetMethodID(clazz, "reportStatus", "(I)V");
////// .... 省略 ..... ///////
/*
* Save a pointer to JVM.
*/
jint jvmStatus = env->GetJavaVM(&sJvm);
if (jvmStatus != JNI_OK) {
LOG_ALWAYS_FATAL("Unable to get Java VM. Error: %d", jvmStatus);
}
if (gnssHal != nullptr) {
gnssHalDeathRecipient = new GnssDeathRecipient();
hardware::Return<bool> linked = gnssHal->linkToDeath(
gnssHalDeathRecipient, /*cookie*/ 0);
if (!linked.isOk()) {
ALOGE("Transaction error in linking to GnssHAL death: %s",
linked.description().c_str());
} else if (!linked) {
ALOGW("Unable to link to GnssHal death notifications");
} else {
ALOGD("Link to death notification successful");
}
auto gnssXtra = gnssHal->getExtensionXtra();
if (!gnssXtra.isOk()) {
ALOGD("Unable to get a handle to Xtra");
} else {
gnssXtraIface = gnssXtra;
}
/////....省略 ...///////
} else {
ALOGE("Unable to get GPS service\n");
}
}
native_init() 做了哪些事情呢?主要包括:
- 保存一个java实例的对象指针mCallbacksObj,用于后面回掉Java层的接口。
- 创建GnssCallback并给HAL层注册
static jboolean android_location_GnssLocationProvider_init(JNIEnv* env, jobject obj) {
/*
* This must be set before calling into the HAL library.
*/
if (!mCallbacksObj)
mCallbacksObj = env->NewGlobalRef(obj);
/*
* Fail if the main interface fails to initialize
*/
if (gnssHal == nullptr) {
ALOGE("Unable to Initialize GNSS HAL\n");
return JNI_FALSE;
}
sp<IGnssCallback> gnssCbIface = new GnssCallback();
Return<bool> result = false;
if (gnssHal_V1_1 != nullptr) {
result = gnssHal_V1_1->setCallback_1_1(gnssCbIface);
} else {
result = gnssHal->setCallback(gnssCbIface);
}
if (!result.isOk() || !result) {
ALOGE("SetCallback for Gnss Interface fails\n");
return JNI_FALSE;
}
///// .... 省略 .... //////
return JNI_TRUE;
}
做完上面两部分,基本的初始化工作就完成了,剩下的就是业务逻辑了。
这里就要注意一点,我们在实现HAL层Service的时候,如果发现GNSSProvider没有启用,那么很可能是初始化异常

浙公网安备 33010602011771号