com_android_server_location_GpsLocationProvider.cpp revision c21a08f747f6fd1d7b8c98176ff70abc57cf58a0
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; 3458bda987665af759c379cd494ff4873ac61acf29Mike Lockwoodstatic jmethodID method_reportSuplStatus; 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; 39105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Projectstatic const GpsSuplInterface* sGpsSuplInterface = 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; 4558bda987665af759c379cd494ff4873ac61acf29Mike Lockwoodstatic GpsSuplStatus sGpsSuplStatus; 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; 5258bda987665af759c379cd494ff4873ac61acf29Mike Lockwoodstatic GpsSuplStatus sGpsSuplStatusCopy; 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, 5858bda987665af759c379cd494ff4873ac61acf29Mike Lockwood kSuplStatus = 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 9958bda987665af759c379cd494ff4873ac61acf29Mike Lockwoodstatic void supl_status_callback(GpsSuplStatus* supl_status) 10058bda987665af759c379cd494ff4873ac61acf29Mike Lockwood{ 10158bda987665af759c379cd494ff4873ac61acf29Mike Lockwood pthread_mutex_lock(&sEventMutex); 10258bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 10358bda987665af759c379cd494ff4873ac61acf29Mike Lockwood sPendingCallbacks |= kSuplStatus; 10458bda987665af759c379cd494ff4873ac61acf29Mike Lockwood memcpy(&sGpsSuplStatus, supl_status, sizeof(GpsSuplStatus)); 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 12958bda987665af759c379cd494ff4873ac61acf29Mike LockwoodGpsSuplCallbacks sGpsSuplCallbacks = { 13058bda987665af759c379cd494ff4873ac61acf29Mike Lockwood supl_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"); 13758bda987665af759c379cd494ff4873ac61acf29Mike Lockwood method_reportSuplStatus = env->GetMethodID(clazz, "reportSuplStatus", "(I)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 15458bda987665af759c379cd494ff4873ac61acf29Mike Lockwood if (!sGpsSuplInterface) 15558bda987665af759c379cd494ff4873ac61acf29Mike Lockwood sGpsSuplInterface = (const GpsSuplInterface*)sGpsInterface->get_extension(GPS_SUPL_INTERFACE); 15658bda987665af759c379cd494ff4873ac61acf29Mike Lockwood if (sGpsSuplInterface) 15758bda987665af759c379cd494ff4873ac61acf29Mike Lockwood sGpsSuplInterface->init(&sGpsSuplCallbacks); 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) { 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return result; 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_set_fix_frequency(JNIEnv* env, jobject obj, jint fixFrequency) 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sGpsInterface->set_fix_frequency) 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sGpsInterface->set_fix_frequency(fixFrequency); 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_location_GpsLocationProvider_delete_aiding_data(JNIEnv* env, jobject obj, jint flags) 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sGpsInterface->delete_aiding_data(flags); 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_location_GpsLocationProvider_wait_for_event(JNIEnv* env, jobject obj) 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pthread_mutex_lock(&sEventMutex); 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pthread_cond_wait(&sEventCond, &sEventMutex); 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // copy and clear the callback flags 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int pendingCallbacks = sPendingCallbacks; 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sPendingCallbacks = 0; 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // copy everything and unlock the mutex before calling into Java code to avoid the possibility 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // of timeouts in the GPS engine. 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memcpy(&sGpsLocationCopy, &sGpsLocation, sizeof(sGpsLocationCopy)); 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memcpy(&sGpsStatusCopy, &sGpsStatus, sizeof(sGpsStatusCopy)); 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memcpy(&sGpsSvStatusCopy, &sGpsSvStatus, sizeof(sGpsSvStatusCopy)); 21558bda987665af759c379cd494ff4873ac61acf29Mike Lockwood memcpy(&sGpsSuplStatusCopy, &sGpsSuplStatus, sizeof(sGpsSuplStatusCopy)); 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pthread_mutex_unlock(&sEventMutex); 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pendingCallbacks & kLocation) { 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->CallVoidMethod(obj, method_reportLocation, sGpsLocationCopy.flags, 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (jdouble)sGpsLocationCopy.latitude, (jdouble)sGpsLocationCopy.longitude, 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (jdouble)sGpsLocationCopy.altitude, 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (jfloat)sGpsLocationCopy.speed, (jfloat)sGpsLocationCopy.bearing, 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (jfloat)sGpsLocationCopy.accuracy, (jlong)sGpsLocationCopy.timestamp); 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pendingCallbacks & kStatus) { 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->CallVoidMethod(obj, method_reportStatus, sGpsStatusCopy.status); 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pendingCallbacks & kSvStatus) { 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->CallVoidMethod(obj, method_reportSvStatus); 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23158bda987665af759c379cd494ff4873ac61acf29Mike Lockwood if (pendingCallbacks & kSuplStatus) { 23258bda987665af759c379cd494ff4873ac61acf29Mike Lockwood env->CallVoidMethod(obj, method_reportSuplStatus, sGpsSuplStatusCopy.status); 23358bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pendingCallbacks & kXtraDownloadRequest) { 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->CallVoidMethod(obj, method_xtraDownloadRequest); 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pendingCallbacks & kDisableRequest) { 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // don't need to do anything - we are just poking so wait_for_event will return. 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint android_location_GpsLocationProvider_read_sv_status(JNIEnv* env, jobject obj, 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jintArray prnArray, jfloatArray snrArray, jfloatArray elevArray, jfloatArray azumArray, 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jintArray maskArray) 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // this should only be called from within a call to reportStatus, so we don't need to lock here 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jint* prns = env->GetIntArrayElements(prnArray, 0); 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfloat* snrs = env->GetFloatArrayElements(snrArray, 0); 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfloat* elev = env->GetFloatArrayElements(elevArray, 0); 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfloat* azim = env->GetFloatArrayElements(azumArray, 0); 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jint* mask = env->GetIntArrayElements(maskArray, 0); 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int num_svs = sGpsSvStatusCopy.num_svs; 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < num_svs; i++) { 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project prns[i] = sGpsSvStatusCopy.sv_list[i].prn; 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project snrs[i] = sGpsSvStatusCopy.sv_list[i].snr; 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project elev[i] = sGpsSvStatusCopy.sv_list[i].elevation; 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project azim[i] = sGpsSvStatusCopy.sv_list[i].azimuth; 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mask[0] = sGpsSvStatusCopy.ephemeris_mask; 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mask[1] = sGpsSvStatusCopy.almanac_mask; 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mask[2] = sGpsSvStatusCopy.used_in_fix_mask; 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->ReleaseIntArrayElements(prnArray, prns, 0); 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->ReleaseFloatArrayElements(snrArray, snrs, 0); 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->ReleaseFloatArrayElements(elevArray, elev, 0); 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->ReleaseFloatArrayElements(azumArray, azim, 0); 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->ReleaseIntArrayElements(maskArray, mask, 0); 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return num_svs; 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_location_GpsLocationProvider_inject_time(JNIEnv* env, jobject obj, jlong time, 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jlong timeReference, jint uncertainty) 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sGpsInterface->inject_time(time, timeReference, uncertainty); 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 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 30258bda987665af759c379cd494ff4873ac61acf29Mike Lockwoodstatic void android_location_GpsLocationProvider_supl_data_conn_open(JNIEnv* env, jobject obj, jstring apn) 303105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project{ 304105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (!sGpsSuplInterface) { 305105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project sGpsSuplInterface = (const GpsSuplInterface*)sGpsInterface->get_extension(GPS_SUPL_INTERFACE); 306105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 307105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (sGpsSuplInterface) { 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); 31358bda987665af759c379cd494ff4873ac61acf29Mike Lockwood sGpsSuplInterface->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 31858bda987665af759c379cd494ff4873ac61acf29Mike Lockwoodstatic void android_location_GpsLocationProvider_supl_data_conn_closed(JNIEnv* env, jobject obj) 319105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project{ 320105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (!sGpsSuplInterface) { 321105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project sGpsSuplInterface = (const GpsSuplInterface*)sGpsInterface->get_extension(GPS_SUPL_INTERFACE); 322105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 323105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (sGpsSuplInterface) { 32458bda987665af759c379cd494ff4873ac61acf29Mike Lockwood sGpsSuplInterface->data_conn_closed(); 32558bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } 32658bda987665af759c379cd494ff4873ac61acf29Mike Lockwood} 32758bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 32858bda987665af759c379cd494ff4873ac61acf29Mike Lockwoodstatic void android_location_GpsLocationProvider_supl_data_conn_failed(JNIEnv* env, jobject obj) 32958bda987665af759c379cd494ff4873ac61acf29Mike Lockwood{ 33058bda987665af759c379cd494ff4873ac61acf29Mike Lockwood if (!sGpsSuplInterface) { 33158bda987665af759c379cd494ff4873ac61acf29Mike Lockwood sGpsSuplInterface = (const GpsSuplInterface*)sGpsInterface->get_extension(GPS_SUPL_INTERFACE); 33258bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } 33358bda987665af759c379cd494ff4873ac61acf29Mike Lockwood if (sGpsSuplInterface) { 33458bda987665af759c379cd494ff4873ac61acf29Mike Lockwood sGpsSuplInterface->data_conn_failed(); 33558bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } 33658bda987665af759c379cd494ff4873ac61acf29Mike Lockwood} 33758bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 33858bda987665af759c379cd494ff4873ac61acf29Mike Lockwoodstatic void android_location_GpsLocationProvider_set_supl_server(JNIEnv* env, jobject obj, 33958bda987665af759c379cd494ff4873ac61acf29Mike Lockwood jint addr, jint port) 34058bda987665af759c379cd494ff4873ac61acf29Mike Lockwood{ 34158bda987665af759c379cd494ff4873ac61acf29Mike Lockwood if (!sGpsSuplInterface) { 34258bda987665af759c379cd494ff4873ac61acf29Mike Lockwood sGpsSuplInterface = (const GpsSuplInterface*)sGpsInterface->get_extension(GPS_SUPL_INTERFACE); 34358bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } 34458bda987665af759c379cd494ff4873ac61acf29Mike Lockwood if (sGpsSuplInterface) { 34558bda987665af759c379cd494ff4873ac61acf29Mike Lockwood sGpsSuplInterface->set_server(addr, port); 346105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 347105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project} 348105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNINativeMethod sMethods[] = { 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* name, signature, funcPtr */ 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"class_init_native", "()V", (void *)android_location_GpsLocationProvider_class_init_native}, 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_is_supported", "()Z", (void*)android_location_GpsLocationProvider_is_supported}, 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_init", "()Z", (void*)android_location_GpsLocationProvider_init}, 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_disable", "()V", (void*)android_location_GpsLocationProvider_disable}, 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_cleanup", "()V", (void*)android_location_GpsLocationProvider_cleanup}, 356105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project {"native_start", "(IZI)Z", (void*)android_location_GpsLocationProvider_start}, 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_stop", "()Z", (void*)android_location_GpsLocationProvider_stop}, 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_set_fix_frequency", "(I)V", (void*)android_location_GpsLocationProvider_set_fix_frequency}, 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_delete_aiding_data", "(I)V", (void*)android_location_GpsLocationProvider_delete_aiding_data}, 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_wait_for_event", "()V", (void*)android_location_GpsLocationProvider_wait_for_event}, 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_read_sv_status", "([I[F[F[F[I)I", (void*)android_location_GpsLocationProvider_read_sv_status}, 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_inject_time", "(JJI)V", (void*)android_location_GpsLocationProvider_inject_time}, 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_supports_xtra", "()Z", (void*)android_location_GpsLocationProvider_supports_xtra}, 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_inject_xtra_data", "([BI)V", (void*)android_location_GpsLocationProvider_inject_xtra_data}, 36558bda987665af759c379cd494ff4873ac61acf29Mike Lockwood {"native_supl_data_conn_open", "(Ljava/lang/String;)V", (void*)android_location_GpsLocationProvider_supl_data_conn_open}, 36658bda987665af759c379cd494ff4873ac61acf29Mike Lockwood {"native_supl_data_conn_closed", "()V", (void*)android_location_GpsLocationProvider_supl_data_conn_closed}, 36758bda987665af759c379cd494ff4873ac61acf29Mike Lockwood {"native_supl_data_conn_failed", "()V", (void*)android_location_GpsLocationProvider_supl_data_conn_failed}, 368105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project {"native_set_supl_server", "(II)V", (void*)android_location_GpsLocationProvider_set_supl_server}, 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint register_android_location_GpsLocationProvider(JNIEnv* env) 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return jniRegisterNativeMethods(env, "com/android/internal/location/GpsLocationProvider", sMethods, NELEM(sMethods)); 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} /* namespace android */ 377