blob: 4cbe64d26863728ffe4e994ea24f9a0640fb482f [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
Wyatt Rileyfb840922017-11-08 15:07:58 -080021#include <android/hardware/gnss/1.1/IGnss.h>
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070022
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
Wyatt Rileyfb840922017-11-08 15:07:58 -080081using android::hardware::gnss::V1_0::GnssLocation;
82using android::hardware::gnss::V1_0::GnssLocationFlags;
83
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070084using android::hardware::gnss::V1_0::IAGnss;
85using android::hardware::gnss::V1_0::IAGnssCallback;
86using android::hardware::gnss::V1_0::IAGnssCallback;
87using android::hardware::gnss::V1_0::IAGnssRil;
88using android::hardware::gnss::V1_0::IAGnssRilCallback;
89using android::hardware::gnss::V1_0::IGnss;
Wyatt Rileycf879db2017-01-12 13:57:38 -080090using android::hardware::gnss::V1_0::IGnssBatching;
91using android::hardware::gnss::V1_0::IGnssBatchingCallback;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070092using android::hardware::gnss::V1_0::IGnssConfiguration;
93using android::hardware::gnss::V1_0::IGnssDebug;
94using android::hardware::gnss::V1_0::IGnssGeofenceCallback;
95using android::hardware::gnss::V1_0::IGnssGeofencing;
96using android::hardware::gnss::V1_0::IGnssMeasurement;
97using android::hardware::gnss::V1_0::IGnssMeasurementCallback;
98using android::hardware::gnss::V1_0::IGnssNavigationMessage;
99using android::hardware::gnss::V1_0::IGnssNavigationMessageCallback;
100using android::hardware::gnss::V1_0::IGnssNi;
101using android::hardware::gnss::V1_0::IGnssNiCallback;
102using android::hardware::gnss::V1_0::IGnssXtra;
103using android::hardware::gnss::V1_0::IGnssXtraCallback;
Wyatt Riley49d98912016-05-17 16:14:48 -0700104
Wyatt Rileyfb840922017-11-08 15:07:58 -0800105using IGnssV1_1 = android::hardware::gnss::V1_1::IGnss;
106using android::hardware::gnss::V1_1::IGnssCallback;
107
gomo25208882017-04-15 02:05:25 -0700108struct GnssDeathRecipient : virtual public hidl_death_recipient
109{
110 // hidl_death_recipient interface
111 virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override {
Wyatt Rileyfb840922017-11-08 15:07:58 -0800112 // TODO(b/37460011): implement a better death recovery mechanism without
gomo25208882017-04-15 02:05:25 -0700113 // crashing system server process as described in go//treble-gnss-death
114 LOG_ALWAYS_FATAL("Abort due to IGNSS hidl service failure,"
115 " restarting system server");
116 }
117};
Wyatt Rileyf6527ae2016-05-23 15:23:12 -0700118
gomo25208882017-04-15 02:05:25 -0700119sp<GnssDeathRecipient> gnssHalDeathRecipient = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700120sp<IGnss> gnssHal = nullptr;
Wyatt Rileyfb840922017-11-08 15:07:58 -0800121sp<IGnssV1_1> gnssHalV1_1 = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700122sp<IGnssXtra> gnssXtraIface = nullptr;
123sp<IAGnssRil> agnssRilIface = nullptr;
124sp<IGnssGeofencing> gnssGeofencingIface = nullptr;
125sp<IAGnss> agnssIface = nullptr;
Wyatt Rileycf879db2017-01-12 13:57:38 -0800126sp<IGnssBatching> gnssBatchingIface = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700127sp<IGnssDebug> gnssDebugIface = nullptr;
128sp<IGnssConfiguration> gnssConfigurationIface = nullptr;
129sp<IGnssNi> gnssNiIface = nullptr;
130sp<IGnssMeasurement> gnssMeasurementIface = nullptr;
131sp<IGnssNavigationMessage> gnssNavigationMessageIface = nullptr;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800132
Mike Lockwood8f5a8002010-04-07 09:05:26 -0400133#define WAKE_LOCK_NAME "GPS"
134
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800135namespace android {
136
Lifu Tang120480f2016-02-07 18:08:19 -0800137template<class T>
138class JavaMethodHelper {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700139 public:
140 // Helper function to call setter on a Java object.
141 static void callJavaMethod(
Lifu Tang120480f2016-02-07 18:08:19 -0800142 JNIEnv* env,
143 jclass clazz,
144 jobject object,
145 const char* method_name,
146 T value);
destradaaea8a8a62014-06-23 18:19:03 -0700147
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700148 private:
Lifu Tang120480f2016-02-07 18:08:19 -0800149 static const char *const signature_;
150};
Lifu Tange5a0e212016-01-25 18:02:17 -0800151
Lifu Tang120480f2016-02-07 18:08:19 -0800152template<class T>
153void JavaMethodHelper<T>::callJavaMethod(
154 JNIEnv* env,
155 jclass clazz,
156 jobject object,
157 const char* method_name,
158 T value) {
159 jmethodID method = env->GetMethodID(clazz, method_name, signature_);
160 env->CallVoidMethod(object, method, value);
161}
destradaaea8a8a62014-06-23 18:19:03 -0700162
Lifu Tang120480f2016-02-07 18:08:19 -0800163class JavaObject {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700164 public:
165 JavaObject(JNIEnv* env, const char* class_name);
Wyatt Rileycf879db2017-01-12 13:57:38 -0800166 JavaObject(JNIEnv* env, const char* class_name, const char * sz_arg_1);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700167 virtual ~JavaObject();
Lifu Tang120480f2016-02-07 18:08:19 -0800168
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700169 template<class T>
170 void callSetter(const char* method_name, T value);
171 template<class T>
172 void callSetter(const char* method_name, T* value, size_t size);
173 jobject get();
Lifu Tang120480f2016-02-07 18:08:19 -0800174
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700175 private:
176 JNIEnv* env_;
177 jclass clazz_;
178 jobject object_;
Lifu Tang120480f2016-02-07 18:08:19 -0800179};
180
181JavaObject::JavaObject(JNIEnv* env, const char* class_name) : env_(env) {
182 clazz_ = env_->FindClass(class_name);
183 jmethodID ctor = env->GetMethodID(clazz_, "<init>", "()V");
184 object_ = env_->NewObject(clazz_, ctor);
185}
186
Wyatt Rileycf879db2017-01-12 13:57:38 -0800187JavaObject::JavaObject(JNIEnv* env, const char* class_name, const char * sz_arg_1) : env_(env) {
188 clazz_ = env_->FindClass(class_name);
189 jmethodID ctor = env->GetMethodID(clazz_, "<init>", "(Ljava/lang/String;)V");
190 object_ = env_->NewObject(clazz_, ctor, env->NewStringUTF(sz_arg_1));
191}
192
Lifu Tang120480f2016-02-07 18:08:19 -0800193JavaObject::~JavaObject() {
194 env_->DeleteLocalRef(clazz_);
195}
196
197template<class T>
198void JavaObject::callSetter(const char* method_name, T value) {
199 JavaMethodHelper<T>::callJavaMethod(
200 env_, clazz_, object_, method_name, value);
201}
202
203template<>
204void JavaObject::callSetter(
205 const char* method_name, uint8_t* value, size_t size) {
206 jbyteArray array = env_->NewByteArray(size);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700207 env_->SetByteArrayRegion(array, 0, size, reinterpret_cast<jbyte*>(value));
Lifu Tang120480f2016-02-07 18:08:19 -0800208 jmethodID method = env_->GetMethodID(
209 clazz_,
210 method_name,
211 "([B)V");
212 env_->CallVoidMethod(object_, method, array);
Lifu Tangfe427f22016-10-08 02:57:53 -0700213 env_->DeleteLocalRef(array);
Lifu Tang120480f2016-02-07 18:08:19 -0800214}
215
216jobject JavaObject::get() {
217 return object_;
218}
219
220// Define Java method signatures for all known types.
Lifu Tang120480f2016-02-07 18:08:19 -0800221template<>
222const char *const JavaMethodHelper<uint8_t>::signature_ = "(B)V";
223template<>
224const char *const JavaMethodHelper<int8_t>::signature_ = "(B)V";
225template<>
226const char *const JavaMethodHelper<int16_t>::signature_ = "(S)V";
227template<>
228const char *const JavaMethodHelper<uint16_t>::signature_ = "(S)V";
229template<>
Lifu Tang9363b942016-02-16 18:07:00 -0800230const char *const JavaMethodHelper<int32_t>::signature_ = "(I)V";
231template<>
232const char *const JavaMethodHelper<uint32_t>::signature_ = "(I)V";
Lifu Tang120480f2016-02-07 18:08:19 -0800233template<>
234const char *const JavaMethodHelper<int64_t>::signature_ = "(J)V";
235template<>
236const char *const JavaMethodHelper<float>::signature_ = "(F)V";
237template<>
238const char *const JavaMethodHelper<double>::signature_ = "(D)V";
239template<>
240const char *const JavaMethodHelper<bool>::signature_ = "(Z)V";
241
242#define SET(setter, value) object.callSetter("set" # setter, (value))
Lifu Tangccb44882016-03-09 19:32:29 -0800243
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700244static inline jboolean boolToJbool(bool value) {
245 return value ? JNI_TRUE : JNI_FALSE;
246}
Lifu Tang120480f2016-02-07 18:08:19 -0800247
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700248static void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
249 if (env->ExceptionCheck()) {
250 ALOGE("An exception was thrown by callback '%s'.", methodName);
251 LOGE_EX(env);
252 env->ExceptionClear();
253 }
254}
destradaaea8a8a62014-06-23 18:19:03 -0700255
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800256class ScopedJniThreadAttach {
257public:
258 ScopedJniThreadAttach() {
259 /*
260 * attachResult will also be JNI_OK if the thead was already attached to
261 * JNI before the call to AttachCurrentThread().
262 */
263 jint attachResult = sJvm->AttachCurrentThread(&mEnv, nullptr);
264 LOG_ALWAYS_FATAL_IF(attachResult != JNI_OK, "Unable to attach thread. Error %d",
265 attachResult);
266 }
267
268 ~ScopedJniThreadAttach() {
269 jint detachResult = sJvm->DetachCurrentThread();
270 /*
271 * Return if the thread was already detached. Log error for any other
272 * failure.
273 */
274 if (detachResult == JNI_EDETACHED) {
275 return;
276 }
277
278 LOG_ALWAYS_FATAL_IF(detachResult != JNI_OK, "Unable to detach thread. Error %d",
279 detachResult);
280 }
281
282 JNIEnv* getEnv() {
283 /*
284 * Checking validity of mEnv in case the thread was detached elsewhere.
285 */
286 LOG_ALWAYS_FATAL_IF(AndroidRuntime::getJNIEnv() != mEnv);
287 return mEnv;
288 }
289
290private:
291 JNIEnv* mEnv = nullptr;
292};
293
294thread_local std::unique_ptr<ScopedJniThreadAttach> tJniThreadAttacher;
295
296static JNIEnv* getJniEnv() {
297 JNIEnv* env = AndroidRuntime::getJNIEnv();
298
299 /*
300 * If env is nullptr, the thread is not already attached to
301 * JNI. It is attached below and the destructor for ScopedJniThreadAttach
302 * will detach it on thread exit.
303 */
304 if (env == nullptr) {
305 tJniThreadAttacher.reset(new ScopedJniThreadAttach());
306 env = tJniThreadAttacher->getEnv();
307 }
308
309 return env;
310}
311
Wyatt Rileyfb840922017-11-08 15:07:58 -0800312static jobject translateLocation(JNIEnv* env, const GnssLocation& location) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800313 JavaObject object(env, "android/location/Location", "gps");
314
315 uint16_t flags = static_cast<uint32_t>(location.gnssLocationFlags);
Wyatt Rileyfb840922017-11-08 15:07:58 -0800316 if (flags & GnssLocationFlags::HAS_LAT_LONG) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800317 SET(Latitude, location.latitudeDegrees);
318 SET(Longitude, location.longitudeDegrees);
319 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800320 if (flags & GnssLocationFlags::HAS_ALTITUDE) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800321 SET(Altitude, location.altitudeMeters);
322 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800323 if (flags & GnssLocationFlags::HAS_SPEED) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800324 SET(Speed, location.speedMetersPerSec);
325 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800326 if (flags & GnssLocationFlags::HAS_BEARING) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800327 SET(Bearing, location.bearingDegrees);
328 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800329 if (flags & GnssLocationFlags::HAS_HORIZONTAL_ACCURACY) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800330 SET(Accuracy, location.horizontalAccuracyMeters);
331 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800332 if (flags & GnssLocationFlags::HAS_VERTICAL_ACCURACY) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800333 SET(VerticalAccuracyMeters, location.verticalAccuracyMeters);
334 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800335 if (flags & GnssLocationFlags::HAS_SPEED_ACCURACY) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800336 SET(SpeedAccuracyMetersPerSecond, location.speedAccuracyMetersPerSecond);
337 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800338 if (flags & GnssLocationFlags::HAS_BEARING_ACCURACY) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800339 SET(BearingAccuracyDegrees, location.bearingAccuracyDegrees);
340 }
341 SET(Time, location.timestamp);
342
343 return object.get();
344}
345
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700346/*
347 * GnssCallback class implements the callback methods for IGnss interface.
348 */
349struct GnssCallback : public IGnssCallback {
Wyatt Rileyfb840922017-11-08 15:07:58 -0800350 Return<void> gnssLocationCb(const GnssLocation& location) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700351 Return<void> gnssStatusCb(const IGnssCallback::GnssStatusValue status) override;
352 Return<void> gnssSvStatusCb(const IGnssCallback::GnssSvStatus& svStatus) override;
353 Return<void> gnssNmeaCb(int64_t timestamp, const android::hardware::hidl_string& nmea) override;
354 Return<void> gnssSetCapabilitesCb(uint32_t capabilities) override;
355 Return<void> gnssAcquireWakelockCb() override;
356 Return<void> gnssReleaseWakelockCb() override;
357 Return<void> gnssRequestTimeCb() override;
358 Return<void> gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo& info) override;
Lifu Tang38bce792016-02-24 17:17:38 -0800359
Wyatt Rileyfb840922017-11-08 15:07:58 -0800360 // New in 1.1
361 Return<void> gnssNameCb(const android::hardware::hidl_string& name) override;
362
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700363 static GnssSvInfo sGnssSvList[static_cast<uint32_t>(
364 android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)];
365 static size_t sGnssSvListSize;
366
367 static const char* sNmeaString;
368 static size_t sNmeaStringLength;
369};
370
Wyatt Rileyfb840922017-11-08 15:07:58 -0800371Return<void> GnssCallback::gnssNameCb(const android::hardware::hidl_string& name) {
372 ALOGD("%s: name=%s\n", __func__, name.c_str());
373
374 // TODO(b/38003769): build Java code to connect to below code
375 /*
376 JNIEnv* env = getJniEnv();
377 env->CallVoidMethod(mCallbacksObj, method_setGnssHardwareName, name);
378 checkAndClearExceptionFromCallback(env, __FUNCTION__);
379 */
380 return Void();
381}
382
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700383IGnssCallback::GnssSvInfo GnssCallback::sGnssSvList[static_cast<uint32_t>(
384 android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)];
385const char* GnssCallback::sNmeaString = nullptr;
386size_t GnssCallback::sNmeaStringLength = 0;
387size_t GnssCallback::sGnssSvListSize = 0;
388
Wyatt Rileyfb840922017-11-08 15:07:58 -0800389Return<void> GnssCallback::gnssLocationCb(const GnssLocation& location) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800390 JNIEnv* env = getJniEnv();
Wyatt Riley5d229832017-02-10 17:06:00 -0800391
392 jobject jLocation = translateLocation(env, location);
393 bool hasLatLong = (static_cast<uint32_t>(location.gnssLocationFlags) &
Wyatt Rileyfb840922017-11-08 15:07:58 -0800394 GnssLocationFlags::HAS_LAT_LONG) != 0;
Wyatt Riley5d229832017-02-10 17:06:00 -0800395
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700396 env->CallVoidMethod(mCallbacksObj,
397 method_reportLocation,
Wyatt Riley5d229832017-02-10 17:06:00 -0800398 boolToJbool(hasLatLong),
399 jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700400 checkAndClearExceptionFromCallback(env, __FUNCTION__);
401 return Void();
402}
403
404Return<void> GnssCallback::gnssStatusCb(const IGnssCallback::GnssStatusValue status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800405 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700406 env->CallVoidMethod(mCallbacksObj, method_reportStatus, status);
407 checkAndClearExceptionFromCallback(env, __FUNCTION__);
408 return Void();
409}
410
411Return<void> GnssCallback::gnssSvStatusCb(const IGnssCallback::GnssSvStatus& svStatus) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800412 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700413
414 sGnssSvListSize = svStatus.numSvs;
415 if (sGnssSvListSize > static_cast<uint32_t>(
416 android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)) {
417 ALOGD("Too many satellites %zd. Clamps to %u.", sGnssSvListSize,
418 static_cast<uint32_t>(android::hardware::gnss::V1_0::GnssMax::SVS_COUNT));
419 sGnssSvListSize = static_cast<uint32_t>(android::hardware::gnss::V1_0::GnssMax::SVS_COUNT);
Lifu Tang38bce792016-02-24 17:17:38 -0800420 }
421
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700422 // Copy GNSS SV info into sGnssSvList, if any.
423 if (svStatus.numSvs > 0) {
424 memcpy(sGnssSvList, svStatus.gnssSvList.data(), sizeof(GnssSvInfo) * sGnssSvListSize);
Lifu Tang9363b942016-02-16 18:07:00 -0800425 }
destradaaea8a8a62014-06-23 18:19:03 -0700426
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700427 env->CallVoidMethod(mCallbacksObj, method_reportSvStatus);
428 checkAndClearExceptionFromCallback(env, __FUNCTION__);
429 return Void();
destradaaea8a8a62014-06-23 18:19:03 -0700430}
431
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700432Return<void> GnssCallback::gnssNmeaCb(
433 int64_t timestamp, const ::android::hardware::hidl_string& nmea) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800434 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700435 /*
436 * The Java code will call back to read these values.
437 * We do this to avoid creating unnecessary String objects.
438 */
439 sNmeaString = nmea.c_str();
440 sNmeaStringLength = nmea.size();
441
442 env->CallVoidMethod(mCallbacksObj, method_reportNmea, timestamp);
443 checkAndClearExceptionFromCallback(env, __FUNCTION__);
444 return Void();
445}
446
447Return<void> GnssCallback::gnssSetCapabilitesCb(uint32_t capabilities) {
448 ALOGD("%s: %du\n", __func__, capabilities);
449
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800450 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700451 env->CallVoidMethod(mCallbacksObj, method_setEngineCapabilities, capabilities);
452 checkAndClearExceptionFromCallback(env, __FUNCTION__);
453 return Void();
454}
455
456Return<void> GnssCallback::gnssAcquireWakelockCb() {
457 acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
458 return Void();
459}
460
461Return<void> GnssCallback::gnssReleaseWakelockCb() {
462 release_wake_lock(WAKE_LOCK_NAME);
463 return Void();
464}
465
466Return<void> GnssCallback::gnssRequestTimeCb() {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800467 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700468 env->CallVoidMethod(mCallbacksObj, method_requestUtcTime);
469 checkAndClearExceptionFromCallback(env, __FUNCTION__);
470 return Void();
471}
472
473Return<void> GnssCallback::gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo& info) {
474 ALOGD("%s: yearOfHw=%d\n", __func__, info.yearOfHw);
475
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800476 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700477 env->CallVoidMethod(mCallbacksObj, method_setGnssYearOfHardware,
478 info.yearOfHw);
479 checkAndClearExceptionFromCallback(env, __FUNCTION__);
480 return Void();
481}
482
483class GnssXtraCallback : public IGnssXtraCallback {
484 Return<void> downloadRequestCb() override;
485};
486
487/*
488 * GnssXtraCallback class implements the callback methods for the IGnssXtra
489 * interface.
490 */
491Return<void> GnssXtraCallback::downloadRequestCb() {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800492 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700493 env->CallVoidMethod(mCallbacksObj, method_xtraDownloadRequest);
494 checkAndClearExceptionFromCallback(env, __FUNCTION__);
495 return Void();
496}
497
498/*
499 * GnssGeofenceCallback class implements the callback methods for the
500 * IGnssGeofence interface.
501 */
502struct GnssGeofenceCallback : public IGnssGeofenceCallback {
503 // Methods from ::android::hardware::gps::V1_0::IGnssGeofenceCallback follow.
504 Return<void> gnssGeofenceTransitionCb(
505 int32_t geofenceId,
Wyatt Rileyfb840922017-11-08 15:07:58 -0800506 const GnssLocation& location,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700507 GeofenceTransition transition,
508 hardware::gnss::V1_0::GnssUtcTime timestamp) override;
509 Return<void> gnssGeofenceStatusCb(
510 GeofenceAvailability status,
Wyatt Rileyfb840922017-11-08 15:07:58 -0800511 const GnssLocation& location) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700512 Return<void> gnssGeofenceAddCb(int32_t geofenceId,
513 GeofenceStatus status) override;
514 Return<void> gnssGeofenceRemoveCb(int32_t geofenceId,
515 GeofenceStatus status) override;
516 Return<void> gnssGeofencePauseCb(int32_t geofenceId,
517 GeofenceStatus status) override;
518 Return<void> gnssGeofenceResumeCb(int32_t geofenceId,
519 GeofenceStatus status) override;
520};
521
522Return<void> GnssGeofenceCallback::gnssGeofenceTransitionCb(
523 int32_t geofenceId,
Wyatt Rileyfb840922017-11-08 15:07:58 -0800524 const GnssLocation& location,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700525 GeofenceTransition transition,
526 hardware::gnss::V1_0::GnssUtcTime timestamp) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800527 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700528
Wyatt Riley5d229832017-02-10 17:06:00 -0800529 jobject jLocation = translateLocation(env, location);
530
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700531 env->CallVoidMethod(mCallbacksObj,
532 method_reportGeofenceTransition,
533 geofenceId,
Wyatt Riley5d229832017-02-10 17:06:00 -0800534 jLocation,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700535 transition,
536 timestamp);
537
538 checkAndClearExceptionFromCallback(env, __FUNCTION__);
539 return Void();
540}
541
542Return<void> GnssGeofenceCallback::gnssGeofenceStatusCb(
543 GeofenceAvailability status,
Wyatt Rileyfb840922017-11-08 15:07:58 -0800544 const GnssLocation& location) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800545 JNIEnv* env = getJniEnv();
Wyatt Riley5d229832017-02-10 17:06:00 -0800546
547 jobject jLocation = translateLocation(env, location);
548
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700549 env->CallVoidMethod(mCallbacksObj,
550 method_reportGeofenceStatus,
551 status,
Wyatt Riley5d229832017-02-10 17:06:00 -0800552 jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700553 checkAndClearExceptionFromCallback(env, __FUNCTION__);
554 return Void();
555}
556
557Return<void> GnssGeofenceCallback::gnssGeofenceAddCb(int32_t geofenceId,
558 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800559 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700560 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
561 ALOGE("%s: Error in adding a Geofence: %d\n", __func__, status);
562 }
563
564 env->CallVoidMethod(mCallbacksObj,
565 method_reportGeofenceAddStatus,
566 geofenceId,
567 status);
568 checkAndClearExceptionFromCallback(env, __FUNCTION__);
569 return Void();
570}
571
572Return<void> GnssGeofenceCallback::gnssGeofenceRemoveCb(int32_t geofenceId,
573 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800574 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700575 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
576 ALOGE("%s: Error in removing a Geofence: %d\n", __func__, status);
577 }
578
579 env->CallVoidMethod(mCallbacksObj,
580 method_reportGeofenceRemoveStatus,
581 geofenceId, status);
582 checkAndClearExceptionFromCallback(env, __FUNCTION__);
583 return Void();
584}
585
586Return<void> GnssGeofenceCallback::gnssGeofencePauseCb(int32_t geofenceId,
587 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800588 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700589 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
590 ALOGE("%s: Error in pausing Geofence: %d\n", __func__, status);
591 }
592
593 env->CallVoidMethod(mCallbacksObj,
594 method_reportGeofencePauseStatus,
595 geofenceId, status);
596 checkAndClearExceptionFromCallback(env, __FUNCTION__);
597 return Void();
598}
599
600Return<void> GnssGeofenceCallback::gnssGeofenceResumeCb(int32_t geofenceId,
601 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800602 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700603 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
604 ALOGE("%s: Error in resuming Geofence: %d\n", __func__, status);
605 }
606
607 env->CallVoidMethod(mCallbacksObj,
608 method_reportGeofenceResumeStatus,
609 geofenceId, status);
610 checkAndClearExceptionFromCallback(env, __FUNCTION__);
611 return Void();
612}
613
614/*
615 * GnssNavigationMessageCallback interface implements the callback methods
616 * required by the IGnssNavigationMessage interface.
617 */
618struct GnssNavigationMessageCallback : public IGnssNavigationMessageCallback {
619 /*
620 * Methods from ::android::hardware::gps::V1_0::IGnssNavigationMessageCallback
621 * follow.
622 */
623 Return<void> gnssNavigationMessageCb(
624 const IGnssNavigationMessageCallback::GnssNavigationMessage& message) override;
625};
626
627Return<void> GnssNavigationMessageCallback::gnssNavigationMessageCb(
628 const IGnssNavigationMessageCallback::GnssNavigationMessage& message) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800629 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700630
631 size_t dataLength = message.data.size();
632
633 std::vector<uint8_t> navigationData = message.data;
634 uint8_t* data = &(navigationData[0]);
635 if (dataLength == 0 || data == NULL) {
636 ALOGE("Invalid Navigation Message found: data=%p, length=%zd", data,
637 dataLength);
638 return Void();
639 }
640
641 JavaObject object(env, "android/location/GnssNavigationMessage");
642 SET(Type, static_cast<int32_t>(message.type));
643 SET(Svid, static_cast<int32_t>(message.svid));
644 SET(MessageId, static_cast<int32_t>(message.messageId));
645 SET(SubmessageId, static_cast<int32_t>(message.submessageId));
646 object.callSetter("setData", data, dataLength);
647 SET(Status, static_cast<int32_t>(message.status));
648
649 jobject navigationMessage = object.get();
650 env->CallVoidMethod(mCallbacksObj,
651 method_reportNavigationMessages,
652 navigationMessage);
Wyatt Rileycf879db2017-01-12 13:57:38 -0800653 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700654 env->DeleteLocalRef(navigationMessage);
655 return Void();
656}
657
658/*
659 * GnssMeasurementCallback implements the callback methods required for the
660 * GnssMeasurement interface.
661 */
662struct GnssMeasurementCallback : public IGnssMeasurementCallback {
663 Return<void> GnssMeasurementCb(const IGnssMeasurementCallback::GnssData& data);
664 private:
665 jobject translateGnssMeasurement(
666 JNIEnv* env, const IGnssMeasurementCallback::GnssMeasurement* measurement);
667 jobject translateGnssClock(
668 JNIEnv* env, const IGnssMeasurementCallback::GnssClock* clock);
669 jobjectArray translateGnssMeasurements(
670 JNIEnv* env,
671 const IGnssMeasurementCallback::GnssMeasurement* measurements,
672 size_t count);
673 void setMeasurementData(JNIEnv* env, jobject clock, jobjectArray measurementArray);
674};
675
676
677Return<void> GnssMeasurementCallback::GnssMeasurementCb(
678 const IGnssMeasurementCallback::GnssData& data) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800679 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700680
681 jobject clock;
682 jobjectArray measurementArray;
683
684 clock = translateGnssClock(env, &data.clock);
685 measurementArray = translateGnssMeasurements(
686 env, data.measurements.data(), data.measurementCount);
687 setMeasurementData(env, clock, measurementArray);
688
689 env->DeleteLocalRef(clock);
690 env->DeleteLocalRef(measurementArray);
691 return Void();
692}
693
694jobject GnssMeasurementCallback::translateGnssMeasurement(
695 JNIEnv* env, const IGnssMeasurementCallback::GnssMeasurement* measurement) {
Lifu Tang120480f2016-02-07 18:08:19 -0800696 JavaObject object(env, "android/location/GnssMeasurement");
Lifu Tang120480f2016-02-07 18:08:19 -0800697
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700698 uint32_t flags = static_cast<uint32_t>(measurement->flags);
Mike Cailean96635bd2016-03-24 19:34:16 -0700699
700 SET(Svid, static_cast<int32_t>(measurement->svid));
Lifu Tang76a620f2016-02-26 19:53:01 -0800701 SET(ConstellationType, static_cast<int32_t>(measurement->constellation));
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700702 SET(TimeOffsetNanos, measurement->timeOffsetNs);
Lifu Tang76a620f2016-02-26 19:53:01 -0800703 SET(State, static_cast<int32_t>(measurement->state));
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700704 SET(ReceivedSvTimeNanos, measurement->receivedSvTimeInNs);
Lifu Tang76a620f2016-02-26 19:53:01 -0800705 SET(ReceivedSvTimeUncertaintyNanos,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700706 measurement->receivedSvTimeUncertaintyInNs);
707 SET(Cn0DbHz, measurement->cN0DbHz);
708 SET(PseudorangeRateMetersPerSecond, measurement->pseudorangeRateMps);
Lifu Tang76a620f2016-02-26 19:53:01 -0800709 SET(PseudorangeRateUncertaintyMetersPerSecond,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700710 measurement->pseudorangeRateUncertaintyMps);
Lifu Tang76a620f2016-02-26 19:53:01 -0800711 SET(AccumulatedDeltaRangeState,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700712 (static_cast<int32_t>(measurement->accumulatedDeltaRangeState)));
713 SET(AccumulatedDeltaRangeMeters, measurement->accumulatedDeltaRangeM);
Lifu Tang76a620f2016-02-26 19:53:01 -0800714 SET(AccumulatedDeltaRangeUncertaintyMeters,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700715 measurement->accumulatedDeltaRangeUncertaintyM);
716
717 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_FREQUENCY)) {
718 SET(CarrierFrequencyHz, measurement->carrierFrequencyHz);
719 }
720
721 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_PHASE)) {
722 SET(CarrierPhase, measurement->carrierPhase);
723 }
724
725 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_PHASE_UNCERTAINTY)) {
726 SET(CarrierPhaseUncertainty, measurement->carrierPhaseUncertainty);
727 }
728
729 SET(MultipathIndicator, static_cast<int32_t>(measurement->multipathIndicator));
730
731 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_SNR)) {
732 SET(SnrInDb, measurement->snrDb);
733 }
Lifu Tang120480f2016-02-07 18:08:19 -0800734
gomo4402af62017-01-11 13:20:13 -0800735 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_AUTOMATIC_GAIN_CONTROL)) {
gomo127ba322017-01-15 20:26:48 -0800736 SET(AutomaticGainControlLevelInDb, measurement->agcLevelDb);
gomo4402af62017-01-11 13:20:13 -0800737 }
738
Lifu Tang120480f2016-02-07 18:08:19 -0800739 return object.get();
740}
741
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700742jobject GnssMeasurementCallback::translateGnssClock(
743 JNIEnv* env, const IGnssMeasurementCallback::GnssClock* clock) {
744 JavaObject object(env, "android/location/GnssClock");
745
746 uint32_t flags = static_cast<uint32_t>(clock->gnssClockFlags);
747 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_LEAP_SECOND)) {
748 SET(LeapSecond, static_cast<int32_t>(clock->leapSecond));
749 }
750
751 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_TIME_UNCERTAINTY)) {
752 SET(TimeUncertaintyNanos, clock->timeUncertaintyNs);
753 }
754
755 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_FULL_BIAS)) {
756 SET(FullBiasNanos, clock->fullBiasNs);
757 }
758
759 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS)) {
760 SET(BiasNanos, clock->biasNs);
761 }
762
763 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS_UNCERTAINTY)) {
764 SET(BiasUncertaintyNanos, clock->biasUncertaintyNs);
765 }
766
767 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT)) {
768 SET(DriftNanosPerSecond, clock->driftNsps);
769 }
770
771 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT_UNCERTAINTY)) {
772 SET(DriftUncertaintyNanosPerSecond, clock->driftUncertaintyNsps);
773 }
774
775 SET(TimeNanos, clock->timeNs);
776 SET(HardwareClockDiscontinuityCount, clock->hwClockDiscontinuityCount);
777
778 return object.get();
779}
780
781jobjectArray GnssMeasurementCallback::translateGnssMeasurements(JNIEnv* env,
782 const IGnssMeasurementCallback::GnssMeasurement*
783 measurements, size_t count) {
Lifu Tang120480f2016-02-07 18:08:19 -0800784 if (count == 0) {
destradaaea8a8a62014-06-23 18:19:03 -0700785 return NULL;
786 }
787
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700788 jclass gnssMeasurementClass = env->FindClass("android/location/GnssMeasurement");
Lifu Tang818aa2c2016-02-01 01:52:00 -0800789 jobjectArray gnssMeasurementArray = env->NewObjectArray(
Lifu Tang120480f2016-02-07 18:08:19 -0800790 count,
Lifu Tang818aa2c2016-02-01 01:52:00 -0800791 gnssMeasurementClass,
destradaaea8a8a62014-06-23 18:19:03 -0700792 NULL /* initialElement */);
793
Lifu Tang120480f2016-02-07 18:08:19 -0800794 for (uint16_t i = 0; i < count; ++i) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700795 jobject gnssMeasurement = translateGnssMeasurement(
Lifu Tange5a0e212016-01-25 18:02:17 -0800796 env,
Lifu Tang120480f2016-02-07 18:08:19 -0800797 &measurements[i]);
Lifu Tang818aa2c2016-02-01 01:52:00 -0800798 env->SetObjectArrayElement(gnssMeasurementArray, i, gnssMeasurement);
799 env->DeleteLocalRef(gnssMeasurement);
destradaaea8a8a62014-06-23 18:19:03 -0700800 }
801
Lifu Tang818aa2c2016-02-01 01:52:00 -0800802 env->DeleteLocalRef(gnssMeasurementClass);
803 return gnssMeasurementArray;
destradaaea8a8a62014-06-23 18:19:03 -0700804}
805
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700806void GnssMeasurementCallback::setMeasurementData(JNIEnv* env, jobject clock,
807 jobjectArray measurementArray) {
808 jclass gnssMeasurementsEventClass =
809 env->FindClass("android/location/GnssMeasurementsEvent");
810 jmethodID gnssMeasurementsEventCtor =
811 env->GetMethodID(
812 gnssMeasurementsEventClass,
813 "<init>",
814 "(Landroid/location/GnssClock;[Landroid/location/GnssMeasurement;)V");
Lifu Tange5a0e212016-01-25 18:02:17 -0800815
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700816 jobject gnssMeasurementsEvent = env->NewObject(gnssMeasurementsEventClass,
817 gnssMeasurementsEventCtor,
818 clock,
819 measurementArray);
Lifu Tang120480f2016-02-07 18:08:19 -0800820
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700821 env->CallVoidMethod(mCallbacksObj, method_reportMeasurementData,
822 gnssMeasurementsEvent);
Lifu Tange5a0e212016-01-25 18:02:17 -0800823 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Lifu Tang818aa2c2016-02-01 01:52:00 -0800824 env->DeleteLocalRef(gnssMeasurementsEventClass);
825 env->DeleteLocalRef(gnssMeasurementsEvent);
destradaaea8a8a62014-06-23 18:19:03 -0700826}
827
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700828/*
829 * GnssNiCallback implements callback methods required by the IGnssNi interface.
830 */
831struct GnssNiCallback : public IGnssNiCallback {
832 Return<void> niNotifyCb(const IGnssNiCallback::GnssNiNotification& notification)
833 override;
destradaaea8a8a62014-06-23 18:19:03 -0700834};
835
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700836Return<void> GnssNiCallback::niNotifyCb(
837 const IGnssNiCallback::GnssNiNotification& notification) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800838 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700839 jstring requestorId = env->NewStringUTF(notification.requestorId.c_str());
840 jstring text = env->NewStringUTF(notification.notificationMessage.c_str());
841
842 if (requestorId && text) {
843 env->CallVoidMethod(mCallbacksObj, method_reportNiNotification,
844 notification.notificationId, notification.niType,
845 notification.notifyFlags, notification.timeoutSec,
846 notification.defaultResponse, requestorId, text,
847 notification.requestorIdEncoding,
848 notification.notificationIdEncoding);
849 } else {
850 ALOGE("%s: OOM Error\n", __func__);
851 }
852
853 if (requestorId) {
854 env->DeleteLocalRef(requestorId);
855 }
856
857 if (text) {
858 env->DeleteLocalRef(text);
859 }
860 checkAndClearExceptionFromCallback(env, __FUNCTION__);
861 return Void();
862}
863
864/*
865 * AGnssCallback implements callback methods required by the IAGnss interface.
866 */
867struct AGnssCallback : public IAGnssCallback {
868 // Methods from ::android::hardware::gps::V1_0::IAGnssCallback follow.
869 Return<void> agnssStatusIpV6Cb(
870 const IAGnssCallback::AGnssStatusIpV6& agps_status) override;
871
872 Return<void> agnssStatusIpV4Cb(
873 const IAGnssCallback::AGnssStatusIpV4& agps_status) override;
874 private:
875 jbyteArray convertToIpV4(uint32_t ip);
876};
877
878Return<void> AGnssCallback::agnssStatusIpV6Cb(
879 const IAGnssCallback::AGnssStatusIpV6& agps_status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800880 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700881 jbyteArray byteArray = NULL;
882 bool isSupported = false;
883
884 byteArray = env->NewByteArray(16);
885 if (byteArray != NULL) {
886 env->SetByteArrayRegion(byteArray, 0, 16,
887 (const jbyte*)(agps_status.ipV6Addr.data()));
888 isSupported = true;
889 } else {
890 ALOGE("Unable to allocate byte array for IPv6 address.");
891 }
892
893 IF_ALOGD() {
894 // log the IP for reference in case there is a bogus value pushed by HAL
895 char str[INET6_ADDRSTRLEN];
896 inet_ntop(AF_INET6, agps_status.ipV6Addr.data(), str, INET6_ADDRSTRLEN);
897 ALOGD("AGPS IP is v6: %s", str);
898 }
899
900 jsize byteArrayLength = byteArray != NULL ? env->GetArrayLength(byteArray) : 0;
901 ALOGV("Passing AGPS IP addr: size %d", byteArrayLength);
902 env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus,
903 agps_status.type, agps_status.status, byteArray);
904
905 checkAndClearExceptionFromCallback(env, __FUNCTION__);
906
907 if (byteArray) {
908 env->DeleteLocalRef(byteArray);
909 }
910
911 return Void();
912}
913
914Return<void> AGnssCallback::agnssStatusIpV4Cb(
915 const IAGnssCallback::AGnssStatusIpV4& agps_status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800916 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700917 jbyteArray byteArray = NULL;
918
919 uint32_t ipAddr = agps_status.ipV4Addr;
920 byteArray = convertToIpV4(ipAddr);
921
922 IF_ALOGD() {
923 /*
924 * log the IP for reference in case there is a bogus value pushed by
925 * HAL.
926 */
927 char str[INET_ADDRSTRLEN];
928 inet_ntop(AF_INET, &ipAddr, str, INET_ADDRSTRLEN);
929 ALOGD("AGPS IP is v4: %s", str);
930 }
931
932 jsize byteArrayLength =
933 byteArray != NULL ? env->GetArrayLength(byteArray) : 0;
934 ALOGV("Passing AGPS IP addr: size %d", byteArrayLength);
935 env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus,
936 agps_status.type, agps_status.status, byteArray);
937
938 checkAndClearExceptionFromCallback(env, __FUNCTION__);
939
940 if (byteArray) {
941 env->DeleteLocalRef(byteArray);
942 }
943 return Void();
944}
945
946jbyteArray AGnssCallback::convertToIpV4(uint32_t ip) {
947 if (INADDR_NONE == ip) {
948 return NULL;
949 }
950
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800951 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700952 jbyteArray byteArray = env->NewByteArray(4);
953 if (byteArray == NULL) {
954 ALOGE("Unable to allocate byte array for IPv4 address");
955 return NULL;
956 }
957
958 jbyte ipv4[4];
959 ALOGV("Converting IPv4 address byte array (net_order) %x", ip);
960 memcpy(ipv4, &ip, sizeof(ipv4));
961 env->SetByteArrayRegion(byteArray, 0, 4, (const jbyte*)ipv4);
962 return byteArray;
963}
964
965/*
966 * AGnssRilCallback implements the callback methods required by the AGnssRil
967 * interface.
968 */
969struct AGnssRilCallback : IAGnssRilCallback {
Hridya Valsarajub39eb402017-01-11 08:07:40 -0800970 Return<void> requestSetIdCb(uint32_t setIdFlag) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700971 Return<void> requestRefLocCb() override;
972};
973
Hridya Valsarajub39eb402017-01-11 08:07:40 -0800974Return<void> AGnssRilCallback::requestSetIdCb(uint32_t setIdFlag) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800975 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700976 env->CallVoidMethod(mCallbacksObj, method_requestSetID, setIdFlag);
977 checkAndClearExceptionFromCallback(env, __FUNCTION__);
978 return Void();
979}
980
981Return<void> AGnssRilCallback::requestRefLocCb() {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800982 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700983 env->CallVoidMethod(mCallbacksObj, method_requestRefLocation);
984 checkAndClearExceptionFromCallback(env, __FUNCTION__);
985 return Void();
986}
987
Wyatt Rileycf879db2017-01-12 13:57:38 -0800988/*
989 * GnssBatchingCallback interface implements the callback methods
990 * required by the IGnssBatching interface.
991 */
992struct GnssBatchingCallback : public IGnssBatchingCallback {
993 /*
994 * Methods from ::android::hardware::gps::V1_0::IGnssBatchingCallback
995 * follow.
996 */
997 Return<void> gnssLocationBatchCb(
Wyatt Rileyfb840922017-11-08 15:07:58 -0800998 const ::android::hardware::hidl_vec<GnssLocation> & locations)
Wyatt Rileycf879db2017-01-12 13:57:38 -0800999 override;
Wyatt Rileycf879db2017-01-12 13:57:38 -08001000};
1001
1002Return<void> GnssBatchingCallback::gnssLocationBatchCb(
Wyatt Rileyfb840922017-11-08 15:07:58 -08001003 const ::android::hardware::hidl_vec<GnssLocation> & locations) {
Wyatt Rileycf879db2017-01-12 13:57:38 -08001004 JNIEnv* env = getJniEnv();
1005
1006 jobjectArray jLocations = env->NewObjectArray(locations.size(),
1007 env->FindClass("android/location/Location"), nullptr);
1008
1009 for (uint16_t i = 0; i < locations.size(); ++i) {
Wyatt Riley5d229832017-02-10 17:06:00 -08001010 jobject jLocation = translateLocation(env, locations[i]);
Wyatt Rileycf879db2017-01-12 13:57:38 -08001011 env->SetObjectArrayElement(jLocations, i, jLocation);
1012 env->DeleteLocalRef(jLocation);
1013 }
1014
1015 env->CallVoidMethod(mCallbacksObj, method_reportLocationBatch, jLocations);
1016 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1017
1018 env->DeleteLocalRef(jLocations);
1019
1020 return Void();
1021}
1022
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001023static void android_location_GnssLocationProvider_class_init_native(JNIEnv* env, jclass clazz) {
Wyatt Riley5d229832017-02-10 17:06:00 -08001024 method_reportLocation = env->GetMethodID(clazz, "reportLocation",
1025 "(ZLandroid/location/Location;)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001026 method_reportStatus = env->GetMethodID(clazz, "reportStatus", "(I)V");
1027 method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "()V");
1028 method_reportAGpsStatus = env->GetMethodID(clazz, "reportAGpsStatus", "(II[B)V");
1029 method_reportNmea = env->GetMethodID(clazz, "reportNmea", "(J)V");
1030 method_setEngineCapabilities = env->GetMethodID(clazz, "setEngineCapabilities", "(I)V");
1031 method_setGnssYearOfHardware = env->GetMethodID(clazz, "setGnssYearOfHardware", "(I)V");
1032 method_xtraDownloadRequest = env->GetMethodID(clazz, "xtraDownloadRequest", "()V");
1033 method_reportNiNotification = env->GetMethodID(clazz, "reportNiNotification",
1034 "(IIIIILjava/lang/String;Ljava/lang/String;II)V");
1035 method_requestRefLocation = env->GetMethodID(clazz, "requestRefLocation", "()V");
1036 method_requestSetID = env->GetMethodID(clazz, "requestSetID", "(I)V");
1037 method_requestUtcTime = env->GetMethodID(clazz, "requestUtcTime", "()V");
1038 method_reportGeofenceTransition = env->GetMethodID(clazz, "reportGeofenceTransition",
Wyatt Riley5d229832017-02-10 17:06:00 -08001039 "(ILandroid/location/Location;IJ)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001040 method_reportGeofenceStatus = env->GetMethodID(clazz, "reportGeofenceStatus",
Wyatt Riley5d229832017-02-10 17:06:00 -08001041 "(ILandroid/location/Location;)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001042 method_reportGeofenceAddStatus = env->GetMethodID(clazz, "reportGeofenceAddStatus",
1043 "(II)V");
1044 method_reportGeofenceRemoveStatus = env->GetMethodID(clazz, "reportGeofenceRemoveStatus",
1045 "(II)V");
1046 method_reportGeofenceResumeStatus = env->GetMethodID(clazz, "reportGeofenceResumeStatus",
1047 "(II)V");
1048 method_reportGeofencePauseStatus = env->GetMethodID(clazz, "reportGeofencePauseStatus",
1049 "(II)V");
1050 method_reportMeasurementData = env->GetMethodID(
1051 clazz,
1052 "reportMeasurementData",
1053 "(Landroid/location/GnssMeasurementsEvent;)V");
1054 method_reportNavigationMessages = env->GetMethodID(
1055 clazz,
1056 "reportNavigationMessage",
1057 "(Landroid/location/GnssNavigationMessage;)V");
Wyatt Rileycf879db2017-01-12 13:57:38 -08001058 method_reportLocationBatch = env->GetMethodID(
1059 clazz,
1060 "reportLocationBatch",
1061 "([Landroid/location/Location;)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001062
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001063 /*
1064 * Save a pointer to JVM.
1065 */
1066 jint jvmStatus = env->GetJavaVM(&sJvm);
1067 if (jvmStatus != JNI_OK) {
1068 LOG_ALWAYS_FATAL("Unable to get Java VM. Error: %d", jvmStatus);
1069 }
1070
Wyatt Rileyfb840922017-11-08 15:07:58 -08001071 gnssHal = gnssHalV1_1 = IGnssV1_1::getService();
1072
1073 if (gnssHal == nullptr) {
1074 ALOGD("gnssHal 1.1 was null, trying 1.0");
1075 gnssHal = IGnss::getService();
1076 }
1077
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001078 if (gnssHal != nullptr) {
gomo25208882017-04-15 02:05:25 -07001079 gnssHalDeathRecipient = new GnssDeathRecipient();
1080 hardware::Return<bool> linked = gnssHal->linkToDeath(
1081 gnssHalDeathRecipient, /*cookie*/ 0);
1082 if (!linked.isOk()) {
1083 ALOGE("Transaction error in linking to GnssHAL death: %s",
1084 linked.description().c_str());
1085 } else if (!linked) {
1086 ALOGW("Unable to link to GnssHal death notifications");
1087 } else {
1088 ALOGD("Link to death notification successful");
1089 }
1090
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001091 auto gnssXtra = gnssHal->getExtensionXtra();
1092 if (!gnssXtra.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001093 ALOGD("Unable to get a handle to Xtra");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001094 } else {
1095 gnssXtraIface = gnssXtra;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001096 }
1097
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001098 auto gnssRil = gnssHal->getExtensionAGnssRil();
1099 if (!gnssRil.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001100 ALOGD("Unable to get a handle to AGnssRil");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001101 } else {
1102 agnssRilIface = gnssRil;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001103 }
1104
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001105 auto gnssAgnss = gnssHal->getExtensionAGnss();
1106 if (!gnssAgnss.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001107 ALOGD("Unable to get a handle to AGnss");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001108 } else {
1109 agnssIface = gnssAgnss;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001110 }
1111
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001112 auto gnssNavigationMessage = gnssHal->getExtensionGnssNavigationMessage();
1113 if (!gnssNavigationMessage.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001114 ALOGD("Unable to get a handle to GnssNavigationMessage");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001115 } else {
1116 gnssNavigationMessageIface = gnssNavigationMessage;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001117 }
1118
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001119 auto gnssMeasurement = gnssHal->getExtensionGnssMeasurement();
1120 if (!gnssMeasurement.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001121 ALOGD("Unable to get a handle to GnssMeasurement");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001122 } else {
1123 gnssMeasurementIface = gnssMeasurement;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001124 }
1125
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001126 auto gnssDebug = gnssHal->getExtensionGnssDebug();
1127 if (!gnssDebug.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001128 ALOGD("Unable to get a handle to GnssDebug");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001129 } else {
1130 gnssDebugIface = gnssDebug;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001131 }
1132
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001133 auto gnssNi = gnssHal->getExtensionGnssNi();
1134 if (!gnssNi.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001135 ALOGD("Unable to get a handle to GnssNi");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001136 } else {
1137 gnssNiIface = gnssNi;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001138 }
1139
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001140 auto gnssConfiguration = gnssHal->getExtensionGnssConfiguration();
1141 if (!gnssConfiguration.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001142 ALOGD("Unable to get a handle to GnssConfiguration");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001143 } else {
1144 gnssConfigurationIface = gnssConfiguration;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001145 }
1146
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001147 auto gnssGeofencing = gnssHal->getExtensionGnssGeofencing();
1148 if (!gnssGeofencing.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001149 ALOGD("Unable to get a handle to GnssGeofencing");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001150 } else {
1151 gnssGeofencingIface = gnssGeofencing;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001152 }
Wyatt Rileycf879db2017-01-12 13:57:38 -08001153
1154 auto gnssBatching = gnssHal->getExtensionGnssBatching();
1155 if (!gnssBatching.isOk()) {
1156 ALOGD("Unable to get a handle to gnssBatching");
1157 } else {
1158 gnssBatchingIface = gnssBatching;
1159 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001160 } else {
1161 ALOGE("Unable to get GPS service\n");
1162 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001163}
1164
1165static jboolean android_location_GnssLocationProvider_is_supported(
1166 JNIEnv* /* env */, jclass /* clazz */) {
1167 return (gnssHal != nullptr) ? JNI_TRUE : JNI_FALSE;
1168}
1169
1170static jboolean android_location_GnssLocationProvider_is_agps_ril_supported(
1171 JNIEnv* /* env */, jclass /* clazz */) {
1172 return (agnssRilIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1173}
1174
1175static jboolean android_location_gpsLocationProvider_is_gnss_configuration_supported(
1176 JNIEnv* /* env */, jclass /* jclazz */) {
1177 return (gnssConfigurationIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1178}
1179
1180static jboolean android_location_GnssLocationProvider_init(JNIEnv* env, jobject obj) {
1181 /*
1182 * This must be set before calling into the HAL library.
1183 */
1184 if (!mCallbacksObj)
1185 mCallbacksObj = env->NewGlobalRef(obj);
1186
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001187 /*
1188 * Fail if the main interface fails to initialize
1189 */
1190 if (gnssHal == nullptr) {
1191 ALOGE("Unable to Initialize GNSS HAL\n");
1192 return JNI_FALSE;
1193 }
1194
Wyatt Rileyfb840922017-11-08 15:07:58 -08001195 sp<IGnssCallback> gnssCbIface = new GnssCallback();
1196
1197 Return<bool> result = false;
1198 if (gnssHalV1_1 != nullptr) {
1199 result = gnssHalV1_1->setCallback_1_1(gnssCbIface);
1200 } else {
1201 result = gnssHal->setCallback(gnssCbIface);
1202 }
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001203 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001204 ALOGE("SetCallback for Gnss Interface fails\n");
1205 return JNI_FALSE;
1206 }
1207
1208 sp<IGnssXtraCallback> gnssXtraCbIface = new GnssXtraCallback();
1209 if (gnssXtraIface == nullptr) {
1210 ALOGE("Unable to initialize GNSS Xtra interface\n");
Hridya Valsarajue8650322016-12-05 20:23:21 -08001211 } else {
1212 result = gnssXtraIface->setCallback(gnssXtraCbIface);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001213 if (!result.isOk() || !result) {
Hridya Valsarajue8650322016-12-05 20:23:21 -08001214 gnssXtraIface = nullptr;
Wyatt Rileyfb840922017-11-08 15:07:58 -08001215 ALOGI("SetCallback for Gnss Xtra Interface fails\n");
Hridya Valsarajue8650322016-12-05 20:23:21 -08001216 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001217 }
1218
1219 sp<IAGnssCallback> aGnssCbIface = new AGnssCallback();
1220 if (agnssIface != nullptr) {
1221 agnssIface->setCallback(aGnssCbIface);
1222 } else {
Wyatt Rileyfb840922017-11-08 15:07:58 -08001223 ALOGI("Unable to Initialize AGnss interface\n");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001224 }
1225
1226 sp<IGnssGeofenceCallback> gnssGeofencingCbIface = new GnssGeofenceCallback();
1227 if (gnssGeofencingIface != nullptr) {
1228 gnssGeofencingIface->setCallback(gnssGeofencingCbIface);
1229 } else {
Wyatt Rileyfb840922017-11-08 15:07:58 -08001230 ALOGI("Unable to initialize GNSS Geofencing interface\n");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001231 }
1232
1233 sp<IGnssNiCallback> gnssNiCbIface = new GnssNiCallback();
Hridya Valsaraju388e9682017-03-08 10:57:06 -08001234 if (gnssNiIface != nullptr) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001235 gnssNiIface->setCallback(gnssNiCbIface);
1236 } else {
Wyatt Rileyfb840922017-11-08 15:07:58 -08001237 ALOGI("Unable to initialize GNSS NI interface\n");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001238 }
1239
Jaekyun Seokf9038ad2017-11-13 15:03:21 +09001240 sp<IAGnssRilCallback> aGnssRilCbIface = new AGnssRilCallback();
1241 if (agnssRilIface != nullptr) {
1242 agnssRilIface->setCallback(aGnssRilCbIface);
1243 } else {
1244 ALOGI("Unable to Initialize AGnss Ril interface\n");
1245 }
1246
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001247 return JNI_TRUE;
1248}
1249
1250static void android_location_GnssLocationProvider_cleanup(JNIEnv* /* env */, jobject /* obj */) {
1251 if (gnssHal != nullptr) {
1252 gnssHal->cleanup();
1253 }
1254}
1255
1256static jboolean android_location_GnssLocationProvider_set_position_mode(JNIEnv* /* env */,
1257 jobject /* obj */, jint mode, jint recurrence, jint min_interval, jint preferred_accuracy,
1258 jint preferred_time) {
1259 if (gnssHal != nullptr) {
1260 auto result = gnssHal->setPositionMode(static_cast<IGnss::GnssPositionMode>(mode),
1261 static_cast<IGnss::GnssPositionRecurrence>(recurrence),
1262 min_interval,
1263 preferred_accuracy,
1264 preferred_time);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001265 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001266 ALOGE("%s: GNSS setPositionMode failed\n", __func__);
1267 return JNI_FALSE;
1268 } else {
1269 return result;
1270 }
1271 } else {
1272 return JNI_FALSE;
1273 }
1274}
1275
1276static jboolean android_location_GnssLocationProvider_start(JNIEnv* /* env */, jobject /* obj */) {
1277 if (gnssHal != nullptr) {
1278 auto result = gnssHal->start();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001279 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001280 return JNI_FALSE;
1281 } else {
1282 return result;
1283 }
1284 } else {
1285 return JNI_FALSE;
1286 }
1287}
1288
1289static jboolean android_location_GnssLocationProvider_stop(JNIEnv* /* env */, jobject /* obj */) {
1290 if (gnssHal != nullptr) {
1291 auto result = gnssHal->stop();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001292 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001293 return JNI_FALSE;
1294 } else {
1295 return result;
1296 }
1297 } else {
1298 return JNI_FALSE;
1299 }
1300}
1301static void android_location_GnssLocationProvider_delete_aiding_data(JNIEnv* /* env */,
1302 jobject /* obj */,
1303 jint flags) {
1304 if (gnssHal != nullptr) {
1305 auto result = gnssHal->deleteAidingData(static_cast<IGnss::GnssAidingData>(flags));
Steven Morelandd002a8b2017-01-03 17:18:24 -08001306 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001307 ALOGE("Error in deleting aiding data");
1308 }
1309 }
1310}
1311
1312/*
1313 * This enum is used by the read_sv_status method to combine the svid,
1314 * constellation and svFlag fields.
1315 */
1316enum ShiftWidth: uint8_t {
Yipeng Cao21717812017-04-27 18:35:24 -07001317 SVID_SHIFT_WIDTH = 8,
1318 CONSTELLATION_TYPE_SHIFT_WIDTH = 4
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001319};
1320
1321static jint android_location_GnssLocationProvider_read_sv_status(JNIEnv* env, jobject /* obj */,
1322 jintArray svidWithFlagArray, jfloatArray cn0Array, jfloatArray elevArray,
gomo4402af62017-01-11 13:20:13 -08001323 jfloatArray azumArray, jfloatArray carrierFreqArray) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001324 /*
1325 * This method should only be called from within a call to reportSvStatus.
1326 */
1327 jint* svidWithFlags = env->GetIntArrayElements(svidWithFlagArray, 0);
1328 jfloat* cn0s = env->GetFloatArrayElements(cn0Array, 0);
1329 jfloat* elev = env->GetFloatArrayElements(elevArray, 0);
1330 jfloat* azim = env->GetFloatArrayElements(azumArray, 0);
gomo4402af62017-01-11 13:20:13 -08001331 jfloat* carrierFreq = env->GetFloatArrayElements(carrierFreqArray, 0);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001332
1333 /*
1334 * Read GNSS SV info.
1335 */
1336 for (size_t i = 0; i < GnssCallback::sGnssSvListSize; ++i) {
1337 const IGnssCallback::GnssSvInfo& info = GnssCallback::sGnssSvList[i];
1338 svidWithFlags[i] = (info.svid << SVID_SHIFT_WIDTH) |
1339 (static_cast<uint32_t>(info.constellation) << CONSTELLATION_TYPE_SHIFT_WIDTH) |
1340 static_cast<uint32_t>(info.svFlag);
1341 cn0s[i] = info.cN0Dbhz;
1342 elev[i] = info.elevationDegrees;
1343 azim[i] = info.azimuthDegrees;
gomo4402af62017-01-11 13:20:13 -08001344 carrierFreq[i] = info.carrierFrequencyHz;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001345 }
1346
1347 env->ReleaseIntArrayElements(svidWithFlagArray, svidWithFlags, 0);
1348 env->ReleaseFloatArrayElements(cn0Array, cn0s, 0);
1349 env->ReleaseFloatArrayElements(elevArray, elev, 0);
1350 env->ReleaseFloatArrayElements(azumArray, azim, 0);
gomo4402af62017-01-11 13:20:13 -08001351 env->ReleaseFloatArrayElements(carrierFreqArray, carrierFreq, 0);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001352 return static_cast<jint>(GnssCallback::sGnssSvListSize);
1353}
1354
1355static void android_location_GnssLocationProvider_agps_set_reference_location_cellid(
1356 JNIEnv* /* env */, jobject /* obj */, jint type, jint mcc, jint mnc, jint lac, jint cid) {
1357 IAGnssRil::AGnssRefLocation location;
1358
1359 if (agnssRilIface == nullptr) {
1360 ALOGE("No AGPS RIL interface in agps_set_reference_location_cellid");
1361 return;
1362 }
1363
1364 switch (static_cast<IAGnssRil::AGnssRefLocationType>(type)) {
1365 case IAGnssRil::AGnssRefLocationType::GSM_CELLID:
1366 case IAGnssRil::AGnssRefLocationType::UMTS_CELLID:
1367 location.type = static_cast<IAGnssRil::AGnssRefLocationType>(type);
1368 location.cellID.mcc = mcc;
1369 location.cellID.mnc = mnc;
1370 location.cellID.lac = lac;
1371 location.cellID.cid = cid;
1372 break;
1373 default:
1374 ALOGE("Neither a GSM nor a UMTS cellid (%s:%d).", __FUNCTION__, __LINE__);
1375 return;
1376 break;
1377 }
1378
1379 agnssRilIface->setRefLocation(location);
1380}
1381
1382static void android_location_GnssLocationProvider_agps_set_id(JNIEnv *env, jobject /* obj */,
1383 jint type, jstring setid_string) {
1384 if (agnssRilIface == nullptr) {
1385 ALOGE("no AGPS RIL interface in agps_set_id");
1386 return;
1387 }
1388
1389 const char *setid = env->GetStringUTFChars(setid_string, NULL);
1390 agnssRilIface->setSetId((IAGnssRil::SetIDType)type, setid);
1391 env->ReleaseStringUTFChars(setid_string, setid);
1392}
1393
1394static jint android_location_GnssLocationProvider_read_nmea(JNIEnv* env, jobject /* obj */,
1395 jbyteArray nmeaArray, jint buffer_size) {
1396 // this should only be called from within a call to reportNmea
1397 jbyte* nmea = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(nmeaArray, 0));
1398 int length = GnssCallback::sNmeaStringLength;
1399 if (length > buffer_size)
1400 length = buffer_size;
1401 memcpy(nmea, GnssCallback::sNmeaString, length);
1402 env->ReleasePrimitiveArrayCritical(nmeaArray, nmea, JNI_ABORT);
1403 return (jint) length;
1404}
1405
1406static void android_location_GnssLocationProvider_inject_time(JNIEnv* /* env */, jobject /* obj */,
1407 jlong time, jlong timeReference, jint uncertainty) {
1408 if (gnssHal != nullptr) {
1409 auto result = gnssHal->injectTime(time, timeReference, uncertainty);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001410 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001411 ALOGE("%s: Gnss injectTime() failed", __func__);
1412 }
1413 }
1414}
1415
1416static void android_location_GnssLocationProvider_inject_location(JNIEnv* /* env */,
1417 jobject /* obj */, jdouble latitude, jdouble longitude, jfloat accuracy) {
1418 if (gnssHal != nullptr) {
1419 auto result = gnssHal->injectLocation(latitude, longitude, accuracy);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001420 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001421 ALOGE("%s: Gnss injectLocation() failed", __func__);
1422 }
1423 }
1424}
1425
1426static jboolean android_location_GnssLocationProvider_supports_xtra(
1427 JNIEnv* /* env */, jobject /* obj */) {
1428 return (gnssXtraIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1429}
1430
1431static void android_location_GnssLocationProvider_inject_xtra_data(JNIEnv* env, jobject /* obj */,
1432 jbyteArray data, jint length) {
1433 if (gnssXtraIface == nullptr) {
1434 ALOGE("XTRA Interface not supported");
1435 return;
1436 }
1437
1438 jbyte* bytes = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(data, 0));
1439 gnssXtraIface->injectXtraData(std::string((const char*)bytes, length));
1440 env->ReleasePrimitiveArrayCritical(data, bytes, JNI_ABORT);
1441}
1442
1443static void android_location_GnssLocationProvider_agps_data_conn_open(
1444 JNIEnv* env, jobject /* obj */, jstring apn, jint apnIpType) {
1445 if (agnssIface == nullptr) {
1446 ALOGE("no AGPS interface in agps_data_conn_open");
1447 return;
1448 }
1449 if (apn == NULL) {
1450 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
1451 return;
1452 }
1453
1454 const char *apnStr = env->GetStringUTFChars(apn, NULL);
1455
1456 auto result = agnssIface->dataConnOpen(apnStr, static_cast<IAGnss::ApnIpType>(apnIpType));
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001457 if (!result.isOk() || !result){
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001458 ALOGE("%s: Failed to set APN and its IP type", __func__);
1459 }
1460 env->ReleaseStringUTFChars(apn, apnStr);
1461}
1462
1463static void android_location_GnssLocationProvider_agps_data_conn_closed(JNIEnv* /* env */,
1464 jobject /* obj */) {
1465 if (agnssIface == nullptr) {
1466 ALOGE("%s: AGPS interface not supported", __func__);
1467 return;
1468 }
1469
1470 auto result = agnssIface->dataConnClosed();
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001471 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001472 ALOGE("%s: Failed to close AGnss data connection", __func__);
1473 }
1474}
1475
1476static void android_location_GnssLocationProvider_agps_data_conn_failed(JNIEnv* /* env */,
1477 jobject /* obj */) {
1478 if (agnssIface == nullptr) {
1479 ALOGE("%s: AGPS interface not supported", __func__);
1480 return;
1481 }
1482
1483 auto result = agnssIface->dataConnFailed();
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001484 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001485 ALOGE("%s: Failed to notify unavailability of AGnss data connection", __func__);
1486 }
1487}
1488
1489static void android_location_GnssLocationProvider_set_agps_server(JNIEnv* env, jobject /* obj */,
1490 jint type, jstring hostname, jint port) {
1491 if (agnssIface == nullptr) {
1492 ALOGE("no AGPS interface in set_agps_server");
1493 return;
1494 }
1495
1496 const char *c_hostname = env->GetStringUTFChars(hostname, NULL);
1497 auto result = agnssIface->setServer(static_cast<IAGnssCallback::AGnssType>(type),
1498 c_hostname,
1499 port);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001500 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001501 ALOGE("%s: Failed to set AGnss host name and port", __func__);
1502 }
1503
1504 env->ReleaseStringUTFChars(hostname, c_hostname);
1505}
1506
1507static void android_location_GnssLocationProvider_send_ni_response(JNIEnv* /* env */,
1508 jobject /* obj */, jint notifId, jint response) {
1509 if (gnssNiIface == nullptr) {
1510 ALOGE("no NI interface in send_ni_response");
1511 return;
1512 }
1513
1514 gnssNiIface->respond(notifId, static_cast<IGnssNiCallback::GnssUserResponseType>(response));
1515}
1516
1517static jstring android_location_GnssLocationProvider_get_internal_state(JNIEnv* env,
1518 jobject /* obj */) {
1519 jstring result = NULL;
1520 /*
1521 * TODO(b/33089503) : Create a jobject to represent GnssDebug.
1522 */
Wyatt Riley268c6e02017-03-29 10:21:46 -07001523
1524 std::stringstream internalState;
1525
1526 if (gnssDebugIface == nullptr) {
1527 internalState << "Gnss Debug Interface not available" << std::endl;
1528 } else {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001529 IGnssDebug::DebugData data;
1530 gnssDebugIface->getDebugData([&data](const IGnssDebug::DebugData& debugData) {
1531 data = debugData;
1532 });
1533
Wyatt Riley268c6e02017-03-29 10:21:46 -07001534 internalState << "Gnss Location Data:: ";
1535 if (!data.position.valid) {
1536 internalState << "not valid";
1537 } else {
1538 internalState << "LatitudeDegrees: " << data.position.latitudeDegrees
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001539 << ", LongitudeDegrees: " << data.position.longitudeDegrees
1540 << ", altitudeMeters: " << data.position.altitudeMeters
gomo4402af62017-01-11 13:20:13 -08001541 << ", speedMetersPerSecond: " << data.position.speedMetersPerSec
1542 << ", bearingDegrees: " << data.position.bearingDegrees
Wyatt Riley268c6e02017-03-29 10:21:46 -07001543 << ", horizontalAccuracyMeters: "
1544 << data.position.horizontalAccuracyMeters
gomo4402af62017-01-11 13:20:13 -08001545 << ", verticalAccuracyMeters: " << data.position.verticalAccuracyMeters
Wyatt Riley268c6e02017-03-29 10:21:46 -07001546 << ", speedAccuracyMetersPerSecond: "
1547 << data.position.speedAccuracyMetersPerSecond
gomo4402af62017-01-11 13:20:13 -08001548 << ", bearingAccuracyDegrees: " << data.position.bearingAccuracyDegrees
Wyatt Riley268c6e02017-03-29 10:21:46 -07001549 << ", ageSeconds: " << data.position.ageSeconds;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001550 }
Wyatt Riley268c6e02017-03-29 10:21:46 -07001551 internalState << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001552
Wyatt Riley268c6e02017-03-29 10:21:46 -07001553 internalState << "Gnss Time Data:: timeEstimate: " << data.time.timeEstimate
1554 << ", timeUncertaintyNs: " << data.time.timeUncertaintyNs
1555 << ", frequencyUncertaintyNsPerSec: "
1556 << data.time.frequencyUncertaintyNsPerSec << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001557
1558 if (data.satelliteDataArray.size() != 0) {
Wyatt Riley268c6e02017-03-29 10:21:46 -07001559 internalState << "Satellite Data for " << data.satelliteDataArray.size()
1560 << " satellites:: " << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001561 }
1562
Wyatt Riley77ca4f82017-06-30 18:13:44 -07001563 internalState << "constellation: 1=GPS, 2=SBAS, 3=GLO, 4=QZSS, 5=BDS, 6=GAL; "
1564 << "ephemerisType: 0=Eph, 1=Alm, 2=?; "
1565 << "ephemerisSource: 0=Demod, 1=Supl, 2=Server, 3=?; "
1566 << "ephemerisHealth: 0=Good, 1=Bad, 2=?" << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001567 for (size_t i = 0; i < data.satelliteDataArray.size(); i++) {
1568 internalState << "svid: " << data.satelliteDataArray[i].svid
1569 << ", constellation: "
1570 << static_cast<uint32_t>(data.satelliteDataArray[i].constellation)
1571 << ", ephemerisType: "
1572 << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisType)
Wyatt Riley268c6e02017-03-29 10:21:46 -07001573 << ", ephemerisSource: "
1574 << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisSource)
1575 << ", ephemerisHealth: "
1576 << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisHealth)
1577 << ", serverPredictionIsAvailable: "
1578 << data.satelliteDataArray[i].serverPredictionIsAvailable
1579 << ", serverPredictionAgeSeconds: "
1580 << data.satelliteDataArray[i].serverPredictionAgeSeconds
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001581 << ", ephemerisAgeSeconds: "
1582 << data.satelliteDataArray[i].ephemerisAgeSeconds << std::endl;
1583 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001584 }
Wyatt Riley268c6e02017-03-29 10:21:46 -07001585
1586 result = env->NewStringUTF(internalState.str().c_str());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001587 return result;
1588}
1589
1590static void android_location_GnssLocationProvider_update_network_state(JNIEnv* env,
1591 jobject /* obj */,
1592 jboolean connected,
1593 jint type,
1594 jboolean roaming,
1595 jboolean available,
1596 jstring extraInfo,
1597 jstring apn) {
1598 if (agnssRilIface != nullptr) {
1599 auto result = agnssRilIface->updateNetworkState(connected,
1600 static_cast<IAGnssRil::NetworkType>(type),
1601 roaming);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001602 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001603 ALOGE("updateNetworkState failed");
1604 }
1605
1606 const char *c_apn = env->GetStringUTFChars(apn, NULL);
1607 result = agnssRilIface->updateNetworkAvailability(available, c_apn);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001608 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001609 ALOGE("updateNetworkAvailability failed");
1610 }
1611
1612 env->ReleaseStringUTFChars(apn, c_apn);
1613 } else {
1614 ALOGE("AGnssRilInterface does not exist");
1615 }
1616}
1617
1618static jboolean android_location_GnssLocationProvider_is_geofence_supported(
1619 JNIEnv* /* env */, jobject /* obj */) {
1620 return (gnssGeofencingIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1621}
1622
1623static jboolean android_location_GnssLocationProvider_add_geofence(JNIEnv* /* env */,
1624 jobject /* obj */, jint geofenceId, jdouble latitude, jdouble longitude, jdouble radius,
1625 jint last_transition, jint monitor_transition, jint notification_responsiveness,
1626 jint unknown_timer) {
1627 if (gnssGeofencingIface != nullptr) {
1628 auto result = gnssGeofencingIface->addGeofence(
1629 geofenceId, latitude, longitude, radius,
1630 static_cast<IGnssGeofenceCallback::GeofenceTransition>(last_transition),
1631 monitor_transition, notification_responsiveness, unknown_timer);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001632 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001633 } else {
1634 ALOGE("Geofence Interface not available");
1635 }
1636 return JNI_FALSE;
1637}
1638
1639static jboolean android_location_GnssLocationProvider_remove_geofence(JNIEnv* /* env */,
1640 jobject /* obj */, jint geofenceId) {
1641 if (gnssGeofencingIface != nullptr) {
1642 auto result = gnssGeofencingIface->removeGeofence(geofenceId);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001643 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001644 } else {
1645 ALOGE("Geofence interface not available");
1646 }
1647 return JNI_FALSE;
1648}
1649
1650static jboolean android_location_GnssLocationProvider_pause_geofence(JNIEnv* /* env */,
1651 jobject /* obj */, jint geofenceId) {
1652 if (gnssGeofencingIface != nullptr) {
1653 auto result = gnssGeofencingIface->pauseGeofence(geofenceId);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001654 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001655 } else {
1656 ALOGE("Geofence interface not available");
1657 }
1658 return JNI_FALSE;
1659}
1660
1661static jboolean android_location_GnssLocationProvider_resume_geofence(JNIEnv* /* env */,
1662 jobject /* obj */, jint geofenceId, jint monitor_transition) {
1663 if (gnssGeofencingIface != nullptr) {
1664 auto result = gnssGeofencingIface->resumeGeofence(geofenceId, monitor_transition);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001665 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001666 } else {
1667 ALOGE("Geofence interface not available");
1668 }
1669 return JNI_FALSE;
1670}
1671
Lifu Tang30f95a72016-01-07 23:20:38 -08001672static jboolean android_location_GnssLocationProvider_is_measurement_supported(
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001673 JNIEnv* env, jclass clazz) {
1674 if (gnssMeasurementIface != nullptr) {
destradaaea8a8a62014-06-23 18:19:03 -07001675 return JNI_TRUE;
1676 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001677
destradaaea8a8a62014-06-23 18:19:03 -07001678 return JNI_FALSE;
1679}
1680
Lifu Tang30f95a72016-01-07 23:20:38 -08001681static jboolean android_location_GnssLocationProvider_start_measurement_collection(
destradaaea8a8a62014-06-23 18:19:03 -07001682 JNIEnv* env,
1683 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001684 if (gnssMeasurementIface == nullptr) {
1685 ALOGE("GNSS Measurement interface is not available.");
destradaaea8a8a62014-06-23 18:19:03 -07001686 return JNI_FALSE;
1687 }
1688
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001689 sp<GnssMeasurementCallback> cbIface = new GnssMeasurementCallback();
1690 IGnssMeasurement::GnssMeasurementStatus result = gnssMeasurementIface->setCallback(cbIface);
1691 if (result != IGnssMeasurement::GnssMeasurementStatus::SUCCESS) {
1692 ALOGE("An error has been found on GnssMeasurementInterface::init, status=%d",
1693 static_cast<int32_t>(result));
destradaaea8a8a62014-06-23 18:19:03 -07001694 return JNI_FALSE;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001695 } else {
1696 ALOGD("gnss measurement infc has been enabled");
destradaaea8a8a62014-06-23 18:19:03 -07001697 }
1698
1699 return JNI_TRUE;
1700}
1701
Lifu Tang30f95a72016-01-07 23:20:38 -08001702static jboolean android_location_GnssLocationProvider_stop_measurement_collection(
destradaaea8a8a62014-06-23 18:19:03 -07001703 JNIEnv* env,
1704 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001705 if (gnssMeasurementIface == nullptr) {
destradaaea8a8a62014-06-23 18:19:03 -07001706 ALOGE("Measurement interface not available");
1707 return JNI_FALSE;
1708 }
1709
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001710 auto result = gnssMeasurementIface->close();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001711 return boolToJbool(result.isOk());
destradaaea8a8a62014-06-23 18:19:03 -07001712}
1713
Lifu Tang30f95a72016-01-07 23:20:38 -08001714static jboolean android_location_GnssLocationProvider_is_navigation_message_supported(
destradaa4b3e3932014-07-21 18:01:47 -07001715 JNIEnv* env,
1716 jclass clazz) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001717 if (gnssNavigationMessageIface != nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001718 return JNI_TRUE;
1719 }
1720 return JNI_FALSE;
1721}
1722
Lifu Tang30f95a72016-01-07 23:20:38 -08001723static jboolean android_location_GnssLocationProvider_start_navigation_message_collection(
destradaa4b3e3932014-07-21 18:01:47 -07001724 JNIEnv* env,
1725 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001726 if (gnssNavigationMessageIface == nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001727 ALOGE("Navigation Message interface is not available.");
1728 return JNI_FALSE;
1729 }
1730
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001731 sp<IGnssNavigationMessageCallback> gnssNavigationMessageCbIface =
1732 new GnssNavigationMessageCallback();
1733 IGnssNavigationMessage::GnssNavigationMessageStatus result =
1734 gnssNavigationMessageIface->setCallback(gnssNavigationMessageCbIface);
1735
1736 if (result != IGnssNavigationMessage::GnssNavigationMessageStatus::SUCCESS) {
1737 ALOGE("An error has been found in %s: %d", __FUNCTION__, static_cast<int32_t>(result));
destradaa4b3e3932014-07-21 18:01:47 -07001738 return JNI_FALSE;
1739 }
1740
1741 return JNI_TRUE;
1742}
1743
Lifu Tang30f95a72016-01-07 23:20:38 -08001744static jboolean android_location_GnssLocationProvider_stop_navigation_message_collection(
destradaa4b3e3932014-07-21 18:01:47 -07001745 JNIEnv* env,
1746 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001747 if (gnssNavigationMessageIface == nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001748 ALOGE("Navigation Message interface is not available.");
1749 return JNI_FALSE;
1750 }
1751
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001752 auto result = gnssNavigationMessageIface->close();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001753 return boolToJbool(result.isOk());
destradaa4b3e3932014-07-21 18:01:47 -07001754}
1755
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001756static jboolean android_location_GnssLocationProvider_set_emergency_supl_pdn(JNIEnv*,
1757 jobject,
1758 jint emergencySuplPdn) {
1759 if (gnssConfigurationIface == nullptr) {
1760 ALOGE("no GNSS configuration interface available");
1761 return JNI_FALSE;
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001762 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001763
1764 auto result = gnssConfigurationIface->setEmergencySuplPdn(emergencySuplPdn);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001765 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001766 return result;
1767 } else {
1768 return JNI_FALSE;
1769 }
1770}
1771
1772static jboolean android_location_GnssLocationProvider_set_supl_version(JNIEnv*,
1773 jobject,
1774 jint version) {
1775 if (gnssConfigurationIface == nullptr) {
1776 ALOGE("no GNSS configuration interface available");
1777 return JNI_FALSE;
1778 }
1779 auto result = gnssConfigurationIface->setSuplVersion(version);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001780 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001781 return result;
1782 } else {
1783 return JNI_FALSE;
1784 }
1785}
1786
1787static jboolean android_location_GnssLocationProvider_set_supl_es(JNIEnv*,
1788 jobject,
1789 jint suplEs) {
1790 if (gnssConfigurationIface == nullptr) {
1791 ALOGE("no GNSS configuration interface available");
1792 return JNI_FALSE;
1793 }
1794
1795 auto result = gnssConfigurationIface->setSuplEs(suplEs);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001796 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001797 return result;
1798 } else {
1799 return JNI_FALSE;
1800 }
1801}
1802
1803static jboolean android_location_GnssLocationProvider_set_supl_mode(JNIEnv*,
1804 jobject,
1805 jint mode) {
1806 if (gnssConfigurationIface == nullptr) {
1807 ALOGE("no GNSS configuration interface available");
1808 return JNI_FALSE;
1809 }
1810
1811 auto result = gnssConfigurationIface->setSuplMode(mode);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001812 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001813 return result;
1814 } else {
1815 return JNI_FALSE;
1816 }
1817}
1818
1819static jboolean android_location_GnssLocationProvider_set_gps_lock(JNIEnv*,
1820 jobject,
1821 jint gpsLock) {
1822 if (gnssConfigurationIface == nullptr) {
1823 ALOGE("no GNSS configuration interface available");
1824 return JNI_FALSE;
1825 }
1826
1827 auto result = gnssConfigurationIface->setGpsLock(gpsLock);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001828 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001829 return result;
1830 } else {
1831 return JNI_FALSE;
1832 }
1833}
1834
1835static jboolean android_location_GnssLocationProvider_set_lpp_profile(JNIEnv*,
1836 jobject,
1837 jint lppProfile) {
1838 if (gnssConfigurationIface == nullptr) {
1839 ALOGE("no GNSS configuration interface available");
1840 return JNI_FALSE;
1841 }
1842
1843 auto result = gnssConfigurationIface->setLppProfile(lppProfile);
1844
Steven Morelandd002a8b2017-01-03 17:18:24 -08001845 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001846 return result;
1847 } else {
1848 return JNI_FALSE;
1849 }
1850}
1851
1852static jboolean android_location_GnssLocationProvider_set_gnss_pos_protocol_select(JNIEnv*,
1853 jobject,
1854 jint gnssPosProtocol) {
1855 if (gnssConfigurationIface == nullptr) {
1856 ALOGE("no GNSS configuration interface available");
1857 return JNI_FALSE;
1858 }
1859
1860 auto result = gnssConfigurationIface->setGlonassPositioningProtocol(gnssPosProtocol);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001861 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001862 return result;
1863 } else {
1864 return JNI_FALSE;
1865 }
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001866}
1867
Wyatt Rileycf879db2017-01-12 13:57:38 -08001868static jint android_location_GnssLocationProvider_get_batch_size(JNIEnv*, jclass) {
1869 if (gnssBatchingIface == nullptr) {
1870 return 0; // batching not supported, size = 0
1871 }
1872 auto result = gnssBatchingIface->getBatchSize();
1873 if (result.isOk()) {
1874 return static_cast<jint>(result);
1875 } else {
1876 return 0; // failure in binder, don't support batching
1877 }
1878}
1879
1880static jboolean android_location_GnssLocationProvider_init_batching(JNIEnv*, jclass) {
1881 if (gnssBatchingIface == nullptr) {
1882 return JNI_FALSE; // batching not supported
1883 }
1884 sp<IGnssBatchingCallback> gnssBatchingCbIface = new GnssBatchingCallback();
1885
1886 return static_cast<jboolean>(gnssBatchingIface->init(gnssBatchingCbIface));
1887}
1888
1889static void android_location_GnssLocationProvider_cleanup_batching(JNIEnv*, jclass) {
1890 if (gnssBatchingIface == nullptr) {
1891 return; // batching not supported
1892 }
1893 gnssBatchingIface->cleanup();
1894}
1895
1896static jboolean android_location_GnssLocationProvider_start_batch(JNIEnv*, jclass,
1897 jlong periodNanos, jboolean wakeOnFifoFull) {
1898 if (gnssBatchingIface == nullptr) {
1899 return JNI_FALSE; // batching not supported
1900 }
1901
1902 IGnssBatching::Options options;
1903 options.periodNanos = periodNanos;
1904 if (wakeOnFifoFull) {
1905 options.flags = static_cast<uint8_t>(IGnssBatching::Flag::WAKEUP_ON_FIFO_FULL);
1906 } else {
1907 options.flags = 0;
1908 }
1909
1910 return static_cast<jboolean>(gnssBatchingIface->start(options));
1911}
1912
1913static void android_location_GnssLocationProvider_flush_batch(JNIEnv*, jclass) {
1914 if (gnssBatchingIface == nullptr) {
1915 return; // batching not supported
1916 }
1917
1918 gnssBatchingIface->flush();
1919}
1920
1921static jboolean android_location_GnssLocationProvider_stop_batch(JNIEnv*, jclass) {
1922 if (gnssBatchingIface == nullptr) {
1923 return JNI_FALSE; // batching not supported
1924 }
1925
1926 return gnssBatchingIface->stop();
1927}
1928
Daniel Micay76f6a862015-09-19 17:31:01 -04001929static const JNINativeMethod sMethods[] = {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001930 /* name, signature, funcPtr */
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001931 {"class_init_native", "()V", reinterpret_cast<void *>(
1932 android_location_GnssLocationProvider_class_init_native)},
1933 {"native_is_supported", "()Z", reinterpret_cast<void *>(
1934 android_location_GnssLocationProvider_is_supported)},
destradaaef752b62015-04-17 13:10:47 -07001935 {"native_is_agps_ril_supported", "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001936 reinterpret_cast<void *>(android_location_GnssLocationProvider_is_agps_ril_supported)},
destradaaef752b62015-04-17 13:10:47 -07001937 {"native_is_gnss_configuration_supported", "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001938 reinterpret_cast<void *>(
1939 android_location_gpsLocationProvider_is_gnss_configuration_supported)},
1940 {"native_init", "()Z", reinterpret_cast<void *>(android_location_GnssLocationProvider_init)},
1941 {"native_cleanup", "()V", reinterpret_cast<void *>(
1942 android_location_GnssLocationProvider_cleanup)},
destradaaea8a8a62014-06-23 18:19:03 -07001943 {"native_set_position_mode",
1944 "(IIIII)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001945 reinterpret_cast<void*>(android_location_GnssLocationProvider_set_position_mode)},
1946 {"native_start", "()Z", reinterpret_cast<void*>(android_location_GnssLocationProvider_start)},
1947 {"native_stop", "()Z", reinterpret_cast<void*>(android_location_GnssLocationProvider_stop)},
destradaaea8a8a62014-06-23 18:19:03 -07001948 {"native_delete_aiding_data",
1949 "(I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001950 reinterpret_cast<void*>(android_location_GnssLocationProvider_delete_aiding_data)},
destradaaea8a8a62014-06-23 18:19:03 -07001951 {"native_read_sv_status",
gomo4402af62017-01-11 13:20:13 -08001952 "([I[F[F[F[F)I",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001953 reinterpret_cast<void *>(android_location_GnssLocationProvider_read_sv_status)},
1954 {"native_read_nmea", "([BI)I", reinterpret_cast<void *>(
1955 android_location_GnssLocationProvider_read_nmea)},
1956 {"native_inject_time", "(JJI)V", reinterpret_cast<void *>(
1957 android_location_GnssLocationProvider_inject_time)},
destradaaea8a8a62014-06-23 18:19:03 -07001958 {"native_inject_location",
1959 "(DDF)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001960 reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_location)},
1961 {"native_supports_xtra", "()Z", reinterpret_cast<void *>(
1962 android_location_GnssLocationProvider_supports_xtra)},
destradaaea8a8a62014-06-23 18:19:03 -07001963 {"native_inject_xtra_data",
1964 "([BI)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001965 reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_xtra_data)},
destradaaea8a8a62014-06-23 18:19:03 -07001966 {"native_agps_data_conn_open",
1967 "(Ljava/lang/String;I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001968 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_open)},
destradaaea8a8a62014-06-23 18:19:03 -07001969 {"native_agps_data_conn_closed",
1970 "()V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001971 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_closed)},
destradaaea8a8a62014-06-23 18:19:03 -07001972 {"native_agps_data_conn_failed",
1973 "()V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001974 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_failed)},
destradaaea8a8a62014-06-23 18:19:03 -07001975 {"native_agps_set_id",
1976 "(ILjava/lang/String;)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001977 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_set_id)},
destradaaea8a8a62014-06-23 18:19:03 -07001978 {"native_agps_set_ref_location_cellid",
1979 "(IIIII)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001980 reinterpret_cast<void *>(
1981 android_location_GnssLocationProvider_agps_set_reference_location_cellid)},
destradaaea8a8a62014-06-23 18:19:03 -07001982 {"native_set_agps_server",
1983 "(ILjava/lang/String;I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001984 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_agps_server)},
destradaaea8a8a62014-06-23 18:19:03 -07001985 {"native_send_ni_response",
1986 "(II)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001987 reinterpret_cast<void *>(android_location_GnssLocationProvider_send_ni_response)},
destradaaea8a8a62014-06-23 18:19:03 -07001988 {"native_get_internal_state",
1989 "()Ljava/lang/String;",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001990 reinterpret_cast<void *>(android_location_GnssLocationProvider_get_internal_state)},
destradaaea8a8a62014-06-23 18:19:03 -07001991 {"native_update_network_state",
1992 "(ZIZZLjava/lang/String;Ljava/lang/String;)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001993 reinterpret_cast<void *>(android_location_GnssLocationProvider_update_network_state)},
destradaaea8a8a62014-06-23 18:19:03 -07001994 {"native_is_geofence_supported",
1995 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001996 reinterpret_cast<void *>(android_location_GnssLocationProvider_is_geofence_supported)},
destradaaea8a8a62014-06-23 18:19:03 -07001997 {"native_add_geofence",
1998 "(IDDDIIII)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001999 reinterpret_cast<void *>(android_location_GnssLocationProvider_add_geofence)},
destradaaea8a8a62014-06-23 18:19:03 -07002000 {"native_remove_geofence",
2001 "(I)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002002 reinterpret_cast<void *>(android_location_GnssLocationProvider_remove_geofence)},
2003 {"native_pause_geofence", "(I)Z", reinterpret_cast<void *>(
2004 android_location_GnssLocationProvider_pause_geofence)},
destradaaea8a8a62014-06-23 18:19:03 -07002005 {"native_resume_geofence",
2006 "(II)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002007 reinterpret_cast<void *>(android_location_GnssLocationProvider_resume_geofence)},
destradaaea8a8a62014-06-23 18:19:03 -07002008 {"native_is_measurement_supported",
2009 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002010 reinterpret_cast<void *>(
2011 android_location_GnssLocationProvider_is_measurement_supported)},
destradaaea8a8a62014-06-23 18:19:03 -07002012 {"native_start_measurement_collection",
2013 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002014 reinterpret_cast<void *>(
2015 android_location_GnssLocationProvider_start_measurement_collection)},
destradaaea8a8a62014-06-23 18:19:03 -07002016 {"native_stop_measurement_collection",
2017 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002018 reinterpret_cast<void *>(
2019 android_location_GnssLocationProvider_stop_measurement_collection)},
destradaa4b3e3932014-07-21 18:01:47 -07002020 {"native_is_navigation_message_supported",
2021 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002022 reinterpret_cast<void *>(
2023 android_location_GnssLocationProvider_is_navigation_message_supported)},
destradaa4b3e3932014-07-21 18:01:47 -07002024 {"native_start_navigation_message_collection",
2025 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002026 reinterpret_cast<void *>(
2027 android_location_GnssLocationProvider_start_navigation_message_collection)},
destradaa4b3e3932014-07-21 18:01:47 -07002028 {"native_stop_navigation_message_collection",
2029 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002030 reinterpret_cast<void *>(
2031 android_location_GnssLocationProvider_stop_navigation_message_collection)},
2032 {"native_set_supl_es",
2033 "(I)Z",
2034 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_es)},
2035 {"native_set_supl_version",
2036 "(I)Z",
2037 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_version)},
2038 {"native_set_supl_mode",
2039 "(I)Z",
2040 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_mode)},
2041 {"native_set_lpp_profile",
2042 "(I)Z",
2043 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_lpp_profile)},
2044 {"native_set_gnss_pos_protocol_select",
2045 "(I)Z",
2046 reinterpret_cast<void *>(
2047 android_location_GnssLocationProvider_set_gnss_pos_protocol_select)},
2048 {"native_set_gps_lock",
2049 "(I)Z",
2050 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_gps_lock)},
2051 {"native_set_emergency_supl_pdn",
2052 "(I)Z",
2053 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_emergency_supl_pdn)},
Wyatt Rileycf879db2017-01-12 13:57:38 -08002054 {"native_get_batch_size",
2055 "()I",
2056 reinterpret_cast<void *>(android_location_GnssLocationProvider_get_batch_size)},
2057 {"native_init_batching",
2058 "()Z",
2059 reinterpret_cast<void *>(android_location_GnssLocationProvider_init_batching)},
2060 {"native_start_batch",
2061 "(JZ)Z",
2062 reinterpret_cast<void *>(android_location_GnssLocationProvider_start_batch)},
2063 {"native_flush_batch",
2064 "()V",
2065 reinterpret_cast<void *>(android_location_GnssLocationProvider_flush_batch)},
2066 {"native_stop_batch",
2067 "()Z",
2068 reinterpret_cast<void *>(android_location_GnssLocationProvider_stop_batch)},
2069 {"native_init_batching",
2070 "()Z",
2071 reinterpret_cast<void *>(android_location_GnssLocationProvider_init_batching)},
2072 {"native_cleanup_batching",
2073 "()V",
2074 reinterpret_cast<void *>(android_location_GnssLocationProvider_cleanup_batching)},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002075};
2076
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002077int register_android_server_location_GnssLocationProvider(JNIEnv* env) {
destradaaea8a8a62014-06-23 18:19:03 -07002078 return jniRegisterNativeMethods(
2079 env,
Lifu Tang30f95a72016-01-07 23:20:38 -08002080 "com/android/server/location/GnssLocationProvider",
destradaaea8a8a62014-06-23 18:19:03 -07002081 sMethods,
2082 NELEM(sMethods));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002083}
2084
2085} /* namespace android */