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