com_android_server_location_GpsLocationProvider.cpp revision 8f5a800116f700b0af21d2a8468165bcf51b841c
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 1922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie//#define LOG_NDDEBUG 0 2022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "JNIHelp.h" 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "jni.h" 23b7ff4574b5a8273b0ff43ca7f490ba5ceec42912Mike Lockwood#include "hardware/hardware.h" 24b7ff4574b5a8273b0ff43ca7f490ba5ceec42912Mike Lockwood#include "hardware/gps.h" 258f5a800116f700b0af21d2a8468165bcf51b841cMike Lockwood#include "hardware_legacy/power.h" 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "utils/Log.h" 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "utils/misc.h" 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <string.h> 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <pthread.h> 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic pthread_mutex_t sEventMutex = PTHREAD_MUTEX_INITIALIZER; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic pthread_cond_t sEventCond = PTHREAD_COND_INITIALIZER; 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jmethodID method_reportLocation; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jmethodID method_reportStatus; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jmethodID method_reportSvStatus; 37e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwoodstatic jmethodID method_reportAGpsStatus; 38b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwoodstatic jmethodID method_reportNmea; 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jmethodID method_xtraDownloadRequest; 4022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xiestatic jmethodID method_reportNiNotification; 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const GpsInterface* sGpsInterface = NULL; 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const GpsXtraInterface* sGpsXtraInterface = NULL; 44e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwoodstatic const AGpsInterface* sAGpsInterface = NULL; 4522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xiestatic const GpsNiInterface* sGpsNiInterface = NULL; 463c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettingerstatic const GpsDebugInterface* sGpsDebugInterface = NULL; 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// data written to by GPS callbacks 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic GpsLocation sGpsLocation; 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic GpsStatus sGpsStatus; 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic GpsSvStatus sGpsSvStatus; 52e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwoodstatic AGpsStatus sAGpsStatus; 5322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xiestatic GpsNiNotification sGpsNiNotification; 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 558f5a800116f700b0af21d2a8468165bcf51b841cMike Lockwood#define WAKE_LOCK_NAME "GPS" 568f5a800116f700b0af21d2a8468165bcf51b841cMike Lockwood 57b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood// buffer for NMEA data 58b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood#define NMEA_SENTENCE_LENGTH 100 59b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood#define NMEA_SENTENCE_COUNT 40 60b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwoodstruct NmeaSentence { 61b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood GpsUtcTime timestamp; 62b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood char nmea[NMEA_SENTENCE_LENGTH]; 63b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood}; 643c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettingerstatic NmeaSentence sNmeaBuffer[NMEA_SENTENCE_COUNT]; 65b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwoodstatic int mNmeaSentenceCount = 0; 66b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// a copy of the data shared by android_location_GpsLocationProvider_wait_for_event 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// and android_location_GpsLocationProvider_read_status 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic GpsLocation sGpsLocationCopy; 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic GpsStatus sGpsStatusCopy; 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic GpsSvStatus sGpsSvStatusCopy; 72e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwoodstatic AGpsStatus sAGpsStatusCopy; 733c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettingerstatic NmeaSentence sNmeaBufferCopy[NMEA_SENTENCE_COUNT]; 7422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xiestatic GpsNiNotification sGpsNiNotificationCopy; 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectenum CallbackType { 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project kLocation = 1, 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project kStatus = 2, 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project kSvStatus = 4, 80e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood kAGpsStatus = 8, 8158bda987665af759c379cd494ff4873ac61acf29Mike Lockwood kXtraDownloadRequest = 16, 8258bda987665af759c379cd494ff4873ac61acf29Mike Lockwood kDisableRequest = 32, 83b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood kNmeaAvailable = 64, 8422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie kNiNotification = 128, 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int sPendingCallbacks; 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android { 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void location_callback(GpsLocation* location) 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pthread_mutex_lock(&sEventMutex); 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sPendingCallbacks |= kLocation; 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memcpy(&sGpsLocation, location, sizeof(sGpsLocation)); 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pthread_cond_signal(&sEventCond); 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pthread_mutex_unlock(&sEventMutex); 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void status_callback(GpsStatus* status) 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pthread_mutex_lock(&sEventMutex); 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sPendingCallbacks |= kStatus; 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memcpy(&sGpsStatus, status, sizeof(sGpsStatus)); 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pthread_cond_signal(&sEventCond); 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pthread_mutex_unlock(&sEventMutex); 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void sv_status_callback(GpsSvStatus* sv_status) 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pthread_mutex_lock(&sEventMutex); 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sPendingCallbacks |= kSvStatus; 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memcpy(&sGpsSvStatus, sv_status, sizeof(GpsSvStatus)); 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pthread_cond_signal(&sEventCond); 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pthread_mutex_unlock(&sEventMutex); 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 123b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwoodstatic void nmea_callback(GpsUtcTime timestamp, const char* nmea, int length) 124b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood{ 125b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood pthread_mutex_lock(&sEventMutex); 126b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood 127b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood if (length >= NMEA_SENTENCE_LENGTH) { 128b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood LOGE("NMEA data too long in nmea_callback (length = %d)\n", length); 129b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood length = NMEA_SENTENCE_LENGTH - 1; 130b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood } 131b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood if (mNmeaSentenceCount >= NMEA_SENTENCE_COUNT) { 132b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood LOGE("NMEA data overflowed buffer\n"); 133b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood pthread_mutex_unlock(&sEventMutex); 134b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood return; 135b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood } 136b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood 137b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood sPendingCallbacks |= kNmeaAvailable; 138b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood sNmeaBuffer[mNmeaSentenceCount].timestamp = timestamp; 139b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood memcpy(sNmeaBuffer[mNmeaSentenceCount].nmea, nmea, length); 140b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood sNmeaBuffer[mNmeaSentenceCount].nmea[length] = 0; 141b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood mNmeaSentenceCount++; 142b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood 143b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood pthread_cond_signal(&sEventCond); 144b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood pthread_mutex_unlock(&sEventMutex); 145b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood} 146b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood 1478f5a800116f700b0af21d2a8468165bcf51b841cMike Lockwoodstatic void acquire_wakelock_callback() 1488f5a800116f700b0af21d2a8468165bcf51b841cMike Lockwood{ 1498f5a800116f700b0af21d2a8468165bcf51b841cMike Lockwood acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME); 1508f5a800116f700b0af21d2a8468165bcf51b841cMike Lockwood} 1518f5a800116f700b0af21d2a8468165bcf51b841cMike Lockwood 1528f5a800116f700b0af21d2a8468165bcf51b841cMike Lockwoodstatic void release_wakelock_callback() 1538f5a800116f700b0af21d2a8468165bcf51b841cMike Lockwood{ 1548f5a800116f700b0af21d2a8468165bcf51b841cMike Lockwood release_wake_lock(WAKE_LOCK_NAME); 1558f5a800116f700b0af21d2a8468165bcf51b841cMike Lockwood} 1568f5a800116f700b0af21d2a8468165bcf51b841cMike Lockwood 157e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwoodstatic void agps_status_callback(AGpsStatus* agps_status) 15858bda987665af759c379cd494ff4873ac61acf29Mike Lockwood{ 15958bda987665af759c379cd494ff4873ac61acf29Mike Lockwood pthread_mutex_lock(&sEventMutex); 16058bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 161e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood sPendingCallbacks |= kAGpsStatus; 162e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood memcpy(&sAGpsStatus, agps_status, sizeof(AGpsStatus)); 16358bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 16458bda987665af759c379cd494ff4873ac61acf29Mike Lockwood pthread_cond_signal(&sEventCond); 16558bda987665af759c379cd494ff4873ac61acf29Mike Lockwood pthread_mutex_unlock(&sEventMutex); 16658bda987665af759c379cd494ff4873ac61acf29Mike Lockwood} 16758bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectGpsCallbacks sGpsCallbacks = { 1698f5a800116f700b0af21d2a8468165bcf51b841cMike Lockwood sizeof(GpsCallbacks), 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project location_callback, 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_callback, 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sv_status_callback, 1738f5a800116f700b0af21d2a8468165bcf51b841cMike Lockwood nmea_callback, 1748f5a800116f700b0af21d2a8468165bcf51b841cMike Lockwood acquire_wakelock_callback, 1758f5a800116f700b0af21d2a8468165bcf51b841cMike Lockwood release_wakelock_callback, 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectdownload_request_callback() 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pthread_mutex_lock(&sEventMutex); 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sPendingCallbacks |= kXtraDownloadRequest; 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pthread_cond_signal(&sEventCond); 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pthread_mutex_unlock(&sEventMutex); 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xiestatic void 18822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xiegps_ni_notify_callback(GpsNiNotification *notification) 18922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie{ 19022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie LOGD("gps_ni_notify_callback: notif=%d", notification->notification_id); 19122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 19222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie pthread_mutex_lock(&sEventMutex); 19322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 19422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie sPendingCallbacks |= kNiNotification; 19522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie memcpy(&sGpsNiNotification, notification, sizeof(GpsNiNotification)); 19622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 19722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie pthread_cond_signal(&sEventCond); 19822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie pthread_mutex_unlock(&sEventMutex); 19922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie} 20022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectGpsXtraCallbacks sGpsXtraCallbacks = { 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project download_request_callback, 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 205e3635c9693c4cd9650684f14e19dcabcea0d488aMike LockwoodAGpsCallbacks sAGpsCallbacks = { 206e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood agps_status_callback, 20758bda987665af759c379cd494ff4873ac61acf29Mike Lockwood}; 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke XieGpsNiCallbacks sGpsNiCallbacks = { 21022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie gps_ni_notify_callback, 21122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie}; 21222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_location_GpsLocationProvider_class_init_native(JNIEnv* env, jclass clazz) { 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project method_reportLocation = env->GetMethodID(clazz, "reportLocation", "(IDDDFFFJ)V"); 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project method_reportStatus = env->GetMethodID(clazz, "reportStatus", "(I)V"); 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "()V"); 217e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood method_reportAGpsStatus = env->GetMethodID(clazz, "reportAGpsStatus", "(II)V"); 218b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood method_reportNmea = env->GetMethodID(clazz, "reportNmea", "(IJ)V"); 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project method_xtraDownloadRequest = env->GetMethodID(clazz, "xtraDownloadRequest", "()V"); 22022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie method_reportNiNotification = env->GetMethodID(clazz, "reportNiNotification", "(IIIIILjava/lang/String;Ljava/lang/String;IILjava/lang/String;)V"); 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 223b7ff4574b5a8273b0ff43ca7f490ba5ceec42912Mike Lockwoodstatic const GpsInterface* get_gps_interface() { 224b7ff4574b5a8273b0ff43ca7f490ba5ceec42912Mike Lockwood int err; 225b7ff4574b5a8273b0ff43ca7f490ba5ceec42912Mike Lockwood hw_module_t* module; 226b7ff4574b5a8273b0ff43ca7f490ba5ceec42912Mike Lockwood const GpsInterface* interface = NULL; 227b7ff4574b5a8273b0ff43ca7f490ba5ceec42912Mike Lockwood 228b7ff4574b5a8273b0ff43ca7f490ba5ceec42912Mike Lockwood err = hw_get_module(GPS_HARDWARE_MODULE_ID, (hw_module_t const**)&module); 229b7ff4574b5a8273b0ff43ca7f490ba5ceec42912Mike Lockwood if (err == 0) { 230b7ff4574b5a8273b0ff43ca7f490ba5ceec42912Mike Lockwood hw_device_t* device; 231b7ff4574b5a8273b0ff43ca7f490ba5ceec42912Mike Lockwood err = module->methods->open(module, GPS_HARDWARE_MODULE_ID, &device); 232b7ff4574b5a8273b0ff43ca7f490ba5ceec42912Mike Lockwood if (err == 0) { 233b7ff4574b5a8273b0ff43ca7f490ba5ceec42912Mike Lockwood gps_device_t* gps_device = (gps_device_t *)device; 234b7ff4574b5a8273b0ff43ca7f490ba5ceec42912Mike Lockwood interface = gps_device->get_gps_interface(gps_device); 235b7ff4574b5a8273b0ff43ca7f490ba5ceec42912Mike Lockwood } 236b7ff4574b5a8273b0ff43ca7f490ba5ceec42912Mike Lockwood } 237b7ff4574b5a8273b0ff43ca7f490ba5ceec42912Mike Lockwood 238b7ff4574b5a8273b0ff43ca7f490ba5ceec42912Mike Lockwood return interface; 239b7ff4574b5a8273b0ff43ca7f490ba5ceec42912Mike Lockwood} 240b7ff4574b5a8273b0ff43ca7f490ba5ceec42912Mike Lockwood 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jboolean android_location_GpsLocationProvider_is_supported(JNIEnv* env, jclass clazz) { 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!sGpsInterface) 243b7ff4574b5a8273b0ff43ca7f490ba5ceec42912Mike Lockwood sGpsInterface = get_gps_interface(); 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (sGpsInterface != NULL); 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jboolean android_location_GpsLocationProvider_init(JNIEnv* env, jobject obj) 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!sGpsInterface) 250b7ff4574b5a8273b0ff43ca7f490ba5ceec42912Mike Lockwood sGpsInterface = get_gps_interface(); 25158bda987665af759c379cd494ff4873ac61acf29Mike Lockwood if (!sGpsInterface || sGpsInterface->init(&sGpsCallbacks) != 0) 25258bda987665af759c379cd494ff4873ac61acf29Mike Lockwood return false; 25358bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 254e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood if (!sAGpsInterface) 255e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood sAGpsInterface = (const AGpsInterface*)sGpsInterface->get_extension(AGPS_INTERFACE); 256e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood if (sAGpsInterface) 257e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood sAGpsInterface->init(&sAGpsCallbacks); 25822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 25922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie if (!sGpsNiInterface) 26022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie sGpsNiInterface = (const GpsNiInterface*)sGpsInterface->get_extension(GPS_NI_INTERFACE); 26122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie if (sGpsNiInterface) 26222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie sGpsNiInterface->init(&sGpsNiCallbacks); 26322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 2643c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger if (!sGpsDebugInterface) 2653c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger sGpsDebugInterface = (const GpsDebugInterface*)sGpsInterface->get_extension(GPS_DEBUG_INTERFACE); 2663c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger 267c21a08f747f6fd1d7b8c98176ff70abc57cf58a0Mike Lockwood return true; 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_location_GpsLocationProvider_disable(JNIEnv* env, jobject obj) 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pthread_mutex_lock(&sEventMutex); 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sPendingCallbacks |= kDisableRequest; 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pthread_cond_signal(&sEventCond); 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pthread_mutex_unlock(&sEventMutex); 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_location_GpsLocationProvider_cleanup(JNIEnv* env, jobject obj) 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sGpsInterface->cleanup(); 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 28322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xiestatic jboolean android_location_GpsLocationProvider_start(JNIEnv* env, jobject obj, jint positionMode, 284105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project jboolean singleFix, jint fixFrequency) 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 286105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project int result = sGpsInterface->set_position_mode(positionMode, (singleFix ? 0 : fixFrequency)); 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (result) { 2889a940e8b3d61539392c1a9f925be13cca8b5103dDavid 'Digit' Turner return false; 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (sGpsInterface->start() == 0); 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jboolean android_location_GpsLocationProvider_stop(JNIEnv* env, jobject obj) 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (sGpsInterface->stop() == 0); 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_location_GpsLocationProvider_delete_aiding_data(JNIEnv* env, jobject obj, jint flags) 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sGpsInterface->delete_aiding_data(flags); 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_location_GpsLocationProvider_wait_for_event(JNIEnv* env, jobject obj) 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pthread_mutex_lock(&sEventMutex); 3078b1243e5e4930598e8e78ebd18e7b6cd6fb0445fJared Suttles while (sPendingCallbacks == 0) { 3088b1243e5e4930598e8e78ebd18e7b6cd6fb0445fJared Suttles pthread_cond_wait(&sEventCond, &sEventMutex); 3098b1243e5e4930598e8e78ebd18e7b6cd6fb0445fJared Suttles } 31022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // copy and clear the callback flags 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int pendingCallbacks = sPendingCallbacks; 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sPendingCallbacks = 0; 314b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood int nmeaSentenceCount = mNmeaSentenceCount; 315b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood mNmeaSentenceCount = 0; 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // copy everything and unlock the mutex before calling into Java code to avoid the possibility 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // of timeouts in the GPS engine. 319b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood if (pendingCallbacks & kLocation) 320b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood memcpy(&sGpsLocationCopy, &sGpsLocation, sizeof(sGpsLocationCopy)); 321b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood if (pendingCallbacks & kStatus) 322b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood memcpy(&sGpsStatusCopy, &sGpsStatus, sizeof(sGpsStatusCopy)); 323b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood if (pendingCallbacks & kSvStatus) 324b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood memcpy(&sGpsSvStatusCopy, &sGpsSvStatus, sizeof(sGpsSvStatusCopy)); 325b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood if (pendingCallbacks & kAGpsStatus) 326b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood memcpy(&sAGpsStatusCopy, &sAGpsStatus, sizeof(sAGpsStatusCopy)); 327b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood if (pendingCallbacks & kNmeaAvailable) 328b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood memcpy(&sNmeaBufferCopy, &sNmeaBuffer, nmeaSentenceCount * sizeof(sNmeaBuffer[0])); 32922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie if (pendingCallbacks & kNiNotification) 33022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie memcpy(&sGpsNiNotificationCopy, &sGpsNiNotification, sizeof(sGpsNiNotificationCopy)); 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pthread_mutex_unlock(&sEventMutex); 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 33322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie if (pendingCallbacks & kLocation) { 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->CallVoidMethod(obj, method_reportLocation, sGpsLocationCopy.flags, 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (jdouble)sGpsLocationCopy.latitude, (jdouble)sGpsLocationCopy.longitude, 33622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie (jdouble)sGpsLocationCopy.altitude, 33722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie (jfloat)sGpsLocationCopy.speed, (jfloat)sGpsLocationCopy.bearing, 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (jfloat)sGpsLocationCopy.accuracy, (jlong)sGpsLocationCopy.timestamp); 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pendingCallbacks & kStatus) { 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->CallVoidMethod(obj, method_reportStatus, sGpsStatusCopy.status); 34222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie } 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pendingCallbacks & kSvStatus) { 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->CallVoidMethod(obj, method_reportSvStatus); 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 346e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood if (pendingCallbacks & kAGpsStatus) { 347e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood env->CallVoidMethod(obj, method_reportAGpsStatus, sAGpsStatusCopy.type, sAGpsStatusCopy.status); 34858bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } 349b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood if (pendingCallbacks & kNmeaAvailable) { 350b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood for (int i = 0; i < nmeaSentenceCount; i++) { 351b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood env->CallVoidMethod(obj, method_reportNmea, i, sNmeaBuffer[i].timestamp); 352b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood } 353b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood } 35422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie if (pendingCallbacks & kXtraDownloadRequest) { 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->CallVoidMethod(obj, method_xtraDownloadRequest); 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pendingCallbacks & kDisableRequest) { 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // don't need to do anything - we are just poking so wait_for_event will return. 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 36022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie if (pendingCallbacks & kNiNotification) { 36122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie LOGD("android_location_GpsLocationProvider_wait_for_event: sent notification callback."); 36222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie jstring reqId = env->NewStringUTF(sGpsNiNotificationCopy.requestor_id); 36322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie jstring text = env->NewStringUTF(sGpsNiNotificationCopy.text); 36422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie jstring extras = env->NewStringUTF(sGpsNiNotificationCopy.extras); 36522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie env->CallVoidMethod(obj, method_reportNiNotification, 36622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie sGpsNiNotificationCopy.notification_id, 36722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie sGpsNiNotificationCopy.ni_type, 36822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie sGpsNiNotificationCopy.notify_flags, 36922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie sGpsNiNotificationCopy.timeout, 37022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie sGpsNiNotificationCopy.default_response, 37122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie reqId, 37222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie text, 37322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie sGpsNiNotificationCopy.requestor_id_encoding, 37422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie sGpsNiNotificationCopy.text_encoding, 37522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie extras 37622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie ); 37722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie } 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 38022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xiestatic jint android_location_GpsLocationProvider_read_sv_status(JNIEnv* env, jobject obj, 38122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie jintArray prnArray, jfloatArray snrArray, jfloatArray elevArray, jfloatArray azumArray, 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jintArray maskArray) 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // this should only be called from within a call to reportStatus, so we don't need to lock here 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jint* prns = env->GetIntArrayElements(prnArray, 0); 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfloat* snrs = env->GetFloatArrayElements(snrArray, 0); 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfloat* elev = env->GetFloatArrayElements(elevArray, 0); 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfloat* azim = env->GetFloatArrayElements(azumArray, 0); 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jint* mask = env->GetIntArrayElements(maskArray, 0); 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int num_svs = sGpsSvStatusCopy.num_svs; 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < num_svs; i++) { 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project prns[i] = sGpsSvStatusCopy.sv_list[i].prn; 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project snrs[i] = sGpsSvStatusCopy.sv_list[i].snr; 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project elev[i] = sGpsSvStatusCopy.sv_list[i].elevation; 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project azim[i] = sGpsSvStatusCopy.sv_list[i].azimuth; 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mask[0] = sGpsSvStatusCopy.ephemeris_mask; 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mask[1] = sGpsSvStatusCopy.almanac_mask; 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mask[2] = sGpsSvStatusCopy.used_in_fix_mask; 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->ReleaseIntArrayElements(prnArray, prns, 0); 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->ReleaseFloatArrayElements(snrArray, snrs, 0); 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->ReleaseFloatArrayElements(elevArray, elev, 0); 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->ReleaseFloatArrayElements(azumArray, azim, 0); 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->ReleaseIntArrayElements(maskArray, mask, 0); 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return num_svs; 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 411b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwoodstatic jint android_location_GpsLocationProvider_read_nmea(JNIEnv* env, jobject obj, jint index, jbyteArray nmeaArray, jint buffer_size) 412b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood{ 413eb40aae254642dfcb333798c642920814b410115Eddie Ho // this should only be called from within a call to reportNmea, so we don't need to lock here 414b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood 415b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood jbyte* nmea = env->GetByteArrayElements(nmeaArray, 0); 416b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood 417eb40aae254642dfcb333798c642920814b410115Eddie Ho int length = strlen(sNmeaBufferCopy[index].nmea); 418b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood if (length > buffer_size) 419b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood length = buffer_size; 420eb40aae254642dfcb333798c642920814b410115Eddie Ho memcpy(nmea, sNmeaBufferCopy[index].nmea, length); 421b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood 422b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood env->ReleaseByteArrayElements(nmeaArray, nmea, 0); 423b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood return length; 424b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood} 425b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_location_GpsLocationProvider_inject_time(JNIEnv* env, jobject obj, jlong time, 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jlong timeReference, jint uncertainty) 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sGpsInterface->inject_time(time, timeReference, uncertainty); 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 432d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwoodstatic void android_location_GpsLocationProvider_inject_location(JNIEnv* env, jobject obj, 433d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood jdouble latitude, jdouble longitude, jfloat accuracy) 434d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood{ 435d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood sGpsInterface->inject_location(latitude, longitude, accuracy); 436d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood} 437d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jboolean android_location_GpsLocationProvider_supports_xtra(JNIEnv* env, jobject obj) 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!sGpsXtraInterface) { 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sGpsXtraInterface = (const GpsXtraInterface*)sGpsInterface->get_extension(GPS_XTRA_INTERFACE); 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sGpsXtraInterface) { 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int result = sGpsXtraInterface->init(&sGpsXtraCallbacks); 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (result) { 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sGpsXtraInterface = NULL; 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (sGpsXtraInterface != NULL); 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 45322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xiestatic void android_location_GpsLocationProvider_inject_xtra_data(JNIEnv* env, jobject obj, 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jbyteArray data, jint length) 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jbyte* bytes = env->GetByteArrayElements(data, 0); 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sGpsXtraInterface->inject_xtra_data((char *)bytes, length); 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->ReleaseByteArrayElements(data, bytes, 0); 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 461e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwoodstatic void android_location_GpsLocationProvider_agps_data_conn_open(JNIEnv* env, jobject obj, jstring apn) 462105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project{ 463e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood if (!sAGpsInterface) { 464e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood sAGpsInterface = (const AGpsInterface*)sGpsInterface->get_extension(AGPS_INTERFACE); 465105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 466e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood if (sAGpsInterface) { 46758bda987665af759c379cd494ff4873ac61acf29Mike Lockwood if (apn == NULL) { 46858bda987665af759c379cd494ff4873ac61acf29Mike Lockwood jniThrowException(env, "java/lang/IllegalArgumentException", NULL); 46958bda987665af759c379cd494ff4873ac61acf29Mike Lockwood return; 47058bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } 47158bda987665af759c379cd494ff4873ac61acf29Mike Lockwood const char *apnStr = env->GetStringUTFChars(apn, NULL); 472e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood sAGpsInterface->data_conn_open(apnStr); 47358bda987665af759c379cd494ff4873ac61acf29Mike Lockwood env->ReleaseStringUTFChars(apn, apnStr); 474105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 475105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project} 476105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 477e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwoodstatic void android_location_GpsLocationProvider_agps_data_conn_closed(JNIEnv* env, jobject obj) 478105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project{ 479e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood if (!sAGpsInterface) { 480e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood sAGpsInterface = (const AGpsInterface*)sGpsInterface->get_extension(AGPS_INTERFACE); 481105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 482e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood if (sAGpsInterface) { 483e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood sAGpsInterface->data_conn_closed(); 48458bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } 48558bda987665af759c379cd494ff4873ac61acf29Mike Lockwood} 48658bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 487e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwoodstatic void android_location_GpsLocationProvider_agps_data_conn_failed(JNIEnv* env, jobject obj) 48858bda987665af759c379cd494ff4873ac61acf29Mike Lockwood{ 489e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood if (!sAGpsInterface) { 490e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood sAGpsInterface = (const AGpsInterface*)sGpsInterface->get_extension(AGPS_INTERFACE); 49158bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } 492e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood if (sAGpsInterface) { 493e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood sAGpsInterface->data_conn_failed(); 49458bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } 49558bda987665af759c379cd494ff4873ac61acf29Mike Lockwood} 49658bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 497e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwoodstatic void android_location_GpsLocationProvider_set_agps_server(JNIEnv* env, jobject obj, 498a9e546169b3c2c9c5f248d2f3abe3b934f48695dMike Lockwood jint type, jstring hostname, jint port) 49958bda987665af759c379cd494ff4873ac61acf29Mike Lockwood{ 500e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood if (!sAGpsInterface) { 501e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood sAGpsInterface = (const AGpsInterface*)sGpsInterface->get_extension(AGPS_INTERFACE); 50258bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } 503e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood if (sAGpsInterface) { 504a9e546169b3c2c9c5f248d2f3abe3b934f48695dMike Lockwood const char *c_hostname = env->GetStringUTFChars(hostname, NULL); 505a9e546169b3c2c9c5f248d2f3abe3b934f48695dMike Lockwood sAGpsInterface->set_server(type, c_hostname, port); 506a9e546169b3c2c9c5f248d2f3abe3b934f48695dMike Lockwood env->ReleaseStringUTFChars(hostname, c_hostname); 507105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 508105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project} 509105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 51022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xiestatic void android_location_GpsLocationProvider_send_ni_response(JNIEnv* env, jobject obj, 51122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie jint notifId, jint response) 51222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie{ 5133c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger if (!sGpsNiInterface) { 5143c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger sGpsNiInterface = (const GpsNiInterface*)sGpsInterface->get_extension(GPS_NI_INTERFACE); 5153c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger } 5163c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger if (sGpsNiInterface) { 5173c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger sGpsNiInterface->respond(notifId, response); 5183c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger } 5193c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger} 5203c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger 5213c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettingerstatic jstring android_location_GpsLocationProvider_get_internal_state(JNIEnv* env, jobject obj) 5223c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger{ 5233c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger jstring result = NULL; 5243c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger if (sGpsDebugInterface) { 5253c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger const size_t maxLength = 2047; 5263c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger char buffer[maxLength+1]; 5273c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger size_t length = sGpsDebugInterface->get_internal_state(buffer, maxLength); 5283c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger if (length > maxLength) length = maxLength; 5293c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger buffer[length] = 0; 5303c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger result = env->NewStringUTF(buffer); 5313c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger } 5323c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger return result; 53322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie} 53422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNINativeMethod sMethods[] = { 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* name, signature, funcPtr */ 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"class_init_native", "()V", (void *)android_location_GpsLocationProvider_class_init_native}, 538e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood {"native_is_supported", "()Z", (void*)android_location_GpsLocationProvider_is_supported}, 539e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood {"native_init", "()Z", (void*)android_location_GpsLocationProvider_init}, 540e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood {"native_disable", "()V", (void*)android_location_GpsLocationProvider_disable}, 541e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood {"native_cleanup", "()V", (void*)android_location_GpsLocationProvider_cleanup}, 542e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood {"native_start", "(IZI)Z", (void*)android_location_GpsLocationProvider_start}, 543e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood {"native_stop", "()Z", (void*)android_location_GpsLocationProvider_stop}, 544e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood {"native_delete_aiding_data", "(I)V", (void*)android_location_GpsLocationProvider_delete_aiding_data}, 545e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood {"native_wait_for_event", "()V", (void*)android_location_GpsLocationProvider_wait_for_event}, 546e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood {"native_read_sv_status", "([I[F[F[F[I)I", (void*)android_location_GpsLocationProvider_read_sv_status}, 547b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood {"native_read_nmea", "(I[BI)I", (void*)android_location_GpsLocationProvider_read_nmea}, 548e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood {"native_inject_time", "(JJI)V", (void*)android_location_GpsLocationProvider_inject_time}, 549d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood {"native_inject_location", "(DDF)V", (void*)android_location_GpsLocationProvider_inject_location}, 550e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood {"native_supports_xtra", "()Z", (void*)android_location_GpsLocationProvider_supports_xtra}, 551e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood {"native_inject_xtra_data", "([BI)V", (void*)android_location_GpsLocationProvider_inject_xtra_data}, 552e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood {"native_agps_data_conn_open", "(Ljava/lang/String;)V", (void*)android_location_GpsLocationProvider_agps_data_conn_open}, 553e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood {"native_agps_data_conn_closed", "()V", (void*)android_location_GpsLocationProvider_agps_data_conn_closed}, 554e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood {"native_agps_data_conn_failed", "()V", (void*)android_location_GpsLocationProvider_agps_data_conn_failed}, 555a9e546169b3c2c9c5f248d2f3abe3b934f48695dMike Lockwood {"native_set_agps_server", "(ILjava/lang/String;I)V", (void*)android_location_GpsLocationProvider_set_agps_server}, 55622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie {"native_send_ni_response", "(II)V", (void*)android_location_GpsLocationProvider_send_ni_response}, 5573c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger {"native_get_internal_state", "()Ljava/lang/String;", (void*)android_location_GpsLocationProvider_get_internal_state}, 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 56000b74270c9f136a8727c5f6cda0997a3a905f385Mike Lockwoodint register_android_server_location_GpsLocationProvider(JNIEnv* env) 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 56200b74270c9f136a8727c5f6cda0997a3a905f385Mike Lockwood return jniRegisterNativeMethods(env, "com/android/server/location/GpsLocationProvider", sMethods, NELEM(sMethods)); 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} /* namespace android */ 566