com_android_server_location_GpsLocationProvider.cpp revision 1e84da822e7aa4d494b31c8759917d2751611f84
1/* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#define LOG_TAG "GpsLocationProvider" 18 19//#define LOG_NDEBUG 0 20 21#include "JNIHelp.h" 22#include "jni.h" 23#include "hardware/hardware.h" 24#include "hardware/gps.h" 25#include "hardware_legacy/power.h" 26#include "utils/Log.h" 27#include "utils/misc.h" 28#include "android_runtime/AndroidRuntime.h" 29 30#include <string.h> 31#include <pthread.h> 32 33static jobject mCallbacksObj = NULL; 34 35static jmethodID method_reportLocation; 36static jmethodID method_reportStatus; 37static jmethodID method_reportSvStatus; 38static jmethodID method_reportAGpsStatus; 39static jmethodID method_reportNmea; 40static jmethodID method_setEngineCapabilities; 41static jmethodID method_xtraDownloadRequest; 42static jmethodID method_reportNiNotification; 43static jmethodID method_requestRefLocation; 44static jmethodID method_requestSetID; 45 46static const GpsInterface* sGpsInterface = NULL; 47static const GpsXtraInterface* sGpsXtraInterface = NULL; 48static const AGpsInterface* sAGpsInterface = NULL; 49static const GpsNiInterface* sGpsNiInterface = NULL; 50static const GpsDebugInterface* sGpsDebugInterface = NULL; 51static const AGpsRilInterface* sAGpsRilInterface = NULL; 52 53// temporary storage for GPS callbacks 54static GpsSvStatus sGpsSvStatus; 55static const char* sNmeaString; 56static int sNmeaStringLength; 57 58#define WAKE_LOCK_NAME "GPS" 59 60namespace android { 61 62static void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) { 63 if (env->ExceptionCheck()) { 64 LOGE("An exception was thrown by callback '%s'.", methodName); 65 LOGE_EX(env); 66 env->ExceptionClear(); 67 } 68} 69 70static void location_callback(GpsLocation* location) 71{ 72 JNIEnv* env = AndroidRuntime::getJNIEnv(); 73 env->CallVoidMethod(mCallbacksObj, method_reportLocation, location->flags, 74 (jdouble)location->latitude, (jdouble)location->longitude, 75 (jdouble)location->altitude, 76 (jfloat)location->speed, (jfloat)location->bearing, 77 (jfloat)location->accuracy, (jlong)location->timestamp); 78 checkAndClearExceptionFromCallback(env, __FUNCTION__); 79} 80 81static void status_callback(GpsStatus* status) 82{ 83 JNIEnv* env = AndroidRuntime::getJNIEnv(); 84 env->CallVoidMethod(mCallbacksObj, method_reportStatus, status->status); 85 checkAndClearExceptionFromCallback(env, __FUNCTION__); 86} 87 88static void sv_status_callback(GpsSvStatus* sv_status) 89{ 90 JNIEnv* env = AndroidRuntime::getJNIEnv(); 91 memcpy(&sGpsSvStatus, sv_status, sizeof(sGpsSvStatus)); 92 env->CallVoidMethod(mCallbacksObj, method_reportSvStatus); 93 checkAndClearExceptionFromCallback(env, __FUNCTION__); 94} 95 96static void nmea_callback(GpsUtcTime timestamp, const char* nmea, int length) 97{ 98 JNIEnv* env = AndroidRuntime::getJNIEnv(); 99 // The Java code will call back to read these values 100 // We do this to avoid creating unnecessary String objects 101 sNmeaString = nmea; 102 sNmeaStringLength = length; 103 env->CallVoidMethod(mCallbacksObj, method_reportNmea, timestamp); 104 checkAndClearExceptionFromCallback(env, __FUNCTION__); 105} 106 107static void set_capabilities_callback(uint32_t capabilities) 108{ 109 JNIEnv* env = AndroidRuntime::getJNIEnv(); 110 env->CallVoidMethod(mCallbacksObj, method_setEngineCapabilities, capabilities); 111 checkAndClearExceptionFromCallback(env, __FUNCTION__); 112} 113 114static void acquire_wakelock_callback() 115{ 116 acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME); 117} 118 119static void release_wakelock_callback() 120{ 121 release_wake_lock(WAKE_LOCK_NAME); 122} 123 124static pthread_t create_thread_callback(const char* name, void (*start)(void *), void* arg) 125{ 126 return (pthread_t)AndroidRuntime::createJavaThread(name, start, arg); 127} 128 129GpsCallbacks sGpsCallbacks = { 130 sizeof(GpsCallbacks), 131 location_callback, 132 status_callback, 133 sv_status_callback, 134 nmea_callback, 135 set_capabilities_callback, 136 acquire_wakelock_callback, 137 release_wakelock_callback, 138 create_thread_callback, 139}; 140 141static void xtra_download_request_callback() 142{ 143 JNIEnv* env = AndroidRuntime::getJNIEnv(); 144 env->CallVoidMethod(mCallbacksObj, method_xtraDownloadRequest); 145 checkAndClearExceptionFromCallback(env, __FUNCTION__); 146} 147 148GpsXtraCallbacks sGpsXtraCallbacks = { 149 xtra_download_request_callback, 150 create_thread_callback, 151}; 152 153static void agps_status_callback(AGpsStatus* agps_status) 154{ 155 JNIEnv* env = AndroidRuntime::getJNIEnv(); 156 env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus, 157 agps_status->type, agps_status->status); 158 checkAndClearExceptionFromCallback(env, __FUNCTION__); 159} 160 161AGpsCallbacks sAGpsCallbacks = { 162 agps_status_callback, 163 create_thread_callback, 164}; 165 166static void gps_ni_notify_callback(GpsNiNotification *notification) 167{ 168 LOGD("gps_ni_notify_callback\n"); 169 JNIEnv* env = AndroidRuntime::getJNIEnv(); 170 jstring requestor_id = env->NewStringUTF(notification->requestor_id); 171 jstring text = env->NewStringUTF(notification->text); 172 jstring extras = env->NewStringUTF(notification->extras); 173 174 if (requestor_id && text && extras) { 175 env->CallVoidMethod(mCallbacksObj, method_reportNiNotification, 176 notification->notification_id, notification->ni_type, 177 notification->notify_flags, notification->timeout, 178 notification->default_response, requestor_id, text, 179 notification->requestor_id_encoding, 180 notification->text_encoding, extras); 181 } else { 182 LOGE("out of memory in gps_ni_notify_callback\n"); 183 } 184 185 if (requestor_id) 186 env->DeleteLocalRef(requestor_id); 187 if (text) 188 env->DeleteLocalRef(text); 189 if (extras) 190 env->DeleteLocalRef(extras); 191 checkAndClearExceptionFromCallback(env, __FUNCTION__); 192} 193 194GpsNiCallbacks sGpsNiCallbacks = { 195 gps_ni_notify_callback, 196 create_thread_callback, 197}; 198 199static void agps_request_set_id(uint32_t flags) 200{ 201 LOGD("agps_request_set_id: flags (%d)", flags); 202 203 JNIEnv* env = AndroidRuntime::getJNIEnv(); 204 env->CallVoidMethod(mCallbacksObj, method_requestSetID, flags); 205 checkAndClearExceptionFromCallback(env, __FUNCTION__); 206} 207 208static void agps_request_ref_location(uint32_t flags) 209{ 210 LOGD("agps_ref_location: flags (%d)", flags); 211 212 JNIEnv* env = AndroidRuntime::getJNIEnv(); 213 env->CallVoidMethod(mCallbacksObj, method_requestRefLocation, flags); 214 checkAndClearExceptionFromCallback(env, __FUNCTION__); 215} 216 217AGpsRilCallbacks sAGpsRilCallbacks = { 218 agps_request_set_id, 219 agps_request_ref_location, 220 create_thread_callback, 221}; 222 223static void android_location_GpsLocationProvider_class_init_native(JNIEnv* env, jclass clazz) { 224 method_reportLocation = env->GetMethodID(clazz, "reportLocation", "(IDDDFFFJ)V"); 225 method_reportStatus = env->GetMethodID(clazz, "reportStatus", "(I)V"); 226 method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "()V"); 227 method_reportAGpsStatus = env->GetMethodID(clazz, "reportAGpsStatus", "(II)V"); 228 method_reportNmea = env->GetMethodID(clazz, "reportNmea", "(J)V"); 229 method_setEngineCapabilities = env->GetMethodID(clazz, "setEngineCapabilities", "(I)V"); 230 method_xtraDownloadRequest = env->GetMethodID(clazz, "xtraDownloadRequest", "()V"); 231 method_reportNiNotification = env->GetMethodID(clazz, "reportNiNotification", "(IIIIILjava/lang/String;Ljava/lang/String;IILjava/lang/String;)V"); 232 method_requestRefLocation = env->GetMethodID(clazz,"requestRefLocation","(I)V"); 233 method_requestSetID = env->GetMethodID(clazz,"requestSetID","(I)V"); 234} 235 236static const GpsInterface* get_gps_interface() { 237 int err; 238 hw_module_t* module; 239 const GpsInterface* interface = NULL; 240 241 err = hw_get_module(GPS_HARDWARE_MODULE_ID, (hw_module_t const**)&module); 242 if (err == 0) { 243 hw_device_t* device; 244 err = module->methods->open(module, GPS_HARDWARE_MODULE_ID, &device); 245 if (err == 0) { 246 gps_device_t* gps_device = (gps_device_t *)device; 247 interface = gps_device->get_gps_interface(gps_device); 248 } 249 } 250 251 return interface; 252} 253 254static jboolean android_location_GpsLocationProvider_is_supported(JNIEnv* env, jclass clazz) { 255 if (!sGpsInterface) 256 sGpsInterface = get_gps_interface(); 257 return (sGpsInterface != NULL); 258} 259 260static jboolean android_location_GpsLocationProvider_init(JNIEnv* env, jobject obj) 261{ 262 // this must be set before calling into the HAL library 263 if (!mCallbacksObj) 264 mCallbacksObj = env->NewGlobalRef(obj); 265 266 if (!sGpsInterface) 267 sGpsInterface = get_gps_interface(); 268 if (!sGpsInterface || sGpsInterface->init(&sGpsCallbacks) != 0) 269 return false; 270 271 if (!sAGpsInterface) 272 sAGpsInterface = (const AGpsInterface*)sGpsInterface->get_extension(AGPS_INTERFACE); 273 if (sAGpsInterface) 274 sAGpsInterface->init(&sAGpsCallbacks); 275 276 if (!sGpsNiInterface) 277 sGpsNiInterface = (const GpsNiInterface*)sGpsInterface->get_extension(GPS_NI_INTERFACE); 278 if (sGpsNiInterface) 279 sGpsNiInterface->init(&sGpsNiCallbacks); 280 281 if (!sGpsDebugInterface) 282 sGpsDebugInterface = (const GpsDebugInterface*)sGpsInterface->get_extension(GPS_DEBUG_INTERFACE); 283 284 if (!sAGpsRilInterface) 285 sAGpsRilInterface = (const AGpsRilInterface*)sGpsInterface->get_extension(AGPS_RIL_INTERFACE); 286 if (sAGpsRilInterface) 287 sAGpsRilInterface->init(&sAGpsRilCallbacks); 288 289 return true; 290} 291 292static void android_location_GpsLocationProvider_cleanup(JNIEnv* env, jobject obj) 293{ 294 sGpsInterface->cleanup(); 295} 296 297static jboolean android_location_GpsLocationProvider_set_position_mode(JNIEnv* env, jobject obj, 298 jint mode, jint recurrence, jint min_interval, jint preferred_accuracy, jint preferred_time) 299{ 300 return (sGpsInterface->set_position_mode(mode, recurrence, min_interval, preferred_accuracy, 301 preferred_time) == 0); 302} 303 304static jboolean android_location_GpsLocationProvider_start(JNIEnv* env, jobject obj) 305{ 306 return (sGpsInterface->start() == 0); 307} 308 309static jboolean android_location_GpsLocationProvider_stop(JNIEnv* env, jobject obj) 310{ 311 return (sGpsInterface->stop() == 0); 312} 313 314static void android_location_GpsLocationProvider_delete_aiding_data(JNIEnv* env, jobject obj, jint flags) 315{ 316 sGpsInterface->delete_aiding_data(flags); 317} 318 319static jint android_location_GpsLocationProvider_read_sv_status(JNIEnv* env, jobject obj, 320 jintArray prnArray, jfloatArray snrArray, jfloatArray elevArray, jfloatArray azumArray, 321 jintArray maskArray) 322{ 323 // this should only be called from within a call to reportSvStatus 324 325 jint* prns = env->GetIntArrayElements(prnArray, 0); 326 jfloat* snrs = env->GetFloatArrayElements(snrArray, 0); 327 jfloat* elev = env->GetFloatArrayElements(elevArray, 0); 328 jfloat* azim = env->GetFloatArrayElements(azumArray, 0); 329 jint* mask = env->GetIntArrayElements(maskArray, 0); 330 331 int num_svs = sGpsSvStatus.num_svs; 332 for (int i = 0; i < num_svs; i++) { 333 prns[i] = sGpsSvStatus.sv_list[i].prn; 334 snrs[i] = sGpsSvStatus.sv_list[i].snr; 335 elev[i] = sGpsSvStatus.sv_list[i].elevation; 336 azim[i] = sGpsSvStatus.sv_list[i].azimuth; 337 } 338 mask[0] = sGpsSvStatus.ephemeris_mask; 339 mask[1] = sGpsSvStatus.almanac_mask; 340 mask[2] = sGpsSvStatus.used_in_fix_mask; 341 342 env->ReleaseIntArrayElements(prnArray, prns, 0); 343 env->ReleaseFloatArrayElements(snrArray, snrs, 0); 344 env->ReleaseFloatArrayElements(elevArray, elev, 0); 345 env->ReleaseFloatArrayElements(azumArray, azim, 0); 346 env->ReleaseIntArrayElements(maskArray, mask, 0); 347 return num_svs; 348} 349 350static void android_location_GpsLocationProvider_agps_set_reference_location_cellid(JNIEnv* env, 351 jobject obj, jint type, jint mcc, jint mnc, jint lac, jint cid) 352{ 353 AGpsRefLocation location; 354 if (!sAGpsRilInterface) 355 sAGpsRilInterface = (const AGpsRilInterface *)sGpsInterface->get_extension(AGPS_RIL_INTERFACE); 356 if (!sAGpsRilInterface) 357 return; 358 switch(type) { 359 case AGPS_REF_LOCATION_TYPE_GSM_CELLID: 360 case AGPS_REF_LOCATION_TYPE_UMTS_CELLID: 361 location.type = type; 362 location.u.cellID.mcc = mcc; 363 location.u.cellID.mnc = mnc; 364 location.u.cellID.lac = lac; 365 location.u.cellID.cid = cid; 366 break; 367 default: 368 LOGE("Neither a GSM nor a UMTS cellid (%s:%d).",__FUNCTION__,__LINE__); 369 return; 370 break; 371 } 372 sAGpsRilInterface->set_ref_location(&location, sizeof(location)); 373} 374 375static void android_location_GpsLocationProvider_agps_send_ni_message(JNIEnv* env, 376 jobject obj, jbyteArray ni_msg, jint size) 377{ 378 size_t sz; 379 if (!sAGpsRilInterface) 380 sAGpsRilInterface =(const AGpsRilInterface *)sGpsInterface->get_extension(AGPS_RIL_INTERFACE); 381 if (!sAGpsRilInterface) 382 return; 383 if (size < 0) 384 return; 385 sz = (size_t)size; 386 jbyte* b = env->GetByteArrayElements(ni_msg, 0); 387 sAGpsRilInterface->ni_message((uint8_t *)b,sz); 388 env->ReleaseByteArrayElements(ni_msg,b,0); 389} 390 391static void android_location_GpsLocationProvider_agps_set_id(JNIEnv *env, 392 jobject obj, jint type, jstring setid_string) 393{ 394 if (!sAGpsRilInterface) { 395 sAGpsRilInterface =(const AGpsRilInterface *)sGpsInterface->get_extension(AGPS_RIL_INTERFACE); 396 } 397 if (!sAGpsRilInterface) 398 return; 399 400 const char *setid = env->GetStringUTFChars(setid_string, NULL); 401 sAGpsRilInterface->set_set_id(type, setid); 402 env->ReleaseStringUTFChars(setid_string, setid); 403} 404 405static jint android_location_GpsLocationProvider_read_nmea(JNIEnv* env, jobject obj, 406 jbyteArray nmeaArray, jint buffer_size) 407{ 408 // this should only be called from within a call to reportNmea 409 jbyte* nmea = (jbyte *)env->GetPrimitiveArrayCritical(nmeaArray, 0); 410 int length = sNmeaStringLength; 411 if (length > buffer_size) 412 length = buffer_size; 413 memcpy(nmea, sNmeaString, length); 414 env->ReleasePrimitiveArrayCritical(nmeaArray, nmea, JNI_ABORT); 415 return length; 416} 417 418static void android_location_GpsLocationProvider_inject_time(JNIEnv* env, jobject obj, 419 jlong time, jlong timeReference, jint uncertainty) 420{ 421 sGpsInterface->inject_time(time, timeReference, uncertainty); 422} 423 424static void android_location_GpsLocationProvider_inject_location(JNIEnv* env, jobject obj, 425 jdouble latitude, jdouble longitude, jfloat accuracy) 426{ 427 sGpsInterface->inject_location(latitude, longitude, accuracy); 428} 429 430static jboolean android_location_GpsLocationProvider_supports_xtra(JNIEnv* env, jobject obj) 431{ 432 if (!sGpsXtraInterface) { 433 sGpsXtraInterface = (const GpsXtraInterface*)sGpsInterface->get_extension(GPS_XTRA_INTERFACE); 434 if (sGpsXtraInterface) { 435 int result = sGpsXtraInterface->init(&sGpsXtraCallbacks); 436 if (result) { 437 sGpsXtraInterface = NULL; 438 } 439 } 440 } 441 442 return (sGpsXtraInterface != NULL); 443} 444 445static void android_location_GpsLocationProvider_inject_xtra_data(JNIEnv* env, jobject obj, 446 jbyteArray data, jint length) 447{ 448 jbyte* bytes = (jbyte *)env->GetPrimitiveArrayCritical(data, 0); 449 sGpsXtraInterface->inject_xtra_data((char *)bytes, length); 450 env->ReleasePrimitiveArrayCritical(data, bytes, JNI_ABORT); 451} 452 453static void android_location_GpsLocationProvider_agps_data_conn_open(JNIEnv* env, jobject obj, jstring apn) 454{ 455 if (!sAGpsInterface) { 456 sAGpsInterface = (const AGpsInterface*)sGpsInterface->get_extension(AGPS_INTERFACE); 457 } 458 if (sAGpsInterface) { 459 if (apn == NULL) { 460 jniThrowException(env, "java/lang/IllegalArgumentException", NULL); 461 return; 462 } 463 const char *apnStr = env->GetStringUTFChars(apn, NULL); 464 sAGpsInterface->data_conn_open(apnStr); 465 env->ReleaseStringUTFChars(apn, apnStr); 466 } 467} 468 469static void android_location_GpsLocationProvider_agps_data_conn_closed(JNIEnv* env, jobject obj) 470{ 471 if (!sAGpsInterface) { 472 sAGpsInterface = (const AGpsInterface*)sGpsInterface->get_extension(AGPS_INTERFACE); 473 } 474 if (sAGpsInterface) { 475 sAGpsInterface->data_conn_closed(); 476 } 477} 478 479static void android_location_GpsLocationProvider_agps_data_conn_failed(JNIEnv* env, jobject obj) 480{ 481 if (!sAGpsInterface) { 482 sAGpsInterface = (const AGpsInterface*)sGpsInterface->get_extension(AGPS_INTERFACE); 483 } 484 if (sAGpsInterface) { 485 sAGpsInterface->data_conn_failed(); 486 } 487} 488 489static void android_location_GpsLocationProvider_set_agps_server(JNIEnv* env, jobject obj, 490 jint type, jstring hostname, jint port) 491{ 492 if (!sAGpsInterface) { 493 sAGpsInterface = (const AGpsInterface*)sGpsInterface->get_extension(AGPS_INTERFACE); 494 } 495 if (sAGpsInterface) { 496 const char *c_hostname = env->GetStringUTFChars(hostname, NULL); 497 sAGpsInterface->set_server(type, c_hostname, port); 498 env->ReleaseStringUTFChars(hostname, c_hostname); 499 } 500} 501 502static void android_location_GpsLocationProvider_send_ni_response(JNIEnv* env, jobject obj, 503 jint notifId, jint response) 504{ 505 if (!sGpsNiInterface) { 506 sGpsNiInterface = (const GpsNiInterface*)sGpsInterface->get_extension(GPS_NI_INTERFACE); 507 } 508 if (sGpsNiInterface) { 509 sGpsNiInterface->respond(notifId, response); 510 } 511} 512 513static jstring android_location_GpsLocationProvider_get_internal_state(JNIEnv* env, jobject obj) 514{ 515 jstring result = NULL; 516 if (sGpsDebugInterface) { 517 const size_t maxLength = 2047; 518 char buffer[maxLength+1]; 519 size_t length = sGpsDebugInterface->get_internal_state(buffer, maxLength); 520 if (length > maxLength) length = maxLength; 521 buffer[length] = 0; 522 result = env->NewStringUTF(buffer); 523 } 524 return result; 525} 526 527static JNINativeMethod sMethods[] = { 528 /* name, signature, funcPtr */ 529 {"class_init_native", "()V", (void *)android_location_GpsLocationProvider_class_init_native}, 530 {"native_is_supported", "()Z", (void*)android_location_GpsLocationProvider_is_supported}, 531 {"native_init", "()Z", (void*)android_location_GpsLocationProvider_init}, 532 {"native_cleanup", "()V", (void*)android_location_GpsLocationProvider_cleanup}, 533 {"native_set_position_mode", "(IIIII)Z", (void*)android_location_GpsLocationProvider_set_position_mode}, 534 {"native_start", "()Z", (void*)android_location_GpsLocationProvider_start}, 535 {"native_stop", "()Z", (void*)android_location_GpsLocationProvider_stop}, 536 {"native_delete_aiding_data", "(I)V", (void*)android_location_GpsLocationProvider_delete_aiding_data}, 537 {"native_read_sv_status", "([I[F[F[F[I)I", (void*)android_location_GpsLocationProvider_read_sv_status}, 538 {"native_read_nmea", "([BI)I", (void*)android_location_GpsLocationProvider_read_nmea}, 539 {"native_inject_time", "(JJI)V", (void*)android_location_GpsLocationProvider_inject_time}, 540 {"native_inject_location", "(DDF)V", (void*)android_location_GpsLocationProvider_inject_location}, 541 {"native_supports_xtra", "()Z", (void*)android_location_GpsLocationProvider_supports_xtra}, 542 {"native_inject_xtra_data", "([BI)V", (void*)android_location_GpsLocationProvider_inject_xtra_data}, 543 {"native_agps_data_conn_open", "(Ljava/lang/String;)V", (void*)android_location_GpsLocationProvider_agps_data_conn_open}, 544 {"native_agps_data_conn_closed", "()V", (void*)android_location_GpsLocationProvider_agps_data_conn_closed}, 545 {"native_agps_data_conn_failed", "()V", (void*)android_location_GpsLocationProvider_agps_data_conn_failed}, 546 {"native_agps_set_id","(ILjava/lang/String;)V",(void*)android_location_GpsLocationProvider_agps_set_id}, 547 {"native_agps_set_ref_location_cellid","(IIIII)V",(void*)android_location_GpsLocationProvider_agps_set_reference_location_cellid}, 548 {"native_set_agps_server", "(ILjava/lang/String;I)V", (void*)android_location_GpsLocationProvider_set_agps_server}, 549 {"native_send_ni_response", "(II)V", (void*)android_location_GpsLocationProvider_send_ni_response}, 550 {"native_agps_ni_message", "([BI)V", (void *)android_location_GpsLocationProvider_agps_send_ni_message}, 551 {"native_get_internal_state", "()Ljava/lang/String;", (void*)android_location_GpsLocationProvider_get_internal_state}, 552}; 553 554int register_android_server_location_GpsLocationProvider(JNIEnv* env) 555{ 556 return jniRegisterNativeMethods(env, "com/android/server/location/GpsLocationProvider", sMethods, NELEM(sMethods)); 557} 558 559} /* namespace android */ 560