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 33 static jobject mCallbacksObj = NULL; 34 35 static jmethodID method_reportLocation; 36 static jmethodID method_reportStatus; 37 static jmethodID method_reportSvStatus; 38 static jmethodID method_reportAGpsStatus; 39 static jmethodID method_reportNmea; 40 static jmethodID method_setEngineCapabilities; 41 static jmethodID method_xtraDownloadRequest; 42 static jmethodID method_reportNiNotification; 43 static jmethodID method_requestRefLocation; 44 static jmethodID method_requestSetID; 45 46 static const GpsInterface* sGpsInterface = NULL; 47 static const GpsXtraInterface* sGpsXtraInterface = NULL; 48 static const AGpsInterface* sAGpsInterface = NULL; 49 static const GpsNiInterface* sGpsNiInterface = NULL; 50 static const GpsDebugInterface* sGpsDebugInterface = NULL; 51 static const AGpsRilInterface* sAGpsRilInterface = NULL; 52 53 // temporary storage for GPS callbacks 54 static GpsSvStatus sGpsSvStatus; 55 static const char* sNmeaString; 56 static int sNmeaStringLength; 57 58 #define WAKE_LOCK_NAME "GPS" 59 60 namespace android { 61 62 static 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 70 static 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 81 static 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 88 static 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 96 static 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 107 static void set_capabilities_callback(uint32_t capabilities) 108 { 109 LOGD("set_capabilities_callback: %ld\n", capabilities); 110 JNIEnv* env = AndroidRuntime::getJNIEnv(); 111 env->CallVoidMethod(mCallbacksObj, method_setEngineCapabilities, capabilities); 112 checkAndClearExceptionFromCallback(env, __FUNCTION__); 113 } 114 115 static void acquire_wakelock_callback() 116 { 117 acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME); 118 } 119 120 static void release_wakelock_callback() 121 { 122 release_wake_lock(WAKE_LOCK_NAME); 123 } 124 125 static pthread_t create_thread_callback(const char* name, void (*start)(void *), void* arg) 126 { 127 return (pthread_t)AndroidRuntime::createJavaThread(name, start, arg); 128 } 129 130 GpsCallbacks sGpsCallbacks = { 131 sizeof(GpsCallbacks), 132 location_callback, 133 status_callback, 134 sv_status_callback, 135 nmea_callback, 136 set_capabilities_callback, 137 acquire_wakelock_callback, 138 release_wakelock_callback, 139 create_thread_callback, 140 }; 141 142 static void xtra_download_request_callback() 143 { 144 JNIEnv* env = AndroidRuntime::getJNIEnv(); 145 env->CallVoidMethod(mCallbacksObj, method_xtraDownloadRequest); 146 checkAndClearExceptionFromCallback(env, __FUNCTION__); 147 } 148 149 GpsXtraCallbacks sGpsXtraCallbacks = { 150 xtra_download_request_callback, 151 create_thread_callback, 152 }; 153 154 static void agps_status_callback(AGpsStatus* agps_status) 155 { 156 JNIEnv* env = AndroidRuntime::getJNIEnv(); 157 env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus, 158 agps_status->type, agps_status->status); 159 checkAndClearExceptionFromCallback(env, __FUNCTION__); 160 } 161 162 AGpsCallbacks sAGpsCallbacks = { 163 agps_status_callback, 164 create_thread_callback, 165 }; 166 167 static void gps_ni_notify_callback(GpsNiNotification *notification) 168 { 169 LOGD("gps_ni_notify_callback\n"); 170 JNIEnv* env = AndroidRuntime::getJNIEnv(); 171 jstring requestor_id = env->NewStringUTF(notification->requestor_id); 172 jstring text = env->NewStringUTF(notification->text); 173 jstring extras = env->NewStringUTF(notification->extras); 174 175 if (requestor_id && text && extras) { 176 env->CallVoidMethod(mCallbacksObj, method_reportNiNotification, 177 notification->notification_id, notification->ni_type, 178 notification->notify_flags, notification->timeout, 179 notification->default_response, requestor_id, text, 180 notification->requestor_id_encoding, 181 notification->text_encoding, extras); 182 } else { 183 LOGE("out of memory in gps_ni_notify_callback\n"); 184 } 185 186 if (requestor_id) 187 env->DeleteLocalRef(requestor_id); 188 if (text) 189 env->DeleteLocalRef(text); 190 if (extras) 191 env->DeleteLocalRef(extras); 192 checkAndClearExceptionFromCallback(env, __FUNCTION__); 193 } 194 195 GpsNiCallbacks sGpsNiCallbacks = { 196 gps_ni_notify_callback, 197 create_thread_callback, 198 }; 199 200 static void agps_request_set_id(uint32_t flags) 201 { 202 JNIEnv* env = AndroidRuntime::getJNIEnv(); 203 env->CallVoidMethod(mCallbacksObj, method_requestSetID, flags); 204 checkAndClearExceptionFromCallback(env, __FUNCTION__); 205 } 206 207 static void agps_request_ref_location(uint32_t flags) 208 { 209 JNIEnv* env = AndroidRuntime::getJNIEnv(); 210 env->CallVoidMethod(mCallbacksObj, method_requestRefLocation, flags); 211 checkAndClearExceptionFromCallback(env, __FUNCTION__); 212 } 213 214 AGpsRilCallbacks sAGpsRilCallbacks = { 215 agps_request_set_id, 216 agps_request_ref_location, 217 create_thread_callback, 218 }; 219 220 static const GpsInterface* get_gps_interface() { 221 int err; 222 hw_module_t* module; 223 const GpsInterface* interface = NULL; 224 225 err = hw_get_module(GPS_HARDWARE_MODULE_ID, (hw_module_t const**)&module); 226 if (err == 0) { 227 hw_device_t* device; 228 err = module->methods->open(module, GPS_HARDWARE_MODULE_ID, &device); 229 if (err == 0) { 230 gps_device_t* gps_device = (gps_device_t *)device; 231 interface = gps_device->get_gps_interface(gps_device); 232 } 233 } 234 235 return interface; 236 } 237 238 static const GpsInterface* GetGpsInterface(JNIEnv* env, jobject obj) { 239 // this must be set before calling into the HAL library 240 if (!mCallbacksObj) 241 mCallbacksObj = env->NewGlobalRef(obj); 242 243 if (!sGpsInterface) { 244 sGpsInterface = get_gps_interface(); 245 if (!sGpsInterface || sGpsInterface->init(&sGpsCallbacks) != 0) { 246 sGpsInterface = NULL; 247 return NULL; 248 } 249 } 250 return sGpsInterface; 251 } 252 253 static const AGpsInterface* GetAGpsInterface(JNIEnv* env, jobject obj) 254 { 255 const GpsInterface* interface = GetGpsInterface(env, obj); 256 if (!interface) 257 return NULL; 258 259 if (!sAGpsInterface) { 260 sAGpsInterface = (const AGpsInterface*)interface->get_extension(AGPS_INTERFACE); 261 if (sAGpsInterface) 262 sAGpsInterface->init(&sAGpsCallbacks); 263 } 264 return sAGpsInterface; 265 } 266 267 static const GpsNiInterface* GetNiInterface(JNIEnv* env, jobject obj) 268 { 269 const GpsInterface* interface = GetGpsInterface(env, obj); 270 if (!interface) 271 return NULL; 272 273 if (!sGpsNiInterface) { 274 sGpsNiInterface = (const GpsNiInterface*)interface->get_extension(GPS_NI_INTERFACE); 275 if (sGpsNiInterface) 276 sGpsNiInterface->init(&sGpsNiCallbacks); 277 } 278 return sGpsNiInterface; 279 } 280 281 static const AGpsRilInterface* GetAGpsRilInterface(JNIEnv* env, jobject obj) 282 { 283 const GpsInterface* interface = GetGpsInterface(env, obj); 284 if (!interface) 285 return NULL; 286 287 if (!sAGpsRilInterface) { 288 sAGpsRilInterface = (const AGpsRilInterface*)interface->get_extension(AGPS_RIL_INTERFACE); 289 if (sAGpsRilInterface) 290 sAGpsRilInterface->init(&sAGpsRilCallbacks); 291 } 292 return sAGpsRilInterface; 293 } 294 295 static void android_location_GpsLocationProvider_class_init_native(JNIEnv* env, jclass clazz) { 296 method_reportLocation = env->GetMethodID(clazz, "reportLocation", "(IDDDFFFJ)V"); 297 method_reportStatus = env->GetMethodID(clazz, "reportStatus", "(I)V"); 298 method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "()V"); 299 method_reportAGpsStatus = env->GetMethodID(clazz, "reportAGpsStatus", "(II)V"); 300 method_reportNmea = env->GetMethodID(clazz, "reportNmea", "(J)V"); 301 method_setEngineCapabilities = env->GetMethodID(clazz, "setEngineCapabilities", "(I)V"); 302 method_xtraDownloadRequest = env->GetMethodID(clazz, "xtraDownloadRequest", "()V"); 303 method_reportNiNotification = env->GetMethodID(clazz, "reportNiNotification", "(IIIIILjava/lang/String;Ljava/lang/String;IILjava/lang/String;)V"); 304 method_requestRefLocation = env->GetMethodID(clazz,"requestRefLocation","(I)V"); 305 method_requestSetID = env->GetMethodID(clazz,"requestSetID","(I)V"); 306 } 307 308 static jboolean android_location_GpsLocationProvider_is_supported(JNIEnv* env, jclass clazz) { 309 return (sGpsInterface != NULL || get_gps_interface() != NULL); 310 } 311 312 static jboolean android_location_GpsLocationProvider_init(JNIEnv* env, jobject obj) 313 { 314 const GpsInterface* interface = GetGpsInterface(env, obj); 315 if (!interface) 316 return false; 317 318 if (!sGpsDebugInterface) 319 sGpsDebugInterface = (const GpsDebugInterface*)interface->get_extension(GPS_DEBUG_INTERFACE); 320 321 return true; 322 } 323 324 static void android_location_GpsLocationProvider_cleanup(JNIEnv* env, jobject obj) 325 { 326 const GpsInterface* interface = GetGpsInterface(env, obj); 327 if (interface) 328 interface->cleanup(); 329 } 330 331 static jboolean android_location_GpsLocationProvider_set_position_mode(JNIEnv* env, jobject obj, 332 jint mode, jint recurrence, jint min_interval, jint preferred_accuracy, jint preferred_time) 333 { 334 const GpsInterface* interface = GetGpsInterface(env, obj); 335 if (interface) 336 return (interface->set_position_mode(mode, recurrence, min_interval, preferred_accuracy, 337 preferred_time) == 0); 338 else 339 return false; 340 } 341 342 static jboolean android_location_GpsLocationProvider_start(JNIEnv* env, jobject obj) 343 { 344 const GpsInterface* interface = GetGpsInterface(env, obj); 345 if (interface) 346 return (interface->start() == 0); 347 else 348 return false; 349 } 350 351 static jboolean android_location_GpsLocationProvider_stop(JNIEnv* env, jobject obj) 352 { 353 const GpsInterface* interface = GetGpsInterface(env, obj); 354 if (interface) 355 return (interface->stop() == 0); 356 else 357 return false; 358 } 359 360 static void android_location_GpsLocationProvider_delete_aiding_data(JNIEnv* env, jobject obj, jint flags) 361 { 362 const GpsInterface* interface = GetGpsInterface(env, obj); 363 if (interface) 364 interface->delete_aiding_data(flags); 365 } 366 367 static jint android_location_GpsLocationProvider_read_sv_status(JNIEnv* env, jobject obj, 368 jintArray prnArray, jfloatArray snrArray, jfloatArray elevArray, jfloatArray azumArray, 369 jintArray maskArray) 370 { 371 // this should only be called from within a call to reportSvStatus 372 373 jint* prns = env->GetIntArrayElements(prnArray, 0); 374 jfloat* snrs = env->GetFloatArrayElements(snrArray, 0); 375 jfloat* elev = env->GetFloatArrayElements(elevArray, 0); 376 jfloat* azim = env->GetFloatArrayElements(azumArray, 0); 377 jint* mask = env->GetIntArrayElements(maskArray, 0); 378 379 int num_svs = sGpsSvStatus.num_svs; 380 for (int i = 0; i < num_svs; i++) { 381 prns[i] = sGpsSvStatus.sv_list[i].prn; 382 snrs[i] = sGpsSvStatus.sv_list[i].snr; 383 elev[i] = sGpsSvStatus.sv_list[i].elevation; 384 azim[i] = sGpsSvStatus.sv_list[i].azimuth; 385 } 386 mask[0] = sGpsSvStatus.ephemeris_mask; 387 mask[1] = sGpsSvStatus.almanac_mask; 388 mask[2] = sGpsSvStatus.used_in_fix_mask; 389 390 env->ReleaseIntArrayElements(prnArray, prns, 0); 391 env->ReleaseFloatArrayElements(snrArray, snrs, 0); 392 env->ReleaseFloatArrayElements(elevArray, elev, 0); 393 env->ReleaseFloatArrayElements(azumArray, azim, 0); 394 env->ReleaseIntArrayElements(maskArray, mask, 0); 395 return num_svs; 396 } 397 398 static void android_location_GpsLocationProvider_agps_set_reference_location_cellid(JNIEnv* env, 399 jobject obj, jint type, jint mcc, jint mnc, jint lac, jint cid) 400 { 401 AGpsRefLocation location; 402 const AGpsRilInterface* interface = GetAGpsRilInterface(env, obj); 403 if (!interface) { 404 LOGE("no AGPS RIL interface in agps_set_reference_location_cellid"); 405 return; 406 } 407 408 switch(type) { 409 case AGPS_REF_LOCATION_TYPE_GSM_CELLID: 410 case AGPS_REF_LOCATION_TYPE_UMTS_CELLID: 411 location.type = type; 412 location.u.cellID.mcc = mcc; 413 location.u.cellID.mnc = mnc; 414 location.u.cellID.lac = lac; 415 location.u.cellID.cid = cid; 416 break; 417 default: 418 LOGE("Neither a GSM nor a UMTS cellid (%s:%d).",__FUNCTION__,__LINE__); 419 return; 420 break; 421 } 422 interface->set_ref_location(&location, sizeof(location)); 423 } 424 425 static void android_location_GpsLocationProvider_agps_send_ni_message(JNIEnv* env, 426 jobject obj, jbyteArray ni_msg, jint size) 427 { 428 size_t sz; 429 const AGpsRilInterface* interface = GetAGpsRilInterface(env, obj); 430 if (!interface) { 431 LOGE("no AGPS RIL interface in send_ni_message"); 432 return; 433 } 434 if (size < 0) 435 return; 436 sz = (size_t)size; 437 jbyte* b = env->GetByteArrayElements(ni_msg, 0); 438 interface->ni_message((uint8_t *)b,sz); 439 env->ReleaseByteArrayElements(ni_msg,b,0); 440 } 441 442 static void android_location_GpsLocationProvider_agps_set_id(JNIEnv *env, 443 jobject obj, jint type, jstring setid_string) 444 { 445 const AGpsRilInterface* interface = GetAGpsRilInterface(env, obj); 446 if (!interface) { 447 LOGE("no AGPS RIL interface in agps_set_id"); 448 return; 449 } 450 451 const char *setid = env->GetStringUTFChars(setid_string, NULL); 452 interface->set_set_id(type, setid); 453 env->ReleaseStringUTFChars(setid_string, setid); 454 } 455 456 static jint android_location_GpsLocationProvider_read_nmea(JNIEnv* env, jobject obj, 457 jbyteArray nmeaArray, jint buffer_size) 458 { 459 // this should only be called from within a call to reportNmea 460 jbyte* nmea = (jbyte *)env->GetPrimitiveArrayCritical(nmeaArray, 0); 461 int length = sNmeaStringLength; 462 if (length > buffer_size) 463 length = buffer_size; 464 memcpy(nmea, sNmeaString, length); 465 env->ReleasePrimitiveArrayCritical(nmeaArray, nmea, JNI_ABORT); 466 return length; 467 } 468 469 static void android_location_GpsLocationProvider_inject_time(JNIEnv* env, jobject obj, 470 jlong time, jlong timeReference, jint uncertainty) 471 { 472 const GpsInterface* interface = GetGpsInterface(env, obj); 473 if (interface) 474 interface->inject_time(time, timeReference, uncertainty); 475 } 476 477 static void android_location_GpsLocationProvider_inject_location(JNIEnv* env, jobject obj, 478 jdouble latitude, jdouble longitude, jfloat accuracy) 479 { 480 const GpsInterface* interface = GetGpsInterface(env, obj); 481 if (interface) 482 interface->inject_location(latitude, longitude, accuracy); 483 } 484 485 static jboolean android_location_GpsLocationProvider_supports_xtra(JNIEnv* env, jobject obj) 486 { 487 if (!sGpsXtraInterface) { 488 const GpsInterface* interface = GetGpsInterface(env, obj); 489 if (!interface) 490 return false; 491 sGpsXtraInterface = (const GpsXtraInterface*)interface->get_extension(GPS_XTRA_INTERFACE); 492 if (sGpsXtraInterface) { 493 int result = sGpsXtraInterface->init(&sGpsXtraCallbacks); 494 if (result) { 495 sGpsXtraInterface = NULL; 496 } 497 } 498 } 499 500 return (sGpsXtraInterface != NULL); 501 } 502 503 static void android_location_GpsLocationProvider_inject_xtra_data(JNIEnv* env, jobject obj, 504 jbyteArray data, jint length) 505 { 506 jbyte* bytes = (jbyte *)env->GetPrimitiveArrayCritical(data, 0); 507 sGpsXtraInterface->inject_xtra_data((char *)bytes, length); 508 env->ReleasePrimitiveArrayCritical(data, bytes, JNI_ABORT); 509 } 510 511 static void android_location_GpsLocationProvider_agps_data_conn_open(JNIEnv* env, jobject obj, jstring apn) 512 { 513 const AGpsInterface* interface = GetAGpsInterface(env, obj); 514 if (!interface) { 515 LOGE("no AGPS interface in agps_data_conn_open"); 516 return; 517 } 518 if (apn == NULL) { 519 jniThrowException(env, "java/lang/IllegalArgumentException", NULL); 520 return; 521 } 522 const char *apnStr = env->GetStringUTFChars(apn, NULL); 523 interface->data_conn_open(apnStr); 524 env->ReleaseStringUTFChars(apn, apnStr); 525 } 526 527 static void android_location_GpsLocationProvider_agps_data_conn_closed(JNIEnv* env, jobject obj) 528 { 529 const AGpsInterface* interface = GetAGpsInterface(env, obj); 530 if (!interface) { 531 LOGE("no AGPS interface in agps_data_conn_open"); 532 return; 533 } 534 interface->data_conn_closed(); 535 } 536 537 static void android_location_GpsLocationProvider_agps_data_conn_failed(JNIEnv* env, jobject obj) 538 { 539 const AGpsInterface* interface = GetAGpsInterface(env, obj); 540 if (!interface) { 541 LOGE("no AGPS interface in agps_data_conn_open"); 542 return; 543 } 544 interface->data_conn_failed(); 545 } 546 547 static void android_location_GpsLocationProvider_set_agps_server(JNIEnv* env, jobject obj, 548 jint type, jstring hostname, jint port) 549 { 550 const AGpsInterface* interface = GetAGpsInterface(env, obj); 551 if (!interface) { 552 LOGE("no AGPS interface in agps_data_conn_open"); 553 return; 554 } 555 const char *c_hostname = env->GetStringUTFChars(hostname, NULL); 556 interface->set_server(type, c_hostname, port); 557 env->ReleaseStringUTFChars(hostname, c_hostname); 558 } 559 560 static void android_location_GpsLocationProvider_send_ni_response(JNIEnv* env, jobject obj, 561 jint notifId, jint response) 562 { 563 const GpsNiInterface* interface = GetNiInterface(env, obj); 564 if (!interface) { 565 LOGE("no NI interface in send_ni_response"); 566 return; 567 } 568 569 interface->respond(notifId, response); 570 } 571 572 static jstring android_location_GpsLocationProvider_get_internal_state(JNIEnv* env, jobject obj) 573 { 574 jstring result = NULL; 575 if (sGpsDebugInterface) { 576 const size_t maxLength = 2047; 577 char buffer[maxLength+1]; 578 size_t length = sGpsDebugInterface->get_internal_state(buffer, maxLength); 579 if (length > maxLength) length = maxLength; 580 buffer[length] = 0; 581 result = env->NewStringUTF(buffer); 582 } 583 return result; 584 } 585 586 static void android_location_GpsLocationProvider_update_network_state(JNIEnv* env, jobject obj, 587 jboolean connected, int type, jboolean roaming, jstring extraInfo) 588 { 589 const AGpsRilInterface* interface = GetAGpsRilInterface(env, obj); 590 if (interface && interface->update_network_state) { 591 if (extraInfo) { 592 const char *extraInfoStr = env->GetStringUTFChars(extraInfo, NULL); 593 interface->update_network_state(connected, type, roaming, extraInfoStr); 594 env->ReleaseStringUTFChars(extraInfo, extraInfoStr); 595 } else { 596 interface->update_network_state(connected, type, roaming, NULL); 597 } 598 } 599 } 600 601 static JNINativeMethod sMethods[] = { 602 /* name, signature, funcPtr */ 603 {"class_init_native", "()V", (void *)android_location_GpsLocationProvider_class_init_native}, 604 {"native_is_supported", "()Z", (void*)android_location_GpsLocationProvider_is_supported}, 605 {"native_init", "()Z", (void*)android_location_GpsLocationProvider_init}, 606 {"native_cleanup", "()V", (void*)android_location_GpsLocationProvider_cleanup}, 607 {"native_set_position_mode", "(IIIII)Z", (void*)android_location_GpsLocationProvider_set_position_mode}, 608 {"native_start", "()Z", (void*)android_location_GpsLocationProvider_start}, 609 {"native_stop", "()Z", (void*)android_location_GpsLocationProvider_stop}, 610 {"native_delete_aiding_data", "(I)V", (void*)android_location_GpsLocationProvider_delete_aiding_data}, 611 {"native_read_sv_status", "([I[F[F[F[I)I", (void*)android_location_GpsLocationProvider_read_sv_status}, 612 {"native_read_nmea", "([BI)I", (void*)android_location_GpsLocationProvider_read_nmea}, 613 {"native_inject_time", "(JJI)V", (void*)android_location_GpsLocationProvider_inject_time}, 614 {"native_inject_location", "(DDF)V", (void*)android_location_GpsLocationProvider_inject_location}, 615 {"native_supports_xtra", "()Z", (void*)android_location_GpsLocationProvider_supports_xtra}, 616 {"native_inject_xtra_data", "([BI)V", (void*)android_location_GpsLocationProvider_inject_xtra_data}, 617 {"native_agps_data_conn_open", "(Ljava/lang/String;)V", (void*)android_location_GpsLocationProvider_agps_data_conn_open}, 618 {"native_agps_data_conn_closed", "()V", (void*)android_location_GpsLocationProvider_agps_data_conn_closed}, 619 {"native_agps_data_conn_failed", "()V", (void*)android_location_GpsLocationProvider_agps_data_conn_failed}, 620 {"native_agps_set_id","(ILjava/lang/String;)V",(void*)android_location_GpsLocationProvider_agps_set_id}, 621 {"native_agps_set_ref_location_cellid","(IIIII)V",(void*)android_location_GpsLocationProvider_agps_set_reference_location_cellid}, 622 {"native_set_agps_server", "(ILjava/lang/String;I)V", (void*)android_location_GpsLocationProvider_set_agps_server}, 623 {"native_send_ni_response", "(II)V", (void*)android_location_GpsLocationProvider_send_ni_response}, 624 {"native_agps_ni_message", "([BI)V", (void *)android_location_GpsLocationProvider_agps_send_ni_message}, 625 {"native_get_internal_state", "()Ljava/lang/String;", (void*)android_location_GpsLocationProvider_get_internal_state}, 626 {"native_update_network_state", "(ZIZLjava/lang/String;)V", (void*)android_location_GpsLocationProvider_update_network_state }, 627 }; 628 629 int register_android_server_location_GpsLocationProvider(JNIEnv* env) 630 { 631 return jniRegisterNativeMethods(env, "com/android/server/location/GpsLocationProvider", sMethods, NELEM(sMethods)); 632 } 633 634 } /* namespace android */ 635