com_android_server_location_GpsLocationProvider.cpp revision a9e546169b3c2c9c5f248d2f3abe3b934f48695d
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define LOG_TAG "GpsLocationProvider" 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "JNIHelp.h" 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "jni.h" 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "hardware_legacy/gps.h" 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "utils/Log.h" 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "utils/misc.h" 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <string.h> 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <pthread.h> 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic pthread_mutex_t sEventMutex = PTHREAD_MUTEX_INITIALIZER; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic pthread_cond_t sEventCond = PTHREAD_COND_INITIALIZER; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jmethodID method_reportLocation; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jmethodID method_reportStatus; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jmethodID method_reportSvStatus; 34e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwoodstatic jmethodID method_reportAGpsStatus; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jmethodID method_xtraDownloadRequest; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const GpsInterface* sGpsInterface = NULL; 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const GpsXtraInterface* sGpsXtraInterface = NULL; 39e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwoodstatic const AGpsInterface* sAGpsInterface = NULL; 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// data written to by GPS callbacks 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic GpsLocation sGpsLocation; 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic GpsStatus sGpsStatus; 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic GpsSvStatus sGpsSvStatus; 45e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwoodstatic AGpsStatus sAGpsStatus; 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// a copy of the data shared by android_location_GpsLocationProvider_wait_for_event 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// and android_location_GpsLocationProvider_read_status 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic GpsLocation sGpsLocationCopy; 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic GpsStatus sGpsStatusCopy; 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic GpsSvStatus sGpsSvStatusCopy; 52e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwoodstatic AGpsStatus sAGpsStatusCopy; 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectenum CallbackType { 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project kLocation = 1, 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project kStatus = 2, 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project kSvStatus = 4, 58e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood kAGpsStatus = 8, 5958bda987665af759c379cd494ff4873ac61acf29Mike Lockwood kXtraDownloadRequest = 16, 6058bda987665af759c379cd494ff4873ac61acf29Mike Lockwood kDisableRequest = 32, 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int sPendingCallbacks; 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android { 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void location_callback(GpsLocation* location) 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pthread_mutex_lock(&sEventMutex); 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sPendingCallbacks |= kLocation; 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memcpy(&sGpsLocation, location, sizeof(sGpsLocation)); 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pthread_cond_signal(&sEventCond); 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pthread_mutex_unlock(&sEventMutex); 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void status_callback(GpsStatus* status) 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pthread_mutex_lock(&sEventMutex); 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sPendingCallbacks |= kStatus; 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memcpy(&sGpsStatus, status, sizeof(sGpsStatus)); 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pthread_cond_signal(&sEventCond); 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pthread_mutex_unlock(&sEventMutex); 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void sv_status_callback(GpsSvStatus* sv_status) 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pthread_mutex_lock(&sEventMutex); 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sPendingCallbacks |= kSvStatus; 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memcpy(&sGpsSvStatus, sv_status, sizeof(GpsSvStatus)); 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pthread_cond_signal(&sEventCond); 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pthread_mutex_unlock(&sEventMutex); 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 99e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwoodstatic void agps_status_callback(AGpsStatus* agps_status) 10058bda987665af759c379cd494ff4873ac61acf29Mike Lockwood{ 10158bda987665af759c379cd494ff4873ac61acf29Mike Lockwood pthread_mutex_lock(&sEventMutex); 10258bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 103e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood sPendingCallbacks |= kAGpsStatus; 104e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood memcpy(&sAGpsStatus, agps_status, sizeof(AGpsStatus)); 10558bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 10658bda987665af759c379cd494ff4873ac61acf29Mike Lockwood pthread_cond_signal(&sEventCond); 10758bda987665af759c379cd494ff4873ac61acf29Mike Lockwood pthread_mutex_unlock(&sEventMutex); 10858bda987665af759c379cd494ff4873ac61acf29Mike Lockwood} 10958bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectGpsCallbacks sGpsCallbacks = { 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project location_callback, 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_callback, 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sv_status_callback, 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectdownload_request_callback() 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pthread_mutex_lock(&sEventMutex); 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sPendingCallbacks |= kXtraDownloadRequest; 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pthread_cond_signal(&sEventCond); 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pthread_mutex_unlock(&sEventMutex); 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectGpsXtraCallbacks sGpsXtraCallbacks = { 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project download_request_callback, 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 129e3635c9693c4cd9650684f14e19dcabcea0d488aMike LockwoodAGpsCallbacks sAGpsCallbacks = { 130e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood agps_status_callback, 13158bda987665af759c379cd494ff4873ac61acf29Mike Lockwood}; 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_location_GpsLocationProvider_class_init_native(JNIEnv* env, jclass clazz) { 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project method_reportLocation = env->GetMethodID(clazz, "reportLocation", "(IDDDFFFJ)V"); 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project method_reportStatus = env->GetMethodID(clazz, "reportStatus", "(I)V"); 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "()V"); 137e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood method_reportAGpsStatus = env->GetMethodID(clazz, "reportAGpsStatus", "(II)V"); 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project method_xtraDownloadRequest = env->GetMethodID(clazz, "xtraDownloadRequest", "()V"); 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jboolean android_location_GpsLocationProvider_is_supported(JNIEnv* env, jclass clazz) { 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!sGpsInterface) 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sGpsInterface = gps_get_interface(); 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (sGpsInterface != NULL); 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jboolean android_location_GpsLocationProvider_init(JNIEnv* env, jobject obj) 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!sGpsInterface) 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sGpsInterface = gps_get_interface(); 15158bda987665af759c379cd494ff4873ac61acf29Mike Lockwood if (!sGpsInterface || sGpsInterface->init(&sGpsCallbacks) != 0) 15258bda987665af759c379cd494ff4873ac61acf29Mike Lockwood return false; 15358bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 154e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood if (!sAGpsInterface) 155e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood sAGpsInterface = (const AGpsInterface*)sGpsInterface->get_extension(AGPS_INTERFACE); 156e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood if (sAGpsInterface) 157e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood sAGpsInterface->init(&sAGpsCallbacks); 158c21a08f747f6fd1d7b8c98176ff70abc57cf58a0Mike Lockwood return true; 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_location_GpsLocationProvider_disable(JNIEnv* env, jobject obj) 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pthread_mutex_lock(&sEventMutex); 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sPendingCallbacks |= kDisableRequest; 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pthread_cond_signal(&sEventCond); 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pthread_mutex_unlock(&sEventMutex); 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_location_GpsLocationProvider_cleanup(JNIEnv* env, jobject obj) 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sGpsInterface->cleanup(); 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 174105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Projectstatic jboolean android_location_GpsLocationProvider_start(JNIEnv* env, jobject obj, jint positionMode, 175105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project jboolean singleFix, jint fixFrequency) 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 177105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project int result = sGpsInterface->set_position_mode(positionMode, (singleFix ? 0 : fixFrequency)); 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (result) { 1799a940e8b3d61539392c1a9f925be13cca8b5103dDavid 'Digit' Turner return false; 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (sGpsInterface->start() == 0); 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jboolean android_location_GpsLocationProvider_stop(JNIEnv* env, jobject obj) 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (sGpsInterface->stop() == 0); 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_location_GpsLocationProvider_delete_aiding_data(JNIEnv* env, jobject obj, jint flags) 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sGpsInterface->delete_aiding_data(flags); 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_location_GpsLocationProvider_wait_for_event(JNIEnv* env, jobject obj) 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pthread_mutex_lock(&sEventMutex); 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pthread_cond_wait(&sEventCond, &sEventMutex); 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // copy and clear the callback flags 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int pendingCallbacks = sPendingCallbacks; 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sPendingCallbacks = 0; 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // copy everything and unlock the mutex before calling into Java code to avoid the possibility 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // of timeouts in the GPS engine. 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memcpy(&sGpsLocationCopy, &sGpsLocation, sizeof(sGpsLocationCopy)); 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memcpy(&sGpsStatusCopy, &sGpsStatus, sizeof(sGpsStatusCopy)); 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memcpy(&sGpsSvStatusCopy, &sGpsSvStatus, sizeof(sGpsSvStatusCopy)); 209e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood memcpy(&sAGpsStatusCopy, &sAGpsStatus, sizeof(sAGpsStatusCopy)); 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pthread_mutex_unlock(&sEventMutex); 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pendingCallbacks & kLocation) { 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->CallVoidMethod(obj, method_reportLocation, sGpsLocationCopy.flags, 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (jdouble)sGpsLocationCopy.latitude, (jdouble)sGpsLocationCopy.longitude, 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (jdouble)sGpsLocationCopy.altitude, 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (jfloat)sGpsLocationCopy.speed, (jfloat)sGpsLocationCopy.bearing, 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (jfloat)sGpsLocationCopy.accuracy, (jlong)sGpsLocationCopy.timestamp); 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pendingCallbacks & kStatus) { 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->CallVoidMethod(obj, method_reportStatus, sGpsStatusCopy.status); 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pendingCallbacks & kSvStatus) { 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->CallVoidMethod(obj, method_reportSvStatus); 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 225e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood if (pendingCallbacks & kAGpsStatus) { 226e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood env->CallVoidMethod(obj, method_reportAGpsStatus, sAGpsStatusCopy.type, sAGpsStatusCopy.status); 22758bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pendingCallbacks & kXtraDownloadRequest) { 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->CallVoidMethod(obj, method_xtraDownloadRequest); 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pendingCallbacks & kDisableRequest) { 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // don't need to do anything - we are just poking so wait_for_event will return. 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint android_location_GpsLocationProvider_read_sv_status(JNIEnv* env, jobject obj, 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jintArray prnArray, jfloatArray snrArray, jfloatArray elevArray, jfloatArray azumArray, 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jintArray maskArray) 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // this should only be called from within a call to reportStatus, so we don't need to lock here 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jint* prns = env->GetIntArrayElements(prnArray, 0); 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfloat* snrs = env->GetFloatArrayElements(snrArray, 0); 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfloat* elev = env->GetFloatArrayElements(elevArray, 0); 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfloat* azim = env->GetFloatArrayElements(azumArray, 0); 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jint* mask = env->GetIntArrayElements(maskArray, 0); 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int num_svs = sGpsSvStatusCopy.num_svs; 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < num_svs; i++) { 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project prns[i] = sGpsSvStatusCopy.sv_list[i].prn; 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project snrs[i] = sGpsSvStatusCopy.sv_list[i].snr; 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project elev[i] = sGpsSvStatusCopy.sv_list[i].elevation; 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project azim[i] = sGpsSvStatusCopy.sv_list[i].azimuth; 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mask[0] = sGpsSvStatusCopy.ephemeris_mask; 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mask[1] = sGpsSvStatusCopy.almanac_mask; 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mask[2] = sGpsSvStatusCopy.used_in_fix_mask; 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->ReleaseIntArrayElements(prnArray, prns, 0); 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->ReleaseFloatArrayElements(snrArray, snrs, 0); 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->ReleaseFloatArrayElements(elevArray, elev, 0); 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->ReleaseFloatArrayElements(azumArray, azim, 0); 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->ReleaseIntArrayElements(maskArray, mask, 0); 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return num_svs; 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_location_GpsLocationProvider_inject_time(JNIEnv* env, jobject obj, jlong time, 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jlong timeReference, jint uncertainty) 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sGpsInterface->inject_time(time, timeReference, uncertainty); 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 273d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwoodstatic void android_location_GpsLocationProvider_inject_location(JNIEnv* env, jobject obj, 274d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood jdouble latitude, jdouble longitude, jfloat accuracy) 275d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood{ 276d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood sGpsInterface->inject_location(latitude, longitude, accuracy); 277d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood} 278d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jboolean android_location_GpsLocationProvider_supports_xtra(JNIEnv* env, jobject obj) 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!sGpsXtraInterface) { 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sGpsXtraInterface = (const GpsXtraInterface*)sGpsInterface->get_extension(GPS_XTRA_INTERFACE); 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sGpsXtraInterface) { 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int result = sGpsXtraInterface->init(&sGpsXtraCallbacks); 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (result) { 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sGpsXtraInterface = NULL; 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (sGpsXtraInterface != NULL); 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_location_GpsLocationProvider_inject_xtra_data(JNIEnv* env, jobject obj, 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jbyteArray data, jint length) 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jbyte* bytes = env->GetByteArrayElements(data, 0); 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sGpsXtraInterface->inject_xtra_data((char *)bytes, length); 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->ReleaseByteArrayElements(data, bytes, 0); 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 302e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwoodstatic void android_location_GpsLocationProvider_agps_data_conn_open(JNIEnv* env, jobject obj, jstring apn) 303105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project{ 304e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood if (!sAGpsInterface) { 305e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood sAGpsInterface = (const AGpsInterface*)sGpsInterface->get_extension(AGPS_INTERFACE); 306105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 307e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood if (sAGpsInterface) { 30858bda987665af759c379cd494ff4873ac61acf29Mike Lockwood if (apn == NULL) { 30958bda987665af759c379cd494ff4873ac61acf29Mike Lockwood jniThrowException(env, "java/lang/IllegalArgumentException", NULL); 31058bda987665af759c379cd494ff4873ac61acf29Mike Lockwood return; 31158bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } 31258bda987665af759c379cd494ff4873ac61acf29Mike Lockwood const char *apnStr = env->GetStringUTFChars(apn, NULL); 313e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood sAGpsInterface->data_conn_open(apnStr); 31458bda987665af759c379cd494ff4873ac61acf29Mike Lockwood env->ReleaseStringUTFChars(apn, apnStr); 315105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 316105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project} 317105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 318e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwoodstatic void android_location_GpsLocationProvider_agps_data_conn_closed(JNIEnv* env, jobject obj) 319105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project{ 320e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood if (!sAGpsInterface) { 321e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood sAGpsInterface = (const AGpsInterface*)sGpsInterface->get_extension(AGPS_INTERFACE); 322105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 323e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood if (sAGpsInterface) { 324e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood sAGpsInterface->data_conn_closed(); 32558bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } 32658bda987665af759c379cd494ff4873ac61acf29Mike Lockwood} 32758bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 328e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwoodstatic void android_location_GpsLocationProvider_agps_data_conn_failed(JNIEnv* env, jobject obj) 32958bda987665af759c379cd494ff4873ac61acf29Mike Lockwood{ 330e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood if (!sAGpsInterface) { 331e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood sAGpsInterface = (const AGpsInterface*)sGpsInterface->get_extension(AGPS_INTERFACE); 33258bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } 333e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood if (sAGpsInterface) { 334e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood sAGpsInterface->data_conn_failed(); 33558bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } 33658bda987665af759c379cd494ff4873ac61acf29Mike Lockwood} 33758bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 338e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwoodstatic void android_location_GpsLocationProvider_set_agps_server(JNIEnv* env, jobject obj, 339a9e546169b3c2c9c5f248d2f3abe3b934f48695dMike Lockwood jint type, jstring hostname, jint port) 34058bda987665af759c379cd494ff4873ac61acf29Mike Lockwood{ 341e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood if (!sAGpsInterface) { 342e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood sAGpsInterface = (const AGpsInterface*)sGpsInterface->get_extension(AGPS_INTERFACE); 34358bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } 344e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood if (sAGpsInterface) { 345a9e546169b3c2c9c5f248d2f3abe3b934f48695dMike Lockwood const char *c_hostname = env->GetStringUTFChars(hostname, NULL); 346a9e546169b3c2c9c5f248d2f3abe3b934f48695dMike Lockwood sAGpsInterface->set_server(type, c_hostname, port); 347a9e546169b3c2c9c5f248d2f3abe3b934f48695dMike Lockwood env->ReleaseStringUTFChars(hostname, c_hostname); 348105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 349105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project} 350105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNINativeMethod sMethods[] = { 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* name, signature, funcPtr */ 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"class_init_native", "()V", (void *)android_location_GpsLocationProvider_class_init_native}, 354e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood {"native_is_supported", "()Z", (void*)android_location_GpsLocationProvider_is_supported}, 355e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood {"native_init", "()Z", (void*)android_location_GpsLocationProvider_init}, 356e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood {"native_disable", "()V", (void*)android_location_GpsLocationProvider_disable}, 357e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood {"native_cleanup", "()V", (void*)android_location_GpsLocationProvider_cleanup}, 358e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood {"native_start", "(IZI)Z", (void*)android_location_GpsLocationProvider_start}, 359e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood {"native_stop", "()Z", (void*)android_location_GpsLocationProvider_stop}, 360e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood {"native_delete_aiding_data", "(I)V", (void*)android_location_GpsLocationProvider_delete_aiding_data}, 361e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood {"native_wait_for_event", "()V", (void*)android_location_GpsLocationProvider_wait_for_event}, 362e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood {"native_read_sv_status", "([I[F[F[F[I)I", (void*)android_location_GpsLocationProvider_read_sv_status}, 363e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood {"native_inject_time", "(JJI)V", (void*)android_location_GpsLocationProvider_inject_time}, 364d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood {"native_inject_location", "(DDF)V", (void*)android_location_GpsLocationProvider_inject_location}, 365e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood {"native_supports_xtra", "()Z", (void*)android_location_GpsLocationProvider_supports_xtra}, 366e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood {"native_inject_xtra_data", "([BI)V", (void*)android_location_GpsLocationProvider_inject_xtra_data}, 367e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood {"native_agps_data_conn_open", "(Ljava/lang/String;)V", (void*)android_location_GpsLocationProvider_agps_data_conn_open}, 368e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood {"native_agps_data_conn_closed", "()V", (void*)android_location_GpsLocationProvider_agps_data_conn_closed}, 369e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood {"native_agps_data_conn_failed", "()V", (void*)android_location_GpsLocationProvider_agps_data_conn_failed}, 370a9e546169b3c2c9c5f248d2f3abe3b934f48695dMike Lockwood {"native_set_agps_server", "(ILjava/lang/String;I)V", (void*)android_location_GpsLocationProvider_set_agps_server}, 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint register_android_location_GpsLocationProvider(JNIEnv* env) 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return jniRegisterNativeMethods(env, "com/android/internal/location/GpsLocationProvider", sMethods, NELEM(sMethods)); 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} /* namespace android */ 379