blob: daf3f2fc74864e07ca91bf8235c42db7caa5665d [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
Steven Morelandc95dca82017-08-01 10:18:40 -070023#include <nativehelper/JNIHelp.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080024#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;
gomo25208882017-04-15 02:05:25 -070071using android::wp;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070072using android::status_t;
73using android::String16;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080074
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070075using android::hardware::Return;
76using android::hardware::Void;
77using android::hardware::hidl_vec;
gomo25208882017-04-15 02:05:25 -070078using android::hardware::hidl_death_recipient;
79using android::hidl::base::V1_0::IBase;
Lifu Tang30f95a72016-01-07 23:20:38 -080080
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070081using android::hardware::gnss::V1_0::IAGnss;
82using android::hardware::gnss::V1_0::IAGnssCallback;
83using android::hardware::gnss::V1_0::IAGnssCallback;
84using android::hardware::gnss::V1_0::IAGnssRil;
85using android::hardware::gnss::V1_0::IAGnssRilCallback;
86using android::hardware::gnss::V1_0::IGnss;
Wyatt Rileycf879db2017-01-12 13:57:38 -080087using android::hardware::gnss::V1_0::IGnssBatching;
88using android::hardware::gnss::V1_0::IGnssBatchingCallback;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070089using android::hardware::gnss::V1_0::IGnssCallback;
90using android::hardware::gnss::V1_0::IGnssConfiguration;
91using android::hardware::gnss::V1_0::IGnssDebug;
92using android::hardware::gnss::V1_0::IGnssGeofenceCallback;
93using android::hardware::gnss::V1_0::IGnssGeofencing;
94using android::hardware::gnss::V1_0::IGnssMeasurement;
95using android::hardware::gnss::V1_0::IGnssMeasurementCallback;
96using android::hardware::gnss::V1_0::IGnssNavigationMessage;
97using android::hardware::gnss::V1_0::IGnssNavigationMessageCallback;
98using android::hardware::gnss::V1_0::IGnssNi;
99using android::hardware::gnss::V1_0::IGnssNiCallback;
100using android::hardware::gnss::V1_0::IGnssXtra;
101using android::hardware::gnss::V1_0::IGnssXtraCallback;
Wyatt Riley49d98912016-05-17 16:14:48 -0700102
gomo25208882017-04-15 02:05:25 -0700103struct GnssDeathRecipient : virtual public hidl_death_recipient
104{
105 // hidl_death_recipient interface
106 virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override {
107 // TODO(gomo): implement a better death recovery mechanism without
108 // crashing system server process as described in go//treble-gnss-death
109 LOG_ALWAYS_FATAL("Abort due to IGNSS hidl service failure,"
110 " restarting system server");
111 }
112};
Wyatt Rileyf6527ae2016-05-23 15:23:12 -0700113
gomo25208882017-04-15 02:05:25 -0700114sp<GnssDeathRecipient> gnssHalDeathRecipient = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700115sp<IGnss> gnssHal = nullptr;
116sp<IGnssXtra> gnssXtraIface = nullptr;
117sp<IAGnssRil> agnssRilIface = nullptr;
118sp<IGnssGeofencing> gnssGeofencingIface = nullptr;
119sp<IAGnss> agnssIface = nullptr;
Wyatt Rileycf879db2017-01-12 13:57:38 -0800120sp<IGnssBatching> gnssBatchingIface = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700121sp<IGnssDebug> gnssDebugIface = nullptr;
122sp<IGnssConfiguration> gnssConfigurationIface = nullptr;
123sp<IGnssNi> gnssNiIface = nullptr;
124sp<IGnssMeasurement> gnssMeasurementIface = nullptr;
125sp<IGnssNavigationMessage> gnssNavigationMessageIface = nullptr;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800126
Mike Lockwood8f5a8002010-04-07 09:05:26 -0400127#define WAKE_LOCK_NAME "GPS"
128
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800129namespace android {
130
Lifu Tang120480f2016-02-07 18:08:19 -0800131template<class T>
132class JavaMethodHelper {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700133 public:
134 // Helper function to call setter on a Java object.
135 static void callJavaMethod(
Lifu Tang120480f2016-02-07 18:08:19 -0800136 JNIEnv* env,
137 jclass clazz,
138 jobject object,
139 const char* method_name,
140 T value);
destradaaea8a8a62014-06-23 18:19:03 -0700141
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700142 private:
Lifu Tang120480f2016-02-07 18:08:19 -0800143 static const char *const signature_;
144};
Lifu Tange5a0e212016-01-25 18:02:17 -0800145
Lifu Tang120480f2016-02-07 18:08:19 -0800146template<class T>
147void JavaMethodHelper<T>::callJavaMethod(
148 JNIEnv* env,
149 jclass clazz,
150 jobject object,
151 const char* method_name,
152 T value) {
153 jmethodID method = env->GetMethodID(clazz, method_name, signature_);
154 env->CallVoidMethod(object, method, value);
155}
destradaaea8a8a62014-06-23 18:19:03 -0700156
Lifu Tang120480f2016-02-07 18:08:19 -0800157class JavaObject {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700158 public:
159 JavaObject(JNIEnv* env, const char* class_name);
Wyatt Rileycf879db2017-01-12 13:57:38 -0800160 JavaObject(JNIEnv* env, const char* class_name, const char * sz_arg_1);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700161 virtual ~JavaObject();
Lifu Tang120480f2016-02-07 18:08:19 -0800162
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700163 template<class T>
164 void callSetter(const char* method_name, T value);
165 template<class T>
166 void callSetter(const char* method_name, T* value, size_t size);
167 jobject get();
Lifu Tang120480f2016-02-07 18:08:19 -0800168
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700169 private:
170 JNIEnv* env_;
171 jclass clazz_;
172 jobject object_;
Lifu Tang120480f2016-02-07 18:08:19 -0800173};
174
175JavaObject::JavaObject(JNIEnv* env, const char* class_name) : env_(env) {
176 clazz_ = env_->FindClass(class_name);
177 jmethodID ctor = env->GetMethodID(clazz_, "<init>", "()V");
178 object_ = env_->NewObject(clazz_, ctor);
179}
180
Wyatt Rileycf879db2017-01-12 13:57:38 -0800181JavaObject::JavaObject(JNIEnv* env, const char* class_name, const char * sz_arg_1) : env_(env) {
182 clazz_ = env_->FindClass(class_name);
183 jmethodID ctor = env->GetMethodID(clazz_, "<init>", "(Ljava/lang/String;)V");
184 object_ = env_->NewObject(clazz_, ctor, env->NewStringUTF(sz_arg_1));
185}
186
Lifu Tang120480f2016-02-07 18:08:19 -0800187JavaObject::~JavaObject() {
188 env_->DeleteLocalRef(clazz_);
189}
190
191template<class T>
192void JavaObject::callSetter(const char* method_name, T value) {
193 JavaMethodHelper<T>::callJavaMethod(
194 env_, clazz_, object_, method_name, value);
195}
196
197template<>
198void JavaObject::callSetter(
199 const char* method_name, uint8_t* value, size_t size) {
200 jbyteArray array = env_->NewByteArray(size);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700201 env_->SetByteArrayRegion(array, 0, size, reinterpret_cast<jbyte*>(value));
Lifu Tang120480f2016-02-07 18:08:19 -0800202 jmethodID method = env_->GetMethodID(
203 clazz_,
204 method_name,
205 "([B)V");
206 env_->CallVoidMethod(object_, method, array);
Lifu Tangfe427f22016-10-08 02:57:53 -0700207 env_->DeleteLocalRef(array);
Lifu Tang120480f2016-02-07 18:08:19 -0800208}
209
210jobject JavaObject::get() {
211 return object_;
212}
213
214// Define Java method signatures for all known types.
Lifu Tang120480f2016-02-07 18:08:19 -0800215template<>
216const char *const JavaMethodHelper<uint8_t>::signature_ = "(B)V";
217template<>
218const char *const JavaMethodHelper<int8_t>::signature_ = "(B)V";
219template<>
220const char *const JavaMethodHelper<int16_t>::signature_ = "(S)V";
221template<>
222const char *const JavaMethodHelper<uint16_t>::signature_ = "(S)V";
223template<>
Lifu Tang9363b942016-02-16 18:07:00 -0800224const char *const JavaMethodHelper<int32_t>::signature_ = "(I)V";
225template<>
226const char *const JavaMethodHelper<uint32_t>::signature_ = "(I)V";
Lifu Tang120480f2016-02-07 18:08:19 -0800227template<>
228const char *const JavaMethodHelper<int64_t>::signature_ = "(J)V";
229template<>
230const char *const JavaMethodHelper<float>::signature_ = "(F)V";
231template<>
232const char *const JavaMethodHelper<double>::signature_ = "(D)V";
233template<>
234const char *const JavaMethodHelper<bool>::signature_ = "(Z)V";
235
236#define SET(setter, value) object.callSetter("set" # setter, (value))
Lifu Tangccb44882016-03-09 19:32:29 -0800237
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700238static inline jboolean boolToJbool(bool value) {
239 return value ? JNI_TRUE : JNI_FALSE;
240}
Lifu Tang120480f2016-02-07 18:08:19 -0800241
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700242static void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
243 if (env->ExceptionCheck()) {
244 ALOGE("An exception was thrown by callback '%s'.", methodName);
245 LOGE_EX(env);
246 env->ExceptionClear();
247 }
248}
destradaaea8a8a62014-06-23 18:19:03 -0700249
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800250class ScopedJniThreadAttach {
251public:
252 ScopedJniThreadAttach() {
253 /*
254 * attachResult will also be JNI_OK if the thead was already attached to
255 * JNI before the call to AttachCurrentThread().
256 */
257 jint attachResult = sJvm->AttachCurrentThread(&mEnv, nullptr);
258 LOG_ALWAYS_FATAL_IF(attachResult != JNI_OK, "Unable to attach thread. Error %d",
259 attachResult);
260 }
261
262 ~ScopedJniThreadAttach() {
263 jint detachResult = sJvm->DetachCurrentThread();
264 /*
265 * Return if the thread was already detached. Log error for any other
266 * failure.
267 */
268 if (detachResult == JNI_EDETACHED) {
269 return;
270 }
271
272 LOG_ALWAYS_FATAL_IF(detachResult != JNI_OK, "Unable to detach thread. Error %d",
273 detachResult);
274 }
275
276 JNIEnv* getEnv() {
277 /*
278 * Checking validity of mEnv in case the thread was detached elsewhere.
279 */
280 LOG_ALWAYS_FATAL_IF(AndroidRuntime::getJNIEnv() != mEnv);
281 return mEnv;
282 }
283
284private:
285 JNIEnv* mEnv = nullptr;
286};
287
288thread_local std::unique_ptr<ScopedJniThreadAttach> tJniThreadAttacher;
289
290static JNIEnv* getJniEnv() {
291 JNIEnv* env = AndroidRuntime::getJNIEnv();
292
293 /*
294 * If env is nullptr, the thread is not already attached to
295 * JNI. It is attached below and the destructor for ScopedJniThreadAttach
296 * will detach it on thread exit.
297 */
298 if (env == nullptr) {
299 tJniThreadAttacher.reset(new ScopedJniThreadAttach());
300 env = tJniThreadAttacher->getEnv();
301 }
302
303 return env;
304}
305
Wyatt Riley5d229832017-02-10 17:06:00 -0800306static jobject translateLocation(JNIEnv* env, const hardware::gnss::V1_0::GnssLocation& location) {
307 JavaObject object(env, "android/location/Location", "gps");
308
309 uint16_t flags = static_cast<uint32_t>(location.gnssLocationFlags);
310 if (flags & hardware::gnss::V1_0::GnssLocationFlags::HAS_LAT_LONG) {
311 SET(Latitude, location.latitudeDegrees);
312 SET(Longitude, location.longitudeDegrees);
313 }
314 if (flags & hardware::gnss::V1_0::GnssLocationFlags::HAS_ALTITUDE) {
315 SET(Altitude, location.altitudeMeters);
316 }
317 if (flags & hardware::gnss::V1_0::GnssLocationFlags::HAS_SPEED) {
318 SET(Speed, location.speedMetersPerSec);
319 }
320 if (flags & hardware::gnss::V1_0::GnssLocationFlags::HAS_BEARING) {
321 SET(Bearing, location.bearingDegrees);
322 }
323 if (flags & hardware::gnss::V1_0::GnssLocationFlags::HAS_HORIZONTAL_ACCURACY) {
324 SET(Accuracy, location.horizontalAccuracyMeters);
325 }
326 if (flags & hardware::gnss::V1_0::GnssLocationFlags::HAS_VERTICAL_ACCURACY) {
327 SET(VerticalAccuracyMeters, location.verticalAccuracyMeters);
328 }
329 if (flags & hardware::gnss::V1_0::GnssLocationFlags::HAS_SPEED_ACCURACY) {
330 SET(SpeedAccuracyMetersPerSecond, location.speedAccuracyMetersPerSecond);
331 }
332 if (flags & hardware::gnss::V1_0::GnssLocationFlags::HAS_BEARING_ACCURACY) {
333 SET(BearingAccuracyDegrees, location.bearingAccuracyDegrees);
334 }
335 SET(Time, location.timestamp);
336
337 return object.get();
338}
339
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700340/*
341 * GnssCallback class implements the callback methods for IGnss interface.
342 */
343struct GnssCallback : public IGnssCallback {
344 Return<void> gnssLocationCb(
345 const android::hardware::gnss::V1_0::GnssLocation& location) override;
346 Return<void> gnssStatusCb(const IGnssCallback::GnssStatusValue status) override;
347 Return<void> gnssSvStatusCb(const IGnssCallback::GnssSvStatus& svStatus) override;
348 Return<void> gnssNmeaCb(int64_t timestamp, const android::hardware::hidl_string& nmea) override;
349 Return<void> gnssSetCapabilitesCb(uint32_t capabilities) override;
350 Return<void> gnssAcquireWakelockCb() override;
351 Return<void> gnssReleaseWakelockCb() override;
352 Return<void> gnssRequestTimeCb() override;
353 Return<void> gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo& info) override;
Lifu Tang38bce792016-02-24 17:17:38 -0800354
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700355 static GnssSvInfo sGnssSvList[static_cast<uint32_t>(
356 android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)];
357 static size_t sGnssSvListSize;
358
359 static const char* sNmeaString;
360 static size_t sNmeaStringLength;
361};
362
363IGnssCallback::GnssSvInfo GnssCallback::sGnssSvList[static_cast<uint32_t>(
364 android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)];
365const char* GnssCallback::sNmeaString = nullptr;
366size_t GnssCallback::sNmeaStringLength = 0;
367size_t GnssCallback::sGnssSvListSize = 0;
368
369Return<void> GnssCallback::gnssLocationCb(
370 const ::android::hardware::gnss::V1_0::GnssLocation& location) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800371 JNIEnv* env = getJniEnv();
Wyatt Riley5d229832017-02-10 17:06:00 -0800372
373 jobject jLocation = translateLocation(env, location);
374 bool hasLatLong = (static_cast<uint32_t>(location.gnssLocationFlags) &
375 hardware::gnss::V1_0::GnssLocationFlags::HAS_LAT_LONG) != 0;
376
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700377 env->CallVoidMethod(mCallbacksObj,
378 method_reportLocation,
Wyatt Riley5d229832017-02-10 17:06:00 -0800379 boolToJbool(hasLatLong),
380 jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700381 checkAndClearExceptionFromCallback(env, __FUNCTION__);
382 return Void();
383}
384
385Return<void> GnssCallback::gnssStatusCb(const IGnssCallback::GnssStatusValue status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800386 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700387 env->CallVoidMethod(mCallbacksObj, method_reportStatus, status);
388 checkAndClearExceptionFromCallback(env, __FUNCTION__);
389 return Void();
390}
391
392Return<void> GnssCallback::gnssSvStatusCb(const IGnssCallback::GnssSvStatus& svStatus) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800393 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700394
395 sGnssSvListSize = svStatus.numSvs;
396 if (sGnssSvListSize > static_cast<uint32_t>(
397 android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)) {
398 ALOGD("Too many satellites %zd. Clamps to %u.", sGnssSvListSize,
399 static_cast<uint32_t>(android::hardware::gnss::V1_0::GnssMax::SVS_COUNT));
400 sGnssSvListSize = static_cast<uint32_t>(android::hardware::gnss::V1_0::GnssMax::SVS_COUNT);
Lifu Tang38bce792016-02-24 17:17:38 -0800401 }
402
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700403 // Copy GNSS SV info into sGnssSvList, if any.
404 if (svStatus.numSvs > 0) {
405 memcpy(sGnssSvList, svStatus.gnssSvList.data(), sizeof(GnssSvInfo) * sGnssSvListSize);
Lifu Tang9363b942016-02-16 18:07:00 -0800406 }
destradaaea8a8a62014-06-23 18:19:03 -0700407
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700408 env->CallVoidMethod(mCallbacksObj, method_reportSvStatus);
409 checkAndClearExceptionFromCallback(env, __FUNCTION__);
410 return Void();
destradaaea8a8a62014-06-23 18:19:03 -0700411}
412
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700413Return<void> GnssCallback::gnssNmeaCb(
414 int64_t timestamp, const ::android::hardware::hidl_string& nmea) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800415 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700416 /*
417 * The Java code will call back to read these values.
418 * We do this to avoid creating unnecessary String objects.
419 */
420 sNmeaString = nmea.c_str();
421 sNmeaStringLength = nmea.size();
422
423 env->CallVoidMethod(mCallbacksObj, method_reportNmea, timestamp);
424 checkAndClearExceptionFromCallback(env, __FUNCTION__);
425 return Void();
426}
427
428Return<void> GnssCallback::gnssSetCapabilitesCb(uint32_t capabilities) {
429 ALOGD("%s: %du\n", __func__, capabilities);
430
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800431 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700432 env->CallVoidMethod(mCallbacksObj, method_setEngineCapabilities, capabilities);
433 checkAndClearExceptionFromCallback(env, __FUNCTION__);
434 return Void();
435}
436
437Return<void> GnssCallback::gnssAcquireWakelockCb() {
438 acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
439 return Void();
440}
441
442Return<void> GnssCallback::gnssReleaseWakelockCb() {
443 release_wake_lock(WAKE_LOCK_NAME);
444 return Void();
445}
446
447Return<void> GnssCallback::gnssRequestTimeCb() {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800448 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700449 env->CallVoidMethod(mCallbacksObj, method_requestUtcTime);
450 checkAndClearExceptionFromCallback(env, __FUNCTION__);
451 return Void();
452}
453
454Return<void> GnssCallback::gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo& info) {
455 ALOGD("%s: yearOfHw=%d\n", __func__, info.yearOfHw);
456
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800457 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700458 env->CallVoidMethod(mCallbacksObj, method_setGnssYearOfHardware,
459 info.yearOfHw);
460 checkAndClearExceptionFromCallback(env, __FUNCTION__);
461 return Void();
462}
463
464class GnssXtraCallback : public IGnssXtraCallback {
465 Return<void> downloadRequestCb() override;
466};
467
468/*
469 * GnssXtraCallback class implements the callback methods for the IGnssXtra
470 * interface.
471 */
472Return<void> GnssXtraCallback::downloadRequestCb() {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800473 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700474 env->CallVoidMethod(mCallbacksObj, method_xtraDownloadRequest);
475 checkAndClearExceptionFromCallback(env, __FUNCTION__);
476 return Void();
477}
478
479/*
480 * GnssGeofenceCallback class implements the callback methods for the
481 * IGnssGeofence interface.
482 */
483struct GnssGeofenceCallback : public IGnssGeofenceCallback {
484 // Methods from ::android::hardware::gps::V1_0::IGnssGeofenceCallback follow.
485 Return<void> gnssGeofenceTransitionCb(
486 int32_t geofenceId,
487 const android::hardware::gnss::V1_0::GnssLocation& location,
488 GeofenceTransition transition,
489 hardware::gnss::V1_0::GnssUtcTime timestamp) override;
490 Return<void> gnssGeofenceStatusCb(
491 GeofenceAvailability status,
492 const android::hardware::gnss::V1_0::GnssLocation& location) override;
493 Return<void> gnssGeofenceAddCb(int32_t geofenceId,
494 GeofenceStatus status) override;
495 Return<void> gnssGeofenceRemoveCb(int32_t geofenceId,
496 GeofenceStatus status) override;
497 Return<void> gnssGeofencePauseCb(int32_t geofenceId,
498 GeofenceStatus status) override;
499 Return<void> gnssGeofenceResumeCb(int32_t geofenceId,
500 GeofenceStatus status) override;
501};
502
503Return<void> GnssGeofenceCallback::gnssGeofenceTransitionCb(
504 int32_t geofenceId,
505 const android::hardware::gnss::V1_0::GnssLocation& location,
506 GeofenceTransition transition,
507 hardware::gnss::V1_0::GnssUtcTime timestamp) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800508 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700509
Wyatt Riley5d229832017-02-10 17:06:00 -0800510 jobject jLocation = translateLocation(env, location);
511
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700512 env->CallVoidMethod(mCallbacksObj,
513 method_reportGeofenceTransition,
514 geofenceId,
Wyatt Riley5d229832017-02-10 17:06:00 -0800515 jLocation,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700516 transition,
517 timestamp);
518
519 checkAndClearExceptionFromCallback(env, __FUNCTION__);
520 return Void();
521}
522
523Return<void> GnssGeofenceCallback::gnssGeofenceStatusCb(
524 GeofenceAvailability status,
525 const android::hardware::gnss::V1_0::GnssLocation& location) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800526 JNIEnv* env = getJniEnv();
Wyatt Riley5d229832017-02-10 17:06:00 -0800527
528 jobject jLocation = translateLocation(env, location);
529
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700530 env->CallVoidMethod(mCallbacksObj,
531 method_reportGeofenceStatus,
532 status,
Wyatt Riley5d229832017-02-10 17:06:00 -0800533 jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700534 checkAndClearExceptionFromCallback(env, __FUNCTION__);
535 return Void();
536}
537
538Return<void> GnssGeofenceCallback::gnssGeofenceAddCb(int32_t geofenceId,
539 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800540 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700541 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
542 ALOGE("%s: Error in adding a Geofence: %d\n", __func__, status);
543 }
544
545 env->CallVoidMethod(mCallbacksObj,
546 method_reportGeofenceAddStatus,
547 geofenceId,
548 status);
549 checkAndClearExceptionFromCallback(env, __FUNCTION__);
550 return Void();
551}
552
553Return<void> GnssGeofenceCallback::gnssGeofenceRemoveCb(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 removing a Geofence: %d\n", __func__, status);
558 }
559
560 env->CallVoidMethod(mCallbacksObj,
561 method_reportGeofenceRemoveStatus,
562 geofenceId, status);
563 checkAndClearExceptionFromCallback(env, __FUNCTION__);
564 return Void();
565}
566
567Return<void> GnssGeofenceCallback::gnssGeofencePauseCb(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 pausing Geofence: %d\n", __func__, status);
572 }
573
574 env->CallVoidMethod(mCallbacksObj,
575 method_reportGeofencePauseStatus,
576 geofenceId, status);
577 checkAndClearExceptionFromCallback(env, __FUNCTION__);
578 return Void();
579}
580
581Return<void> GnssGeofenceCallback::gnssGeofenceResumeCb(int32_t geofenceId,
582 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800583 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700584 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
585 ALOGE("%s: Error in resuming Geofence: %d\n", __func__, status);
586 }
587
588 env->CallVoidMethod(mCallbacksObj,
589 method_reportGeofenceResumeStatus,
590 geofenceId, status);
591 checkAndClearExceptionFromCallback(env, __FUNCTION__);
592 return Void();
593}
594
595/*
596 * GnssNavigationMessageCallback interface implements the callback methods
597 * required by the IGnssNavigationMessage interface.
598 */
599struct GnssNavigationMessageCallback : public IGnssNavigationMessageCallback {
600 /*
601 * Methods from ::android::hardware::gps::V1_0::IGnssNavigationMessageCallback
602 * follow.
603 */
604 Return<void> gnssNavigationMessageCb(
605 const IGnssNavigationMessageCallback::GnssNavigationMessage& message) override;
606};
607
608Return<void> GnssNavigationMessageCallback::gnssNavigationMessageCb(
609 const IGnssNavigationMessageCallback::GnssNavigationMessage& message) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800610 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700611
612 size_t dataLength = message.data.size();
613
614 std::vector<uint8_t> navigationData = message.data;
615 uint8_t* data = &(navigationData[0]);
616 if (dataLength == 0 || data == NULL) {
617 ALOGE("Invalid Navigation Message found: data=%p, length=%zd", data,
618 dataLength);
619 return Void();
620 }
621
622 JavaObject object(env, "android/location/GnssNavigationMessage");
623 SET(Type, static_cast<int32_t>(message.type));
624 SET(Svid, static_cast<int32_t>(message.svid));
625 SET(MessageId, static_cast<int32_t>(message.messageId));
626 SET(SubmessageId, static_cast<int32_t>(message.submessageId));
627 object.callSetter("setData", data, dataLength);
628 SET(Status, static_cast<int32_t>(message.status));
629
630 jobject navigationMessage = object.get();
631 env->CallVoidMethod(mCallbacksObj,
632 method_reportNavigationMessages,
633 navigationMessage);
Wyatt Rileycf879db2017-01-12 13:57:38 -0800634 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700635 env->DeleteLocalRef(navigationMessage);
636 return Void();
637}
638
639/*
640 * GnssMeasurementCallback implements the callback methods required for the
641 * GnssMeasurement interface.
642 */
643struct GnssMeasurementCallback : public IGnssMeasurementCallback {
644 Return<void> GnssMeasurementCb(const IGnssMeasurementCallback::GnssData& data);
645 private:
646 jobject translateGnssMeasurement(
647 JNIEnv* env, const IGnssMeasurementCallback::GnssMeasurement* measurement);
648 jobject translateGnssClock(
649 JNIEnv* env, const IGnssMeasurementCallback::GnssClock* clock);
650 jobjectArray translateGnssMeasurements(
651 JNIEnv* env,
652 const IGnssMeasurementCallback::GnssMeasurement* measurements,
653 size_t count);
654 void setMeasurementData(JNIEnv* env, jobject clock, jobjectArray measurementArray);
655};
656
657
658Return<void> GnssMeasurementCallback::GnssMeasurementCb(
659 const IGnssMeasurementCallback::GnssData& data) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800660 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700661
662 jobject clock;
663 jobjectArray measurementArray;
664
665 clock = translateGnssClock(env, &data.clock);
666 measurementArray = translateGnssMeasurements(
667 env, data.measurements.data(), data.measurementCount);
668 setMeasurementData(env, clock, measurementArray);
669
670 env->DeleteLocalRef(clock);
671 env->DeleteLocalRef(measurementArray);
672 return Void();
673}
674
675jobject GnssMeasurementCallback::translateGnssMeasurement(
676 JNIEnv* env, const IGnssMeasurementCallback::GnssMeasurement* measurement) {
Lifu Tang120480f2016-02-07 18:08:19 -0800677 JavaObject object(env, "android/location/GnssMeasurement");
Lifu Tang120480f2016-02-07 18:08:19 -0800678
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700679 uint32_t flags = static_cast<uint32_t>(measurement->flags);
Mike Cailean96635bd2016-03-24 19:34:16 -0700680
681 SET(Svid, static_cast<int32_t>(measurement->svid));
Lifu Tang76a620f2016-02-26 19:53:01 -0800682 SET(ConstellationType, static_cast<int32_t>(measurement->constellation));
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700683 SET(TimeOffsetNanos, measurement->timeOffsetNs);
Lifu Tang76a620f2016-02-26 19:53:01 -0800684 SET(State, static_cast<int32_t>(measurement->state));
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700685 SET(ReceivedSvTimeNanos, measurement->receivedSvTimeInNs);
Lifu Tang76a620f2016-02-26 19:53:01 -0800686 SET(ReceivedSvTimeUncertaintyNanos,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700687 measurement->receivedSvTimeUncertaintyInNs);
688 SET(Cn0DbHz, measurement->cN0DbHz);
689 SET(PseudorangeRateMetersPerSecond, measurement->pseudorangeRateMps);
Lifu Tang76a620f2016-02-26 19:53:01 -0800690 SET(PseudorangeRateUncertaintyMetersPerSecond,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700691 measurement->pseudorangeRateUncertaintyMps);
Lifu Tang76a620f2016-02-26 19:53:01 -0800692 SET(AccumulatedDeltaRangeState,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700693 (static_cast<int32_t>(measurement->accumulatedDeltaRangeState)));
694 SET(AccumulatedDeltaRangeMeters, measurement->accumulatedDeltaRangeM);
Lifu Tang76a620f2016-02-26 19:53:01 -0800695 SET(AccumulatedDeltaRangeUncertaintyMeters,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700696 measurement->accumulatedDeltaRangeUncertaintyM);
697
698 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_FREQUENCY)) {
699 SET(CarrierFrequencyHz, measurement->carrierFrequencyHz);
700 }
701
702 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_PHASE)) {
703 SET(CarrierPhase, measurement->carrierPhase);
704 }
705
706 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_PHASE_UNCERTAINTY)) {
707 SET(CarrierPhaseUncertainty, measurement->carrierPhaseUncertainty);
708 }
709
710 SET(MultipathIndicator, static_cast<int32_t>(measurement->multipathIndicator));
711
712 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_SNR)) {
713 SET(SnrInDb, measurement->snrDb);
714 }
Lifu Tang120480f2016-02-07 18:08:19 -0800715
gomo4402af62017-01-11 13:20:13 -0800716 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_AUTOMATIC_GAIN_CONTROL)) {
gomo127ba322017-01-15 20:26:48 -0800717 SET(AutomaticGainControlLevelInDb, measurement->agcLevelDb);
gomo4402af62017-01-11 13:20:13 -0800718 }
719
Lifu Tang120480f2016-02-07 18:08:19 -0800720 return object.get();
721}
722
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700723jobject GnssMeasurementCallback::translateGnssClock(
724 JNIEnv* env, const IGnssMeasurementCallback::GnssClock* clock) {
725 JavaObject object(env, "android/location/GnssClock");
726
727 uint32_t flags = static_cast<uint32_t>(clock->gnssClockFlags);
728 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_LEAP_SECOND)) {
729 SET(LeapSecond, static_cast<int32_t>(clock->leapSecond));
730 }
731
732 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_TIME_UNCERTAINTY)) {
733 SET(TimeUncertaintyNanos, clock->timeUncertaintyNs);
734 }
735
736 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_FULL_BIAS)) {
737 SET(FullBiasNanos, clock->fullBiasNs);
738 }
739
740 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS)) {
741 SET(BiasNanos, clock->biasNs);
742 }
743
744 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS_UNCERTAINTY)) {
745 SET(BiasUncertaintyNanos, clock->biasUncertaintyNs);
746 }
747
748 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT)) {
749 SET(DriftNanosPerSecond, clock->driftNsps);
750 }
751
752 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT_UNCERTAINTY)) {
753 SET(DriftUncertaintyNanosPerSecond, clock->driftUncertaintyNsps);
754 }
755
756 SET(TimeNanos, clock->timeNs);
757 SET(HardwareClockDiscontinuityCount, clock->hwClockDiscontinuityCount);
758
759 return object.get();
760}
761
762jobjectArray GnssMeasurementCallback::translateGnssMeasurements(JNIEnv* env,
763 const IGnssMeasurementCallback::GnssMeasurement*
764 measurements, size_t count) {
Lifu Tang120480f2016-02-07 18:08:19 -0800765 if (count == 0) {
destradaaea8a8a62014-06-23 18:19:03 -0700766 return NULL;
767 }
768
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700769 jclass gnssMeasurementClass = env->FindClass("android/location/GnssMeasurement");
Lifu Tang818aa2c2016-02-01 01:52:00 -0800770 jobjectArray gnssMeasurementArray = env->NewObjectArray(
Lifu Tang120480f2016-02-07 18:08:19 -0800771 count,
Lifu Tang818aa2c2016-02-01 01:52:00 -0800772 gnssMeasurementClass,
destradaaea8a8a62014-06-23 18:19:03 -0700773 NULL /* initialElement */);
774
Lifu Tang120480f2016-02-07 18:08:19 -0800775 for (uint16_t i = 0; i < count; ++i) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700776 jobject gnssMeasurement = translateGnssMeasurement(
Lifu Tange5a0e212016-01-25 18:02:17 -0800777 env,
Lifu Tang120480f2016-02-07 18:08:19 -0800778 &measurements[i]);
Lifu Tang818aa2c2016-02-01 01:52:00 -0800779 env->SetObjectArrayElement(gnssMeasurementArray, i, gnssMeasurement);
780 env->DeleteLocalRef(gnssMeasurement);
destradaaea8a8a62014-06-23 18:19:03 -0700781 }
782
Lifu Tang818aa2c2016-02-01 01:52:00 -0800783 env->DeleteLocalRef(gnssMeasurementClass);
784 return gnssMeasurementArray;
destradaaea8a8a62014-06-23 18:19:03 -0700785}
786
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700787void GnssMeasurementCallback::setMeasurementData(JNIEnv* env, jobject clock,
788 jobjectArray measurementArray) {
789 jclass gnssMeasurementsEventClass =
790 env->FindClass("android/location/GnssMeasurementsEvent");
791 jmethodID gnssMeasurementsEventCtor =
792 env->GetMethodID(
793 gnssMeasurementsEventClass,
794 "<init>",
795 "(Landroid/location/GnssClock;[Landroid/location/GnssMeasurement;)V");
Lifu Tange5a0e212016-01-25 18:02:17 -0800796
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700797 jobject gnssMeasurementsEvent = env->NewObject(gnssMeasurementsEventClass,
798 gnssMeasurementsEventCtor,
799 clock,
800 measurementArray);
Lifu Tang120480f2016-02-07 18:08:19 -0800801
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700802 env->CallVoidMethod(mCallbacksObj, method_reportMeasurementData,
803 gnssMeasurementsEvent);
Lifu Tange5a0e212016-01-25 18:02:17 -0800804 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Lifu Tang818aa2c2016-02-01 01:52:00 -0800805 env->DeleteLocalRef(gnssMeasurementsEventClass);
806 env->DeleteLocalRef(gnssMeasurementsEvent);
destradaaea8a8a62014-06-23 18:19:03 -0700807}
808
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700809/*
810 * GnssNiCallback implements callback methods required by the IGnssNi interface.
811 */
812struct GnssNiCallback : public IGnssNiCallback {
813 Return<void> niNotifyCb(const IGnssNiCallback::GnssNiNotification& notification)
814 override;
destradaaea8a8a62014-06-23 18:19:03 -0700815};
816
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700817Return<void> GnssNiCallback::niNotifyCb(
818 const IGnssNiCallback::GnssNiNotification& notification) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800819 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700820 jstring requestorId = env->NewStringUTF(notification.requestorId.c_str());
821 jstring text = env->NewStringUTF(notification.notificationMessage.c_str());
822
823 if (requestorId && text) {
824 env->CallVoidMethod(mCallbacksObj, method_reportNiNotification,
825 notification.notificationId, notification.niType,
826 notification.notifyFlags, notification.timeoutSec,
827 notification.defaultResponse, requestorId, text,
828 notification.requestorIdEncoding,
829 notification.notificationIdEncoding);
830 } else {
831 ALOGE("%s: OOM Error\n", __func__);
832 }
833
834 if (requestorId) {
835 env->DeleteLocalRef(requestorId);
836 }
837
838 if (text) {
839 env->DeleteLocalRef(text);
840 }
841 checkAndClearExceptionFromCallback(env, __FUNCTION__);
842 return Void();
843}
844
845/*
846 * AGnssCallback implements callback methods required by the IAGnss interface.
847 */
848struct AGnssCallback : public IAGnssCallback {
849 // Methods from ::android::hardware::gps::V1_0::IAGnssCallback follow.
850 Return<void> agnssStatusIpV6Cb(
851 const IAGnssCallback::AGnssStatusIpV6& agps_status) override;
852
853 Return<void> agnssStatusIpV4Cb(
854 const IAGnssCallback::AGnssStatusIpV4& agps_status) override;
855 private:
856 jbyteArray convertToIpV4(uint32_t ip);
857};
858
859Return<void> AGnssCallback::agnssStatusIpV6Cb(
860 const IAGnssCallback::AGnssStatusIpV6& agps_status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800861 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700862 jbyteArray byteArray = NULL;
863 bool isSupported = false;
864
865 byteArray = env->NewByteArray(16);
866 if (byteArray != NULL) {
867 env->SetByteArrayRegion(byteArray, 0, 16,
868 (const jbyte*)(agps_status.ipV6Addr.data()));
869 isSupported = true;
870 } else {
871 ALOGE("Unable to allocate byte array for IPv6 address.");
872 }
873
874 IF_ALOGD() {
875 // log the IP for reference in case there is a bogus value pushed by HAL
876 char str[INET6_ADDRSTRLEN];
877 inet_ntop(AF_INET6, agps_status.ipV6Addr.data(), str, INET6_ADDRSTRLEN);
878 ALOGD("AGPS IP is v6: %s", str);
879 }
880
881 jsize byteArrayLength = byteArray != NULL ? env->GetArrayLength(byteArray) : 0;
882 ALOGV("Passing AGPS IP addr: size %d", byteArrayLength);
883 env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus,
884 agps_status.type, agps_status.status, byteArray);
885
886 checkAndClearExceptionFromCallback(env, __FUNCTION__);
887
888 if (byteArray) {
889 env->DeleteLocalRef(byteArray);
890 }
891
892 return Void();
893}
894
895Return<void> AGnssCallback::agnssStatusIpV4Cb(
896 const IAGnssCallback::AGnssStatusIpV4& agps_status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800897 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700898 jbyteArray byteArray = NULL;
899
900 uint32_t ipAddr = agps_status.ipV4Addr;
901 byteArray = convertToIpV4(ipAddr);
902
903 IF_ALOGD() {
904 /*
905 * log the IP for reference in case there is a bogus value pushed by
906 * HAL.
907 */
908 char str[INET_ADDRSTRLEN];
909 inet_ntop(AF_INET, &ipAddr, str, INET_ADDRSTRLEN);
910 ALOGD("AGPS IP is v4: %s", str);
911 }
912
913 jsize byteArrayLength =
914 byteArray != NULL ? env->GetArrayLength(byteArray) : 0;
915 ALOGV("Passing AGPS IP addr: size %d", byteArrayLength);
916 env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus,
917 agps_status.type, agps_status.status, byteArray);
918
919 checkAndClearExceptionFromCallback(env, __FUNCTION__);
920
921 if (byteArray) {
922 env->DeleteLocalRef(byteArray);
923 }
924 return Void();
925}
926
927jbyteArray AGnssCallback::convertToIpV4(uint32_t ip) {
928 if (INADDR_NONE == ip) {
929 return NULL;
930 }
931
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800932 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700933 jbyteArray byteArray = env->NewByteArray(4);
934 if (byteArray == NULL) {
935 ALOGE("Unable to allocate byte array for IPv4 address");
936 return NULL;
937 }
938
939 jbyte ipv4[4];
940 ALOGV("Converting IPv4 address byte array (net_order) %x", ip);
941 memcpy(ipv4, &ip, sizeof(ipv4));
942 env->SetByteArrayRegion(byteArray, 0, 4, (const jbyte*)ipv4);
943 return byteArray;
944}
945
946/*
947 * AGnssRilCallback implements the callback methods required by the AGnssRil
948 * interface.
949 */
950struct AGnssRilCallback : IAGnssRilCallback {
Hridya Valsarajub39eb402017-01-11 08:07:40 -0800951 Return<void> requestSetIdCb(uint32_t setIdFlag) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700952 Return<void> requestRefLocCb() override;
953};
954
Hridya Valsarajub39eb402017-01-11 08:07:40 -0800955Return<void> AGnssRilCallback::requestSetIdCb(uint32_t setIdFlag) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800956 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700957 env->CallVoidMethod(mCallbacksObj, method_requestSetID, setIdFlag);
958 checkAndClearExceptionFromCallback(env, __FUNCTION__);
959 return Void();
960}
961
962Return<void> AGnssRilCallback::requestRefLocCb() {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800963 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700964 env->CallVoidMethod(mCallbacksObj, method_requestRefLocation);
965 checkAndClearExceptionFromCallback(env, __FUNCTION__);
966 return Void();
967}
968
Wyatt Rileycf879db2017-01-12 13:57:38 -0800969/*
970 * GnssBatchingCallback interface implements the callback methods
971 * required by the IGnssBatching interface.
972 */
973struct GnssBatchingCallback : public IGnssBatchingCallback {
974 /*
975 * Methods from ::android::hardware::gps::V1_0::IGnssBatchingCallback
976 * follow.
977 */
978 Return<void> gnssLocationBatchCb(
979 const ::android::hardware::hidl_vec<hardware::gnss::V1_0::GnssLocation> & locations)
980 override;
Wyatt Rileycf879db2017-01-12 13:57:38 -0800981};
982
983Return<void> GnssBatchingCallback::gnssLocationBatchCb(
984 const ::android::hardware::hidl_vec<hardware::gnss::V1_0::GnssLocation> & locations) {
985 JNIEnv* env = getJniEnv();
986
987 jobjectArray jLocations = env->NewObjectArray(locations.size(),
988 env->FindClass("android/location/Location"), nullptr);
989
990 for (uint16_t i = 0; i < locations.size(); ++i) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800991 jobject jLocation = translateLocation(env, locations[i]);
Wyatt Rileycf879db2017-01-12 13:57:38 -0800992 env->SetObjectArrayElement(jLocations, i, jLocation);
993 env->DeleteLocalRef(jLocation);
994 }
995
996 env->CallVoidMethod(mCallbacksObj, method_reportLocationBatch, jLocations);
997 checkAndClearExceptionFromCallback(env, __FUNCTION__);
998
999 env->DeleteLocalRef(jLocations);
1000
1001 return Void();
1002}
1003
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001004static void android_location_GnssLocationProvider_class_init_native(JNIEnv* env, jclass clazz) {
Wyatt Riley5d229832017-02-10 17:06:00 -08001005 method_reportLocation = env->GetMethodID(clazz, "reportLocation",
1006 "(ZLandroid/location/Location;)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001007 method_reportStatus = env->GetMethodID(clazz, "reportStatus", "(I)V");
1008 method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "()V");
1009 method_reportAGpsStatus = env->GetMethodID(clazz, "reportAGpsStatus", "(II[B)V");
1010 method_reportNmea = env->GetMethodID(clazz, "reportNmea", "(J)V");
1011 method_setEngineCapabilities = env->GetMethodID(clazz, "setEngineCapabilities", "(I)V");
1012 method_setGnssYearOfHardware = env->GetMethodID(clazz, "setGnssYearOfHardware", "(I)V");
1013 method_xtraDownloadRequest = env->GetMethodID(clazz, "xtraDownloadRequest", "()V");
1014 method_reportNiNotification = env->GetMethodID(clazz, "reportNiNotification",
1015 "(IIIIILjava/lang/String;Ljava/lang/String;II)V");
1016 method_requestRefLocation = env->GetMethodID(clazz, "requestRefLocation", "()V");
1017 method_requestSetID = env->GetMethodID(clazz, "requestSetID", "(I)V");
1018 method_requestUtcTime = env->GetMethodID(clazz, "requestUtcTime", "()V");
1019 method_reportGeofenceTransition = env->GetMethodID(clazz, "reportGeofenceTransition",
Wyatt Riley5d229832017-02-10 17:06:00 -08001020 "(ILandroid/location/Location;IJ)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001021 method_reportGeofenceStatus = env->GetMethodID(clazz, "reportGeofenceStatus",
Wyatt Riley5d229832017-02-10 17:06:00 -08001022 "(ILandroid/location/Location;)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001023 method_reportGeofenceAddStatus = env->GetMethodID(clazz, "reportGeofenceAddStatus",
1024 "(II)V");
1025 method_reportGeofenceRemoveStatus = env->GetMethodID(clazz, "reportGeofenceRemoveStatus",
1026 "(II)V");
1027 method_reportGeofenceResumeStatus = env->GetMethodID(clazz, "reportGeofenceResumeStatus",
1028 "(II)V");
1029 method_reportGeofencePauseStatus = env->GetMethodID(clazz, "reportGeofencePauseStatus",
1030 "(II)V");
1031 method_reportMeasurementData = env->GetMethodID(
1032 clazz,
1033 "reportMeasurementData",
1034 "(Landroid/location/GnssMeasurementsEvent;)V");
1035 method_reportNavigationMessages = env->GetMethodID(
1036 clazz,
1037 "reportNavigationMessage",
1038 "(Landroid/location/GnssNavigationMessage;)V");
Wyatt Rileycf879db2017-01-12 13:57:38 -08001039 method_reportLocationBatch = env->GetMethodID(
1040 clazz,
1041 "reportLocationBatch",
1042 "([Landroid/location/Location;)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001043
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001044 /*
1045 * Save a pointer to JVM.
1046 */
1047 jint jvmStatus = env->GetJavaVM(&sJvm);
1048 if (jvmStatus != JNI_OK) {
1049 LOG_ALWAYS_FATAL("Unable to get Java VM. Error: %d", jvmStatus);
1050 }
1051
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001052 // TODO(b/31632518)
Chris Phoenixf9133782017-01-23 15:15:15 -08001053 gnssHal = IGnss::getService();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001054 if (gnssHal != nullptr) {
gomo25208882017-04-15 02:05:25 -07001055 gnssHalDeathRecipient = new GnssDeathRecipient();
1056 hardware::Return<bool> linked = gnssHal->linkToDeath(
1057 gnssHalDeathRecipient, /*cookie*/ 0);
1058 if (!linked.isOk()) {
1059 ALOGE("Transaction error in linking to GnssHAL death: %s",
1060 linked.description().c_str());
1061 } else if (!linked) {
1062 ALOGW("Unable to link to GnssHal death notifications");
1063 } else {
1064 ALOGD("Link to death notification successful");
1065 }
1066
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001067 auto gnssXtra = gnssHal->getExtensionXtra();
1068 if (!gnssXtra.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001069 ALOGD("Unable to get a handle to Xtra");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001070 } else {
1071 gnssXtraIface = gnssXtra;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001072 }
1073
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001074 auto gnssRil = gnssHal->getExtensionAGnssRil();
1075 if (!gnssRil.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001076 ALOGD("Unable to get a handle to AGnssRil");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001077 } else {
1078 agnssRilIface = gnssRil;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001079 }
1080
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001081 auto gnssAgnss = gnssHal->getExtensionAGnss();
1082 if (!gnssAgnss.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001083 ALOGD("Unable to get a handle to AGnss");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001084 } else {
1085 agnssIface = gnssAgnss;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001086 }
1087
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001088 auto gnssNavigationMessage = gnssHal->getExtensionGnssNavigationMessage();
1089 if (!gnssNavigationMessage.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001090 ALOGD("Unable to get a handle to GnssNavigationMessage");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001091 } else {
1092 gnssNavigationMessageIface = gnssNavigationMessage;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001093 }
1094
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001095 auto gnssMeasurement = gnssHal->getExtensionGnssMeasurement();
1096 if (!gnssMeasurement.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001097 ALOGD("Unable to get a handle to GnssMeasurement");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001098 } else {
1099 gnssMeasurementIface = gnssMeasurement;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001100 }
1101
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001102 auto gnssDebug = gnssHal->getExtensionGnssDebug();
1103 if (!gnssDebug.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001104 ALOGD("Unable to get a handle to GnssDebug");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001105 } else {
1106 gnssDebugIface = gnssDebug;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001107 }
1108
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001109 auto gnssNi = gnssHal->getExtensionGnssNi();
1110 if (!gnssNi.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001111 ALOGD("Unable to get a handle to GnssNi");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001112 } else {
1113 gnssNiIface = gnssNi;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001114 }
1115
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001116 auto gnssConfiguration = gnssHal->getExtensionGnssConfiguration();
1117 if (!gnssConfiguration.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001118 ALOGD("Unable to get a handle to GnssConfiguration");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001119 } else {
1120 gnssConfigurationIface = gnssConfiguration;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001121 }
1122
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001123 auto gnssGeofencing = gnssHal->getExtensionGnssGeofencing();
1124 if (!gnssGeofencing.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001125 ALOGD("Unable to get a handle to GnssGeofencing");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001126 } else {
1127 gnssGeofencingIface = gnssGeofencing;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001128 }
Wyatt Rileycf879db2017-01-12 13:57:38 -08001129
1130 auto gnssBatching = gnssHal->getExtensionGnssBatching();
1131 if (!gnssBatching.isOk()) {
1132 ALOGD("Unable to get a handle to gnssBatching");
1133 } else {
1134 gnssBatchingIface = gnssBatching;
1135 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001136 } else {
1137 ALOGE("Unable to get GPS service\n");
1138 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001139}
1140
1141static jboolean android_location_GnssLocationProvider_is_supported(
1142 JNIEnv* /* env */, jclass /* clazz */) {
1143 return (gnssHal != nullptr) ? JNI_TRUE : JNI_FALSE;
1144}
1145
1146static jboolean android_location_GnssLocationProvider_is_agps_ril_supported(
1147 JNIEnv* /* env */, jclass /* clazz */) {
1148 return (agnssRilIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1149}
1150
1151static jboolean android_location_gpsLocationProvider_is_gnss_configuration_supported(
1152 JNIEnv* /* env */, jclass /* jclazz */) {
1153 return (gnssConfigurationIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1154}
1155
1156static jboolean android_location_GnssLocationProvider_init(JNIEnv* env, jobject obj) {
1157 /*
1158 * This must be set before calling into the HAL library.
1159 */
1160 if (!mCallbacksObj)
1161 mCallbacksObj = env->NewGlobalRef(obj);
1162
1163 sp<IGnssCallback> gnssCbIface = new GnssCallback();
1164 /*
1165 * Fail if the main interface fails to initialize
1166 */
1167 if (gnssHal == nullptr) {
1168 ALOGE("Unable to Initialize GNSS HAL\n");
1169 return JNI_FALSE;
1170 }
1171
1172 auto result = gnssHal->setCallback(gnssCbIface);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001173 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001174 ALOGE("SetCallback for Gnss Interface fails\n");
1175 return JNI_FALSE;
1176 }
1177
1178 sp<IGnssXtraCallback> gnssXtraCbIface = new GnssXtraCallback();
1179 if (gnssXtraIface == nullptr) {
1180 ALOGE("Unable to initialize GNSS Xtra interface\n");
Hridya Valsarajue8650322016-12-05 20:23:21 -08001181 } else {
1182 result = gnssXtraIface->setCallback(gnssXtraCbIface);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001183 if (!result.isOk() || !result) {
Hridya Valsarajue8650322016-12-05 20:23:21 -08001184 gnssXtraIface = nullptr;
1185 ALOGE("SetCallback for Gnss Xtra Interface fails\n");
1186 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001187 }
1188
1189 sp<IAGnssCallback> aGnssCbIface = new AGnssCallback();
1190 if (agnssIface != nullptr) {
1191 agnssIface->setCallback(aGnssCbIface);
1192 } else {
1193 ALOGE("Unable to Initialize AGnss interface\n");
1194 }
1195
1196 sp<IGnssGeofenceCallback> gnssGeofencingCbIface = new GnssGeofenceCallback();
1197 if (gnssGeofencingIface != nullptr) {
1198 gnssGeofencingIface->setCallback(gnssGeofencingCbIface);
1199 } else {
1200 ALOGE("Unable to initialize GNSS Geofencing interface\n");
1201 }
1202
1203 sp<IGnssNiCallback> gnssNiCbIface = new GnssNiCallback();
Hridya Valsaraju388e9682017-03-08 10:57:06 -08001204 if (gnssNiIface != nullptr) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001205 gnssNiIface->setCallback(gnssNiCbIface);
1206 } else {
1207 ALOGE("Unable to initialize GNSS NI interface\n");
1208 }
1209
Jaekyun Seokf9038ad2017-11-13 15:03:21 +09001210 sp<IAGnssRilCallback> aGnssRilCbIface = new AGnssRilCallback();
1211 if (agnssRilIface != nullptr) {
1212 agnssRilIface->setCallback(aGnssRilCbIface);
1213 } else {
1214 ALOGI("Unable to Initialize AGnss Ril interface\n");
1215 }
1216
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001217 return JNI_TRUE;
1218}
1219
1220static void android_location_GnssLocationProvider_cleanup(JNIEnv* /* env */, jobject /* obj */) {
1221 if (gnssHal != nullptr) {
1222 gnssHal->cleanup();
1223 }
1224}
1225
1226static jboolean android_location_GnssLocationProvider_set_position_mode(JNIEnv* /* env */,
1227 jobject /* obj */, jint mode, jint recurrence, jint min_interval, jint preferred_accuracy,
1228 jint preferred_time) {
1229 if (gnssHal != nullptr) {
1230 auto result = gnssHal->setPositionMode(static_cast<IGnss::GnssPositionMode>(mode),
1231 static_cast<IGnss::GnssPositionRecurrence>(recurrence),
1232 min_interval,
1233 preferred_accuracy,
1234 preferred_time);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001235 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001236 ALOGE("%s: GNSS setPositionMode failed\n", __func__);
1237 return JNI_FALSE;
1238 } else {
1239 return result;
1240 }
1241 } else {
1242 return JNI_FALSE;
1243 }
1244}
1245
1246static jboolean android_location_GnssLocationProvider_start(JNIEnv* /* env */, jobject /* obj */) {
1247 if (gnssHal != nullptr) {
1248 auto result = gnssHal->start();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001249 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001250 return JNI_FALSE;
1251 } else {
1252 return result;
1253 }
1254 } else {
1255 return JNI_FALSE;
1256 }
1257}
1258
1259static jboolean android_location_GnssLocationProvider_stop(JNIEnv* /* env */, jobject /* obj */) {
1260 if (gnssHal != nullptr) {
1261 auto result = gnssHal->stop();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001262 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001263 return JNI_FALSE;
1264 } else {
1265 return result;
1266 }
1267 } else {
1268 return JNI_FALSE;
1269 }
1270}
1271static void android_location_GnssLocationProvider_delete_aiding_data(JNIEnv* /* env */,
1272 jobject /* obj */,
1273 jint flags) {
1274 if (gnssHal != nullptr) {
1275 auto result = gnssHal->deleteAidingData(static_cast<IGnss::GnssAidingData>(flags));
Steven Morelandd002a8b2017-01-03 17:18:24 -08001276 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001277 ALOGE("Error in deleting aiding data");
1278 }
1279 }
1280}
1281
1282/*
1283 * This enum is used by the read_sv_status method to combine the svid,
1284 * constellation and svFlag fields.
1285 */
1286enum ShiftWidth: uint8_t {
Yipeng Cao21717812017-04-27 18:35:24 -07001287 SVID_SHIFT_WIDTH = 8,
1288 CONSTELLATION_TYPE_SHIFT_WIDTH = 4
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001289};
1290
1291static jint android_location_GnssLocationProvider_read_sv_status(JNIEnv* env, jobject /* obj */,
1292 jintArray svidWithFlagArray, jfloatArray cn0Array, jfloatArray elevArray,
gomo4402af62017-01-11 13:20:13 -08001293 jfloatArray azumArray, jfloatArray carrierFreqArray) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001294 /*
1295 * This method should only be called from within a call to reportSvStatus.
1296 */
1297 jint* svidWithFlags = env->GetIntArrayElements(svidWithFlagArray, 0);
1298 jfloat* cn0s = env->GetFloatArrayElements(cn0Array, 0);
1299 jfloat* elev = env->GetFloatArrayElements(elevArray, 0);
1300 jfloat* azim = env->GetFloatArrayElements(azumArray, 0);
gomo4402af62017-01-11 13:20:13 -08001301 jfloat* carrierFreq = env->GetFloatArrayElements(carrierFreqArray, 0);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001302
1303 /*
1304 * Read GNSS SV info.
1305 */
1306 for (size_t i = 0; i < GnssCallback::sGnssSvListSize; ++i) {
1307 const IGnssCallback::GnssSvInfo& info = GnssCallback::sGnssSvList[i];
1308 svidWithFlags[i] = (info.svid << SVID_SHIFT_WIDTH) |
1309 (static_cast<uint32_t>(info.constellation) << CONSTELLATION_TYPE_SHIFT_WIDTH) |
1310 static_cast<uint32_t>(info.svFlag);
1311 cn0s[i] = info.cN0Dbhz;
1312 elev[i] = info.elevationDegrees;
1313 azim[i] = info.azimuthDegrees;
gomo4402af62017-01-11 13:20:13 -08001314 carrierFreq[i] = info.carrierFrequencyHz;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001315 }
1316
1317 env->ReleaseIntArrayElements(svidWithFlagArray, svidWithFlags, 0);
1318 env->ReleaseFloatArrayElements(cn0Array, cn0s, 0);
1319 env->ReleaseFloatArrayElements(elevArray, elev, 0);
1320 env->ReleaseFloatArrayElements(azumArray, azim, 0);
gomo4402af62017-01-11 13:20:13 -08001321 env->ReleaseFloatArrayElements(carrierFreqArray, carrierFreq, 0);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001322 return static_cast<jint>(GnssCallback::sGnssSvListSize);
1323}
1324
1325static void android_location_GnssLocationProvider_agps_set_reference_location_cellid(
1326 JNIEnv* /* env */, jobject /* obj */, jint type, jint mcc, jint mnc, jint lac, jint cid) {
1327 IAGnssRil::AGnssRefLocation location;
1328
1329 if (agnssRilIface == nullptr) {
1330 ALOGE("No AGPS RIL interface in agps_set_reference_location_cellid");
1331 return;
1332 }
1333
1334 switch (static_cast<IAGnssRil::AGnssRefLocationType>(type)) {
1335 case IAGnssRil::AGnssRefLocationType::GSM_CELLID:
1336 case IAGnssRil::AGnssRefLocationType::UMTS_CELLID:
1337 location.type = static_cast<IAGnssRil::AGnssRefLocationType>(type);
1338 location.cellID.mcc = mcc;
1339 location.cellID.mnc = mnc;
1340 location.cellID.lac = lac;
1341 location.cellID.cid = cid;
1342 break;
1343 default:
1344 ALOGE("Neither a GSM nor a UMTS cellid (%s:%d).", __FUNCTION__, __LINE__);
1345 return;
1346 break;
1347 }
1348
1349 agnssRilIface->setRefLocation(location);
1350}
1351
1352static void android_location_GnssLocationProvider_agps_set_id(JNIEnv *env, jobject /* obj */,
1353 jint type, jstring setid_string) {
1354 if (agnssRilIface == nullptr) {
1355 ALOGE("no AGPS RIL interface in agps_set_id");
1356 return;
1357 }
1358
1359 const char *setid = env->GetStringUTFChars(setid_string, NULL);
1360 agnssRilIface->setSetId((IAGnssRil::SetIDType)type, setid);
1361 env->ReleaseStringUTFChars(setid_string, setid);
1362}
1363
1364static jint android_location_GnssLocationProvider_read_nmea(JNIEnv* env, jobject /* obj */,
1365 jbyteArray nmeaArray, jint buffer_size) {
1366 // this should only be called from within a call to reportNmea
1367 jbyte* nmea = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(nmeaArray, 0));
1368 int length = GnssCallback::sNmeaStringLength;
1369 if (length > buffer_size)
1370 length = buffer_size;
1371 memcpy(nmea, GnssCallback::sNmeaString, length);
1372 env->ReleasePrimitiveArrayCritical(nmeaArray, nmea, JNI_ABORT);
1373 return (jint) length;
1374}
1375
1376static void android_location_GnssLocationProvider_inject_time(JNIEnv* /* env */, jobject /* obj */,
1377 jlong time, jlong timeReference, jint uncertainty) {
1378 if (gnssHal != nullptr) {
1379 auto result = gnssHal->injectTime(time, timeReference, uncertainty);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001380 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001381 ALOGE("%s: Gnss injectTime() failed", __func__);
1382 }
1383 }
1384}
1385
1386static void android_location_GnssLocationProvider_inject_location(JNIEnv* /* env */,
1387 jobject /* obj */, jdouble latitude, jdouble longitude, jfloat accuracy) {
1388 if (gnssHal != nullptr) {
1389 auto result = gnssHal->injectLocation(latitude, longitude, accuracy);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001390 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001391 ALOGE("%s: Gnss injectLocation() failed", __func__);
1392 }
1393 }
1394}
1395
1396static jboolean android_location_GnssLocationProvider_supports_xtra(
1397 JNIEnv* /* env */, jobject /* obj */) {
1398 return (gnssXtraIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1399}
1400
1401static void android_location_GnssLocationProvider_inject_xtra_data(JNIEnv* env, jobject /* obj */,
1402 jbyteArray data, jint length) {
1403 if (gnssXtraIface == nullptr) {
1404 ALOGE("XTRA Interface not supported");
1405 return;
1406 }
1407
1408 jbyte* bytes = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(data, 0));
1409 gnssXtraIface->injectXtraData(std::string((const char*)bytes, length));
1410 env->ReleasePrimitiveArrayCritical(data, bytes, JNI_ABORT);
1411}
1412
1413static void android_location_GnssLocationProvider_agps_data_conn_open(
1414 JNIEnv* env, jobject /* obj */, jstring apn, jint apnIpType) {
1415 if (agnssIface == nullptr) {
1416 ALOGE("no AGPS interface in agps_data_conn_open");
1417 return;
1418 }
1419 if (apn == NULL) {
1420 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
1421 return;
1422 }
1423
1424 const char *apnStr = env->GetStringUTFChars(apn, NULL);
1425
1426 auto result = agnssIface->dataConnOpen(apnStr, static_cast<IAGnss::ApnIpType>(apnIpType));
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001427 if (!result.isOk() || !result){
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001428 ALOGE("%s: Failed to set APN and its IP type", __func__);
1429 }
1430 env->ReleaseStringUTFChars(apn, apnStr);
1431}
1432
1433static void android_location_GnssLocationProvider_agps_data_conn_closed(JNIEnv* /* env */,
1434 jobject /* obj */) {
1435 if (agnssIface == nullptr) {
1436 ALOGE("%s: AGPS interface not supported", __func__);
1437 return;
1438 }
1439
1440 auto result = agnssIface->dataConnClosed();
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001441 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001442 ALOGE("%s: Failed to close AGnss data connection", __func__);
1443 }
1444}
1445
1446static void android_location_GnssLocationProvider_agps_data_conn_failed(JNIEnv* /* env */,
1447 jobject /* obj */) {
1448 if (agnssIface == nullptr) {
1449 ALOGE("%s: AGPS interface not supported", __func__);
1450 return;
1451 }
1452
1453 auto result = agnssIface->dataConnFailed();
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001454 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001455 ALOGE("%s: Failed to notify unavailability of AGnss data connection", __func__);
1456 }
1457}
1458
1459static void android_location_GnssLocationProvider_set_agps_server(JNIEnv* env, jobject /* obj */,
1460 jint type, jstring hostname, jint port) {
1461 if (agnssIface == nullptr) {
1462 ALOGE("no AGPS interface in set_agps_server");
1463 return;
1464 }
1465
1466 const char *c_hostname = env->GetStringUTFChars(hostname, NULL);
1467 auto result = agnssIface->setServer(static_cast<IAGnssCallback::AGnssType>(type),
1468 c_hostname,
1469 port);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001470 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001471 ALOGE("%s: Failed to set AGnss host name and port", __func__);
1472 }
1473
1474 env->ReleaseStringUTFChars(hostname, c_hostname);
1475}
1476
1477static void android_location_GnssLocationProvider_send_ni_response(JNIEnv* /* env */,
1478 jobject /* obj */, jint notifId, jint response) {
1479 if (gnssNiIface == nullptr) {
1480 ALOGE("no NI interface in send_ni_response");
1481 return;
1482 }
1483
1484 gnssNiIface->respond(notifId, static_cast<IGnssNiCallback::GnssUserResponseType>(response));
1485}
1486
1487static jstring android_location_GnssLocationProvider_get_internal_state(JNIEnv* env,
1488 jobject /* obj */) {
1489 jstring result = NULL;
1490 /*
1491 * TODO(b/33089503) : Create a jobject to represent GnssDebug.
1492 */
Wyatt Riley268c6e02017-03-29 10:21:46 -07001493
1494 std::stringstream internalState;
1495
1496 if (gnssDebugIface == nullptr) {
1497 internalState << "Gnss Debug Interface not available" << std::endl;
1498 } else {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001499 IGnssDebug::DebugData data;
1500 gnssDebugIface->getDebugData([&data](const IGnssDebug::DebugData& debugData) {
1501 data = debugData;
1502 });
1503
Wyatt Riley268c6e02017-03-29 10:21:46 -07001504 internalState << "Gnss Location Data:: ";
1505 if (!data.position.valid) {
1506 internalState << "not valid";
1507 } else {
1508 internalState << "LatitudeDegrees: " << data.position.latitudeDegrees
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001509 << ", LongitudeDegrees: " << data.position.longitudeDegrees
1510 << ", altitudeMeters: " << data.position.altitudeMeters
gomo4402af62017-01-11 13:20:13 -08001511 << ", speedMetersPerSecond: " << data.position.speedMetersPerSec
1512 << ", bearingDegrees: " << data.position.bearingDegrees
Wyatt Riley268c6e02017-03-29 10:21:46 -07001513 << ", horizontalAccuracyMeters: "
1514 << data.position.horizontalAccuracyMeters
gomo4402af62017-01-11 13:20:13 -08001515 << ", verticalAccuracyMeters: " << data.position.verticalAccuracyMeters
Wyatt Riley268c6e02017-03-29 10:21:46 -07001516 << ", speedAccuracyMetersPerSecond: "
1517 << data.position.speedAccuracyMetersPerSecond
gomo4402af62017-01-11 13:20:13 -08001518 << ", bearingAccuracyDegrees: " << data.position.bearingAccuracyDegrees
Wyatt Riley268c6e02017-03-29 10:21:46 -07001519 << ", ageSeconds: " << data.position.ageSeconds;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001520 }
Wyatt Riley268c6e02017-03-29 10:21:46 -07001521 internalState << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001522
Wyatt Riley268c6e02017-03-29 10:21:46 -07001523 internalState << "Gnss Time Data:: timeEstimate: " << data.time.timeEstimate
1524 << ", timeUncertaintyNs: " << data.time.timeUncertaintyNs
1525 << ", frequencyUncertaintyNsPerSec: "
1526 << data.time.frequencyUncertaintyNsPerSec << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001527
1528 if (data.satelliteDataArray.size() != 0) {
Wyatt Riley268c6e02017-03-29 10:21:46 -07001529 internalState << "Satellite Data for " << data.satelliteDataArray.size()
1530 << " satellites:: " << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001531 }
1532
Wyatt Riley77ca4f82017-06-30 18:13:44 -07001533 internalState << "constellation: 1=GPS, 2=SBAS, 3=GLO, 4=QZSS, 5=BDS, 6=GAL; "
1534 << "ephemerisType: 0=Eph, 1=Alm, 2=?; "
1535 << "ephemerisSource: 0=Demod, 1=Supl, 2=Server, 3=?; "
1536 << "ephemerisHealth: 0=Good, 1=Bad, 2=?" << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001537 for (size_t i = 0; i < data.satelliteDataArray.size(); i++) {
1538 internalState << "svid: " << data.satelliteDataArray[i].svid
1539 << ", constellation: "
1540 << static_cast<uint32_t>(data.satelliteDataArray[i].constellation)
1541 << ", ephemerisType: "
1542 << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisType)
Wyatt Riley268c6e02017-03-29 10:21:46 -07001543 << ", ephemerisSource: "
1544 << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisSource)
1545 << ", ephemerisHealth: "
1546 << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisHealth)
1547 << ", serverPredictionIsAvailable: "
1548 << data.satelliteDataArray[i].serverPredictionIsAvailable
1549 << ", serverPredictionAgeSeconds: "
1550 << data.satelliteDataArray[i].serverPredictionAgeSeconds
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001551 << ", ephemerisAgeSeconds: "
1552 << data.satelliteDataArray[i].ephemerisAgeSeconds << std::endl;
1553 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001554 }
Wyatt Riley268c6e02017-03-29 10:21:46 -07001555
1556 result = env->NewStringUTF(internalState.str().c_str());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001557 return result;
1558}
1559
1560static void android_location_GnssLocationProvider_update_network_state(JNIEnv* env,
1561 jobject /* obj */,
1562 jboolean connected,
1563 jint type,
1564 jboolean roaming,
1565 jboolean available,
1566 jstring extraInfo,
1567 jstring apn) {
1568 if (agnssRilIface != nullptr) {
1569 auto result = agnssRilIface->updateNetworkState(connected,
1570 static_cast<IAGnssRil::NetworkType>(type),
1571 roaming);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001572 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001573 ALOGE("updateNetworkState failed");
1574 }
1575
1576 const char *c_apn = env->GetStringUTFChars(apn, NULL);
1577 result = agnssRilIface->updateNetworkAvailability(available, c_apn);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001578 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001579 ALOGE("updateNetworkAvailability failed");
1580 }
1581
1582 env->ReleaseStringUTFChars(apn, c_apn);
1583 } else {
1584 ALOGE("AGnssRilInterface does not exist");
1585 }
1586}
1587
1588static jboolean android_location_GnssLocationProvider_is_geofence_supported(
1589 JNIEnv* /* env */, jobject /* obj */) {
1590 return (gnssGeofencingIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1591}
1592
1593static jboolean android_location_GnssLocationProvider_add_geofence(JNIEnv* /* env */,
1594 jobject /* obj */, jint geofenceId, jdouble latitude, jdouble longitude, jdouble radius,
1595 jint last_transition, jint monitor_transition, jint notification_responsiveness,
1596 jint unknown_timer) {
1597 if (gnssGeofencingIface != nullptr) {
1598 auto result = gnssGeofencingIface->addGeofence(
1599 geofenceId, latitude, longitude, radius,
1600 static_cast<IGnssGeofenceCallback::GeofenceTransition>(last_transition),
1601 monitor_transition, notification_responsiveness, unknown_timer);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001602 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001603 } else {
1604 ALOGE("Geofence Interface not available");
1605 }
1606 return JNI_FALSE;
1607}
1608
1609static jboolean android_location_GnssLocationProvider_remove_geofence(JNIEnv* /* env */,
1610 jobject /* obj */, jint geofenceId) {
1611 if (gnssGeofencingIface != nullptr) {
1612 auto result = gnssGeofencingIface->removeGeofence(geofenceId);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001613 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001614 } else {
1615 ALOGE("Geofence interface not available");
1616 }
1617 return JNI_FALSE;
1618}
1619
1620static jboolean android_location_GnssLocationProvider_pause_geofence(JNIEnv* /* env */,
1621 jobject /* obj */, jint geofenceId) {
1622 if (gnssGeofencingIface != nullptr) {
1623 auto result = gnssGeofencingIface->pauseGeofence(geofenceId);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001624 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001625 } else {
1626 ALOGE("Geofence interface not available");
1627 }
1628 return JNI_FALSE;
1629}
1630
1631static jboolean android_location_GnssLocationProvider_resume_geofence(JNIEnv* /* env */,
1632 jobject /* obj */, jint geofenceId, jint monitor_transition) {
1633 if (gnssGeofencingIface != nullptr) {
1634 auto result = gnssGeofencingIface->resumeGeofence(geofenceId, monitor_transition);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001635 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001636 } else {
1637 ALOGE("Geofence interface not available");
1638 }
1639 return JNI_FALSE;
1640}
1641
Lifu Tang30f95a72016-01-07 23:20:38 -08001642static jboolean android_location_GnssLocationProvider_is_measurement_supported(
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001643 JNIEnv* env, jclass clazz) {
1644 if (gnssMeasurementIface != nullptr) {
destradaaea8a8a62014-06-23 18:19:03 -07001645 return JNI_TRUE;
1646 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001647
destradaaea8a8a62014-06-23 18:19:03 -07001648 return JNI_FALSE;
1649}
1650
Lifu Tang30f95a72016-01-07 23:20:38 -08001651static jboolean android_location_GnssLocationProvider_start_measurement_collection(
destradaaea8a8a62014-06-23 18:19:03 -07001652 JNIEnv* env,
1653 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001654 if (gnssMeasurementIface == nullptr) {
1655 ALOGE("GNSS Measurement interface is not available.");
destradaaea8a8a62014-06-23 18:19:03 -07001656 return JNI_FALSE;
1657 }
1658
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001659 sp<GnssMeasurementCallback> cbIface = new GnssMeasurementCallback();
1660 IGnssMeasurement::GnssMeasurementStatus result = gnssMeasurementIface->setCallback(cbIface);
1661 if (result != IGnssMeasurement::GnssMeasurementStatus::SUCCESS) {
1662 ALOGE("An error has been found on GnssMeasurementInterface::init, status=%d",
1663 static_cast<int32_t>(result));
destradaaea8a8a62014-06-23 18:19:03 -07001664 return JNI_FALSE;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001665 } else {
1666 ALOGD("gnss measurement infc has been enabled");
destradaaea8a8a62014-06-23 18:19:03 -07001667 }
1668
1669 return JNI_TRUE;
1670}
1671
Lifu Tang30f95a72016-01-07 23:20:38 -08001672static jboolean android_location_GnssLocationProvider_stop_measurement_collection(
destradaaea8a8a62014-06-23 18:19:03 -07001673 JNIEnv* env,
1674 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001675 if (gnssMeasurementIface == nullptr) {
destradaaea8a8a62014-06-23 18:19:03 -07001676 ALOGE("Measurement interface not available");
1677 return JNI_FALSE;
1678 }
1679
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001680 auto result = gnssMeasurementIface->close();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001681 return boolToJbool(result.isOk());
destradaaea8a8a62014-06-23 18:19:03 -07001682}
1683
Lifu Tang30f95a72016-01-07 23:20:38 -08001684static jboolean android_location_GnssLocationProvider_is_navigation_message_supported(
destradaa4b3e3932014-07-21 18:01:47 -07001685 JNIEnv* env,
1686 jclass clazz) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001687 if (gnssNavigationMessageIface != nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001688 return JNI_TRUE;
1689 }
1690 return JNI_FALSE;
1691}
1692
Lifu Tang30f95a72016-01-07 23:20:38 -08001693static jboolean android_location_GnssLocationProvider_start_navigation_message_collection(
destradaa4b3e3932014-07-21 18:01:47 -07001694 JNIEnv* env,
1695 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001696 if (gnssNavigationMessageIface == nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001697 ALOGE("Navigation Message interface is not available.");
1698 return JNI_FALSE;
1699 }
1700
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001701 sp<IGnssNavigationMessageCallback> gnssNavigationMessageCbIface =
1702 new GnssNavigationMessageCallback();
1703 IGnssNavigationMessage::GnssNavigationMessageStatus result =
1704 gnssNavigationMessageIface->setCallback(gnssNavigationMessageCbIface);
1705
1706 if (result != IGnssNavigationMessage::GnssNavigationMessageStatus::SUCCESS) {
1707 ALOGE("An error has been found in %s: %d", __FUNCTION__, static_cast<int32_t>(result));
destradaa4b3e3932014-07-21 18:01:47 -07001708 return JNI_FALSE;
1709 }
1710
1711 return JNI_TRUE;
1712}
1713
Lifu Tang30f95a72016-01-07 23:20:38 -08001714static jboolean android_location_GnssLocationProvider_stop_navigation_message_collection(
destradaa4b3e3932014-07-21 18:01:47 -07001715 JNIEnv* env,
1716 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001717 if (gnssNavigationMessageIface == nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001718 ALOGE("Navigation Message interface is not available.");
1719 return JNI_FALSE;
1720 }
1721
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001722 auto result = gnssNavigationMessageIface->close();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001723 return boolToJbool(result.isOk());
destradaa4b3e3932014-07-21 18:01:47 -07001724}
1725
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001726static jboolean android_location_GnssLocationProvider_set_emergency_supl_pdn(JNIEnv*,
1727 jobject,
1728 jint emergencySuplPdn) {
1729 if (gnssConfigurationIface == nullptr) {
1730 ALOGE("no GNSS configuration interface available");
1731 return JNI_FALSE;
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001732 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001733
1734 auto result = gnssConfigurationIface->setEmergencySuplPdn(emergencySuplPdn);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001735 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001736 return result;
1737 } else {
1738 return JNI_FALSE;
1739 }
1740}
1741
1742static jboolean android_location_GnssLocationProvider_set_supl_version(JNIEnv*,
1743 jobject,
1744 jint version) {
1745 if (gnssConfigurationIface == nullptr) {
1746 ALOGE("no GNSS configuration interface available");
1747 return JNI_FALSE;
1748 }
1749 auto result = gnssConfigurationIface->setSuplVersion(version);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001750 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001751 return result;
1752 } else {
1753 return JNI_FALSE;
1754 }
1755}
1756
1757static jboolean android_location_GnssLocationProvider_set_supl_es(JNIEnv*,
1758 jobject,
1759 jint suplEs) {
1760 if (gnssConfigurationIface == nullptr) {
1761 ALOGE("no GNSS configuration interface available");
1762 return JNI_FALSE;
1763 }
1764
1765 auto result = gnssConfigurationIface->setSuplEs(suplEs);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001766 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001767 return result;
1768 } else {
1769 return JNI_FALSE;
1770 }
1771}
1772
1773static jboolean android_location_GnssLocationProvider_set_supl_mode(JNIEnv*,
1774 jobject,
1775 jint mode) {
1776 if (gnssConfigurationIface == nullptr) {
1777 ALOGE("no GNSS configuration interface available");
1778 return JNI_FALSE;
1779 }
1780
1781 auto result = gnssConfigurationIface->setSuplMode(mode);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001782 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001783 return result;
1784 } else {
1785 return JNI_FALSE;
1786 }
1787}
1788
1789static jboolean android_location_GnssLocationProvider_set_gps_lock(JNIEnv*,
1790 jobject,
1791 jint gpsLock) {
1792 if (gnssConfigurationIface == nullptr) {
1793 ALOGE("no GNSS configuration interface available");
1794 return JNI_FALSE;
1795 }
1796
1797 auto result = gnssConfigurationIface->setGpsLock(gpsLock);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001798 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001799 return result;
1800 } else {
1801 return JNI_FALSE;
1802 }
1803}
1804
1805static jboolean android_location_GnssLocationProvider_set_lpp_profile(JNIEnv*,
1806 jobject,
1807 jint lppProfile) {
1808 if (gnssConfigurationIface == nullptr) {
1809 ALOGE("no GNSS configuration interface available");
1810 return JNI_FALSE;
1811 }
1812
1813 auto result = gnssConfigurationIface->setLppProfile(lppProfile);
1814
Steven Morelandd002a8b2017-01-03 17:18:24 -08001815 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001816 return result;
1817 } else {
1818 return JNI_FALSE;
1819 }
1820}
1821
1822static jboolean android_location_GnssLocationProvider_set_gnss_pos_protocol_select(JNIEnv*,
1823 jobject,
1824 jint gnssPosProtocol) {
1825 if (gnssConfigurationIface == nullptr) {
1826 ALOGE("no GNSS configuration interface available");
1827 return JNI_FALSE;
1828 }
1829
1830 auto result = gnssConfigurationIface->setGlonassPositioningProtocol(gnssPosProtocol);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001831 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001832 return result;
1833 } else {
1834 return JNI_FALSE;
1835 }
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001836}
1837
Wyatt Rileycf879db2017-01-12 13:57:38 -08001838static jint android_location_GnssLocationProvider_get_batch_size(JNIEnv*, jclass) {
1839 if (gnssBatchingIface == nullptr) {
1840 return 0; // batching not supported, size = 0
1841 }
1842 auto result = gnssBatchingIface->getBatchSize();
1843 if (result.isOk()) {
1844 return static_cast<jint>(result);
1845 } else {
1846 return 0; // failure in binder, don't support batching
1847 }
1848}
1849
1850static jboolean android_location_GnssLocationProvider_init_batching(JNIEnv*, jclass) {
1851 if (gnssBatchingIface == nullptr) {
1852 return JNI_FALSE; // batching not supported
1853 }
1854 sp<IGnssBatchingCallback> gnssBatchingCbIface = new GnssBatchingCallback();
1855
1856 return static_cast<jboolean>(gnssBatchingIface->init(gnssBatchingCbIface));
1857}
1858
1859static void android_location_GnssLocationProvider_cleanup_batching(JNIEnv*, jclass) {
1860 if (gnssBatchingIface == nullptr) {
1861 return; // batching not supported
1862 }
1863 gnssBatchingIface->cleanup();
1864}
1865
1866static jboolean android_location_GnssLocationProvider_start_batch(JNIEnv*, jclass,
1867 jlong periodNanos, jboolean wakeOnFifoFull) {
1868 if (gnssBatchingIface == nullptr) {
1869 return JNI_FALSE; // batching not supported
1870 }
1871
1872 IGnssBatching::Options options;
1873 options.periodNanos = periodNanos;
1874 if (wakeOnFifoFull) {
1875 options.flags = static_cast<uint8_t>(IGnssBatching::Flag::WAKEUP_ON_FIFO_FULL);
1876 } else {
1877 options.flags = 0;
1878 }
1879
1880 return static_cast<jboolean>(gnssBatchingIface->start(options));
1881}
1882
1883static void android_location_GnssLocationProvider_flush_batch(JNIEnv*, jclass) {
1884 if (gnssBatchingIface == nullptr) {
1885 return; // batching not supported
1886 }
1887
1888 gnssBatchingIface->flush();
1889}
1890
1891static jboolean android_location_GnssLocationProvider_stop_batch(JNIEnv*, jclass) {
1892 if (gnssBatchingIface == nullptr) {
1893 return JNI_FALSE; // batching not supported
1894 }
1895
1896 return gnssBatchingIface->stop();
1897}
1898
Daniel Micay76f6a862015-09-19 17:31:01 -04001899static const JNINativeMethod sMethods[] = {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001900 /* name, signature, funcPtr */
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001901 {"class_init_native", "()V", reinterpret_cast<void *>(
1902 android_location_GnssLocationProvider_class_init_native)},
1903 {"native_is_supported", "()Z", reinterpret_cast<void *>(
1904 android_location_GnssLocationProvider_is_supported)},
destradaaef752b62015-04-17 13:10:47 -07001905 {"native_is_agps_ril_supported", "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001906 reinterpret_cast<void *>(android_location_GnssLocationProvider_is_agps_ril_supported)},
destradaaef752b62015-04-17 13:10:47 -07001907 {"native_is_gnss_configuration_supported", "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001908 reinterpret_cast<void *>(
1909 android_location_gpsLocationProvider_is_gnss_configuration_supported)},
1910 {"native_init", "()Z", reinterpret_cast<void *>(android_location_GnssLocationProvider_init)},
1911 {"native_cleanup", "()V", reinterpret_cast<void *>(
1912 android_location_GnssLocationProvider_cleanup)},
destradaaea8a8a62014-06-23 18:19:03 -07001913 {"native_set_position_mode",
1914 "(IIIII)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001915 reinterpret_cast<void*>(android_location_GnssLocationProvider_set_position_mode)},
1916 {"native_start", "()Z", reinterpret_cast<void*>(android_location_GnssLocationProvider_start)},
1917 {"native_stop", "()Z", reinterpret_cast<void*>(android_location_GnssLocationProvider_stop)},
destradaaea8a8a62014-06-23 18:19:03 -07001918 {"native_delete_aiding_data",
1919 "(I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001920 reinterpret_cast<void*>(android_location_GnssLocationProvider_delete_aiding_data)},
destradaaea8a8a62014-06-23 18:19:03 -07001921 {"native_read_sv_status",
gomo4402af62017-01-11 13:20:13 -08001922 "([I[F[F[F[F)I",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001923 reinterpret_cast<void *>(android_location_GnssLocationProvider_read_sv_status)},
1924 {"native_read_nmea", "([BI)I", reinterpret_cast<void *>(
1925 android_location_GnssLocationProvider_read_nmea)},
1926 {"native_inject_time", "(JJI)V", reinterpret_cast<void *>(
1927 android_location_GnssLocationProvider_inject_time)},
destradaaea8a8a62014-06-23 18:19:03 -07001928 {"native_inject_location",
1929 "(DDF)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001930 reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_location)},
1931 {"native_supports_xtra", "()Z", reinterpret_cast<void *>(
1932 android_location_GnssLocationProvider_supports_xtra)},
destradaaea8a8a62014-06-23 18:19:03 -07001933 {"native_inject_xtra_data",
1934 "([BI)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001935 reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_xtra_data)},
destradaaea8a8a62014-06-23 18:19:03 -07001936 {"native_agps_data_conn_open",
1937 "(Ljava/lang/String;I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001938 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_open)},
destradaaea8a8a62014-06-23 18:19:03 -07001939 {"native_agps_data_conn_closed",
1940 "()V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001941 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_closed)},
destradaaea8a8a62014-06-23 18:19:03 -07001942 {"native_agps_data_conn_failed",
1943 "()V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001944 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_failed)},
destradaaea8a8a62014-06-23 18:19:03 -07001945 {"native_agps_set_id",
1946 "(ILjava/lang/String;)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001947 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_set_id)},
destradaaea8a8a62014-06-23 18:19:03 -07001948 {"native_agps_set_ref_location_cellid",
1949 "(IIIII)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001950 reinterpret_cast<void *>(
1951 android_location_GnssLocationProvider_agps_set_reference_location_cellid)},
destradaaea8a8a62014-06-23 18:19:03 -07001952 {"native_set_agps_server",
1953 "(ILjava/lang/String;I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001954 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_agps_server)},
destradaaea8a8a62014-06-23 18:19:03 -07001955 {"native_send_ni_response",
1956 "(II)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001957 reinterpret_cast<void *>(android_location_GnssLocationProvider_send_ni_response)},
destradaaea8a8a62014-06-23 18:19:03 -07001958 {"native_get_internal_state",
1959 "()Ljava/lang/String;",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001960 reinterpret_cast<void *>(android_location_GnssLocationProvider_get_internal_state)},
destradaaea8a8a62014-06-23 18:19:03 -07001961 {"native_update_network_state",
1962 "(ZIZZLjava/lang/String;Ljava/lang/String;)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001963 reinterpret_cast<void *>(android_location_GnssLocationProvider_update_network_state)},
destradaaea8a8a62014-06-23 18:19:03 -07001964 {"native_is_geofence_supported",
1965 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001966 reinterpret_cast<void *>(android_location_GnssLocationProvider_is_geofence_supported)},
destradaaea8a8a62014-06-23 18:19:03 -07001967 {"native_add_geofence",
1968 "(IDDDIIII)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001969 reinterpret_cast<void *>(android_location_GnssLocationProvider_add_geofence)},
destradaaea8a8a62014-06-23 18:19:03 -07001970 {"native_remove_geofence",
1971 "(I)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001972 reinterpret_cast<void *>(android_location_GnssLocationProvider_remove_geofence)},
1973 {"native_pause_geofence", "(I)Z", reinterpret_cast<void *>(
1974 android_location_GnssLocationProvider_pause_geofence)},
destradaaea8a8a62014-06-23 18:19:03 -07001975 {"native_resume_geofence",
1976 "(II)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001977 reinterpret_cast<void *>(android_location_GnssLocationProvider_resume_geofence)},
destradaaea8a8a62014-06-23 18:19:03 -07001978 {"native_is_measurement_supported",
1979 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001980 reinterpret_cast<void *>(
1981 android_location_GnssLocationProvider_is_measurement_supported)},
destradaaea8a8a62014-06-23 18:19:03 -07001982 {"native_start_measurement_collection",
1983 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001984 reinterpret_cast<void *>(
1985 android_location_GnssLocationProvider_start_measurement_collection)},
destradaaea8a8a62014-06-23 18:19:03 -07001986 {"native_stop_measurement_collection",
1987 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001988 reinterpret_cast<void *>(
1989 android_location_GnssLocationProvider_stop_measurement_collection)},
destradaa4b3e3932014-07-21 18:01:47 -07001990 {"native_is_navigation_message_supported",
1991 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001992 reinterpret_cast<void *>(
1993 android_location_GnssLocationProvider_is_navigation_message_supported)},
destradaa4b3e3932014-07-21 18:01:47 -07001994 {"native_start_navigation_message_collection",
1995 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001996 reinterpret_cast<void *>(
1997 android_location_GnssLocationProvider_start_navigation_message_collection)},
destradaa4b3e3932014-07-21 18:01:47 -07001998 {"native_stop_navigation_message_collection",
1999 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002000 reinterpret_cast<void *>(
2001 android_location_GnssLocationProvider_stop_navigation_message_collection)},
2002 {"native_set_supl_es",
2003 "(I)Z",
2004 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_es)},
2005 {"native_set_supl_version",
2006 "(I)Z",
2007 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_version)},
2008 {"native_set_supl_mode",
2009 "(I)Z",
2010 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_mode)},
2011 {"native_set_lpp_profile",
2012 "(I)Z",
2013 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_lpp_profile)},
2014 {"native_set_gnss_pos_protocol_select",
2015 "(I)Z",
2016 reinterpret_cast<void *>(
2017 android_location_GnssLocationProvider_set_gnss_pos_protocol_select)},
2018 {"native_set_gps_lock",
2019 "(I)Z",
2020 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_gps_lock)},
2021 {"native_set_emergency_supl_pdn",
2022 "(I)Z",
2023 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_emergency_supl_pdn)},
Wyatt Rileycf879db2017-01-12 13:57:38 -08002024 {"native_get_batch_size",
2025 "()I",
2026 reinterpret_cast<void *>(android_location_GnssLocationProvider_get_batch_size)},
2027 {"native_init_batching",
2028 "()Z",
2029 reinterpret_cast<void *>(android_location_GnssLocationProvider_init_batching)},
2030 {"native_start_batch",
2031 "(JZ)Z",
2032 reinterpret_cast<void *>(android_location_GnssLocationProvider_start_batch)},
2033 {"native_flush_batch",
2034 "()V",
2035 reinterpret_cast<void *>(android_location_GnssLocationProvider_flush_batch)},
2036 {"native_stop_batch",
2037 "()Z",
2038 reinterpret_cast<void *>(android_location_GnssLocationProvider_stop_batch)},
2039 {"native_init_batching",
2040 "()Z",
2041 reinterpret_cast<void *>(android_location_GnssLocationProvider_init_batching)},
2042 {"native_cleanup_batching",
2043 "()V",
2044 reinterpret_cast<void *>(android_location_GnssLocationProvider_cleanup_batching)},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002045};
2046
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002047int register_android_server_location_GnssLocationProvider(JNIEnv* env) {
destradaaea8a8a62014-06-23 18:19:03 -07002048 return jniRegisterNativeMethods(
2049 env,
Lifu Tang30f95a72016-01-07 23:20:38 -08002050 "com/android/server/location/GnssLocationProvider",
destradaaea8a8a62014-06-23 18:19:03 -07002051 sMethods,
2052 NELEM(sMethods));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002053}
2054
2055} /* namespace android */