blob: 36ae94b88b232351e09e5be30974d0e7e04c70a2 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Lifu Tang30f95a72016-01-07 23:20:38 -080017#define LOG_TAG "GnssLocationProvider"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080018
Mike Lockwoodb8d90332010-10-18 17:59:48 -040019#define LOG_NDEBUG 0
Danke Xie22d1f9f2009-08-18 18:28:45 -040020
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070021#include <android/hardware/gnss/1.0/IGnss.h>
22
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080023#include "JNIHelp.h"
24#include "jni.h"
Mike Lockwood8f5a8002010-04-07 09:05:26 -040025#include "hardware_legacy/power.h"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080026#include "utils/Log.h"
27#include "utils/misc.h"
Mike Lockwoodf602d362010-06-20 14:28:16 -070028#include "android_runtime/AndroidRuntime.h"
Ruben Brunk87eac992013-09-09 17:44:59 -070029#include "android_runtime/Log.h"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030
destradaa931a37f2014-08-12 16:36:59 -070031#include <arpa/inet.h>
Lifu Tang38bce792016-02-24 17:17:38 -080032#include <limits>
destradaa96a14702014-06-05 11:36:30 -070033#include <linux/in.h>
34#include <linux/in6.h>
Lifu Tang38bce792016-02-24 17:17:38 -080035#include <pthread.h>
36#include <string.h>
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070037#include <cinttypes>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080038
Mike Lockwoodf602d362010-06-20 14:28:16 -070039static jobject mCallbacksObj = NULL;
40
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041static jmethodID method_reportLocation;
42static jmethodID method_reportStatus;
43static jmethodID method_reportSvStatus;
Mike Lockwoode3635c92009-05-11 08:38:02 -040044static jmethodID method_reportAGpsStatus;
Mike Lockwoodb16e7802009-08-06 09:26:02 -040045static jmethodID method_reportNmea;
Mike Lockwood04598b62010-04-14 17:17:24 -040046static jmethodID method_setEngineCapabilities;
Lifu Tang9363b942016-02-16 18:07:00 -080047static jmethodID method_setGnssYearOfHardware;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080048static jmethodID method_xtraDownloadRequest;
Danke Xie22d1f9f2009-08-18 18:28:45 -040049static jmethodID method_reportNiNotification;
Miguel Torroja1e84da82010-07-27 07:02:24 +020050static jmethodID method_requestRefLocation;
51static jmethodID method_requestSetID;
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -040052static jmethodID method_requestUtcTime;
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -070053static jmethodID method_reportGeofenceTransition;
54static jmethodID method_reportGeofenceStatus;
55static jmethodID method_reportGeofenceAddStatus;
56static jmethodID method_reportGeofenceRemoveStatus;
57static jmethodID method_reportGeofencePauseStatus;
58static jmethodID method_reportGeofenceResumeStatus;
destradaaea8a8a62014-06-23 18:19:03 -070059static jmethodID method_reportMeasurementData;
destradaa4b3e3932014-07-21 18:01:47 -070060static jmethodID method_reportNavigationMessages;
Wyatt Rileycf879db2017-01-12 13:57:38 -080061static jmethodID method_reportLocationBatch;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080062
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -080063/*
64 * Save a pointer to JavaVm to attach/detach threads executing
65 * callback methods that need to make JNI calls.
66 */
67static JavaVM* sJvm;
68
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070069using android::OK;
70using android::sp;
71using android::status_t;
72using android::String16;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080073
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070074using android::hardware::Return;
75using android::hardware::Void;
76using android::hardware::hidl_vec;
Lifu Tang30f95a72016-01-07 23:20:38 -080077
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070078using android::hardware::gnss::V1_0::IAGnss;
79using android::hardware::gnss::V1_0::IAGnssCallback;
80using android::hardware::gnss::V1_0::IAGnssCallback;
81using android::hardware::gnss::V1_0::IAGnssRil;
82using android::hardware::gnss::V1_0::IAGnssRilCallback;
83using android::hardware::gnss::V1_0::IGnss;
Wyatt Rileycf879db2017-01-12 13:57:38 -080084using android::hardware::gnss::V1_0::IGnssBatching;
85using android::hardware::gnss::V1_0::IGnssBatchingCallback;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070086using android::hardware::gnss::V1_0::IGnssCallback;
87using android::hardware::gnss::V1_0::IGnssConfiguration;
88using android::hardware::gnss::V1_0::IGnssDebug;
89using android::hardware::gnss::V1_0::IGnssGeofenceCallback;
90using android::hardware::gnss::V1_0::IGnssGeofencing;
91using android::hardware::gnss::V1_0::IGnssMeasurement;
92using android::hardware::gnss::V1_0::IGnssMeasurementCallback;
93using android::hardware::gnss::V1_0::IGnssNavigationMessage;
94using android::hardware::gnss::V1_0::IGnssNavigationMessageCallback;
95using android::hardware::gnss::V1_0::IGnssNi;
96using android::hardware::gnss::V1_0::IGnssNiCallback;
97using android::hardware::gnss::V1_0::IGnssXtra;
98using android::hardware::gnss::V1_0::IGnssXtraCallback;
Wyatt Riley49d98912016-05-17 16:14:48 -070099
Wyatt Rileyf6527ae2016-05-23 15:23:12 -0700100
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700101sp<IGnss> gnssHal = nullptr;
102sp<IGnssXtra> gnssXtraIface = nullptr;
103sp<IAGnssRil> agnssRilIface = nullptr;
104sp<IGnssGeofencing> gnssGeofencingIface = nullptr;
105sp<IAGnss> agnssIface = nullptr;
Wyatt Rileycf879db2017-01-12 13:57:38 -0800106sp<IGnssBatching> gnssBatchingIface = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700107sp<IGnssDebug> gnssDebugIface = nullptr;
108sp<IGnssConfiguration> gnssConfigurationIface = nullptr;
109sp<IGnssNi> gnssNiIface = nullptr;
110sp<IGnssMeasurement> gnssMeasurementIface = nullptr;
111sp<IGnssNavigationMessage> gnssNavigationMessageIface = nullptr;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800112
Mike Lockwood8f5a8002010-04-07 09:05:26 -0400113#define WAKE_LOCK_NAME "GPS"
114
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800115namespace android {
116
Lifu Tang120480f2016-02-07 18:08:19 -0800117template<class T>
118class JavaMethodHelper {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700119 public:
120 // Helper function to call setter on a Java object.
121 static void callJavaMethod(
Lifu Tang120480f2016-02-07 18:08:19 -0800122 JNIEnv* env,
123 jclass clazz,
124 jobject object,
125 const char* method_name,
126 T value);
destradaaea8a8a62014-06-23 18:19:03 -0700127
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700128 private:
Lifu Tang120480f2016-02-07 18:08:19 -0800129 static const char *const signature_;
130};
Lifu Tange5a0e212016-01-25 18:02:17 -0800131
Lifu Tang120480f2016-02-07 18:08:19 -0800132template<class T>
133void JavaMethodHelper<T>::callJavaMethod(
134 JNIEnv* env,
135 jclass clazz,
136 jobject object,
137 const char* method_name,
138 T value) {
139 jmethodID method = env->GetMethodID(clazz, method_name, signature_);
140 env->CallVoidMethod(object, method, value);
141}
destradaaea8a8a62014-06-23 18:19:03 -0700142
Lifu Tang120480f2016-02-07 18:08:19 -0800143class JavaObject {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700144 public:
145 JavaObject(JNIEnv* env, const char* class_name);
Wyatt Rileycf879db2017-01-12 13:57:38 -0800146 JavaObject(JNIEnv* env, const char* class_name, const char * sz_arg_1);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700147 virtual ~JavaObject();
Lifu Tang120480f2016-02-07 18:08:19 -0800148
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700149 template<class T>
150 void callSetter(const char* method_name, T value);
151 template<class T>
152 void callSetter(const char* method_name, T* value, size_t size);
153 jobject get();
Lifu Tang120480f2016-02-07 18:08:19 -0800154
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700155 private:
156 JNIEnv* env_;
157 jclass clazz_;
158 jobject object_;
Lifu Tang120480f2016-02-07 18:08:19 -0800159};
160
161JavaObject::JavaObject(JNIEnv* env, const char* class_name) : env_(env) {
162 clazz_ = env_->FindClass(class_name);
163 jmethodID ctor = env->GetMethodID(clazz_, "<init>", "()V");
164 object_ = env_->NewObject(clazz_, ctor);
165}
166
Wyatt Rileycf879db2017-01-12 13:57:38 -0800167JavaObject::JavaObject(JNIEnv* env, const char* class_name, const char * sz_arg_1) : env_(env) {
168 clazz_ = env_->FindClass(class_name);
169 jmethodID ctor = env->GetMethodID(clazz_, "<init>", "(Ljava/lang/String;)V");
170 object_ = env_->NewObject(clazz_, ctor, env->NewStringUTF(sz_arg_1));
171}
172
Lifu Tang120480f2016-02-07 18:08:19 -0800173JavaObject::~JavaObject() {
174 env_->DeleteLocalRef(clazz_);
175}
176
177template<class T>
178void JavaObject::callSetter(const char* method_name, T value) {
179 JavaMethodHelper<T>::callJavaMethod(
180 env_, clazz_, object_, method_name, value);
181}
182
183template<>
184void JavaObject::callSetter(
185 const char* method_name, uint8_t* value, size_t size) {
186 jbyteArray array = env_->NewByteArray(size);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700187 env_->SetByteArrayRegion(array, 0, size, reinterpret_cast<jbyte*>(value));
Lifu Tang120480f2016-02-07 18:08:19 -0800188 jmethodID method = env_->GetMethodID(
189 clazz_,
190 method_name,
191 "([B)V");
192 env_->CallVoidMethod(object_, method, array);
Lifu Tangfe427f22016-10-08 02:57:53 -0700193 env_->DeleteLocalRef(array);
Lifu Tang120480f2016-02-07 18:08:19 -0800194}
195
196jobject JavaObject::get() {
197 return object_;
198}
199
200// Define Java method signatures for all known types.
Lifu Tang120480f2016-02-07 18:08:19 -0800201template<>
202const char *const JavaMethodHelper<uint8_t>::signature_ = "(B)V";
203template<>
204const char *const JavaMethodHelper<int8_t>::signature_ = "(B)V";
205template<>
206const char *const JavaMethodHelper<int16_t>::signature_ = "(S)V";
207template<>
208const char *const JavaMethodHelper<uint16_t>::signature_ = "(S)V";
209template<>
Lifu Tang9363b942016-02-16 18:07:00 -0800210const char *const JavaMethodHelper<int32_t>::signature_ = "(I)V";
211template<>
212const char *const JavaMethodHelper<uint32_t>::signature_ = "(I)V";
Lifu Tang120480f2016-02-07 18:08:19 -0800213template<>
214const char *const JavaMethodHelper<int64_t>::signature_ = "(J)V";
215template<>
216const char *const JavaMethodHelper<float>::signature_ = "(F)V";
217template<>
218const char *const JavaMethodHelper<double>::signature_ = "(D)V";
219template<>
220const char *const JavaMethodHelper<bool>::signature_ = "(Z)V";
221
222#define SET(setter, value) object.callSetter("set" # setter, (value))
Lifu Tangccb44882016-03-09 19:32:29 -0800223
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700224static inline jboolean boolToJbool(bool value) {
225 return value ? JNI_TRUE : JNI_FALSE;
226}
Lifu Tang120480f2016-02-07 18:08:19 -0800227
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700228static void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
229 if (env->ExceptionCheck()) {
230 ALOGE("An exception was thrown by callback '%s'.", methodName);
231 LOGE_EX(env);
232 env->ExceptionClear();
233 }
234}
destradaaea8a8a62014-06-23 18:19:03 -0700235
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800236class ScopedJniThreadAttach {
237public:
238 ScopedJniThreadAttach() {
239 /*
240 * attachResult will also be JNI_OK if the thead was already attached to
241 * JNI before the call to AttachCurrentThread().
242 */
243 jint attachResult = sJvm->AttachCurrentThread(&mEnv, nullptr);
244 LOG_ALWAYS_FATAL_IF(attachResult != JNI_OK, "Unable to attach thread. Error %d",
245 attachResult);
246 }
247
248 ~ScopedJniThreadAttach() {
249 jint detachResult = sJvm->DetachCurrentThread();
250 /*
251 * Return if the thread was already detached. Log error for any other
252 * failure.
253 */
254 if (detachResult == JNI_EDETACHED) {
255 return;
256 }
257
258 LOG_ALWAYS_FATAL_IF(detachResult != JNI_OK, "Unable to detach thread. Error %d",
259 detachResult);
260 }
261
262 JNIEnv* getEnv() {
263 /*
264 * Checking validity of mEnv in case the thread was detached elsewhere.
265 */
266 LOG_ALWAYS_FATAL_IF(AndroidRuntime::getJNIEnv() != mEnv);
267 return mEnv;
268 }
269
270private:
271 JNIEnv* mEnv = nullptr;
272};
273
274thread_local std::unique_ptr<ScopedJniThreadAttach> tJniThreadAttacher;
275
276static JNIEnv* getJniEnv() {
277 JNIEnv* env = AndroidRuntime::getJNIEnv();
278
279 /*
280 * If env is nullptr, the thread is not already attached to
281 * JNI. It is attached below and the destructor for ScopedJniThreadAttach
282 * will detach it on thread exit.
283 */
284 if (env == nullptr) {
285 tJniThreadAttacher.reset(new ScopedJniThreadAttach());
286 env = tJniThreadAttacher->getEnv();
287 }
288
289 return env;
290}
291
Wyatt Riley5d229832017-02-10 17:06:00 -0800292static jobject translateLocation(JNIEnv* env, const hardware::gnss::V1_0::GnssLocation& location) {
293 JavaObject object(env, "android/location/Location", "gps");
294
295 uint16_t flags = static_cast<uint32_t>(location.gnssLocationFlags);
296 if (flags & hardware::gnss::V1_0::GnssLocationFlags::HAS_LAT_LONG) {
297 SET(Latitude, location.latitudeDegrees);
298 SET(Longitude, location.longitudeDegrees);
299 }
300 if (flags & hardware::gnss::V1_0::GnssLocationFlags::HAS_ALTITUDE) {
301 SET(Altitude, location.altitudeMeters);
302 }
303 if (flags & hardware::gnss::V1_0::GnssLocationFlags::HAS_SPEED) {
304 SET(Speed, location.speedMetersPerSec);
305 }
306 if (flags & hardware::gnss::V1_0::GnssLocationFlags::HAS_BEARING) {
307 SET(Bearing, location.bearingDegrees);
308 }
309 if (flags & hardware::gnss::V1_0::GnssLocationFlags::HAS_HORIZONTAL_ACCURACY) {
310 SET(Accuracy, location.horizontalAccuracyMeters);
311 }
312 if (flags & hardware::gnss::V1_0::GnssLocationFlags::HAS_VERTICAL_ACCURACY) {
313 SET(VerticalAccuracyMeters, location.verticalAccuracyMeters);
314 }
315 if (flags & hardware::gnss::V1_0::GnssLocationFlags::HAS_SPEED_ACCURACY) {
316 SET(SpeedAccuracyMetersPerSecond, location.speedAccuracyMetersPerSecond);
317 }
318 if (flags & hardware::gnss::V1_0::GnssLocationFlags::HAS_BEARING_ACCURACY) {
319 SET(BearingAccuracyDegrees, location.bearingAccuracyDegrees);
320 }
321 SET(Time, location.timestamp);
322
323 return object.get();
324}
325
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700326/*
327 * GnssCallback class implements the callback methods for IGnss interface.
328 */
329struct GnssCallback : public IGnssCallback {
330 Return<void> gnssLocationCb(
331 const android::hardware::gnss::V1_0::GnssLocation& location) override;
332 Return<void> gnssStatusCb(const IGnssCallback::GnssStatusValue status) override;
333 Return<void> gnssSvStatusCb(const IGnssCallback::GnssSvStatus& svStatus) override;
334 Return<void> gnssNmeaCb(int64_t timestamp, const android::hardware::hidl_string& nmea) override;
335 Return<void> gnssSetCapabilitesCb(uint32_t capabilities) override;
336 Return<void> gnssAcquireWakelockCb() override;
337 Return<void> gnssReleaseWakelockCb() override;
338 Return<void> gnssRequestTimeCb() override;
339 Return<void> gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo& info) override;
Lifu Tang38bce792016-02-24 17:17:38 -0800340
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700341 static GnssSvInfo sGnssSvList[static_cast<uint32_t>(
342 android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)];
343 static size_t sGnssSvListSize;
344
345 static const char* sNmeaString;
346 static size_t sNmeaStringLength;
347};
348
349IGnssCallback::GnssSvInfo GnssCallback::sGnssSvList[static_cast<uint32_t>(
350 android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)];
351const char* GnssCallback::sNmeaString = nullptr;
352size_t GnssCallback::sNmeaStringLength = 0;
353size_t GnssCallback::sGnssSvListSize = 0;
354
355Return<void> GnssCallback::gnssLocationCb(
356 const ::android::hardware::gnss::V1_0::GnssLocation& location) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800357 JNIEnv* env = getJniEnv();
Wyatt Riley5d229832017-02-10 17:06:00 -0800358
359 jobject jLocation = translateLocation(env, location);
360 bool hasLatLong = (static_cast<uint32_t>(location.gnssLocationFlags) &
361 hardware::gnss::V1_0::GnssLocationFlags::HAS_LAT_LONG) != 0;
362
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700363 env->CallVoidMethod(mCallbacksObj,
364 method_reportLocation,
Wyatt Riley5d229832017-02-10 17:06:00 -0800365 boolToJbool(hasLatLong),
366 jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700367 checkAndClearExceptionFromCallback(env, __FUNCTION__);
368 return Void();
369}
370
371Return<void> GnssCallback::gnssStatusCb(const IGnssCallback::GnssStatusValue status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800372 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700373 env->CallVoidMethod(mCallbacksObj, method_reportStatus, status);
374 checkAndClearExceptionFromCallback(env, __FUNCTION__);
375 return Void();
376}
377
378Return<void> GnssCallback::gnssSvStatusCb(const IGnssCallback::GnssSvStatus& svStatus) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800379 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700380
381 sGnssSvListSize = svStatus.numSvs;
382 if (sGnssSvListSize > static_cast<uint32_t>(
383 android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)) {
384 ALOGD("Too many satellites %zd. Clamps to %u.", sGnssSvListSize,
385 static_cast<uint32_t>(android::hardware::gnss::V1_0::GnssMax::SVS_COUNT));
386 sGnssSvListSize = static_cast<uint32_t>(android::hardware::gnss::V1_0::GnssMax::SVS_COUNT);
Lifu Tang38bce792016-02-24 17:17:38 -0800387 }
388
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700389 // Copy GNSS SV info into sGnssSvList, if any.
390 if (svStatus.numSvs > 0) {
391 memcpy(sGnssSvList, svStatus.gnssSvList.data(), sizeof(GnssSvInfo) * sGnssSvListSize);
Lifu Tang9363b942016-02-16 18:07:00 -0800392 }
destradaaea8a8a62014-06-23 18:19:03 -0700393
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700394 env->CallVoidMethod(mCallbacksObj, method_reportSvStatus);
395 checkAndClearExceptionFromCallback(env, __FUNCTION__);
396 return Void();
destradaaea8a8a62014-06-23 18:19:03 -0700397}
398
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700399Return<void> GnssCallback::gnssNmeaCb(
400 int64_t timestamp, const ::android::hardware::hidl_string& nmea) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800401 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700402 /*
403 * The Java code will call back to read these values.
404 * We do this to avoid creating unnecessary String objects.
405 */
406 sNmeaString = nmea.c_str();
407 sNmeaStringLength = nmea.size();
408
409 env->CallVoidMethod(mCallbacksObj, method_reportNmea, timestamp);
410 checkAndClearExceptionFromCallback(env, __FUNCTION__);
411 return Void();
412}
413
414Return<void> GnssCallback::gnssSetCapabilitesCb(uint32_t capabilities) {
415 ALOGD("%s: %du\n", __func__, capabilities);
416
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800417 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700418 env->CallVoidMethod(mCallbacksObj, method_setEngineCapabilities, capabilities);
419 checkAndClearExceptionFromCallback(env, __FUNCTION__);
420 return Void();
421}
422
423Return<void> GnssCallback::gnssAcquireWakelockCb() {
424 acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
425 return Void();
426}
427
428Return<void> GnssCallback::gnssReleaseWakelockCb() {
429 release_wake_lock(WAKE_LOCK_NAME);
430 return Void();
431}
432
433Return<void> GnssCallback::gnssRequestTimeCb() {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800434 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700435 env->CallVoidMethod(mCallbacksObj, method_requestUtcTime);
436 checkAndClearExceptionFromCallback(env, __FUNCTION__);
437 return Void();
438}
439
440Return<void> GnssCallback::gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo& info) {
441 ALOGD("%s: yearOfHw=%d\n", __func__, info.yearOfHw);
442
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800443 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700444 env->CallVoidMethod(mCallbacksObj, method_setGnssYearOfHardware,
445 info.yearOfHw);
446 checkAndClearExceptionFromCallback(env, __FUNCTION__);
447 return Void();
448}
449
450class GnssXtraCallback : public IGnssXtraCallback {
451 Return<void> downloadRequestCb() override;
452};
453
454/*
455 * GnssXtraCallback class implements the callback methods for the IGnssXtra
456 * interface.
457 */
458Return<void> GnssXtraCallback::downloadRequestCb() {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800459 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700460 env->CallVoidMethod(mCallbacksObj, method_xtraDownloadRequest);
461 checkAndClearExceptionFromCallback(env, __FUNCTION__);
462 return Void();
463}
464
465/*
466 * GnssGeofenceCallback class implements the callback methods for the
467 * IGnssGeofence interface.
468 */
469struct GnssGeofenceCallback : public IGnssGeofenceCallback {
470 // Methods from ::android::hardware::gps::V1_0::IGnssGeofenceCallback follow.
471 Return<void> gnssGeofenceTransitionCb(
472 int32_t geofenceId,
473 const android::hardware::gnss::V1_0::GnssLocation& location,
474 GeofenceTransition transition,
475 hardware::gnss::V1_0::GnssUtcTime timestamp) override;
476 Return<void> gnssGeofenceStatusCb(
477 GeofenceAvailability status,
478 const android::hardware::gnss::V1_0::GnssLocation& location) override;
479 Return<void> gnssGeofenceAddCb(int32_t geofenceId,
480 GeofenceStatus status) override;
481 Return<void> gnssGeofenceRemoveCb(int32_t geofenceId,
482 GeofenceStatus status) override;
483 Return<void> gnssGeofencePauseCb(int32_t geofenceId,
484 GeofenceStatus status) override;
485 Return<void> gnssGeofenceResumeCb(int32_t geofenceId,
486 GeofenceStatus status) override;
487};
488
489Return<void> GnssGeofenceCallback::gnssGeofenceTransitionCb(
490 int32_t geofenceId,
491 const android::hardware::gnss::V1_0::GnssLocation& location,
492 GeofenceTransition transition,
493 hardware::gnss::V1_0::GnssUtcTime timestamp) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800494 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700495
Wyatt Riley5d229832017-02-10 17:06:00 -0800496 jobject jLocation = translateLocation(env, location);
497
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700498 env->CallVoidMethod(mCallbacksObj,
499 method_reportGeofenceTransition,
500 geofenceId,
Wyatt Riley5d229832017-02-10 17:06:00 -0800501 jLocation,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700502 transition,
503 timestamp);
504
505 checkAndClearExceptionFromCallback(env, __FUNCTION__);
506 return Void();
507}
508
509Return<void> GnssGeofenceCallback::gnssGeofenceStatusCb(
510 GeofenceAvailability status,
511 const android::hardware::gnss::V1_0::GnssLocation& location) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800512 JNIEnv* env = getJniEnv();
Wyatt Riley5d229832017-02-10 17:06:00 -0800513
514 jobject jLocation = translateLocation(env, location);
515
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700516 env->CallVoidMethod(mCallbacksObj,
517 method_reportGeofenceStatus,
518 status,
Wyatt Riley5d229832017-02-10 17:06:00 -0800519 jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700520 checkAndClearExceptionFromCallback(env, __FUNCTION__);
521 return Void();
522}
523
524Return<void> GnssGeofenceCallback::gnssGeofenceAddCb(int32_t geofenceId,
525 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800526 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700527 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
528 ALOGE("%s: Error in adding a Geofence: %d\n", __func__, status);
529 }
530
531 env->CallVoidMethod(mCallbacksObj,
532 method_reportGeofenceAddStatus,
533 geofenceId,
534 status);
535 checkAndClearExceptionFromCallback(env, __FUNCTION__);
536 return Void();
537}
538
539Return<void> GnssGeofenceCallback::gnssGeofenceRemoveCb(int32_t geofenceId,
540 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800541 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700542 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
543 ALOGE("%s: Error in removing a Geofence: %d\n", __func__, status);
544 }
545
546 env->CallVoidMethod(mCallbacksObj,
547 method_reportGeofenceRemoveStatus,
548 geofenceId, status);
549 checkAndClearExceptionFromCallback(env, __FUNCTION__);
550 return Void();
551}
552
553Return<void> GnssGeofenceCallback::gnssGeofencePauseCb(int32_t geofenceId,
554 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800555 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700556 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
557 ALOGE("%s: Error in pausing Geofence: %d\n", __func__, status);
558 }
559
560 env->CallVoidMethod(mCallbacksObj,
561 method_reportGeofencePauseStatus,
562 geofenceId, status);
563 checkAndClearExceptionFromCallback(env, __FUNCTION__);
564 return Void();
565}
566
567Return<void> GnssGeofenceCallback::gnssGeofenceResumeCb(int32_t geofenceId,
568 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800569 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700570 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
571 ALOGE("%s: Error in resuming Geofence: %d\n", __func__, status);
572 }
573
574 env->CallVoidMethod(mCallbacksObj,
575 method_reportGeofenceResumeStatus,
576 geofenceId, status);
577 checkAndClearExceptionFromCallback(env, __FUNCTION__);
578 return Void();
579}
580
581/*
582 * GnssNavigationMessageCallback interface implements the callback methods
583 * required by the IGnssNavigationMessage interface.
584 */
585struct GnssNavigationMessageCallback : public IGnssNavigationMessageCallback {
586 /*
587 * Methods from ::android::hardware::gps::V1_0::IGnssNavigationMessageCallback
588 * follow.
589 */
590 Return<void> gnssNavigationMessageCb(
591 const IGnssNavigationMessageCallback::GnssNavigationMessage& message) override;
592};
593
594Return<void> GnssNavigationMessageCallback::gnssNavigationMessageCb(
595 const IGnssNavigationMessageCallback::GnssNavigationMessage& message) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800596 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700597
598 size_t dataLength = message.data.size();
599
600 std::vector<uint8_t> navigationData = message.data;
601 uint8_t* data = &(navigationData[0]);
602 if (dataLength == 0 || data == NULL) {
603 ALOGE("Invalid Navigation Message found: data=%p, length=%zd", data,
604 dataLength);
605 return Void();
606 }
607
608 JavaObject object(env, "android/location/GnssNavigationMessage");
609 SET(Type, static_cast<int32_t>(message.type));
610 SET(Svid, static_cast<int32_t>(message.svid));
611 SET(MessageId, static_cast<int32_t>(message.messageId));
612 SET(SubmessageId, static_cast<int32_t>(message.submessageId));
613 object.callSetter("setData", data, dataLength);
614 SET(Status, static_cast<int32_t>(message.status));
615
616 jobject navigationMessage = object.get();
617 env->CallVoidMethod(mCallbacksObj,
618 method_reportNavigationMessages,
619 navigationMessage);
Wyatt Rileycf879db2017-01-12 13:57:38 -0800620 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700621 env->DeleteLocalRef(navigationMessage);
622 return Void();
623}
624
625/*
626 * GnssMeasurementCallback implements the callback methods required for the
627 * GnssMeasurement interface.
628 */
629struct GnssMeasurementCallback : public IGnssMeasurementCallback {
630 Return<void> GnssMeasurementCb(const IGnssMeasurementCallback::GnssData& data);
631 private:
632 jobject translateGnssMeasurement(
633 JNIEnv* env, const IGnssMeasurementCallback::GnssMeasurement* measurement);
634 jobject translateGnssClock(
635 JNIEnv* env, const IGnssMeasurementCallback::GnssClock* clock);
636 jobjectArray translateGnssMeasurements(
637 JNIEnv* env,
638 const IGnssMeasurementCallback::GnssMeasurement* measurements,
639 size_t count);
640 void setMeasurementData(JNIEnv* env, jobject clock, jobjectArray measurementArray);
641};
642
643
644Return<void> GnssMeasurementCallback::GnssMeasurementCb(
645 const IGnssMeasurementCallback::GnssData& data) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800646 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700647
648 jobject clock;
649 jobjectArray measurementArray;
650
651 clock = translateGnssClock(env, &data.clock);
652 measurementArray = translateGnssMeasurements(
653 env, data.measurements.data(), data.measurementCount);
654 setMeasurementData(env, clock, measurementArray);
655
656 env->DeleteLocalRef(clock);
657 env->DeleteLocalRef(measurementArray);
658 return Void();
659}
660
661jobject GnssMeasurementCallback::translateGnssMeasurement(
662 JNIEnv* env, const IGnssMeasurementCallback::GnssMeasurement* measurement) {
Lifu Tang120480f2016-02-07 18:08:19 -0800663 JavaObject object(env, "android/location/GnssMeasurement");
Lifu Tang120480f2016-02-07 18:08:19 -0800664
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700665 uint32_t flags = static_cast<uint32_t>(measurement->flags);
Mike Cailean96635bd2016-03-24 19:34:16 -0700666
667 SET(Svid, static_cast<int32_t>(measurement->svid));
Lifu Tang76a620f2016-02-26 19:53:01 -0800668 SET(ConstellationType, static_cast<int32_t>(measurement->constellation));
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700669 SET(TimeOffsetNanos, measurement->timeOffsetNs);
Lifu Tang76a620f2016-02-26 19:53:01 -0800670 SET(State, static_cast<int32_t>(measurement->state));
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700671 SET(ReceivedSvTimeNanos, measurement->receivedSvTimeInNs);
Lifu Tang76a620f2016-02-26 19:53:01 -0800672 SET(ReceivedSvTimeUncertaintyNanos,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700673 measurement->receivedSvTimeUncertaintyInNs);
674 SET(Cn0DbHz, measurement->cN0DbHz);
675 SET(PseudorangeRateMetersPerSecond, measurement->pseudorangeRateMps);
Lifu Tang76a620f2016-02-26 19:53:01 -0800676 SET(PseudorangeRateUncertaintyMetersPerSecond,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700677 measurement->pseudorangeRateUncertaintyMps);
Lifu Tang76a620f2016-02-26 19:53:01 -0800678 SET(AccumulatedDeltaRangeState,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700679 (static_cast<int32_t>(measurement->accumulatedDeltaRangeState)));
680 SET(AccumulatedDeltaRangeMeters, measurement->accumulatedDeltaRangeM);
Lifu Tang76a620f2016-02-26 19:53:01 -0800681 SET(AccumulatedDeltaRangeUncertaintyMeters,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700682 measurement->accumulatedDeltaRangeUncertaintyM);
683
684 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_FREQUENCY)) {
685 SET(CarrierFrequencyHz, measurement->carrierFrequencyHz);
686 }
687
688 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_PHASE)) {
689 SET(CarrierPhase, measurement->carrierPhase);
690 }
691
692 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_PHASE_UNCERTAINTY)) {
693 SET(CarrierPhaseUncertainty, measurement->carrierPhaseUncertainty);
694 }
695
696 SET(MultipathIndicator, static_cast<int32_t>(measurement->multipathIndicator));
697
698 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_SNR)) {
699 SET(SnrInDb, measurement->snrDb);
700 }
Lifu Tang120480f2016-02-07 18:08:19 -0800701
gomo4402af62017-01-11 13:20:13 -0800702 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_AUTOMATIC_GAIN_CONTROL)) {
gomo127ba322017-01-15 20:26:48 -0800703 SET(AutomaticGainControlLevelInDb, measurement->agcLevelDb);
gomo4402af62017-01-11 13:20:13 -0800704 }
705
Lifu Tang120480f2016-02-07 18:08:19 -0800706 return object.get();
707}
708
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700709jobject GnssMeasurementCallback::translateGnssClock(
710 JNIEnv* env, const IGnssMeasurementCallback::GnssClock* clock) {
711 JavaObject object(env, "android/location/GnssClock");
712
713 uint32_t flags = static_cast<uint32_t>(clock->gnssClockFlags);
714 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_LEAP_SECOND)) {
715 SET(LeapSecond, static_cast<int32_t>(clock->leapSecond));
716 }
717
718 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_TIME_UNCERTAINTY)) {
719 SET(TimeUncertaintyNanos, clock->timeUncertaintyNs);
720 }
721
722 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_FULL_BIAS)) {
723 SET(FullBiasNanos, clock->fullBiasNs);
724 }
725
726 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS)) {
727 SET(BiasNanos, clock->biasNs);
728 }
729
730 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS_UNCERTAINTY)) {
731 SET(BiasUncertaintyNanos, clock->biasUncertaintyNs);
732 }
733
734 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT)) {
735 SET(DriftNanosPerSecond, clock->driftNsps);
736 }
737
738 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT_UNCERTAINTY)) {
739 SET(DriftUncertaintyNanosPerSecond, clock->driftUncertaintyNsps);
740 }
741
742 SET(TimeNanos, clock->timeNs);
743 SET(HardwareClockDiscontinuityCount, clock->hwClockDiscontinuityCount);
744
745 return object.get();
746}
747
748jobjectArray GnssMeasurementCallback::translateGnssMeasurements(JNIEnv* env,
749 const IGnssMeasurementCallback::GnssMeasurement*
750 measurements, size_t count) {
Lifu Tang120480f2016-02-07 18:08:19 -0800751 if (count == 0) {
destradaaea8a8a62014-06-23 18:19:03 -0700752 return NULL;
753 }
754
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700755 jclass gnssMeasurementClass = env->FindClass("android/location/GnssMeasurement");
Lifu Tang818aa2c2016-02-01 01:52:00 -0800756 jobjectArray gnssMeasurementArray = env->NewObjectArray(
Lifu Tang120480f2016-02-07 18:08:19 -0800757 count,
Lifu Tang818aa2c2016-02-01 01:52:00 -0800758 gnssMeasurementClass,
destradaaea8a8a62014-06-23 18:19:03 -0700759 NULL /* initialElement */);
760
Lifu Tang120480f2016-02-07 18:08:19 -0800761 for (uint16_t i = 0; i < count; ++i) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700762 jobject gnssMeasurement = translateGnssMeasurement(
Lifu Tange5a0e212016-01-25 18:02:17 -0800763 env,
Lifu Tang120480f2016-02-07 18:08:19 -0800764 &measurements[i]);
Lifu Tang818aa2c2016-02-01 01:52:00 -0800765 env->SetObjectArrayElement(gnssMeasurementArray, i, gnssMeasurement);
766 env->DeleteLocalRef(gnssMeasurement);
destradaaea8a8a62014-06-23 18:19:03 -0700767 }
768
Lifu Tang818aa2c2016-02-01 01:52:00 -0800769 env->DeleteLocalRef(gnssMeasurementClass);
770 return gnssMeasurementArray;
destradaaea8a8a62014-06-23 18:19:03 -0700771}
772
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700773void GnssMeasurementCallback::setMeasurementData(JNIEnv* env, jobject clock,
774 jobjectArray measurementArray) {
775 jclass gnssMeasurementsEventClass =
776 env->FindClass("android/location/GnssMeasurementsEvent");
777 jmethodID gnssMeasurementsEventCtor =
778 env->GetMethodID(
779 gnssMeasurementsEventClass,
780 "<init>",
781 "(Landroid/location/GnssClock;[Landroid/location/GnssMeasurement;)V");
Lifu Tange5a0e212016-01-25 18:02:17 -0800782
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700783 jobject gnssMeasurementsEvent = env->NewObject(gnssMeasurementsEventClass,
784 gnssMeasurementsEventCtor,
785 clock,
786 measurementArray);
Lifu Tang120480f2016-02-07 18:08:19 -0800787
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700788 env->CallVoidMethod(mCallbacksObj, method_reportMeasurementData,
789 gnssMeasurementsEvent);
Lifu Tange5a0e212016-01-25 18:02:17 -0800790 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Lifu Tang818aa2c2016-02-01 01:52:00 -0800791 env->DeleteLocalRef(gnssMeasurementsEventClass);
792 env->DeleteLocalRef(gnssMeasurementsEvent);
destradaaea8a8a62014-06-23 18:19:03 -0700793}
794
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700795/*
796 * GnssNiCallback implements callback methods required by the IGnssNi interface.
797 */
798struct GnssNiCallback : public IGnssNiCallback {
799 Return<void> niNotifyCb(const IGnssNiCallback::GnssNiNotification& notification)
800 override;
destradaaea8a8a62014-06-23 18:19:03 -0700801};
802
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700803Return<void> GnssNiCallback::niNotifyCb(
804 const IGnssNiCallback::GnssNiNotification& notification) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800805 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700806 jstring requestorId = env->NewStringUTF(notification.requestorId.c_str());
807 jstring text = env->NewStringUTF(notification.notificationMessage.c_str());
808
809 if (requestorId && text) {
810 env->CallVoidMethod(mCallbacksObj, method_reportNiNotification,
811 notification.notificationId, notification.niType,
812 notification.notifyFlags, notification.timeoutSec,
813 notification.defaultResponse, requestorId, text,
814 notification.requestorIdEncoding,
815 notification.notificationIdEncoding);
816 } else {
817 ALOGE("%s: OOM Error\n", __func__);
818 }
819
820 if (requestorId) {
821 env->DeleteLocalRef(requestorId);
822 }
823
824 if (text) {
825 env->DeleteLocalRef(text);
826 }
827 checkAndClearExceptionFromCallback(env, __FUNCTION__);
828 return Void();
829}
830
831/*
832 * AGnssCallback implements callback methods required by the IAGnss interface.
833 */
834struct AGnssCallback : public IAGnssCallback {
835 // Methods from ::android::hardware::gps::V1_0::IAGnssCallback follow.
836 Return<void> agnssStatusIpV6Cb(
837 const IAGnssCallback::AGnssStatusIpV6& agps_status) override;
838
839 Return<void> agnssStatusIpV4Cb(
840 const IAGnssCallback::AGnssStatusIpV4& agps_status) override;
841 private:
842 jbyteArray convertToIpV4(uint32_t ip);
843};
844
845Return<void> AGnssCallback::agnssStatusIpV6Cb(
846 const IAGnssCallback::AGnssStatusIpV6& agps_status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800847 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700848 jbyteArray byteArray = NULL;
849 bool isSupported = false;
850
851 byteArray = env->NewByteArray(16);
852 if (byteArray != NULL) {
853 env->SetByteArrayRegion(byteArray, 0, 16,
854 (const jbyte*)(agps_status.ipV6Addr.data()));
855 isSupported = true;
856 } else {
857 ALOGE("Unable to allocate byte array for IPv6 address.");
858 }
859
860 IF_ALOGD() {
861 // log the IP for reference in case there is a bogus value pushed by HAL
862 char str[INET6_ADDRSTRLEN];
863 inet_ntop(AF_INET6, agps_status.ipV6Addr.data(), str, INET6_ADDRSTRLEN);
864 ALOGD("AGPS IP is v6: %s", str);
865 }
866
867 jsize byteArrayLength = byteArray != NULL ? env->GetArrayLength(byteArray) : 0;
868 ALOGV("Passing AGPS IP addr: size %d", byteArrayLength);
869 env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus,
870 agps_status.type, agps_status.status, byteArray);
871
872 checkAndClearExceptionFromCallback(env, __FUNCTION__);
873
874 if (byteArray) {
875 env->DeleteLocalRef(byteArray);
876 }
877
878 return Void();
879}
880
881Return<void> AGnssCallback::agnssStatusIpV4Cb(
882 const IAGnssCallback::AGnssStatusIpV4& agps_status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800883 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700884 jbyteArray byteArray = NULL;
885
886 uint32_t ipAddr = agps_status.ipV4Addr;
887 byteArray = convertToIpV4(ipAddr);
888
889 IF_ALOGD() {
890 /*
891 * log the IP for reference in case there is a bogus value pushed by
892 * HAL.
893 */
894 char str[INET_ADDRSTRLEN];
895 inet_ntop(AF_INET, &ipAddr, str, INET_ADDRSTRLEN);
896 ALOGD("AGPS IP is v4: %s", str);
897 }
898
899 jsize byteArrayLength =
900 byteArray != NULL ? env->GetArrayLength(byteArray) : 0;
901 ALOGV("Passing AGPS IP addr: size %d", byteArrayLength);
902 env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus,
903 agps_status.type, agps_status.status, byteArray);
904
905 checkAndClearExceptionFromCallback(env, __FUNCTION__);
906
907 if (byteArray) {
908 env->DeleteLocalRef(byteArray);
909 }
910 return Void();
911}
912
913jbyteArray AGnssCallback::convertToIpV4(uint32_t ip) {
914 if (INADDR_NONE == ip) {
915 return NULL;
916 }
917
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800918 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700919 jbyteArray byteArray = env->NewByteArray(4);
920 if (byteArray == NULL) {
921 ALOGE("Unable to allocate byte array for IPv4 address");
922 return NULL;
923 }
924
925 jbyte ipv4[4];
926 ALOGV("Converting IPv4 address byte array (net_order) %x", ip);
927 memcpy(ipv4, &ip, sizeof(ipv4));
928 env->SetByteArrayRegion(byteArray, 0, 4, (const jbyte*)ipv4);
929 return byteArray;
930}
931
932/*
933 * AGnssRilCallback implements the callback methods required by the AGnssRil
934 * interface.
935 */
936struct AGnssRilCallback : IAGnssRilCallback {
Hridya Valsarajub39eb402017-01-11 08:07:40 -0800937 Return<void> requestSetIdCb(uint32_t setIdFlag) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700938 Return<void> requestRefLocCb() override;
939};
940
Hridya Valsarajub39eb402017-01-11 08:07:40 -0800941Return<void> AGnssRilCallback::requestSetIdCb(uint32_t setIdFlag) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800942 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700943 env->CallVoidMethod(mCallbacksObj, method_requestSetID, setIdFlag);
944 checkAndClearExceptionFromCallback(env, __FUNCTION__);
945 return Void();
946}
947
948Return<void> AGnssRilCallback::requestRefLocCb() {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800949 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700950 env->CallVoidMethod(mCallbacksObj, method_requestRefLocation);
951 checkAndClearExceptionFromCallback(env, __FUNCTION__);
952 return Void();
953}
954
Wyatt Rileycf879db2017-01-12 13:57:38 -0800955/*
956 * GnssBatchingCallback interface implements the callback methods
957 * required by the IGnssBatching interface.
958 */
959struct GnssBatchingCallback : public IGnssBatchingCallback {
960 /*
961 * Methods from ::android::hardware::gps::V1_0::IGnssBatchingCallback
962 * follow.
963 */
964 Return<void> gnssLocationBatchCb(
965 const ::android::hardware::hidl_vec<hardware::gnss::V1_0::GnssLocation> & locations)
966 override;
Wyatt Rileycf879db2017-01-12 13:57:38 -0800967};
968
969Return<void> GnssBatchingCallback::gnssLocationBatchCb(
970 const ::android::hardware::hidl_vec<hardware::gnss::V1_0::GnssLocation> & locations) {
971 JNIEnv* env = getJniEnv();
972
973 jobjectArray jLocations = env->NewObjectArray(locations.size(),
974 env->FindClass("android/location/Location"), nullptr);
975
976 for (uint16_t i = 0; i < locations.size(); ++i) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800977 jobject jLocation = translateLocation(env, locations[i]);
Wyatt Rileycf879db2017-01-12 13:57:38 -0800978 env->SetObjectArrayElement(jLocations, i, jLocation);
979 env->DeleteLocalRef(jLocation);
980 }
981
982 env->CallVoidMethod(mCallbacksObj, method_reportLocationBatch, jLocations);
983 checkAndClearExceptionFromCallback(env, __FUNCTION__);
984
985 env->DeleteLocalRef(jLocations);
986
987 return Void();
988}
989
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700990static void android_location_GnssLocationProvider_class_init_native(JNIEnv* env, jclass clazz) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800991 method_reportLocation = env->GetMethodID(clazz, "reportLocation",
992 "(ZLandroid/location/Location;)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700993 method_reportStatus = env->GetMethodID(clazz, "reportStatus", "(I)V");
994 method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "()V");
995 method_reportAGpsStatus = env->GetMethodID(clazz, "reportAGpsStatus", "(II[B)V");
996 method_reportNmea = env->GetMethodID(clazz, "reportNmea", "(J)V");
997 method_setEngineCapabilities = env->GetMethodID(clazz, "setEngineCapabilities", "(I)V");
998 method_setGnssYearOfHardware = env->GetMethodID(clazz, "setGnssYearOfHardware", "(I)V");
999 method_xtraDownloadRequest = env->GetMethodID(clazz, "xtraDownloadRequest", "()V");
1000 method_reportNiNotification = env->GetMethodID(clazz, "reportNiNotification",
1001 "(IIIIILjava/lang/String;Ljava/lang/String;II)V");
1002 method_requestRefLocation = env->GetMethodID(clazz, "requestRefLocation", "()V");
1003 method_requestSetID = env->GetMethodID(clazz, "requestSetID", "(I)V");
1004 method_requestUtcTime = env->GetMethodID(clazz, "requestUtcTime", "()V");
1005 method_reportGeofenceTransition = env->GetMethodID(clazz, "reportGeofenceTransition",
Wyatt Riley5d229832017-02-10 17:06:00 -08001006 "(ILandroid/location/Location;IJ)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001007 method_reportGeofenceStatus = env->GetMethodID(clazz, "reportGeofenceStatus",
Wyatt Riley5d229832017-02-10 17:06:00 -08001008 "(ILandroid/location/Location;)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001009 method_reportGeofenceAddStatus = env->GetMethodID(clazz, "reportGeofenceAddStatus",
1010 "(II)V");
1011 method_reportGeofenceRemoveStatus = env->GetMethodID(clazz, "reportGeofenceRemoveStatus",
1012 "(II)V");
1013 method_reportGeofenceResumeStatus = env->GetMethodID(clazz, "reportGeofenceResumeStatus",
1014 "(II)V");
1015 method_reportGeofencePauseStatus = env->GetMethodID(clazz, "reportGeofencePauseStatus",
1016 "(II)V");
1017 method_reportMeasurementData = env->GetMethodID(
1018 clazz,
1019 "reportMeasurementData",
1020 "(Landroid/location/GnssMeasurementsEvent;)V");
1021 method_reportNavigationMessages = env->GetMethodID(
1022 clazz,
1023 "reportNavigationMessage",
1024 "(Landroid/location/GnssNavigationMessage;)V");
Wyatt Rileycf879db2017-01-12 13:57:38 -08001025 method_reportLocationBatch = env->GetMethodID(
1026 clazz,
1027 "reportLocationBatch",
1028 "([Landroid/location/Location;)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001029
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001030 /*
1031 * Save a pointer to JVM.
1032 */
1033 jint jvmStatus = env->GetJavaVM(&sJvm);
1034 if (jvmStatus != JNI_OK) {
1035 LOG_ALWAYS_FATAL("Unable to get Java VM. Error: %d", jvmStatus);
1036 }
1037
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001038 // TODO(b/31632518)
Chris Phoenixf9133782017-01-23 15:15:15 -08001039 gnssHal = IGnss::getService();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001040 if (gnssHal != nullptr) {
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001041 auto gnssXtra = gnssHal->getExtensionXtra();
1042 if (!gnssXtra.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001043 ALOGD("Unable to get a handle to Xtra");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001044 } else {
1045 gnssXtraIface = gnssXtra;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001046 }
1047
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001048 auto gnssRil = gnssHal->getExtensionAGnssRil();
1049 if (!gnssRil.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001050 ALOGD("Unable to get a handle to AGnssRil");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001051 } else {
1052 agnssRilIface = gnssRil;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001053 }
1054
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001055 auto gnssAgnss = gnssHal->getExtensionAGnss();
1056 if (!gnssAgnss.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001057 ALOGD("Unable to get a handle to AGnss");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001058 } else {
1059 agnssIface = gnssAgnss;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001060 }
1061
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001062 auto gnssNavigationMessage = gnssHal->getExtensionGnssNavigationMessage();
1063 if (!gnssNavigationMessage.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001064 ALOGD("Unable to get a handle to GnssNavigationMessage");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001065 } else {
1066 gnssNavigationMessageIface = gnssNavigationMessage;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001067 }
1068
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001069 auto gnssMeasurement = gnssHal->getExtensionGnssMeasurement();
1070 if (!gnssMeasurement.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001071 ALOGD("Unable to get a handle to GnssMeasurement");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001072 } else {
1073 gnssMeasurementIface = gnssMeasurement;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001074 }
1075
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001076 auto gnssDebug = gnssHal->getExtensionGnssDebug();
1077 if (!gnssDebug.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001078 ALOGD("Unable to get a handle to GnssDebug");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001079 } else {
1080 gnssDebugIface = gnssDebug;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001081 }
1082
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001083 auto gnssNi = gnssHal->getExtensionGnssNi();
1084 if (!gnssNi.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001085 ALOGD("Unable to get a handle to GnssNi");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001086 } else {
1087 gnssNiIface = gnssNi;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001088 }
1089
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001090 auto gnssConfiguration = gnssHal->getExtensionGnssConfiguration();
1091 if (!gnssConfiguration.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001092 ALOGD("Unable to get a handle to GnssConfiguration");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001093 } else {
1094 gnssConfigurationIface = gnssConfiguration;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001095 }
1096
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001097 auto gnssGeofencing = gnssHal->getExtensionGnssGeofencing();
1098 if (!gnssGeofencing.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001099 ALOGD("Unable to get a handle to GnssGeofencing");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001100 } else {
1101 gnssGeofencingIface = gnssGeofencing;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001102 }
Wyatt Rileycf879db2017-01-12 13:57:38 -08001103
1104 auto gnssBatching = gnssHal->getExtensionGnssBatching();
1105 if (!gnssBatching.isOk()) {
1106 ALOGD("Unable to get a handle to gnssBatching");
1107 } else {
1108 gnssBatchingIface = gnssBatching;
1109 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001110 } else {
1111 ALOGE("Unable to get GPS service\n");
1112 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001113}
1114
1115static jboolean android_location_GnssLocationProvider_is_supported(
1116 JNIEnv* /* env */, jclass /* clazz */) {
1117 return (gnssHal != nullptr) ? JNI_TRUE : JNI_FALSE;
1118}
1119
1120static jboolean android_location_GnssLocationProvider_is_agps_ril_supported(
1121 JNIEnv* /* env */, jclass /* clazz */) {
1122 return (agnssRilIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1123}
1124
1125static jboolean android_location_gpsLocationProvider_is_gnss_configuration_supported(
1126 JNIEnv* /* env */, jclass /* jclazz */) {
1127 return (gnssConfigurationIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1128}
1129
1130static jboolean android_location_GnssLocationProvider_init(JNIEnv* env, jobject obj) {
1131 /*
1132 * This must be set before calling into the HAL library.
1133 */
1134 if (!mCallbacksObj)
1135 mCallbacksObj = env->NewGlobalRef(obj);
1136
1137 sp<IGnssCallback> gnssCbIface = new GnssCallback();
1138 /*
1139 * Fail if the main interface fails to initialize
1140 */
1141 if (gnssHal == nullptr) {
1142 ALOGE("Unable to Initialize GNSS HAL\n");
1143 return JNI_FALSE;
1144 }
1145
1146 auto result = gnssHal->setCallback(gnssCbIface);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001147 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001148 ALOGE("SetCallback for Gnss Interface fails\n");
1149 return JNI_FALSE;
1150 }
1151
1152 sp<IGnssXtraCallback> gnssXtraCbIface = new GnssXtraCallback();
1153 if (gnssXtraIface == nullptr) {
1154 ALOGE("Unable to initialize GNSS Xtra interface\n");
Hridya Valsarajue8650322016-12-05 20:23:21 -08001155 } else {
1156 result = gnssXtraIface->setCallback(gnssXtraCbIface);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001157 if (!result.isOk() || !result) {
Hridya Valsarajue8650322016-12-05 20:23:21 -08001158 gnssXtraIface = nullptr;
1159 ALOGE("SetCallback for Gnss Xtra Interface fails\n");
1160 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001161 }
1162
1163 sp<IAGnssCallback> aGnssCbIface = new AGnssCallback();
1164 if (agnssIface != nullptr) {
1165 agnssIface->setCallback(aGnssCbIface);
1166 } else {
1167 ALOGE("Unable to Initialize AGnss interface\n");
1168 }
1169
1170 sp<IGnssGeofenceCallback> gnssGeofencingCbIface = new GnssGeofenceCallback();
1171 if (gnssGeofencingIface != nullptr) {
1172 gnssGeofencingIface->setCallback(gnssGeofencingCbIface);
1173 } else {
1174 ALOGE("Unable to initialize GNSS Geofencing interface\n");
1175 }
1176
1177 sp<IGnssNiCallback> gnssNiCbIface = new GnssNiCallback();
1178 if (gnssNiCbIface != nullptr) {
1179 gnssNiIface->setCallback(gnssNiCbIface);
1180 } else {
1181 ALOGE("Unable to initialize GNSS NI interface\n");
1182 }
1183
1184 return JNI_TRUE;
1185}
1186
1187static void android_location_GnssLocationProvider_cleanup(JNIEnv* /* env */, jobject /* obj */) {
1188 if (gnssHal != nullptr) {
1189 gnssHal->cleanup();
1190 }
1191}
1192
1193static jboolean android_location_GnssLocationProvider_set_position_mode(JNIEnv* /* env */,
1194 jobject /* obj */, jint mode, jint recurrence, jint min_interval, jint preferred_accuracy,
1195 jint preferred_time) {
1196 if (gnssHal != nullptr) {
1197 auto result = gnssHal->setPositionMode(static_cast<IGnss::GnssPositionMode>(mode),
1198 static_cast<IGnss::GnssPositionRecurrence>(recurrence),
1199 min_interval,
1200 preferred_accuracy,
1201 preferred_time);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001202 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001203 ALOGE("%s: GNSS setPositionMode failed\n", __func__);
1204 return JNI_FALSE;
1205 } else {
1206 return result;
1207 }
1208 } else {
1209 return JNI_FALSE;
1210 }
1211}
1212
1213static jboolean android_location_GnssLocationProvider_start(JNIEnv* /* env */, jobject /* obj */) {
1214 if (gnssHal != nullptr) {
1215 auto result = gnssHal->start();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001216 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001217 return JNI_FALSE;
1218 } else {
1219 return result;
1220 }
1221 } else {
1222 return JNI_FALSE;
1223 }
1224}
1225
1226static jboolean android_location_GnssLocationProvider_stop(JNIEnv* /* env */, jobject /* obj */) {
1227 if (gnssHal != nullptr) {
1228 auto result = gnssHal->stop();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001229 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001230 return JNI_FALSE;
1231 } else {
1232 return result;
1233 }
1234 } else {
1235 return JNI_FALSE;
1236 }
1237}
1238static void android_location_GnssLocationProvider_delete_aiding_data(JNIEnv* /* env */,
1239 jobject /* obj */,
1240 jint flags) {
1241 if (gnssHal != nullptr) {
1242 auto result = gnssHal->deleteAidingData(static_cast<IGnss::GnssAidingData>(flags));
Steven Morelandd002a8b2017-01-03 17:18:24 -08001243 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001244 ALOGE("Error in deleting aiding data");
1245 }
1246 }
1247}
1248
1249/*
1250 * This enum is used by the read_sv_status method to combine the svid,
1251 * constellation and svFlag fields.
1252 */
1253enum ShiftWidth: uint8_t {
1254 SVID_SHIFT_WIDTH = 7,
1255 CONSTELLATION_TYPE_SHIFT_WIDTH = 3
1256};
1257
1258static jint android_location_GnssLocationProvider_read_sv_status(JNIEnv* env, jobject /* obj */,
1259 jintArray svidWithFlagArray, jfloatArray cn0Array, jfloatArray elevArray,
gomo4402af62017-01-11 13:20:13 -08001260 jfloatArray azumArray, jfloatArray carrierFreqArray) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001261 /*
1262 * This method should only be called from within a call to reportSvStatus.
1263 */
1264 jint* svidWithFlags = env->GetIntArrayElements(svidWithFlagArray, 0);
1265 jfloat* cn0s = env->GetFloatArrayElements(cn0Array, 0);
1266 jfloat* elev = env->GetFloatArrayElements(elevArray, 0);
1267 jfloat* azim = env->GetFloatArrayElements(azumArray, 0);
gomo4402af62017-01-11 13:20:13 -08001268 jfloat* carrierFreq = env->GetFloatArrayElements(carrierFreqArray, 0);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001269
1270 /*
1271 * Read GNSS SV info.
1272 */
1273 for (size_t i = 0; i < GnssCallback::sGnssSvListSize; ++i) {
1274 const IGnssCallback::GnssSvInfo& info = GnssCallback::sGnssSvList[i];
1275 svidWithFlags[i] = (info.svid << SVID_SHIFT_WIDTH) |
1276 (static_cast<uint32_t>(info.constellation) << CONSTELLATION_TYPE_SHIFT_WIDTH) |
1277 static_cast<uint32_t>(info.svFlag);
1278 cn0s[i] = info.cN0Dbhz;
1279 elev[i] = info.elevationDegrees;
1280 azim[i] = info.azimuthDegrees;
gomo4402af62017-01-11 13:20:13 -08001281 carrierFreq[i] = info.carrierFrequencyHz;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001282 }
1283
1284 env->ReleaseIntArrayElements(svidWithFlagArray, svidWithFlags, 0);
1285 env->ReleaseFloatArrayElements(cn0Array, cn0s, 0);
1286 env->ReleaseFloatArrayElements(elevArray, elev, 0);
1287 env->ReleaseFloatArrayElements(azumArray, azim, 0);
gomo4402af62017-01-11 13:20:13 -08001288 env->ReleaseFloatArrayElements(carrierFreqArray, carrierFreq, 0);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001289 return static_cast<jint>(GnssCallback::sGnssSvListSize);
1290}
1291
1292static void android_location_GnssLocationProvider_agps_set_reference_location_cellid(
1293 JNIEnv* /* env */, jobject /* obj */, jint type, jint mcc, jint mnc, jint lac, jint cid) {
1294 IAGnssRil::AGnssRefLocation location;
1295
1296 if (agnssRilIface == nullptr) {
1297 ALOGE("No AGPS RIL interface in agps_set_reference_location_cellid");
1298 return;
1299 }
1300
1301 switch (static_cast<IAGnssRil::AGnssRefLocationType>(type)) {
1302 case IAGnssRil::AGnssRefLocationType::GSM_CELLID:
1303 case IAGnssRil::AGnssRefLocationType::UMTS_CELLID:
1304 location.type = static_cast<IAGnssRil::AGnssRefLocationType>(type);
1305 location.cellID.mcc = mcc;
1306 location.cellID.mnc = mnc;
1307 location.cellID.lac = lac;
1308 location.cellID.cid = cid;
1309 break;
1310 default:
1311 ALOGE("Neither a GSM nor a UMTS cellid (%s:%d).", __FUNCTION__, __LINE__);
1312 return;
1313 break;
1314 }
1315
1316 agnssRilIface->setRefLocation(location);
1317}
1318
1319static void android_location_GnssLocationProvider_agps_set_id(JNIEnv *env, jobject /* obj */,
1320 jint type, jstring setid_string) {
1321 if (agnssRilIface == nullptr) {
1322 ALOGE("no AGPS RIL interface in agps_set_id");
1323 return;
1324 }
1325
1326 const char *setid = env->GetStringUTFChars(setid_string, NULL);
1327 agnssRilIface->setSetId((IAGnssRil::SetIDType)type, setid);
1328 env->ReleaseStringUTFChars(setid_string, setid);
1329}
1330
1331static jint android_location_GnssLocationProvider_read_nmea(JNIEnv* env, jobject /* obj */,
1332 jbyteArray nmeaArray, jint buffer_size) {
1333 // this should only be called from within a call to reportNmea
1334 jbyte* nmea = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(nmeaArray, 0));
1335 int length = GnssCallback::sNmeaStringLength;
1336 if (length > buffer_size)
1337 length = buffer_size;
1338 memcpy(nmea, GnssCallback::sNmeaString, length);
1339 env->ReleasePrimitiveArrayCritical(nmeaArray, nmea, JNI_ABORT);
1340 return (jint) length;
1341}
1342
1343static void android_location_GnssLocationProvider_inject_time(JNIEnv* /* env */, jobject /* obj */,
1344 jlong time, jlong timeReference, jint uncertainty) {
1345 if (gnssHal != nullptr) {
1346 auto result = gnssHal->injectTime(time, timeReference, uncertainty);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001347 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001348 ALOGE("%s: Gnss injectTime() failed", __func__);
1349 }
1350 }
1351}
1352
1353static void android_location_GnssLocationProvider_inject_location(JNIEnv* /* env */,
1354 jobject /* obj */, jdouble latitude, jdouble longitude, jfloat accuracy) {
1355 if (gnssHal != nullptr) {
1356 auto result = gnssHal->injectLocation(latitude, longitude, accuracy);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001357 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001358 ALOGE("%s: Gnss injectLocation() failed", __func__);
1359 }
1360 }
1361}
1362
1363static jboolean android_location_GnssLocationProvider_supports_xtra(
1364 JNIEnv* /* env */, jobject /* obj */) {
1365 return (gnssXtraIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1366}
1367
1368static void android_location_GnssLocationProvider_inject_xtra_data(JNIEnv* env, jobject /* obj */,
1369 jbyteArray data, jint length) {
1370 if (gnssXtraIface == nullptr) {
1371 ALOGE("XTRA Interface not supported");
1372 return;
1373 }
1374
1375 jbyte* bytes = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(data, 0));
1376 gnssXtraIface->injectXtraData(std::string((const char*)bytes, length));
1377 env->ReleasePrimitiveArrayCritical(data, bytes, JNI_ABORT);
1378}
1379
1380static void android_location_GnssLocationProvider_agps_data_conn_open(
1381 JNIEnv* env, jobject /* obj */, jstring apn, jint apnIpType) {
1382 if (agnssIface == nullptr) {
1383 ALOGE("no AGPS interface in agps_data_conn_open");
1384 return;
1385 }
1386 if (apn == NULL) {
1387 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
1388 return;
1389 }
1390
1391 const char *apnStr = env->GetStringUTFChars(apn, NULL);
1392
1393 auto result = agnssIface->dataConnOpen(apnStr, static_cast<IAGnss::ApnIpType>(apnIpType));
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001394 if (!result.isOk() || !result){
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001395 ALOGE("%s: Failed to set APN and its IP type", __func__);
1396 }
1397 env->ReleaseStringUTFChars(apn, apnStr);
1398}
1399
1400static void android_location_GnssLocationProvider_agps_data_conn_closed(JNIEnv* /* env */,
1401 jobject /* obj */) {
1402 if (agnssIface == nullptr) {
1403 ALOGE("%s: AGPS interface not supported", __func__);
1404 return;
1405 }
1406
1407 auto result = agnssIface->dataConnClosed();
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001408 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001409 ALOGE("%s: Failed to close AGnss data connection", __func__);
1410 }
1411}
1412
1413static void android_location_GnssLocationProvider_agps_data_conn_failed(JNIEnv* /* env */,
1414 jobject /* obj */) {
1415 if (agnssIface == nullptr) {
1416 ALOGE("%s: AGPS interface not supported", __func__);
1417 return;
1418 }
1419
1420 auto result = agnssIface->dataConnFailed();
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001421 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001422 ALOGE("%s: Failed to notify unavailability of AGnss data connection", __func__);
1423 }
1424}
1425
1426static void android_location_GnssLocationProvider_set_agps_server(JNIEnv* env, jobject /* obj */,
1427 jint type, jstring hostname, jint port) {
1428 if (agnssIface == nullptr) {
1429 ALOGE("no AGPS interface in set_agps_server");
1430 return;
1431 }
1432
1433 const char *c_hostname = env->GetStringUTFChars(hostname, NULL);
1434 auto result = agnssIface->setServer(static_cast<IAGnssCallback::AGnssType>(type),
1435 c_hostname,
1436 port);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001437 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001438 ALOGE("%s: Failed to set AGnss host name and port", __func__);
1439 }
1440
1441 env->ReleaseStringUTFChars(hostname, c_hostname);
1442}
1443
1444static void android_location_GnssLocationProvider_send_ni_response(JNIEnv* /* env */,
1445 jobject /* obj */, jint notifId, jint response) {
1446 if (gnssNiIface == nullptr) {
1447 ALOGE("no NI interface in send_ni_response");
1448 return;
1449 }
1450
1451 gnssNiIface->respond(notifId, static_cast<IGnssNiCallback::GnssUserResponseType>(response));
1452}
1453
1454static jstring android_location_GnssLocationProvider_get_internal_state(JNIEnv* env,
1455 jobject /* obj */) {
1456 jstring result = NULL;
1457 /*
1458 * TODO(b/33089503) : Create a jobject to represent GnssDebug.
1459 */
1460 if (gnssDebugIface != nullptr) {
1461 IGnssDebug::DebugData data;
1462 gnssDebugIface->getDebugData([&data](const IGnssDebug::DebugData& debugData) {
1463 data = debugData;
1464 });
1465
1466 std::stringstream internalState;
1467 if (data.position.valid) {
1468 internalState << "Gnss Location Data:: LatitudeDegrees: " << data.position.latitudeDegrees
1469 << ", LongitudeDegrees: " << data.position.longitudeDegrees
1470 << ", altitudeMeters: " << data.position.altitudeMeters
gomo4402af62017-01-11 13:20:13 -08001471 << ", speedMetersPerSecond: " << data.position.speedMetersPerSec
1472 << ", bearingDegrees: " << data.position.bearingDegrees
1473 << ", horizontalAccuracyMeters: " << data.position.horizontalAccuracyMeters
1474 << ", verticalAccuracyMeters: " << data.position.verticalAccuracyMeters
1475 << ", speedAccuracyMetersPerSecond: " << data.position.speedAccuracyMetersPerSecond
1476 << ", bearingAccuracyDegrees: " << data.position.bearingAccuracyDegrees
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001477 << ", ageSeconds: " << data.position.ageSeconds << std::endl;
1478 }
1479
1480 if (data.time.valid) {
1481 internalState << "Gnss Time Data:: timeEstimate: " << data.time.timeEstimate
1482 << ", timeUncertaintyNs: " << data.time.timeUncertaintyNs << std::endl;
1483 }
1484
1485 if (data.satelliteDataArray.size() != 0) {
1486 internalState << "Satellite Data:: ";
1487 }
1488
1489 for (size_t i = 0; i < data.satelliteDataArray.size(); i++) {
1490 internalState << "svid: " << data.satelliteDataArray[i].svid
1491 << ", constellation: "
1492 << static_cast<uint32_t>(data.satelliteDataArray[i].constellation)
1493 << ", ephemerisType: "
1494 << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisType)
1495 << ", ephemerisAgeSeconds: "
1496 << data.satelliteDataArray[i].ephemerisAgeSeconds << std::endl;
1497 }
1498 result = env->NewStringUTF(internalState.str().c_str());
1499 }
1500 return result;
1501}
1502
1503static void android_location_GnssLocationProvider_update_network_state(JNIEnv* env,
1504 jobject /* obj */,
1505 jboolean connected,
1506 jint type,
1507 jboolean roaming,
1508 jboolean available,
1509 jstring extraInfo,
1510 jstring apn) {
1511 if (agnssRilIface != nullptr) {
1512 auto result = agnssRilIface->updateNetworkState(connected,
1513 static_cast<IAGnssRil::NetworkType>(type),
1514 roaming);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001515 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001516 ALOGE("updateNetworkState failed");
1517 }
1518
1519 const char *c_apn = env->GetStringUTFChars(apn, NULL);
1520 result = agnssRilIface->updateNetworkAvailability(available, c_apn);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001521 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001522 ALOGE("updateNetworkAvailability failed");
1523 }
1524
1525 env->ReleaseStringUTFChars(apn, c_apn);
1526 } else {
1527 ALOGE("AGnssRilInterface does not exist");
1528 }
1529}
1530
1531static jboolean android_location_GnssLocationProvider_is_geofence_supported(
1532 JNIEnv* /* env */, jobject /* obj */) {
1533 return (gnssGeofencingIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1534}
1535
1536static jboolean android_location_GnssLocationProvider_add_geofence(JNIEnv* /* env */,
1537 jobject /* obj */, jint geofenceId, jdouble latitude, jdouble longitude, jdouble radius,
1538 jint last_transition, jint monitor_transition, jint notification_responsiveness,
1539 jint unknown_timer) {
1540 if (gnssGeofencingIface != nullptr) {
1541 auto result = gnssGeofencingIface->addGeofence(
1542 geofenceId, latitude, longitude, radius,
1543 static_cast<IGnssGeofenceCallback::GeofenceTransition>(last_transition),
1544 monitor_transition, notification_responsiveness, unknown_timer);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001545 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001546 } else {
1547 ALOGE("Geofence Interface not available");
1548 }
1549 return JNI_FALSE;
1550}
1551
1552static jboolean android_location_GnssLocationProvider_remove_geofence(JNIEnv* /* env */,
1553 jobject /* obj */, jint geofenceId) {
1554 if (gnssGeofencingIface != nullptr) {
1555 auto result = gnssGeofencingIface->removeGeofence(geofenceId);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001556 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001557 } else {
1558 ALOGE("Geofence interface not available");
1559 }
1560 return JNI_FALSE;
1561}
1562
1563static jboolean android_location_GnssLocationProvider_pause_geofence(JNIEnv* /* env */,
1564 jobject /* obj */, jint geofenceId) {
1565 if (gnssGeofencingIface != nullptr) {
1566 auto result = gnssGeofencingIface->pauseGeofence(geofenceId);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001567 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001568 } else {
1569 ALOGE("Geofence interface not available");
1570 }
1571 return JNI_FALSE;
1572}
1573
1574static jboolean android_location_GnssLocationProvider_resume_geofence(JNIEnv* /* env */,
1575 jobject /* obj */, jint geofenceId, jint monitor_transition) {
1576 if (gnssGeofencingIface != nullptr) {
1577 auto result = gnssGeofencingIface->resumeGeofence(geofenceId, monitor_transition);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001578 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001579 } else {
1580 ALOGE("Geofence interface not available");
1581 }
1582 return JNI_FALSE;
1583}
1584
Lifu Tang30f95a72016-01-07 23:20:38 -08001585static jboolean android_location_GnssLocationProvider_is_measurement_supported(
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001586 JNIEnv* env, jclass clazz) {
1587 if (gnssMeasurementIface != nullptr) {
destradaaea8a8a62014-06-23 18:19:03 -07001588 return JNI_TRUE;
1589 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001590
destradaaea8a8a62014-06-23 18:19:03 -07001591 return JNI_FALSE;
1592}
1593
Lifu Tang30f95a72016-01-07 23:20:38 -08001594static jboolean android_location_GnssLocationProvider_start_measurement_collection(
destradaaea8a8a62014-06-23 18:19:03 -07001595 JNIEnv* env,
1596 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001597 if (gnssMeasurementIface == nullptr) {
1598 ALOGE("GNSS Measurement interface is not available.");
destradaaea8a8a62014-06-23 18:19:03 -07001599 return JNI_FALSE;
1600 }
1601
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001602 sp<GnssMeasurementCallback> cbIface = new GnssMeasurementCallback();
1603 IGnssMeasurement::GnssMeasurementStatus result = gnssMeasurementIface->setCallback(cbIface);
1604 if (result != IGnssMeasurement::GnssMeasurementStatus::SUCCESS) {
1605 ALOGE("An error has been found on GnssMeasurementInterface::init, status=%d",
1606 static_cast<int32_t>(result));
destradaaea8a8a62014-06-23 18:19:03 -07001607 return JNI_FALSE;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001608 } else {
1609 ALOGD("gnss measurement infc has been enabled");
destradaaea8a8a62014-06-23 18:19:03 -07001610 }
1611
1612 return JNI_TRUE;
1613}
1614
Lifu Tang30f95a72016-01-07 23:20:38 -08001615static jboolean android_location_GnssLocationProvider_stop_measurement_collection(
destradaaea8a8a62014-06-23 18:19:03 -07001616 JNIEnv* env,
1617 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001618 if (gnssMeasurementIface == nullptr) {
destradaaea8a8a62014-06-23 18:19:03 -07001619 ALOGE("Measurement interface not available");
1620 return JNI_FALSE;
1621 }
1622
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001623 auto result = gnssMeasurementIface->close();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001624 return boolToJbool(result.isOk());
destradaaea8a8a62014-06-23 18:19:03 -07001625}
1626
Lifu Tang30f95a72016-01-07 23:20:38 -08001627static jboolean android_location_GnssLocationProvider_is_navigation_message_supported(
destradaa4b3e3932014-07-21 18:01:47 -07001628 JNIEnv* env,
1629 jclass clazz) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001630 if (gnssNavigationMessageIface != nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001631 return JNI_TRUE;
1632 }
1633 return JNI_FALSE;
1634}
1635
Lifu Tang30f95a72016-01-07 23:20:38 -08001636static jboolean android_location_GnssLocationProvider_start_navigation_message_collection(
destradaa4b3e3932014-07-21 18:01:47 -07001637 JNIEnv* env,
1638 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001639 if (gnssNavigationMessageIface == nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001640 ALOGE("Navigation Message interface is not available.");
1641 return JNI_FALSE;
1642 }
1643
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001644 sp<IGnssNavigationMessageCallback> gnssNavigationMessageCbIface =
1645 new GnssNavigationMessageCallback();
1646 IGnssNavigationMessage::GnssNavigationMessageStatus result =
1647 gnssNavigationMessageIface->setCallback(gnssNavigationMessageCbIface);
1648
1649 if (result != IGnssNavigationMessage::GnssNavigationMessageStatus::SUCCESS) {
1650 ALOGE("An error has been found in %s: %d", __FUNCTION__, static_cast<int32_t>(result));
destradaa4b3e3932014-07-21 18:01:47 -07001651 return JNI_FALSE;
1652 }
1653
1654 return JNI_TRUE;
1655}
1656
Lifu Tang30f95a72016-01-07 23:20:38 -08001657static jboolean android_location_GnssLocationProvider_stop_navigation_message_collection(
destradaa4b3e3932014-07-21 18:01:47 -07001658 JNIEnv* env,
1659 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001660 if (gnssNavigationMessageIface == nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001661 ALOGE("Navigation Message interface is not available.");
1662 return JNI_FALSE;
1663 }
1664
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001665 auto result = gnssNavigationMessageIface->close();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001666 return boolToJbool(result.isOk());
destradaa4b3e3932014-07-21 18:01:47 -07001667}
1668
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001669static jboolean android_location_GnssLocationProvider_set_emergency_supl_pdn(JNIEnv*,
1670 jobject,
1671 jint emergencySuplPdn) {
1672 if (gnssConfigurationIface == nullptr) {
1673 ALOGE("no GNSS configuration interface available");
1674 return JNI_FALSE;
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001675 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001676
1677 auto result = gnssConfigurationIface->setEmergencySuplPdn(emergencySuplPdn);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001678 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001679 return result;
1680 } else {
1681 return JNI_FALSE;
1682 }
1683}
1684
1685static jboolean android_location_GnssLocationProvider_set_supl_version(JNIEnv*,
1686 jobject,
1687 jint version) {
1688 if (gnssConfigurationIface == nullptr) {
1689 ALOGE("no GNSS configuration interface available");
1690 return JNI_FALSE;
1691 }
1692 auto result = gnssConfigurationIface->setSuplVersion(version);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001693 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001694 return result;
1695 } else {
1696 return JNI_FALSE;
1697 }
1698}
1699
1700static jboolean android_location_GnssLocationProvider_set_supl_es(JNIEnv*,
1701 jobject,
1702 jint suplEs) {
1703 if (gnssConfigurationIface == nullptr) {
1704 ALOGE("no GNSS configuration interface available");
1705 return JNI_FALSE;
1706 }
1707
1708 auto result = gnssConfigurationIface->setSuplEs(suplEs);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001709 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001710 return result;
1711 } else {
1712 return JNI_FALSE;
1713 }
1714}
1715
1716static jboolean android_location_GnssLocationProvider_set_supl_mode(JNIEnv*,
1717 jobject,
1718 jint mode) {
1719 if (gnssConfigurationIface == nullptr) {
1720 ALOGE("no GNSS configuration interface available");
1721 return JNI_FALSE;
1722 }
1723
1724 auto result = gnssConfigurationIface->setSuplMode(mode);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001725 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001726 return result;
1727 } else {
1728 return JNI_FALSE;
1729 }
1730}
1731
1732static jboolean android_location_GnssLocationProvider_set_gps_lock(JNIEnv*,
1733 jobject,
1734 jint gpsLock) {
1735 if (gnssConfigurationIface == nullptr) {
1736 ALOGE("no GNSS configuration interface available");
1737 return JNI_FALSE;
1738 }
1739
1740 auto result = gnssConfigurationIface->setGpsLock(gpsLock);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001741 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001742 return result;
1743 } else {
1744 return JNI_FALSE;
1745 }
1746}
1747
1748static jboolean android_location_GnssLocationProvider_set_lpp_profile(JNIEnv*,
1749 jobject,
1750 jint lppProfile) {
1751 if (gnssConfigurationIface == nullptr) {
1752 ALOGE("no GNSS configuration interface available");
1753 return JNI_FALSE;
1754 }
1755
1756 auto result = gnssConfigurationIface->setLppProfile(lppProfile);
1757
Steven Morelandd002a8b2017-01-03 17:18:24 -08001758 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001759 return result;
1760 } else {
1761 return JNI_FALSE;
1762 }
1763}
1764
1765static jboolean android_location_GnssLocationProvider_set_gnss_pos_protocol_select(JNIEnv*,
1766 jobject,
1767 jint gnssPosProtocol) {
1768 if (gnssConfigurationIface == nullptr) {
1769 ALOGE("no GNSS configuration interface available");
1770 return JNI_FALSE;
1771 }
1772
1773 auto result = gnssConfigurationIface->setGlonassPositioningProtocol(gnssPosProtocol);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001774 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001775 return result;
1776 } else {
1777 return JNI_FALSE;
1778 }
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001779}
1780
Wyatt Rileycf879db2017-01-12 13:57:38 -08001781static jint android_location_GnssLocationProvider_get_batch_size(JNIEnv*, jclass) {
1782 if (gnssBatchingIface == nullptr) {
1783 return 0; // batching not supported, size = 0
1784 }
1785 auto result = gnssBatchingIface->getBatchSize();
1786 if (result.isOk()) {
1787 return static_cast<jint>(result);
1788 } else {
1789 return 0; // failure in binder, don't support batching
1790 }
1791}
1792
1793static jboolean android_location_GnssLocationProvider_init_batching(JNIEnv*, jclass) {
1794 if (gnssBatchingIface == nullptr) {
1795 return JNI_FALSE; // batching not supported
1796 }
1797 sp<IGnssBatchingCallback> gnssBatchingCbIface = new GnssBatchingCallback();
1798
1799 return static_cast<jboolean>(gnssBatchingIface->init(gnssBatchingCbIface));
1800}
1801
1802static void android_location_GnssLocationProvider_cleanup_batching(JNIEnv*, jclass) {
1803 if (gnssBatchingIface == nullptr) {
1804 return; // batching not supported
1805 }
1806 gnssBatchingIface->cleanup();
1807}
1808
1809static jboolean android_location_GnssLocationProvider_start_batch(JNIEnv*, jclass,
1810 jlong periodNanos, jboolean wakeOnFifoFull) {
1811 if (gnssBatchingIface == nullptr) {
1812 return JNI_FALSE; // batching not supported
1813 }
1814
1815 IGnssBatching::Options options;
1816 options.periodNanos = periodNanos;
1817 if (wakeOnFifoFull) {
1818 options.flags = static_cast<uint8_t>(IGnssBatching::Flag::WAKEUP_ON_FIFO_FULL);
1819 } else {
1820 options.flags = 0;
1821 }
1822
1823 return static_cast<jboolean>(gnssBatchingIface->start(options));
1824}
1825
1826static void android_location_GnssLocationProvider_flush_batch(JNIEnv*, jclass) {
1827 if (gnssBatchingIface == nullptr) {
1828 return; // batching not supported
1829 }
1830
1831 gnssBatchingIface->flush();
1832}
1833
1834static jboolean android_location_GnssLocationProvider_stop_batch(JNIEnv*, jclass) {
1835 if (gnssBatchingIface == nullptr) {
1836 return JNI_FALSE; // batching not supported
1837 }
1838
1839 return gnssBatchingIface->stop();
1840}
1841
Daniel Micay76f6a862015-09-19 17:31:01 -04001842static const JNINativeMethod sMethods[] = {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001843 /* name, signature, funcPtr */
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001844 {"class_init_native", "()V", reinterpret_cast<void *>(
1845 android_location_GnssLocationProvider_class_init_native)},
1846 {"native_is_supported", "()Z", reinterpret_cast<void *>(
1847 android_location_GnssLocationProvider_is_supported)},
destradaaef752b62015-04-17 13:10:47 -07001848 {"native_is_agps_ril_supported", "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001849 reinterpret_cast<void *>(android_location_GnssLocationProvider_is_agps_ril_supported)},
destradaaef752b62015-04-17 13:10:47 -07001850 {"native_is_gnss_configuration_supported", "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001851 reinterpret_cast<void *>(
1852 android_location_gpsLocationProvider_is_gnss_configuration_supported)},
1853 {"native_init", "()Z", reinterpret_cast<void *>(android_location_GnssLocationProvider_init)},
1854 {"native_cleanup", "()V", reinterpret_cast<void *>(
1855 android_location_GnssLocationProvider_cleanup)},
destradaaea8a8a62014-06-23 18:19:03 -07001856 {"native_set_position_mode",
1857 "(IIIII)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001858 reinterpret_cast<void*>(android_location_GnssLocationProvider_set_position_mode)},
1859 {"native_start", "()Z", reinterpret_cast<void*>(android_location_GnssLocationProvider_start)},
1860 {"native_stop", "()Z", reinterpret_cast<void*>(android_location_GnssLocationProvider_stop)},
destradaaea8a8a62014-06-23 18:19:03 -07001861 {"native_delete_aiding_data",
1862 "(I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001863 reinterpret_cast<void*>(android_location_GnssLocationProvider_delete_aiding_data)},
destradaaea8a8a62014-06-23 18:19:03 -07001864 {"native_read_sv_status",
gomo4402af62017-01-11 13:20:13 -08001865 "([I[F[F[F[F)I",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001866 reinterpret_cast<void *>(android_location_GnssLocationProvider_read_sv_status)},
1867 {"native_read_nmea", "([BI)I", reinterpret_cast<void *>(
1868 android_location_GnssLocationProvider_read_nmea)},
1869 {"native_inject_time", "(JJI)V", reinterpret_cast<void *>(
1870 android_location_GnssLocationProvider_inject_time)},
destradaaea8a8a62014-06-23 18:19:03 -07001871 {"native_inject_location",
1872 "(DDF)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001873 reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_location)},
1874 {"native_supports_xtra", "()Z", reinterpret_cast<void *>(
1875 android_location_GnssLocationProvider_supports_xtra)},
destradaaea8a8a62014-06-23 18:19:03 -07001876 {"native_inject_xtra_data",
1877 "([BI)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001878 reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_xtra_data)},
destradaaea8a8a62014-06-23 18:19:03 -07001879 {"native_agps_data_conn_open",
1880 "(Ljava/lang/String;I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001881 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_open)},
destradaaea8a8a62014-06-23 18:19:03 -07001882 {"native_agps_data_conn_closed",
1883 "()V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001884 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_closed)},
destradaaea8a8a62014-06-23 18:19:03 -07001885 {"native_agps_data_conn_failed",
1886 "()V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001887 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_failed)},
destradaaea8a8a62014-06-23 18:19:03 -07001888 {"native_agps_set_id",
1889 "(ILjava/lang/String;)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001890 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_set_id)},
destradaaea8a8a62014-06-23 18:19:03 -07001891 {"native_agps_set_ref_location_cellid",
1892 "(IIIII)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001893 reinterpret_cast<void *>(
1894 android_location_GnssLocationProvider_agps_set_reference_location_cellid)},
destradaaea8a8a62014-06-23 18:19:03 -07001895 {"native_set_agps_server",
1896 "(ILjava/lang/String;I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001897 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_agps_server)},
destradaaea8a8a62014-06-23 18:19:03 -07001898 {"native_send_ni_response",
1899 "(II)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001900 reinterpret_cast<void *>(android_location_GnssLocationProvider_send_ni_response)},
destradaaea8a8a62014-06-23 18:19:03 -07001901 {"native_get_internal_state",
1902 "()Ljava/lang/String;",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001903 reinterpret_cast<void *>(android_location_GnssLocationProvider_get_internal_state)},
destradaaea8a8a62014-06-23 18:19:03 -07001904 {"native_update_network_state",
1905 "(ZIZZLjava/lang/String;Ljava/lang/String;)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001906 reinterpret_cast<void *>(android_location_GnssLocationProvider_update_network_state)},
destradaaea8a8a62014-06-23 18:19:03 -07001907 {"native_is_geofence_supported",
1908 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001909 reinterpret_cast<void *>(android_location_GnssLocationProvider_is_geofence_supported)},
destradaaea8a8a62014-06-23 18:19:03 -07001910 {"native_add_geofence",
1911 "(IDDDIIII)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001912 reinterpret_cast<void *>(android_location_GnssLocationProvider_add_geofence)},
destradaaea8a8a62014-06-23 18:19:03 -07001913 {"native_remove_geofence",
1914 "(I)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001915 reinterpret_cast<void *>(android_location_GnssLocationProvider_remove_geofence)},
1916 {"native_pause_geofence", "(I)Z", reinterpret_cast<void *>(
1917 android_location_GnssLocationProvider_pause_geofence)},
destradaaea8a8a62014-06-23 18:19:03 -07001918 {"native_resume_geofence",
1919 "(II)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001920 reinterpret_cast<void *>(android_location_GnssLocationProvider_resume_geofence)},
destradaaea8a8a62014-06-23 18:19:03 -07001921 {"native_is_measurement_supported",
1922 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001923 reinterpret_cast<void *>(
1924 android_location_GnssLocationProvider_is_measurement_supported)},
destradaaea8a8a62014-06-23 18:19:03 -07001925 {"native_start_measurement_collection",
1926 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001927 reinterpret_cast<void *>(
1928 android_location_GnssLocationProvider_start_measurement_collection)},
destradaaea8a8a62014-06-23 18:19:03 -07001929 {"native_stop_measurement_collection",
1930 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001931 reinterpret_cast<void *>(
1932 android_location_GnssLocationProvider_stop_measurement_collection)},
destradaa4b3e3932014-07-21 18:01:47 -07001933 {"native_is_navigation_message_supported",
1934 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001935 reinterpret_cast<void *>(
1936 android_location_GnssLocationProvider_is_navigation_message_supported)},
destradaa4b3e3932014-07-21 18:01:47 -07001937 {"native_start_navigation_message_collection",
1938 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001939 reinterpret_cast<void *>(
1940 android_location_GnssLocationProvider_start_navigation_message_collection)},
destradaa4b3e3932014-07-21 18:01:47 -07001941 {"native_stop_navigation_message_collection",
1942 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001943 reinterpret_cast<void *>(
1944 android_location_GnssLocationProvider_stop_navigation_message_collection)},
1945 {"native_set_supl_es",
1946 "(I)Z",
1947 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_es)},
1948 {"native_set_supl_version",
1949 "(I)Z",
1950 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_version)},
1951 {"native_set_supl_mode",
1952 "(I)Z",
1953 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_mode)},
1954 {"native_set_lpp_profile",
1955 "(I)Z",
1956 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_lpp_profile)},
1957 {"native_set_gnss_pos_protocol_select",
1958 "(I)Z",
1959 reinterpret_cast<void *>(
1960 android_location_GnssLocationProvider_set_gnss_pos_protocol_select)},
1961 {"native_set_gps_lock",
1962 "(I)Z",
1963 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_gps_lock)},
1964 {"native_set_emergency_supl_pdn",
1965 "(I)Z",
1966 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_emergency_supl_pdn)},
Wyatt Rileycf879db2017-01-12 13:57:38 -08001967 {"native_get_batch_size",
1968 "()I",
1969 reinterpret_cast<void *>(android_location_GnssLocationProvider_get_batch_size)},
1970 {"native_init_batching",
1971 "()Z",
1972 reinterpret_cast<void *>(android_location_GnssLocationProvider_init_batching)},
1973 {"native_start_batch",
1974 "(JZ)Z",
1975 reinterpret_cast<void *>(android_location_GnssLocationProvider_start_batch)},
1976 {"native_flush_batch",
1977 "()V",
1978 reinterpret_cast<void *>(android_location_GnssLocationProvider_flush_batch)},
1979 {"native_stop_batch",
1980 "()Z",
1981 reinterpret_cast<void *>(android_location_GnssLocationProvider_stop_batch)},
1982 {"native_init_batching",
1983 "()Z",
1984 reinterpret_cast<void *>(android_location_GnssLocationProvider_init_batching)},
1985 {"native_cleanup_batching",
1986 "()V",
1987 reinterpret_cast<void *>(android_location_GnssLocationProvider_cleanup_batching)},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001988};
1989
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001990int register_android_server_location_GnssLocationProvider(JNIEnv* env) {
destradaaea8a8a62014-06-23 18:19:03 -07001991 return jniRegisterNativeMethods(
1992 env,
Lifu Tang30f95a72016-01-07 23:20:38 -08001993 "com/android/server/location/GnssLocationProvider",
destradaaea8a8a62014-06-23 18:19:03 -07001994 sMethods,
1995 NELEM(sMethods));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001996}
1997
1998} /* namespace android */