Merge changes from topic 'binderized_gnss_hal'
* changes:
Default implementation Gnss HAL
Add IGnssConfiguration Interface
Gnss Hal Minor Cleanup
diff --git a/gnss/1.0/Android.bp b/gnss/1.0/Android.bp
index adac05f..f8d3926 100644
--- a/gnss/1.0/Android.bp
+++ b/gnss/1.0/Android.bp
@@ -12,6 +12,7 @@
"IAGnssRilCallback.hal",
"IGnss.hal",
"IGnssCallback.hal",
+ "IGnssConfiguration.hal",
"IGnssDebug.hal",
"IGnssGeofenceCallback.hal",
"IGnssGeofencing.hal",
@@ -32,6 +33,7 @@
"android/hardware/gnss/1.0/AGnssRilCallbackAll.cpp",
"android/hardware/gnss/1.0/GnssAll.cpp",
"android/hardware/gnss/1.0/GnssCallbackAll.cpp",
+ "android/hardware/gnss/1.0/GnssConfigurationAll.cpp",
"android/hardware/gnss/1.0/GnssDebugAll.cpp",
"android/hardware/gnss/1.0/GnssGeofenceCallbackAll.cpp",
"android/hardware/gnss/1.0/GnssGeofencingAll.cpp",
@@ -58,6 +60,7 @@
"IAGnssRilCallback.hal",
"IGnss.hal",
"IGnssCallback.hal",
+ "IGnssConfiguration.hal",
"IGnssDebug.hal",
"IGnssGeofenceCallback.hal",
"IGnssGeofencing.hal",
@@ -102,6 +105,11 @@
"android/hardware/gnss/1.0/BnGnssCallback.h",
"android/hardware/gnss/1.0/BpGnssCallback.h",
"android/hardware/gnss/1.0/BsGnssCallback.h",
+ "android/hardware/gnss/1.0/IGnssConfiguration.h",
+ "android/hardware/gnss/1.0/IHwGnssConfiguration.h",
+ "android/hardware/gnss/1.0/BnGnssConfiguration.h",
+ "android/hardware/gnss/1.0/BpGnssConfiguration.h",
+ "android/hardware/gnss/1.0/BsGnssConfiguration.h",
"android/hardware/gnss/1.0/IGnssDebug.h",
"android/hardware/gnss/1.0/IHwGnssDebug.h",
"android/hardware/gnss/1.0/BnGnssDebug.h",
diff --git a/gnss/1.0/IAGnss.hal b/gnss/1.0/IAGnss.hal
index a3172f3..2cce519 100644
--- a/gnss/1.0/IAGnss.hal
+++ b/gnss/1.0/IAGnss.hal
@@ -22,7 +22,7 @@
* Extended interface for AGNSS support.
*/
interface IAGnss {
- enum ApnIpType : uint16_t {
+ enum ApnIpType : uint8_t {
INVALID = 0,
IPV4 = 1,
IPV6 = 2,
@@ -72,6 +72,6 @@
*
* @return success True if the operation is successful.
*/
- dataConnOpenWithApnIpType(string apn, ApnIpType apnIpType)
+ dataConnOpen(string apn, ApnIpType apnIpType)
generates (bool success);
};
diff --git a/gnss/1.0/IAGnssCallback.hal b/gnss/1.0/IAGnssCallback.hal
index 46641be..1984725 100644
--- a/gnss/1.0/IAGnssCallback.hal
+++ b/gnss/1.0/IAGnssCallback.hal
@@ -19,12 +19,12 @@
/** Callback structure for the AGNSS interface. */
interface IAGnssCallback {
/** AGNSS type **/
- enum AGnssType : uint16_t {
+ enum AGnssType : uint8_t {
TYPE_SUPL = 1,
TYPE_C2K = 2
};
- enum AGnssStatusValue : uint16_t {
+ enum AGnssStatusValue : uint8_t {
/** GNSS requests data connection for AGNSS. */
REQUEST_AGNSS_DATA_CONN = 1,
/** GNSS releases the AGNSS data connection. */
diff --git a/gnss/1.0/IAGnssRil.hal b/gnss/1.0/IAGnssRil.hal
index 7363d46..499b874 100644
--- a/gnss/1.0/IAGnssRil.hal
+++ b/gnss/1.0/IAGnssRil.hal
@@ -25,13 +25,13 @@
* location, unique subscriber ID, phone number string and network availability changes.
*/
interface IAGnssRil {
- enum SetIDType : uint16_t {
+ enum SetIDType : uint8_t {
NONE = 0,
IMSI = 1,
MSISDM = 2
};
- enum NetworkType : int32_t {
+ enum NetworkType : uint8_t {
MOBILE = 0,
WIFI = 1,
MMS = 2,
@@ -41,10 +41,9 @@
WIMAX = 6,
};
- enum AGnssRefLocationType : int32_t {
+ enum AGnssRefLocationType : uint8_t {
GSM_CELLID = 1,
UMTS_CELLID = 2,
- MAC = 3,
LTE_CELLID = 4,
};
@@ -75,20 +74,11 @@
uint16_t pcid;
};
- struct AGnssRefLocationMac {
- uint8_t[6] mac;
- };
-
/* Represents ref locations */
struct AGnssRefLocation {
AGnssRefLocationType type;
- union RefLoc {
- AGnssRefLocationCellID cellID;
- AGnssRefLocationMac mac;
- };
-
- RefLoc refLocVal;
+ AGnssRefLocationCellID cellID;
};
/*
@@ -102,7 +92,7 @@
/*
* Sets the reference location.
*
- * @param agnssReflocation AGNSS reference location CellID/MAC.
+ * @param agnssReflocation AGNSS reference location CellID.
*/
setRefLocation(AGnssRefLocation agnssReflocation);
diff --git a/gnss/1.0/IAGnssRilCallback.hal b/gnss/1.0/IAGnssRilCallback.hal
index 6f29820..17122b2 100644
--- a/gnss/1.0/IAGnssRilCallback.hal
+++ b/gnss/1.0/IAGnssRilCallback.hal
@@ -27,12 +27,6 @@
MSISDN = 1 << 1L,
};
- /* Kinds of reference location that can be requested. */
- enum RefLoc : uint32_t {
- CELLID = 1 << 0L,
- MAC = 1 << 1L
- };
-
/*
* The Hal uses this API to request a SET ID.
*
@@ -43,9 +37,7 @@
/*
* The Hal uses this API to request a reference location.
*
- * @param refLocflag Specifies the kind of reference location that is required
- * by the HAL.
*/
- requestRefLocCb(RefLoc refLocflag);
+ requestRefLocCb();
};
diff --git a/gnss/1.0/IGnss.hal b/gnss/1.0/IGnss.hal
index bc19e78..cc19ef8 100644
--- a/gnss/1.0/IGnss.hal
+++ b/gnss/1.0/IGnss.hal
@@ -19,6 +19,7 @@
import IAGnss;
import IAGnssRil;
import IGnssCallback;
+import IGnssConfiguration;
import IGnssDebug;
import IGnssMeasurement;
import IGnssNavigationMessage;
@@ -29,7 +30,7 @@
/* Represents the standard GNSS interface. */
interface IGnss {
/* Requested operational mode for GNSS operation. */
- enum GnssPositionMode : uint32_t {
+ enum GnssPositionMode : uint8_t {
/** Mode for running GNSS standalone (no assistance). */
STANDALONE = 0,
/** AGNSS MS-Based mode. */
@@ -110,7 +111,7 @@
* time. Represented in milliseconds.
*
* @return success Returns true if the operation is successful.
- *
+ */
injectTime(GnssUtcTime timeMs, int64_t timeReferenceMs, int32_t uncertaintyMs)
generates (bool success);
@@ -137,6 +138,9 @@
deleteAidingData(GnssAidingData aidingDataFlags);
/*
+ * Sets the GnssPositionMode parameter,its associated recurrence value,
+ * the time between fixes,requested fix accuracy and time to first fix.
+ *
* @param mode Parameter must be one of MS_BASED or STANDALONE.
* It is allowed by the platform (and it is recommended) to fallback to
* MS_BASED if MS_ASSISTED is passed in, and MS_BASED is supported.
@@ -155,56 +159,63 @@
/*
* This method returns the IAGnssRil Interface.
*
- * @return infc Handle to the IAGnssRil interface.
+ * @return aGnssRilIface Handle to the IAGnssRil interface.
*/
- getExtensionAGnssRil() generates (IAGnssRil infc);
+ getExtensionAGnssRil() generates (IAGnssRil aGnssRilIface);
/*
* This method returns the IGnssGeofencing Interface.
*
- * @return infc Handle to the IGnssGeofencing interface.
+ * @return gnssGeofencingIface Handle to the IGnssGeofencing interface.
*/
- getExtensionGnssGeofencing() generates(IGnssGeofencing infc);
+ getExtensionGnssGeofencing() generates(IGnssGeofencing gnssGeofencingIface);
/*
* This method returns the IAGnss Interface.
*
- * @return infc Handle to the IAGnss interface.
+ * @return aGnssIface Handle to the IAGnss interface.
*/
- getExtensionAGnss() generates (IAGnss infc);
+ getExtensionAGnss() generates (IAGnss aGnssIface);
/*
* This method returns the IGnssNi interface.
*
- * @return infc Handle to the IGnssNi interface.
+ * @return gnssNiIface Handle to the IGnssNi interface.
*/
- getExtensionGnssNi() generates (IGnssNi infc);
+ getExtensionGnssNi() generates (IGnssNi gnssNiIface);
/*
* This method returns the IGnssMeasurement interface.
*
- * @return infc Handle to the IGnssMeasurement interface.
+ * @return gnssMeasurementIface Handle to the IGnssMeasurement interface.
*/
- getExtensionGnssMeasurement() generates (IGnssMeasurement infc);
+ getExtensionGnssMeasurement() generates (IGnssMeasurement gnssMeasurementIface);
/*
* This method returns the IGnssNavigationMessage interface.
*
- * @return infc Handle to the IGnssNavigationMessage interface.
+ * @return gnssNavigationIface gnssNavigationIface to the IGnssNavigationMessage interface.
*/
- getExtensionGnssNavigationMessage() generates (IGnssNavigationMessage infc);
+ getExtensionGnssNavigationMessage() generates (IGnssNavigationMessage gnssNavigationIface);
/*
* This method returns the IGnssXtra interface.
*
- * @return infc Handle to the IGnssXtra interface.
+ * @return xtraIface Handle to the IGnssXtra interface.
*/
- getExtensionXtra() generates (IGnssXtra infc);
+ getExtensionXtra() generates (IGnssXtra xtraIface);
+
+ /*
+ * This method returns the IGnssConfiguration interface.
+ *
+ * @return gnssConfigIface Handle to the IGnssConfiguration interface.
+ */
+ getExtensionGnssConfiguration() generates (IGnssConfiguration gnssConfigIface);
/*
* This method returns the IGnssDebug interface.
*
- * @return infc Handle to the IGnssDebug interface.
+ * @return debugIface Handle to the IGnssDebug interface.
*/
- getExtensionGnssDebug() generates (IGnssDebug infc);
+ getExtensionGnssDebug() generates (IGnssDebug debugIface);
};
diff --git a/gnss/1.0/IGnssCallback.hal b/gnss/1.0/IGnssCallback.hal
index 5234688..041f949 100644
--- a/gnss/1.0/IGnssCallback.hal
+++ b/gnss/1.0/IGnssCallback.hal
@@ -47,9 +47,9 @@
};
/* GNSS status event values. */
- enum GnssStatusValue : uint16_t {
+ enum GnssStatusValue : uint8_t {
/** GNSS status unknown. */
- STATUS_NONE = 0,
+ NONE = 0,
/** GNSS has begun navigating. */
SESSION_BEGIN = 1,
/** GNSS has stopped navigating. */
@@ -64,7 +64,7 @@
* Flags that indicate information about the satellite
*/
enum GnssSvFlags : uint8_t {
- FLAGS_NONE = 0,
+ NONE = 0,
HAS_EPHEMERIS_DATA = 1 << 0,
HAS_ALMANAC_DATA = 1 << 1,
USED_IN_FIX = 1 << 2
@@ -121,13 +121,13 @@
/*
* Number of GNSS SVs currently visible, refers to the SVs stored in sv_list
*/
- int32_t numSvs;
+ uint32_t numSvs;
/*
* Pointer to an array of SVs information for all GNSS constellations,
* except GNSS, which is reported using svList
*/
- GnssSvInfo[ConstS32:GNSS_MAX_SVS] gnssSvList;
+ GnssSvInfo[GnssMax:SVS_COUNT] gnssSvList;
};
diff --git a/gnss/1.0/IGnssConfiguration.hal b/gnss/1.0/IGnssConfiguration.hal
new file mode 100644
index 0000000..f8856b0
--- /dev/null
+++ b/gnss/1.0/IGnssConfiguration.hal
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.gnss@1.0;
+
+/*
+ * Interface for passing GNSS configuration info from platform to HAL.
+ */
+interface IGnssConfiguration {
+ /*
+ * Enum which holds the bit masks for SUPL_MODE configuration parameter.
+ */
+ enum SuplMode : uint8_t {
+ /* Mobile Station Based */
+ MSB = 0x01,
+
+ /* Mobile Station Assisted */
+ MSA = 0x02
+ };
+
+ /*
+ * Enum which holds the bit masks for GPS_LOCK configuration parameter.
+ */
+ enum GpsLock : uint8_t {
+ /* Lock Mobile Originated GPS functionalitues. */
+ MO = 0x01,
+
+ /* Lock Network initiated GPS functionalities. */
+ NI = 0x02
+ };
+
+ /*
+ * Enum that hold the bit masks for various LTE Positioning Profile settings (LPP_PROFILE
+ * configuration parameter). If none of the bits in the enum are set, the default setting is
+ * Radio Resource Location Protocol(RRLP).
+ */
+ enum LppProfile : uint8_t {
+ /* Enable LTE Positioning Protocol user plane */
+ USER_PLANE = 0x01,
+
+ /* Enable LTE Positioning Protocol Control plane */
+ CONTROL_PLANE = 0x02
+ };
+
+ /*
+ * Enum which holds the bit masks for A_GLONASS_POS_PROTOCOL_SELECT
+ * configuration parameter.
+ */
+ enum GlonassPosProtocol : uint8_t {
+ /* Radio Resource Control(RRC) control-plane. */
+ RRC_CPLANE = 0x01,
+
+ /* Radio Resource Location user-plane. */
+ RRLP_CPLANE = 0x02,
+
+ /* LTE Positioning Protocol User plane */
+ LPP_UPLANE = 0x04
+ };
+
+ /*
+ * IMPORTANT: GNSS HAL must expect the below methods to be called multiple
+ * times. They can be called even when GnssLocationProvider is already
+ * constructed and enabled. GNSS HAL must maintain the existing requests
+ * for various callbacks regardless the change in configuration data.
+ */
+
+ /*
+ * This method enables or disables emergency SUPL.
+ *
+ * @param enabled True if emergency SUPL is to be enabled.
+ *
+ * @return success True if operation was successful.
+ */
+ setSuplEs(bool enabled) generates (bool success);
+
+ /*
+ * This method sets the SUPL version requested by Carrier. The GNSS HAL
+ * must use this version of the SUPL protocol if supported.
+ *
+ * @param version SUPL version requested by carrier. This is a bit mask
+ * with bits 0:7 representing a service indicator field, bits 8:15
+ * representing the minor version and bits 16:23 representing the
+ * major version.
+ *
+ * @return success True if operation was successful.
+ */
+ setSuplVersion(uint32_t version) generates (bool success);
+
+ /*
+ * This method sets the SUPL mode.
+ *
+ * @param mode Bit mask that specifies the SUPL mode which is set with the SuplMode enum.
+ *
+ * @return success True if operation was successful.
+ */
+ setSuplMode(uint8_t mode) generates (bool success);
+
+ /*
+ * This setting configures how GPS functionalities should be locked when
+ * user turns off GPS On setting.
+ *
+ * @param lock Bitmask that specifies the GPS functionalities to be be
+ * locked as per the GpsLock enum.
+ *
+ * @return success True if operation was successful.
+ */
+ setGpsLock(uint8_t lock) generates (bool success);
+
+ /*
+ * This method sets the LTE Positioning Profile configuration.
+ *
+ * @param lppProfile Bitmask that specifies the LTE Positioning Profile
+ * configuration to be set as per the LppProfile enum.
+ *
+ * @return success True if operation was successful.
+ */
+ setLppProfile(uint8_t lppProfile) generates (bool success);
+
+ /*
+ * This method selects positioning protocol on A-Glonass system.
+ *
+ * @param protocol Bitmask that specifies the positioning protocol to be
+ * set as per GlonassPositioningProtocol enum.
+ *
+ * @return success True if operation was successful.
+ */
+ setGlonassPositioningProtocol(uint8_t protocol) generates (bool success);
+
+ /*
+ * This method configures which PDN to use.
+ *
+ * @param enable Use emergency PDN if true and regular PDN if false.
+ * @return success True if operation was successful.
+ */
+ setEmergencySuplPdn(bool enable) generates (bool success);
+};
diff --git a/gnss/1.0/IGnssDebug.hal b/gnss/1.0/IGnssDebug.hal
index b0ac69d..ff9ea9f 100644
--- a/gnss/1.0/IGnssDebug.hal
+++ b/gnss/1.0/IGnssDebug.hal
@@ -2,7 +2,7 @@
/* Extended interface for DEBUG support. */
interface IGnssDebug {
- enum SatelliteEphemerisType : uint32_t {
+ enum SatelliteEphemerisType : uint8_t {
/* no information is known to the gnss hardware, about this satellite */
UNKNOWN,
/* this satellite is known to exist */
@@ -37,14 +37,14 @@
/*
* Validity of the data in this struct. False only if no
* latitude/longitude information is known.
- * /
+ */
bool valid;
/* Latitude expressed in degrees */
double latitudeDegrees;
/* Longitude expressed in degrees */
double longitudeDegrees;
/* Altitude above ellipsoid expressed in meters */
- float altitudeDegrees;
+ float altitudeMeters;
/*
* estimated horizontal accuracy of position expressed in meters, radial,
* 68% confidence.
diff --git a/gnss/1.0/IGnssGeofenceCallback.hal b/gnss/1.0/IGnssGeofenceCallback.hal
index 06eb62a..5c70c5e 100644
--- a/gnss/1.0/IGnssGeofenceCallback.hal
+++ b/gnss/1.0/IGnssGeofenceCallback.hal
@@ -69,7 +69,7 @@
* addGeofenceArea method.
*
* Even though the diagram and explanation talks about states and transitions,
- * the callee is only interested in the transistions. The states are mentioned
+ * the callee is only interested in the transitions. The states are mentioned
* here for illustrative purposes.
*
* Startup Scenario: When the device boots up, if an application adds geofences,
diff --git a/gnss/1.0/IGnssGeofencing.hal b/gnss/1.0/IGnssGeofencing.hal
index 89301f4..8417333 100644
--- a/gnss/1.0/IGnssGeofencing.hal
+++ b/gnss/1.0/IGnssGeofencing.hal
@@ -53,7 +53,7 @@
* @param unknownTimerMs - The time limit after which the UNCERTAIN transition
* must be triggered. This parameter is defined in milliseconds.
*/
- addGeofenceArea(int32_t geofenceId, double latitudeDegrees, double longitudeDegrees,
+ addGeofence(int32_t geofenceId, double latitudeDegrees, double longitudeDegrees,
double radiusMeters, GeofenceTransition lastTransition,
int32_t monitorTransitions, uint32_t notificationResponsivenessMs,
uint32_t unknownTimerMs);
@@ -82,5 +82,5 @@
*
* @param geofenceId The id of the geofence.
*/
- removeGeofenceArea(int32_t geofenceId);
+ removeGeofence(int32_t geofenceId);
};
diff --git a/gnss/1.0/IGnssMeasurement.hal b/gnss/1.0/IGnssMeasurement.hal
index 5156b32..5174273 100644
--- a/gnss/1.0/IGnssMeasurement.hal
+++ b/gnss/1.0/IGnssMeasurement.hal
@@ -43,7 +43,7 @@
* Returns ERROR_GENERIC for any other error. The HAL must
* not generate any other updates upon returning this error code.
*/
- setCallback(IGnssMeasurementCallback callback) generates (int32_t initRet);
+ setCallback(IGnssMeasurementCallback callback) generates (GnssMeasurementStatus initRet);
/*
* Stops updates from the HAL, and unregisters the callback routines.
diff --git a/gnss/1.0/IGnssMeasurementCallback.hal b/gnss/1.0/IGnssMeasurementCallback.hal
index 3650892..cc34c91 100644
--- a/gnss/1.0/IGnssMeasurementCallback.hal
+++ b/gnss/1.0/IGnssMeasurementCallback.hal
@@ -539,7 +539,7 @@
uint32_t measurementCount;
/* The array of measurements. */
- GnssMeasurement[ConstS32:GNSS_MAX_MEASUREMENT] measurements;
+ GnssMeasurement[GnssMax:SVS_COUNT] measurements;
/** The GNSS clock time reading. */
GnssClock clock;
diff --git a/gnss/1.0/IGnssNavigationMessage.hal b/gnss/1.0/IGnssNavigationMessage.hal
index d59b538..11f2096 100644
--- a/gnss/1.0/IGnssNavigationMessage.hal
+++ b/gnss/1.0/IGnssNavigationMessage.hal
@@ -42,7 +42,7 @@
* expected that the HAL will not generate any updates upon returning
* this error code.
*/
- setCallback(IGnssNavigationMessageCallback callback) generates (int32_t initRet);
+ setCallback(IGnssNavigationMessageCallback callback) generates (GnssNavigationMessageStatus initRet);
/*
* Stops updates from the HAL, and unregisters the callback routines.
diff --git a/gnss/1.0/IGnssNavigationMessageCallback.hal b/gnss/1.0/IGnssNavigationMessageCallback.hal
index a714fd7..6988c9a 100644
--- a/gnss/1.0/IGnssNavigationMessageCallback.hal
+++ b/gnss/1.0/IGnssNavigationMessageCallback.hal
@@ -26,7 +26,7 @@
* is typically transmitted.
*/
enum GnssNavigationMessageType : int16_t {
- TYPE_UNKNOWN = 0,
+ UNKNOWN = 0,
/** GNSS L1 C/A message contained in the structure. */
GNSS_L1CA = 0x0101,
/** GNSS L2-CNAV message contained in the structure. */
@@ -59,7 +59,7 @@
enum NavigationMessageStatus : uint16_t {
PARITY_PASSED = (1 << 0),
PARITY_REBUILT = (1 << 1),
- STATUS_UNKOWN = 0
+ UNKNOWN = 0
};
struct GnssNavigationMessage {
diff --git a/gnss/1.0/IGnssNiCallback.hal b/gnss/1.0/IGnssNiCallback.hal
index c696a92..f23b354 100644
--- a/gnss/1.0/IGnssNiCallback.hal
+++ b/gnss/1.0/IGnssNiCallback.hal
@@ -21,7 +21,7 @@
/*
* GnssNiType constants
*/
- enum GnssNiType : uint32_t {
+ enum GnssNiType : uint8_t {
VOICE = 1,
UMTS_SUPL = 2,
UMTS_CTRL_PLANE = 3
@@ -43,7 +43,7 @@
* GNSS NI responses, used to define the response in
* NI structures
*/
- enum GnssUserResponseType : int32_t {
+ enum GnssUserResponseType : uint8_t {
RESPONSE_ACCEPT = 1,
RESPONSE_DENY = 2,
RESPONSE_NORESP = 3,
diff --git a/gnss/1.0/default/AGnss.cpp b/gnss/1.0/default/AGnss.cpp
new file mode 100644
index 0000000..52fdc26
--- /dev/null
+++ b/gnss/1.0/default/AGnss.cpp
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "GnssHAL_AGnssInterface"
+
+#include "AGnss.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+std::vector<std::unique_ptr<ThreadFuncArgs>> AGnss::sThreadFuncArgsList;
+sp<IAGnssCallback> AGnss::sAGnssCbIface = nullptr;
+bool AGnss::sInterfaceExists = false;
+
+AGpsCallbacks AGnss::sAGnssCb = {
+ .status_cb = statusCb,
+ .create_thread_cb = createThreadCb
+};
+
+AGnss::AGnss(const AGpsInterface* aGpsIface) : mAGnssIface(aGpsIface) {
+ /* Error out if an instance of the interface already exists. */
+ LOG_ALWAYS_FATAL_IF(sInterfaceExists);
+ sInterfaceExists = true;
+}
+
+AGnss::~AGnss() {
+ sThreadFuncArgsList.clear();
+}
+
+void AGnss::statusCb(AGpsStatus* status) {
+ if (sAGnssCbIface == nullptr) {
+ ALOGE("%s: AGNSS Callback Interface configured incorrectly", __func__);
+ return;
+ }
+
+ if (status == nullptr) {
+ ALOGE("AGNSS status is invalid");
+ return;
+ }
+
+ /*
+ * Logic based on AGnssStatus processing by GnssLocationProvider. Size of
+ * AGpsStatus is checked for backward compatibility since some devices may
+ * be sending out an older version of AGpsStatus that only supports IPv4.
+ */
+ size_t statusSize = status->size;
+ if (status->size == sizeof(AGpsStatus)) {
+ switch (status->addr.ss_family)
+ {
+ case AF_INET:
+ {
+ /*
+ * ss_family indicates IPv4.
+ */
+ struct sockaddr_in* in = reinterpret_cast<struct sockaddr_in*>(&(status->addr));
+ IAGnssCallback::AGnssStatusIpV4 aGnssStatusIpV4 = {
+ .type = static_cast<IAGnssCallback::AGnssType>(status->type),
+ .status = static_cast<IAGnssCallback::AGnssStatusValue>(status->status),
+ .ipV4Addr = in->sin_addr.s_addr,
+ };
+
+ /*
+ * Callback to client with agnssStatusIpV4Cb.
+ */
+ sAGnssCbIface->agnssStatusIpV4Cb(aGnssStatusIpV4);
+ break;
+ }
+ case AF_INET6:
+ {
+ /*
+ * ss_family indicates IPv6. Callback to client with agnssStatusIpV6Cb.
+ */
+ IAGnssCallback::AGnssStatusIpV6 aGnssStatusIpV6;
+
+ aGnssStatusIpV6.type = static_cast<IAGnssCallback::AGnssType>(status->type);
+ aGnssStatusIpV6.status = static_cast<IAGnssCallback::AGnssStatusValue>(
+ status->status);
+
+ struct sockaddr_in6* in6 = reinterpret_cast<struct sockaddr_in6 *>(
+ &(status->addr));
+ memcpy(&(aGnssStatusIpV6.ipV6Addr[0]), in6->sin6_addr.s6_addr,
+ aGnssStatusIpV6.ipV6Addr.size());
+ sAGnssCbIface->agnssStatusIpV6Cb(aGnssStatusIpV6);
+ break;
+ }
+ default:
+ ALOGE("Invalid ss_family found: %d", status->addr.ss_family);
+ }
+ } else if (statusSize >= sizeof(AGpsStatus_v2)) {
+ AGpsStatus_v2* statusV2 = reinterpret_cast<AGpsStatus_v2*>(status);
+ uint32_t ipV4Addr = statusV2->ipaddr;
+ IAGnssCallback::AGnssStatusIpV4 aGnssStatusIpV4 = {
+ .type = static_cast<IAGnssCallback::AGnssType>(AF_INET),
+ .status = static_cast<IAGnssCallback::AGnssStatusValue>(status->status),
+ /*
+ * For older versions of AGpsStatus, change IP addr to net order. This
+ * was earlier being done in GnssLocationProvider.
+ */
+ .ipV4Addr = htonl(ipV4Addr)
+ };
+ /*
+ * Callback to client with agnssStatusIpV4Cb.
+ */
+ sAGnssCbIface->agnssStatusIpV4Cb(aGnssStatusIpV4);
+ } else {
+ ALOGE("%s: Invalid size for AGPS Status", __func__);
+ }
+}
+
+pthread_t AGnss::createThreadCb(const char* name, void (*start)(void*), void* arg) {
+ return createPthread(name, start, arg, &sThreadFuncArgsList);
+}
+
+/*
+ * Implementation of methods from ::android::hardware::gnss::V1_0::IAGnss follow.
+ */
+Return<void> AGnss::setCallback(const sp<IAGnssCallback>& callback) {
+ if (mAGnssIface == nullptr) {
+ ALOGE("%s: AGnss interface is unavailable", __func__);
+ return Void();
+ }
+
+ sAGnssCbIface = callback;
+
+ mAGnssIface->init(&sAGnssCb);
+ return Void();
+}
+
+Return<bool> AGnss::dataConnClosed() {
+ if (mAGnssIface == nullptr) {
+ ALOGE("%s: AGnss interface is unavailable", __func__);
+ return false;
+ }
+
+ return (mAGnssIface->data_conn_closed() == 0);
+}
+
+Return<bool> AGnss::dataConnFailed() {
+ if (mAGnssIface == nullptr) {
+ ALOGE("%s: AGnss interface is unavailable", __func__);
+ return false;
+ }
+
+ return (mAGnssIface->data_conn_failed() == 0);
+}
+
+Return<bool> AGnss::setServer(IAGnssCallback::AGnssType type,
+ const hidl_string& hostname,
+ int32_t port) {
+ if (mAGnssIface == nullptr) {
+ ALOGE("%s: AGnss interface is unavailable", __func__);
+ return false;
+ }
+
+ return (mAGnssIface->set_server(static_cast<AGpsType>(type), hostname.c_str(), port) == 0);
+}
+
+Return<bool> AGnss::dataConnOpen(const hidl_string& apn, IAGnss::ApnIpType apnIpType) {
+ if (mAGnssIface == nullptr) {
+ ALOGE("%s: AGnss interface is unavailable", __func__);
+ return false;
+ }
+
+ return (mAGnssIface->data_conn_open_with_apn_ip_type(apn.c_str(),
+ static_cast<uint16_t>(apnIpType)) == 0);
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gnss/1.0/default/AGnss.h b/gnss/1.0/default/AGnss.h
new file mode 100644
index 0000000..2a8eed0
--- /dev/null
+++ b/gnss/1.0/default/AGnss.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef android_hardware_gnss_V1_0_AGnss_H_
+#define android_hardware_gnss_V1_0_AGnss_H_
+
+#include <ThreadCreationWrapper.h>
+#include <android/hardware/gnss/1.0/IAGnss.h>
+#include <hardware/gps_internal.h>
+#include <hidl/Status.h>
+#include <netinet/in.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_0::IAGnss;
+using ::android::hardware::gnss::V1_0::IAGnssCallback;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+/*
+ * Extended interface for AGNSS support. Also contains wrapper methods to allow
+ * methods from IAGnssCallback interface to be passed into the conventional
+ * implementation of the GNSS HAL.
+ */
+struct AGnss : public IAGnss {
+ AGnss(const AGpsInterface* agpsIface);
+ ~AGnss();
+ /*
+ * Methods from ::android::hardware::gnss::V1_0::IAGnss interface follow.
+ * These declarations were generated from IAGnss.hal.
+ */
+ Return<void> setCallback(const sp<IAGnssCallback>& callback) override;
+ Return<bool> dataConnClosed() override;
+ Return<bool> dataConnFailed() override;
+ Return<bool> setServer(IAGnssCallback::AGnssType type,
+ const hidl_string& hostname, int32_t port) override;
+ Return<bool> dataConnOpen(const hidl_string& apn,
+ IAGnss::ApnIpType apnIpType) override;
+
+ /*
+ * Callback methods to be passed into the conventional GNSS HAL by the default
+ * implementation. These methods are not part of the IAGnss base class.
+ */
+ static pthread_t createThreadCb(const char* name, void (*start)(void*), void* arg);
+ static void statusCb(AGpsStatus* status);
+
+ /*
+ * Holds function pointers to the callback methods.
+ */
+ static AGpsCallbacks sAGnssCb;
+
+ private:
+ const AGpsInterface* mAGnssIface = nullptr;
+ static sp<IAGnssCallback> sAGnssCbIface;
+ static std::vector<std::unique_ptr<ThreadFuncArgs>> sThreadFuncArgsList;
+ static bool sInterfaceExists;
+};
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // android_hardware_gnss_V1_0_AGnss_H_
diff --git a/gnss/1.0/default/AGnssRil.cpp b/gnss/1.0/default/AGnssRil.cpp
new file mode 100644
index 0000000..87abad7
--- /dev/null
+++ b/gnss/1.0/default/AGnssRil.cpp
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "GnssHAL_AGnssRilInterface"
+
+#include "AGnssRil.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+std::vector<std::unique_ptr<ThreadFuncArgs>> AGnssRil::sThreadFuncArgsList;
+sp<IAGnssRilCallback> AGnssRil::sAGnssRilCbIface = nullptr;
+bool AGnssRil::sInterfaceExists = false;
+
+AGpsRilCallbacks AGnssRil::sAGnssRilCb = {
+ .request_setid = AGnssRil::requestSetId,
+ .request_refloc = AGnssRil::requestRefLoc,
+ .create_thread_cb = AGnssRil::createThreadCb
+};
+
+AGnssRil::AGnssRil(const AGpsRilInterface* aGpsRilIface) : mAGnssRilIface(aGpsRilIface) {
+ /* Error out if an instance of the interface already exists. */
+ LOG_ALWAYS_FATAL_IF(sInterfaceExists);
+ sInterfaceExists = true;
+}
+
+AGnssRil::~AGnssRil() {
+ sThreadFuncArgsList.clear();
+}
+
+void AGnssRil::requestSetId(uint32_t flags) {
+ if (sAGnssRilCbIface == nullptr) {
+ ALOGE("%s: AGNSSRil Callback Interface configured incorrectly", __func__);
+ return;
+ }
+
+ sAGnssRilCbIface->requestSetIdCb(static_cast<IAGnssRilCallback::ID>(flags));
+}
+
+void AGnssRil::requestRefLoc(uint32_t /*flags*/) {
+ if (sAGnssRilCbIface == nullptr) {
+ ALOGE("%s: AGNSSRil Callback Interface configured incorrectly", __func__);
+ return;
+ }
+
+ sAGnssRilCbIface->requestRefLocCb();
+}
+
+pthread_t AGnssRil::createThreadCb(const char* name, void (*start)(void*), void* arg) {
+ return createPthread(name, start, arg, &sThreadFuncArgsList);
+}
+
+// Methods from ::android::hardware::gnss::V1_0::IAGnssRil follow.
+Return<void> AGnssRil::setCallback(const sp<IAGnssRilCallback>& callback) {
+ if (mAGnssRilIface == nullptr) {
+ ALOGE("%s: AGnssRil interface is unavailable", __func__);
+ return Void();
+ }
+
+ sAGnssRilCbIface = callback;
+
+ mAGnssRilIface->init(&sAGnssRilCb);
+ return Void();
+}
+
+Return<void> AGnssRil::setRefLocation(const IAGnssRil::AGnssRefLocation& aGnssRefLocation) {
+ if (mAGnssRilIface == nullptr) {
+ ALOGE("%s: AGnssRil interface is unavailable", __func__);
+ return Void();
+ }
+
+ AGpsRefLocation aGnssRefloc;
+ aGnssRefloc.type = static_cast<uint16_t>(aGnssRefLocation.type);
+
+ auto& cellID = aGnssRefLocation.cellID;
+ aGnssRefloc.u.cellID = {
+ .type = static_cast<uint16_t>(cellID.type),
+ .mcc = cellID.mcc,
+ .mnc = cellID.mnc,
+ .lac = cellID.lac,
+ .cid = cellID.cid,
+ .tac = cellID.tac,
+ .pcid = cellID.pcid
+ };
+
+ mAGnssRilIface->set_ref_location(&aGnssRefloc, sizeof(aGnssRefloc));
+ return Void();
+}
+
+Return<bool> AGnssRil::setSetId(IAGnssRil::SetIDType type, const hidl_string& setid) {
+ if (mAGnssRilIface == nullptr) {
+ ALOGE("%s: AGnssRil interface is unavailable", __func__);
+ return false;
+ }
+
+ mAGnssRilIface->set_set_id(static_cast<uint16_t>(type), setid.c_str());
+ return true;
+}
+
+Return<bool> AGnssRil::updateNetworkState(bool connected,
+ IAGnssRil::NetworkType type,
+ bool roaming) {
+ if (mAGnssRilIface == nullptr) {
+ ALOGE("%s: AGnssRil interface is unavailable", __func__);
+ return false;
+ }
+
+ mAGnssRilIface->update_network_state(connected,
+ static_cast<int>(type),
+ roaming,
+ nullptr /* extra_info */);
+ return true;
+}
+
+Return<bool> AGnssRil::updateNetworkAvailability(bool available, const hidl_string& apn) {
+ if (mAGnssRilIface == nullptr) {
+ ALOGE("%s: AGnssRil interface is unavailable", __func__);
+ return false;
+ }
+
+ mAGnssRilIface->update_network_availability(available, apn.c_str());
+ return true;
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gnss/1.0/default/AGnssRil.h b/gnss/1.0/default/AGnssRil.h
new file mode 100644
index 0000000..6215a9e
--- /dev/null
+++ b/gnss/1.0/default/AGnssRil.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef android_hardware_gnss_V1_0_AGnssRil_H_
+#define android_hardware_gnss_V1_0_AGnssRil_H_
+
+#include <ThreadCreationWrapper.h>
+#include <android/hardware/gnss/1.0/IAGnssRil.h>
+#include <hardware/gps.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_0::IAGnssRil;
+using ::android::hardware::gnss::V1_0::IAGnssRilCallback;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+/*
+ * Extended interface for AGNSS RIL support. An Assisted GNSS Radio Interface Layer interface
+ * allows the GNSS chipset to request radio interface layer information from Android platform.
+ * Examples of such information are reference location, unique subscriber ID, phone number string
+ * and network availability changes. Also contains wrapper methods to allow methods from
+ * IAGnssiRilCallback interface to be passed into the conventional implementation of the GNSS HAL.
+ */
+struct AGnssRil : public IAGnssRil {
+ AGnssRil(const AGpsRilInterface* aGpsRilIface);
+ ~AGnssRil();
+
+ /*
+ * Methods from ::android::hardware::gnss::V1_0::IAGnssRil follow.
+ * These declarations were generated from IAGnssRil.hal.
+ */
+ Return<void> setCallback(const sp<IAGnssRilCallback>& callback) override;
+ Return<void> setRefLocation(const IAGnssRil::AGnssRefLocation& agnssReflocation) override;
+ Return<bool> setSetId(IAGnssRil::SetIDType type, const hidl_string& setid) override;
+ Return<bool> updateNetworkState(bool connected,
+ IAGnssRil::NetworkType type,
+ bool roaming) override;
+ Return<bool> updateNetworkAvailability(bool available, const hidl_string& apn) override;
+ static void requestSetId(uint32_t flags);
+ static void requestRefLoc(uint32_t flags);
+
+ /*
+ * Callback method to be passed into the conventional GNSS HAL by the default
+ * implementation. This method is not part of the IAGnssRil base class.
+ */
+ static pthread_t createThreadCb(const char* name, void (*start)(void*), void* arg);
+
+ /*
+ * Holds function pointers to the callback methods.
+ */
+ static AGpsRilCallbacks sAGnssRilCb;
+
+ private:
+ const AGpsRilInterface* mAGnssRilIface = nullptr;
+ static sp<IAGnssRilCallback> sAGnssRilCbIface;
+ static std::vector<std::unique_ptr<ThreadFuncArgs>> sThreadFuncArgsList;
+ static bool sInterfaceExists;
+};
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // android_hardware_gnss_V1_0_AGnssRil_H_
diff --git a/gnss/1.0/default/Android.mk b/gnss/1.0/default/Android.mk
new file mode 100644
index 0000000..06ef331
--- /dev/null
+++ b/gnss/1.0/default/Android.mk
@@ -0,0 +1,29 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.gnss@1.0-impl
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_SRC_FILES := \
+ ThreadCreationWrapper.cpp \
+ AGnss.cpp \
+ AGnssRil.cpp \
+ Gnss.cpp \
+ GnssDebug.cpp \
+ GnssGeofencing.cpp \
+ GnssMeasurement.cpp \
+ GnssNavigationMessage.cpp \
+ GnssNi.cpp \
+ GnssXtra.cpp \
+ GnssConfiguration.cpp \
+ GnssUtils.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+ liblog \
+ libhidlbase \
+ libhidltransport \
+ libhwbinder \
+ libutils \
+ android.hardware.gnss@1.0 \
+ libhardware
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/gnss/1.0/default/Gnss.cpp b/gnss/1.0/default/Gnss.cpp
new file mode 100644
index 0000000..37810be
--- /dev/null
+++ b/gnss/1.0/default/Gnss.cpp
@@ -0,0 +1,569 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "GnssHAL_GnssInterface"
+
+#include "Gnss.h"
+#include <GnssUtils.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+std::vector<std::unique_ptr<ThreadFuncArgs>> Gnss::sThreadFuncArgsList;
+sp<IGnssCallback> Gnss::sGnssCbIface = nullptr;
+bool Gnss::sInterfaceExists = false;
+
+GpsCallbacks Gnss::sGnssCb = {
+ .size = sizeof(GpsCallbacks),
+ .location_cb = locationCb,
+ .status_cb = statusCb,
+ .sv_status_cb = gpsSvStatusCb,
+ .nmea_cb = nmeaCb,
+ .set_capabilities_cb = setCapabilitiesCb,
+ .acquire_wakelock_cb = acquireWakelockCb,
+ .release_wakelock_cb = releaseWakelockCb,
+ .create_thread_cb = createThreadCb,
+ .request_utc_time_cb = requestUtcTimeCb,
+ .set_system_info_cb = setSystemInfoCb,
+ .gnss_sv_status_cb = gnssSvStatusCb,
+};
+
+Gnss::Gnss(gps_device_t* gnssDevice) {
+ /* Error out if an instance of the interface already exists. */
+ LOG_ALWAYS_FATAL_IF(sInterfaceExists);
+ sInterfaceExists = true;
+
+ if (gnssDevice == nullptr) {
+ ALOGE("%s: Invalid device_t handle", __func__);
+ return;
+ }
+
+ mGnssIface = gnssDevice->get_gps_interface(gnssDevice);
+}
+
+Gnss::~Gnss() {
+ sThreadFuncArgsList.clear();
+}
+
+void Gnss::locationCb(GpsLocation* location) {
+ if (sGnssCbIface == nullptr) {
+ ALOGE("%s: GNSS Callback Interface configured incorrectly", __func__);
+ return;
+ }
+
+ if (location == nullptr) {
+ ALOGE("%s: Invalid location from GNSS HAL", __func__);
+ return;
+ }
+
+ android::hardware::gnss::V1_0::GnssLocation gnssLocation = convertToGnssLocation(location);
+ sGnssCbIface->gnssLocationCb(gnssLocation);
+}
+
+void Gnss::statusCb(GpsStatus* gnssStatus) {
+ if (sGnssCbIface == nullptr) {
+ ALOGE("%s: GNSS Callback Interface configured incorrectly", __func__);
+ return;
+ }
+
+ if (gnssStatus == nullptr) {
+ ALOGE("%s: Invalid GpsStatus from GNSS HAL", __func__);
+ return;
+ }
+
+ IGnssCallback::GnssStatusValue status =
+ static_cast<IGnssCallback::GnssStatusValue>(gnssStatus->status);
+
+ sGnssCbIface->gnssStatusCb(status);
+}
+
+void Gnss::gnssSvStatusCb(GnssSvStatus* status) {
+ if (sGnssCbIface == nullptr) {
+ ALOGE("%s: GNSS Callback Interface configured incorrectly", __func__);
+ return;
+ }
+
+ if (status == nullptr) {
+ ALOGE("Invalid status from GNSS HAL %s", __func__);
+ return;
+ }
+
+ IGnssCallback::GnssSvStatus svStatus;
+ svStatus.numSvs = status->num_svs;
+
+ if (svStatus.numSvs > static_cast<uint32_t>(GnssMax::SVS_COUNT)) {
+ ALOGW("Too many satellites %zd. Clamps to %d.", svStatus.numSvs, GnssMax::SVS_COUNT);
+ svStatus.numSvs = static_cast<uint32_t>(GnssMax::SVS_COUNT);
+ }
+
+ for (size_t i = 0; i < svStatus.numSvs; i++) {
+ auto svInfo = status->gnss_sv_list[i];
+ IGnssCallback::GnssSvInfo gnssSvInfo = {
+ .svid = svInfo.svid,
+ .constellation = static_cast<android::hardware::gnss::V1_0::GnssConstellationType>(
+ svInfo.constellation),
+ .cN0Dbhz = svInfo.c_n0_dbhz,
+ .elevationDegrees = svInfo.elevation,
+ .azimuthDegrees = svInfo.azimuth,
+ .svFlag = static_cast<IGnssCallback::GnssSvFlags>(svInfo.flags)
+ };
+ svStatus.gnssSvList[i] = gnssSvInfo;
+ }
+
+ sGnssCbIface->gnssSvStatusCb(svStatus);
+}
+
+/*
+ * This enum is used by gpsSvStatusCb() method below to convert GpsSvStatus
+ * to GnssSvStatus for backward compatibility. It is only used by the default
+ * implementation and is not part of the GNSS interface.
+ */
+enum SvidValues : uint16_t {
+ GLONASS_SVID_OFFSET = 64,
+ GLONASS_SVID_COUNT = 24,
+ BEIDOU_SVID_OFFSET = 200,
+ BEIDOU_SVID_COUNT = 35,
+ SBAS_SVID_MIN = 33,
+ SBAS_SVID_MAX = 64,
+ SBAS_SVID_ADD = 87,
+ QZSS_SVID_MIN = 193,
+ QZSS_SVID_MAX = 200
+};
+
+/*
+ * The following code that converts GpsSvStatus to GnssSvStatus is moved here from
+ * GnssLocationProvider. GnssLocationProvider does not require it anymore since GpsSvStatus is
+ * being deprecated and is no longer part of the GNSS interface.
+ */
+void Gnss::gpsSvStatusCb(GpsSvStatus* svInfo) {
+ if (sGnssCbIface == nullptr) {
+ ALOGE("%s: GNSS Callback Interface configured incorrectly", __func__);
+ return;
+ }
+
+ if (svInfo == nullptr) {
+ ALOGE("Invalid status from GNSS HAL %s", __func__);
+ return;
+ }
+
+ IGnssCallback::GnssSvStatus svStatus;
+ svStatus.numSvs = svInfo->num_svs;
+ /*
+ * Clamp the list size since GnssSvStatus can support a maximum of
+ * GnssMax::SVS_COUNT entries.
+ */
+ if (svStatus.numSvs > static_cast<uint32_t>(GnssMax::SVS_COUNT)) {
+ ALOGW("Too many satellites %zd. Clamps to %d.", svStatus.numSvs, GnssMax::SVS_COUNT);
+ svStatus.numSvs = static_cast<uint32_t>(GnssMax::SVS_COUNT);
+ }
+
+ uint32_t ephemerisMask = svInfo->ephemeris_mask;
+ uint32_t almanacMask = svInfo->almanac_mask;
+ uint32_t usedInFixMask = svInfo->used_in_fix_mask;
+ /*
+ * Conversion from GpsSvInfo to IGnssCallback::GnssSvInfo happens below.
+ */
+ for (size_t i = 0; i < svStatus.numSvs; i++) {
+ IGnssCallback::GnssSvInfo& info = svStatus.gnssSvList[i];
+ info.svid = svInfo->sv_list[i].prn;
+ if (info.svid >= 1 && info.svid <= 32) {
+ info.constellation = GnssConstellationType::GPS;
+ } else if (info.svid > GLONASS_SVID_OFFSET &&
+ info.svid <= GLONASS_SVID_OFFSET + GLONASS_SVID_COUNT) {
+ info.constellation = GnssConstellationType::GLONASS;
+ info.svid -= GLONASS_SVID_OFFSET;
+ } else if (info.svid > BEIDOU_SVID_OFFSET &&
+ info.svid <= BEIDOU_SVID_OFFSET + BEIDOU_SVID_COUNT) {
+ info.constellation = GnssConstellationType::BEIDOU;
+ info.svid -= BEIDOU_SVID_OFFSET;
+ } else if (info.svid >= SBAS_SVID_MIN && info.svid <= SBAS_SVID_MAX) {
+ info.constellation = GnssConstellationType::SBAS;
+ info.svid += SBAS_SVID_ADD;
+ } else if (info.svid >= QZSS_SVID_MIN && info.svid <= QZSS_SVID_MAX) {
+ info.constellation = GnssConstellationType::QZSS;
+ } else {
+ ALOGD("Unknown constellation type with Svid = %d.", info.svid);
+ info.constellation = GnssConstellationType::UNKNOWN;
+ }
+
+ info.cN0Dbhz = svInfo->sv_list[i].snr;
+ info.elevationDegrees = svInfo->sv_list[i].elevation;
+ info.azimuthDegrees = svInfo->sv_list[i].azimuth;
+ info.svFlag = IGnssCallback::GnssSvFlags::NONE;
+
+ /*
+ * Only GPS info is valid for these fields, as these masks are just 32
+ * bits, by GPS prn.
+ */
+ if (info.constellation == GnssConstellationType::GPS) {
+ int32_t svidMask = (1 << (info.svid - 1));
+ if ((ephemerisMask & svidMask) != 0) {
+ info.svFlag |= IGnssCallback::GnssSvFlags::HAS_EPHEMERIS_DATA;
+ }
+ if ((almanacMask & svidMask) != 0) {
+ info.svFlag |= IGnssCallback::GnssSvFlags::HAS_ALMANAC_DATA;
+ }
+ if ((usedInFixMask & svidMask) != 0) {
+ info.svFlag |= IGnssCallback::GnssSvFlags::USED_IN_FIX;
+ }
+ }
+ }
+
+ sGnssCbIface->gnssSvStatusCb(svStatus);
+}
+
+void Gnss::nmeaCb(GpsUtcTime timestamp, const char* nmea, int length) {
+ if (sGnssCbIface == nullptr) {
+ ALOGE("%s: GNSS Callback Interface configured incorrectly", __func__);
+ return;
+ }
+
+ android::hardware::hidl_string nmeaString;
+ nmeaString.setToExternal(nmea, length);
+ sGnssCbIface->gnssNmeaCb(timestamp, nmeaString);
+}
+
+void Gnss::setCapabilitiesCb(uint32_t capabilities) {
+ if (sGnssCbIface == nullptr) {
+ ALOGE("%s: GNSS Callback Interface configured incorrectly", __func__);
+ return;
+ }
+
+ sGnssCbIface->gnssSetCapabilitesCb(capabilities);
+}
+
+void Gnss::acquireWakelockCb() {
+ if (sGnssCbIface == nullptr) {
+ ALOGE("%s: GNSS Callback Interface configured incorrectly", __func__);
+ return;
+ }
+
+ sGnssCbIface->gnssAcquireWakelockCb();
+}
+
+void Gnss::releaseWakelockCb() {
+ if (sGnssCbIface == nullptr) {
+ ALOGE("%s: GNSS Callback Interface configured incorrectly", __func__);
+ return;
+ }
+
+ sGnssCbIface->gnssReleaseWakelockCb();
+}
+
+void Gnss::requestUtcTimeCb() {
+ if (sGnssCbIface == nullptr) {
+ ALOGE("%s: GNSS Callback Interface configured incorrectly", __func__);
+ return;
+ }
+
+ sGnssCbIface->gnssRequestTimeCb();
+}
+
+pthread_t Gnss::createThreadCb(const char* name, void (*start)(void*), void* arg) {
+ return createPthread(name, start, arg, &sThreadFuncArgsList);
+}
+
+void Gnss::setSystemInfoCb(const LegacyGnssSystemInfo* info) {
+ if (sGnssCbIface == nullptr) {
+ ALOGE("%s: GNSS Callback Interface configured incorrectly", __func__);
+ return;
+ }
+
+ if (info == nullptr) {
+ ALOGE("Invalid GnssSystemInfo from GNSS HAL %s", __func__);
+ return;
+ }
+
+ IGnssCallback::GnssSystemInfo gnssInfo = {
+ .yearOfHw = info->year_of_hw
+ };
+
+ sGnssCbIface->gnssSetSystemInfoCb(gnssInfo);
+}
+
+
+// Methods from ::android::hardware::gnss::V1_0::IGnss follow.
+Return<bool> Gnss::setCallback(const sp<IGnssCallback>& callback) {
+ if (mGnssIface == nullptr) {
+ ALOGE("%s: Gnss interface is unavailable", __func__);
+ return false;
+ }
+
+ sGnssCbIface = callback;
+
+ return (mGnssIface->init(&sGnssCb) == 0);
+}
+
+Return<bool> Gnss::start() {
+ if (mGnssIface == nullptr) {
+ ALOGE("%s: Gnss interface is unavailable", __func__);
+ return false;
+ }
+
+ return (mGnssIface->start() == 0);
+}
+
+Return<bool> Gnss::stop() {
+ if (mGnssIface == nullptr) {
+ ALOGE("%s: Gnss interface is unavailable", __func__);
+ return false;
+ }
+
+ return (mGnssIface->stop() == 0);
+}
+
+Return<void> Gnss::cleanup() {
+ if (mGnssIface == nullptr) {
+ ALOGE("%s: Gnss interface is unavailable", __func__);
+ } else {
+ mGnssIface->cleanup();
+ }
+ return Void();
+}
+
+Return<bool> Gnss::injectLocation(double latitudeDegrees,
+ double longitudeDegrees,
+ float accuracyMeters) {
+ if (mGnssIface == nullptr) {
+ ALOGE("%s: Gnss interface is unavailable", __func__);
+ return false;
+ }
+
+ return (mGnssIface->inject_location(latitudeDegrees, longitudeDegrees, accuracyMeters) == 0);
+}
+
+Return<bool> Gnss::injectTime(int64_t timeMs, int64_t timeReferenceMs,
+ int32_t uncertaintyMs) {
+ if (mGnssIface == nullptr) {
+ ALOGE("%s: Gnss interface is unavailable", __func__);
+ return false;
+ }
+
+ return (mGnssIface->inject_time(timeMs, timeReferenceMs, uncertaintyMs) == 0);
+}
+
+Return<void> Gnss::deleteAidingData(IGnss::GnssAidingData aidingDataFlags) {
+ if (mGnssIface == nullptr) {
+ ALOGE("%s: Gnss interface is unavailable", __func__);
+ } else {
+ mGnssIface->delete_aiding_data(static_cast<GpsAidingData>(aidingDataFlags));
+ }
+ return Void();
+}
+
+Return<bool> Gnss::setPositionMode(IGnss::GnssPositionMode mode,
+ IGnss::GnssPositionRecurrence recurrence,
+ uint32_t minIntervalMs,
+ uint32_t preferredAccuracyMeters,
+ uint32_t preferredTimeMs) {
+ if (mGnssIface == nullptr) {
+ ALOGE("%s: Gnss interface is unavailable", __func__);
+ return false;
+ }
+
+ return (mGnssIface->set_position_mode(static_cast<GpsPositionMode>(mode),
+ static_cast<GpsPositionRecurrence>(recurrence),
+ minIntervalMs,
+ preferredAccuracyMeters,
+ preferredTimeMs) == 0);
+}
+
+Return<void> Gnss::getExtensionAGnssRil(getExtensionAGnssRil_cb _hidl_cb) {
+ if (mGnssIface == nullptr) {
+ ALOGE("%s: Gnss interface is unavailable", __func__);
+ } else {
+ const AGpsRilInterface* agpsRilIface = static_cast<const AGpsRilInterface*>(
+ mGnssIface->get_extension(AGPS_RIL_INTERFACE));
+ if (agpsRilIface == nullptr) {
+ ALOGE("%s GnssRil interface not implemented by GNSS HAL", __func__);
+ } else {
+ mGnssRil = new AGnssRil(agpsRilIface);
+ }
+ }
+ _hidl_cb(mGnssRil);
+ return Void();
+}
+
+Return<void> Gnss::getExtensionGnssConfiguration(getExtensionGnssConfiguration_cb _hidl_cb) {
+ if (mGnssIface == nullptr) {
+ ALOGE("%s: Gnss interface is unavailable", __func__);
+ } else {
+ const GnssConfigurationInterface* gnssConfigIface =
+ static_cast<const GnssConfigurationInterface*>(
+ mGnssIface->get_extension(GNSS_CONFIGURATION_INTERFACE));
+
+ if (gnssConfigIface == nullptr) {
+ ALOGE("%s GnssConfiguration interface not implemented by GNSS HAL", __func__);
+ } else {
+ mGnssConfig = new GnssConfiguration(gnssConfigIface);
+ }
+ }
+ _hidl_cb(mGnssConfig);
+ return Void();
+}
+Return<void> Gnss::getExtensionGnssGeofencing(getExtensionGnssGeofencing_cb _hidl_cb) {
+ if (mGnssIface == nullptr) {
+ ALOGE("%s: Gnss interface is unavailable", __func__);
+ } else {
+ const GpsGeofencingInterface* gpsGeofencingIface =
+ static_cast<const GpsGeofencingInterface*>(
+ mGnssIface->get_extension(GPS_GEOFENCING_INTERFACE));
+
+ if (gpsGeofencingIface == nullptr) {
+ ALOGE("%s GnssGeofencing interface not implemented by GNSS HAL", __func__);
+ } else {
+ mGnssGeofencingIface = new GnssGeofencing(gpsGeofencingIface);
+ }
+ }
+
+ _hidl_cb(mGnssGeofencingIface);
+ return Void();
+}
+
+Return<void> Gnss::getExtensionAGnss(getExtensionAGnss_cb _hidl_cb) {
+ if (mGnssIface == nullptr) {
+ ALOGE("%s: Gnss interface is unavailable", __func__);
+ } else {
+ const AGpsInterface* agpsIface = static_cast<const AGpsInterface*>(
+ mGnssIface->get_extension(AGPS_INTERFACE));
+ if (agpsIface == nullptr) {
+ ALOGE("%s AGnss interface not implemented by GNSS HAL", __func__);
+ } else {
+ mAGnssIface = new AGnss(agpsIface);
+ }
+ }
+ _hidl_cb(mAGnssIface);
+ return Void();
+}
+
+Return<void> Gnss::getExtensionGnssNi(getExtensionGnssNi_cb _hidl_cb) {
+ if (mGnssIface == nullptr) {
+ ALOGE("%s: Gnss interface is unavailable", __func__);
+ } else {
+ const GpsNiInterface* gpsNiIface = static_cast<const GpsNiInterface*>(
+ mGnssIface->get_extension(GPS_NI_INTERFACE));
+ if (gpsNiIface == nullptr) {
+ ALOGE("%s GnssNi interface not implemented by GNSS HAL", __func__);
+ } else {
+ mGnssNi = new GnssNi(gpsNiIface);
+ }
+ }
+ _hidl_cb(mGnssNi);
+ return Void();
+}
+
+Return<void> Gnss::getExtensionGnssMeasurement(getExtensionGnssMeasurement_cb _hidl_cb) {
+ if (mGnssIface == nullptr) {
+ ALOGE("%s: Gnss interface is unavailable", __func__);
+ } else {
+ const GpsMeasurementInterface* gpsMeasurementIface =
+ static_cast<const GpsMeasurementInterface*>(
+ mGnssIface->get_extension(GPS_MEASUREMENT_INTERFACE));
+
+ if (gpsMeasurementIface == nullptr) {
+ ALOGE("%s GnssMeasurement interface not implemented by GNSS HAL", __func__);
+ } else {
+ mGnssMeasurement = new GnssMeasurement(gpsMeasurementIface);
+ }
+ }
+ _hidl_cb(mGnssMeasurement);
+ return Void();
+}
+
+Return<void> Gnss::getExtensionGnssNavigationMessage(
+ getExtensionGnssNavigationMessage_cb _hidl_cb) {
+ if (mGnssIface == nullptr) {
+ ALOGE("%s: Gnss interface is unavailable", __func__);
+ } else {
+ const GpsNavigationMessageInterface* gpsNavigationMessageIface =
+ static_cast<const GpsNavigationMessageInterface*>(
+ mGnssIface->get_extension(GPS_NAVIGATION_MESSAGE_INTERFACE));
+
+ if (gpsNavigationMessageIface == nullptr) {
+ ALOGE("%s GnssNavigationMessage interface not implemented by GNSS HAL",
+ __func__);
+ } else {
+ mGnssNavigationMessage = new GnssNavigationMessage(gpsNavigationMessageIface);
+ }
+ }
+
+ _hidl_cb(mGnssNavigationMessage);
+ return Void();
+}
+
+Return<void> Gnss::getExtensionXtra(getExtensionXtra_cb _hidl_cb) {
+ if (mGnssIface == nullptr) {
+ ALOGE("%s: Gnss interface is unavailable", __func__);
+ } else {
+ const GpsXtraInterface* gpsXtraIface = static_cast<const GpsXtraInterface*>(
+ mGnssIface->get_extension(GPS_XTRA_INTERFACE));
+
+ if (gpsXtraIface == nullptr) {
+ ALOGE("%s GnssXtra interface not implemented by HAL", __func__);
+ } else {
+ mGnssXtraIface = new GnssXtra(gpsXtraIface);
+ }
+ }
+
+ _hidl_cb(mGnssXtraIface);
+ return Void();
+}
+
+Return<void> Gnss::getExtensionGnssDebug(getExtensionGnssDebug_cb _hidl_cb) {
+ if (mGnssIface == nullptr) {
+ ALOGE("%s: Gnss interface is unavailable", __func__);
+ } else {
+ const GpsDebugInterface* gpsDebugIface = static_cast<const GpsDebugInterface*>(
+ mGnssIface->get_extension(GPS_DEBUG_INTERFACE));
+
+ if (gpsDebugIface == nullptr) {
+ ALOGE("%s: GnssDebug interface is not implemented by HAL", __func__);
+ } else {
+ mGnssDebug = new GnssDebug(gpsDebugIface);
+ }
+ }
+
+ _hidl_cb(mGnssDebug);
+ return Void();
+}
+
+IGnss* HIDL_FETCH_IGnss(const char* hal) {
+ hw_module_t* module;
+ IGnss* iface = nullptr;
+ int err = hw_get_module(GPS_HARDWARE_MODULE_ID, (hw_module_t const**)&module);
+
+ if (err == 0) {
+ hw_device_t* device;
+ err = module->methods->open(module, GPS_HARDWARE_MODULE_ID, &device);
+ if (err == 0) {
+ iface = new Gnss(reinterpret_cast<gps_device_t*>(device));
+ } else {
+ ALOGE("gnssDevice open %s failed: %d", hal, err);
+ }
+ } else {
+ ALOGE("gnss hw_get_module %s failed: %d", hal, err);
+ }
+ return iface;
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gnss/1.0/default/Gnss.h b/gnss/1.0/default/Gnss.h
new file mode 100644
index 0000000..a2c8676
--- /dev/null
+++ b/gnss/1.0/default/Gnss.h
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef android_hardware_gnss_V1_0_Gnss_H_
+#define android_hardware_gnss_V1_0_Gnss_H_
+
+#include <AGnss.h>
+#include <AGnssRil.h>
+#include <GnssConfiguration.h>
+#include <GnssDebug.h>
+#include <GnssGeofencing.h>
+#include <GnssMeasurement.h>
+#include <GnssNavigationMessage.h>
+#include <GnssNi.h>
+#include <GnssXtra.h>
+
+#include <ThreadCreationWrapper.h>
+#include <android/hardware/gnss/1.0/IGnss.h>
+#include <hardware/gps.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+using LegacyGnssSystemInfo = ::GnssSystemInfo;
+
+/*
+ * Represents the standard GNSS interface. Also contains wrapper methods to allow methods from
+ * IGnssCallback interface to be passed into the conventional implementation of the GNSS HAL.
+ */
+struct Gnss : public IGnss {
+ Gnss(gps_device_t* gnss_device);
+ ~Gnss();
+
+ /*
+ * Methods from ::android::hardware::gnss::V1_0::IGnss follow.
+ * These declarations were generated from Gnss.hal.
+ */
+ Return<bool> setCallback(const sp<IGnssCallback>& callback) override;
+ Return<bool> start() override;
+ Return<bool> stop() override;
+ Return<void> cleanup() override;
+ Return<bool> injectLocation(double latitudeDegrees,
+ double longitudeDegrees,
+ float accuracyMeters) override;
+ Return<bool> injectTime(int64_t timeMs,
+ int64_t timeReferenceMs,
+ int32_t uncertaintyMs) override;
+ Return<void> deleteAidingData(IGnss::GnssAidingData aidingDataFlags) override;
+ Return<bool> setPositionMode(IGnss::GnssPositionMode mode,
+ IGnss::GnssPositionRecurrence recurrence,
+ uint32_t minIntervalMs,
+ uint32_t preferredAccuracyMeters,
+ uint32_t preferredTimeMs) override;
+ Return<void> getExtensionAGnssRil(getExtensionAGnssRil_cb _hidl_cb) override;
+ Return<void> getExtensionGnssGeofencing(getExtensionGnssGeofencing_cb _hidl_cb) override;
+ Return<void> getExtensionAGnss(getExtensionAGnss_cb _hidl_cb) override;
+ Return<void> getExtensionGnssNi(getExtensionGnssNi_cb _hidl_cb) override;
+ Return<void> getExtensionGnssMeasurement(getExtensionGnssMeasurement_cb _hidl_cb) override;
+ Return<void> getExtensionGnssNavigationMessage(
+ getExtensionGnssNavigationMessage_cb _hidl_cb) override;
+ Return<void> getExtensionXtra(getExtensionXtra_cb _hidl_cb) override;
+ Return<void> getExtensionGnssDebug(getExtensionGnssDebug_cb _hidl_cb) override;
+ Return<void> getExtensionGnssConfiguration(getExtensionGnssConfiguration_cb _hidl_cb) override;
+
+ /*
+ * Callback methods to be passed into the conventional GNSS HAL by the default
+ * implementation. These methods are not part of the IGnss base class.
+ */
+ static void locationCb(GpsLocation* location);
+ static void statusCb(GpsStatus* gnss_status);
+ static void nmeaCb(GpsUtcTime timestamp, const char* nmea, int length);
+ static void setCapabilitiesCb(uint32_t capabilities);
+ static void acquireWakelockCb();
+ static void releaseWakelockCb();
+ static void requestUtcTimeCb();
+ static pthread_t createThreadCb(const char* name, void (*start)(void*), void* arg);
+ static void gnssSvStatusCb(GnssSvStatus* status);
+ /*
+ * Deprecated callback added for backward compatibility to devices that do
+ * not support GnssSvStatus.
+ */
+ static void gpsSvStatusCb(GpsSvStatus* status);
+ static void setSystemInfoCb(const LegacyGnssSystemInfo* info);
+
+ /*
+ * Holds function pointers to the callback methods.
+ */
+ static GpsCallbacks sGnssCb;
+
+ private:
+ sp<GnssXtra> mGnssXtraIface = nullptr;
+ sp<AGnssRil> mGnssRil = nullptr;
+ sp<GnssGeofencing> mGnssGeofencingIface = nullptr;
+ sp<AGnss> mAGnssIface = nullptr;
+ sp<GnssNi> mGnssNi = nullptr;
+ sp<GnssMeasurement> mGnssMeasurement = nullptr;
+ sp<GnssNavigationMessage> mGnssNavigationMessage = nullptr;
+ sp<GnssDebug> mGnssDebug = nullptr;
+ sp<GnssConfiguration> mGnssConfig = nullptr;
+ const GpsInterface* mGnssIface = nullptr;
+ static sp<IGnssCallback> sGnssCbIface;
+ static std::vector<std::unique_ptr<ThreadFuncArgs>> sThreadFuncArgsList;
+ static bool sInterfaceExists;
+};
+
+extern "C" IGnss* HIDL_FETCH_IGnss(const char* name);
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // android_hardware_gnss_V1_0_Gnss_H_
diff --git a/gnss/1.0/default/GnssConfiguration.cpp b/gnss/1.0/default/GnssConfiguration.cpp
new file mode 100644
index 0000000..9031c06
--- /dev/null
+++ b/gnss/1.0/default/GnssConfiguration.cpp
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "GnssHAL_GnssConfigurationInterface"
+
+#include "GnssConfiguration.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+GnssConfiguration::GnssConfiguration(const GnssConfigurationInterface* gnssConfigInfc)
+ : mGnssConfigIface(gnssConfigInfc) {}
+
+// Methods from ::android::hardware::gps::V1_0::IGnssConfiguration follow.
+Return<bool> GnssConfiguration::setSuplEs(bool enabled) {
+ if (mGnssConfigIface == nullptr) {
+ ALOGE("%s: GNSS Configuration interface is not available.", __func__);
+ return false;
+ }
+
+ std::string config = "SUPL_ES=" + std::to_string(enabled ? 1 : 0) + "\n";
+ mGnssConfigIface->configuration_update(config.c_str(), config.size());
+ return true;
+}
+
+Return<bool> GnssConfiguration::setSuplVersion(uint32_t version) {
+ if (mGnssConfigIface == nullptr) {
+ ALOGE("%s: GNSS Configuration interface is not available.", __func__);
+ return false;
+ }
+
+ std::string config = "SUPL_VER=" + std::to_string(version) + "\n";
+ mGnssConfigIface->configuration_update(config.c_str(), config.size());
+
+ return true;
+}
+
+Return<bool> GnssConfiguration::setSuplMode(uint8_t mode) {
+ if (mGnssConfigIface == nullptr) {
+ ALOGE("%s: GNSS Configuration interface is not available.", __func__);
+ return false;
+ }
+
+ std::string config = "SUPL_MODE=" + std::to_string(mode) + "\n";
+ mGnssConfigIface->configuration_update(config.c_str(), config.size());
+ return true;
+}
+
+Return<bool> GnssConfiguration::setLppProfile(uint8_t lppProfile) {
+ if (mGnssConfigIface == nullptr) {
+ ALOGE("%s: GNSS Configuration interface is not available.", __func__);
+ return false;
+ }
+
+ std::string config = "LPP_PROFILE=" + std::to_string(lppProfile) + "\n";
+ mGnssConfigIface->configuration_update(config.c_str(), config.size());
+ return true;
+}
+
+Return<bool> GnssConfiguration::setGlonassPositioningProtocol(uint8_t protocol) {
+ if (mGnssConfigIface == nullptr) {
+ ALOGE("%s: GNSS Configuration interface is not available.", __func__);
+ return false;
+ }
+
+ std::string config = "A_GLONASS_POS_PROTOCOL_SELECT=" +
+ std::to_string(protocol) + "\n";
+ mGnssConfigIface->configuration_update(config.c_str(), config.size());
+ return true;
+}
+
+Return<bool> GnssConfiguration::setGpsLock(uint8_t lock) {
+ if (mGnssConfigIface == nullptr) {
+ ALOGE("%s: GNSS Configuration interface is not available.", __func__);
+ return false;
+ }
+
+ std::string config = "GPS_LOCK=" + std::to_string(lock) + "\n";
+ mGnssConfigIface->configuration_update(config.c_str(), config.size());
+ return true;
+}
+
+Return<bool> GnssConfiguration::setEmergencySuplPdn(bool enabled) {
+ if (mGnssConfigIface == nullptr) {
+ ALOGE("%s: GNSS Configuration interface is not available.", __func__);
+ return false;
+ }
+
+ std::string config = "USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL=" + std::to_string(enabled ? 1 : 0)
+ + "\n";
+ mGnssConfigIface->configuration_update(config.c_str(), config.size());
+ return true;
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gnss/1.0/default/GnssConfiguration.h b/gnss/1.0/default/GnssConfiguration.h
new file mode 100644
index 0000000..a6eca88
--- /dev/null
+++ b/gnss/1.0/default/GnssConfiguration.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef android_hardware_gnss_V1_0_GnssConfiguration_H_
+#define android_hardware_gnss_V1_0_GnssConfiguration_H_
+
+#include <android/hardware/gnss/1.0/IGnssConfiguration.h>
+#include <hardware/gps.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_0::IGnssConfiguration;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+/*
+ * Interface for passing GNSS configuration info from platform to HAL.
+ */
+struct GnssConfiguration : public IGnssConfiguration {
+ GnssConfiguration(const GnssConfigurationInterface* gnssConfigIface);
+
+ /*
+ * Methods from ::android::hardware::gnss::V1_0::IGnssConfiguration follow.
+ * These declarations were generated from IGnssConfiguration.hal.
+ */
+ Return<bool> setSuplVersion(uint32_t version) override;
+ Return<bool> setSuplMode(uint8_t mode) override;
+ Return<bool> setSuplEs(bool enabled) override;
+ Return<bool> setLppProfile(uint8_t lppProfile) override;
+ Return<bool> setGlonassPositioningProtocol(uint8_t protocol) override;
+ Return<bool> setEmergencySuplPdn(bool enable) override;
+ Return<bool> setGpsLock(uint8_t lock) override;
+
+ private:
+ const GnssConfigurationInterface* mGnssConfigIface = nullptr;
+};
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // android_hardware_gnss_V1_0_GnssConfiguration_H_
diff --git a/gnss/1.0/default/GnssDebug.cpp b/gnss/1.0/default/GnssDebug.cpp
new file mode 100644
index 0000000..e227e17
--- /dev/null
+++ b/gnss/1.0/default/GnssDebug.cpp
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "GnssHAL_GnssDebugInterface"
+
+#include "GnssDebug.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+GnssDebug::GnssDebug(const GpsDebugInterface* gpsDebugIface) : mGnssDebugIface(gpsDebugIface) {}
+
+// Methods from ::android::hardware::gnss::V1_0::IGnssDebug follow.
+Return<void> GnssDebug::getDebugData(getDebugData_cb _hidl_cb) {
+ /*
+ * This is a new interface and hence there is no way to retrieve the
+ * debug data from the HAL.
+ */
+ DebugData data = {};
+
+ _hidl_cb(data);
+
+ /*
+ * Log the debug data sent from the conventional Gnss HAL. This code is
+ * moved here from GnssLocationProvider.
+ */
+ if (mGnssDebugIface) {
+ char buffer[kMaxDebugStrLen + 1];
+ size_t length = mGnssDebugIface->get_internal_state(buffer, kMaxDebugStrLen);
+ length = std::max(length, kMaxDebugStrLen);
+ buffer[length] = '\0';
+ ALOGD("Gnss Debug Data: %s", buffer);
+ }
+ return Void();
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gnss/1.0/default/GnssDebug.h b/gnss/1.0/default/GnssDebug.h
new file mode 100644
index 0000000..9a17dde
--- /dev/null
+++ b/gnss/1.0/default/GnssDebug.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef android_hardware_gnss_V1_0_GnssDebug_H_
+#define android_hardware_gnss_V1_0_GnssDebug_H_
+
+#include <android/hardware/gnss/1.0/IGnssDebug.h>
+#include <hidl/Status.h>
+#include <hardware/gps.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_0::IGnssDebug;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+/* Interface for GNSS Debug support. */
+struct GnssDebug : public IGnssDebug {
+ GnssDebug(const GpsDebugInterface* gpsDebugIface);
+
+ /*
+ * Methods from ::android::hardware::gnss::V1_0::IGnssDebug follow.
+ * These declarations were generated from IGnssDebug.hal.
+ */
+ Return<void> getDebugData(getDebugData_cb _hidl_cb) override;
+
+ private:
+ /*
+ * Constant added for backward compatibility to conventional GPS Hals which
+ * returned a debug string.
+ */
+ const size_t kMaxDebugStrLen = 2047;
+ const GpsDebugInterface* mGnssDebugIface = nullptr;
+};
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // android_hardware_gnss_V1_0_GnssDebug_H_
diff --git a/gnss/1.0/default/GnssGeofencing.cpp b/gnss/1.0/default/GnssGeofencing.cpp
new file mode 100644
index 0000000..f42de42
--- /dev/null
+++ b/gnss/1.0/default/GnssGeofencing.cpp
@@ -0,0 +1,206 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "GnssHal_GnssGeofencing"
+
+#include "GnssGeofencing.h"
+#include <GnssUtils.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+std::vector<std::unique_ptr<ThreadFuncArgs>> GnssGeofencing::sThreadFuncArgsList;
+sp<IGnssGeofenceCallback> GnssGeofencing::mGnssGeofencingCbIface = nullptr;
+bool GnssGeofencing::sInterfaceExists = false;
+
+GpsGeofenceCallbacks GnssGeofencing::sGnssGfCb = {
+ .geofence_transition_callback = gnssGfTransitionCb,
+ .geofence_status_callback = gnssGfStatusCb,
+ .geofence_add_callback = gnssGfAddCb,
+ .geofence_remove_callback = gnssGfRemoveCb,
+ .geofence_pause_callback = gnssGfPauseCb,
+ .geofence_resume_callback = gnssGfResumeCb,
+ .create_thread_cb = createThreadCb
+};
+
+GnssGeofencing::GnssGeofencing(const GpsGeofencingInterface* gpsGeofencingIface)
+ : mGnssGeofencingIface(gpsGeofencingIface) {
+ /* Error out if an instance of the interface already exists. */
+ LOG_ALWAYS_FATAL_IF(sInterfaceExists);
+ sInterfaceExists = true;
+}
+
+GnssGeofencing::~GnssGeofencing() {
+ sThreadFuncArgsList.clear();
+}
+void GnssGeofencing::gnssGfTransitionCb(int32_t geofenceId,
+ GpsLocation* location,
+ int32_t transition,
+ GpsUtcTime timestamp) {
+ if (mGnssGeofencingCbIface == nullptr) {
+ ALOGE("%s: GNSS Geofence Callback Interface configured incorrectly", __func__);
+ return;
+ }
+
+ if (location == nullptr) {
+ ALOGE("%s : Invalid location from GNSS HAL", __func__);
+ return;
+ }
+
+ GnssLocation gnssLocation = convertToGnssLocation(location);
+ mGnssGeofencingCbIface->gnssGeofenceTransitionCb(
+ geofenceId,
+ gnssLocation,
+ static_cast<IGnssGeofenceCallback::GeofenceTransition>(transition),
+ timestamp);
+}
+
+void GnssGeofencing::gnssGfStatusCb(int32_t status, GpsLocation* location) {
+ if (mGnssGeofencingCbIface == nullptr) {
+ ALOGE("%s: GNSS Geofence Callback Interface configured incorrectly", __func__);
+ return;
+ }
+
+ GnssLocation gnssLocation;
+
+ if (location != nullptr) {
+ gnssLocation = convertToGnssLocation(location);
+ } else {
+ gnssLocation = {};
+ }
+
+ mGnssGeofencingCbIface->gnssGeofenceStatusCb(
+ static_cast<IGnssGeofenceCallback::GeofenceAvailability>(status), gnssLocation);
+}
+
+void GnssGeofencing::gnssGfAddCb(int32_t geofenceId, int32_t status) {
+ if (mGnssGeofencingCbIface == nullptr) {
+ ALOGE("%s: GNSS Geofence Callback Interface configured incorrectly", __func__);
+ return;
+ }
+
+ mGnssGeofencingCbIface->gnssGeofenceAddCb(
+ geofenceId, static_cast<IGnssGeofenceCallback::GeofenceStatus>(status));
+}
+
+void GnssGeofencing::gnssGfRemoveCb(int32_t geofenceId, int32_t status) {
+ if (mGnssGeofencingCbIface == nullptr) {
+ ALOGE("%s: GNSS Geofence Callback Interface configured incorrectly", __func__);
+ return;
+ }
+
+ mGnssGeofencingCbIface->gnssGeofenceRemoveCb(
+ geofenceId, static_cast<IGnssGeofenceCallback::GeofenceStatus>(status));
+}
+
+void GnssGeofencing::gnssGfPauseCb(int32_t geofenceId, int32_t status) {
+ if (mGnssGeofencingCbIface == nullptr) {
+ ALOGE("%s: GNSS Geofence Callback Interface configured incorrectly", __func__);
+ return;
+ }
+
+ mGnssGeofencingCbIface->gnssGeofencePauseCb(
+ geofenceId, static_cast<IGnssGeofenceCallback::GeofenceStatus>(status));
+}
+
+void GnssGeofencing::gnssGfResumeCb(int32_t geofenceId, int32_t status) {
+ if (mGnssGeofencingCbIface == nullptr) {
+ ALOGE("%s: GNSS Geofence Callback Interface configured incorrectly", __func__);
+ return;
+ }
+
+ mGnssGeofencingCbIface->gnssGeofenceResumeCb(
+ geofenceId, static_cast<IGnssGeofenceCallback::GeofenceStatus>(status));
+}
+
+pthread_t GnssGeofencing::createThreadCb(const char* name, void (*start)(void*), void* arg) {
+ return createPthread(name, start, arg, &sThreadFuncArgsList);
+}
+
+// Methods from ::android::hardware::gnss::V1_0::IGnssGeofencing follow.
+Return<void> GnssGeofencing::setCallback(const sp<IGnssGeofenceCallback>& callback) {
+ mGnssGeofencingCbIface = callback;
+
+ if (mGnssGeofencingIface == nullptr) {
+ ALOGE("%s: GnssGeofencing interface is not available", __func__);
+ } else {
+ mGnssGeofencingIface->init(&sGnssGfCb);
+ }
+
+ return Void();
+}
+
+Return<void> GnssGeofencing::addGeofence(
+ int32_t geofenceId,
+ double latitudeDegrees,
+ double longitudeDegrees,
+ double radiusMeters,
+ IGnssGeofenceCallback::GeofenceTransition lastTransition,
+ int32_t monitorTransitions,
+ uint32_t notificationResponsivenessMs,
+ uint32_t unknownTimerMs) {
+ if (mGnssGeofencingIface == nullptr) {
+ ALOGE("%s: GnssGeofencing interface is not available", __func__);
+ return Void();
+ } else {
+ mGnssGeofencingIface->add_geofence_area(
+ geofenceId,
+ latitudeDegrees,
+ longitudeDegrees,
+ radiusMeters,
+ static_cast<int32_t>(lastTransition),
+ monitorTransitions,
+ notificationResponsivenessMs,
+ unknownTimerMs);
+ }
+ return Void();
+}
+
+Return<void> GnssGeofencing::pauseGeofence(int32_t geofenceId) {
+ if (mGnssGeofencingIface == nullptr) {
+ ALOGE("%s: GnssGeofencing interface is not available", __func__);
+ } else {
+ mGnssGeofencingIface->pause_geofence(geofenceId);
+ }
+ return Void();
+}
+
+Return<void> GnssGeofencing::resumeGeofence(int32_t geofenceId, int32_t monitorTransitions) {
+ if (mGnssGeofencingIface == nullptr) {
+ ALOGE("%s: GnssGeofencing interface is not available", __func__);
+ } else {
+ mGnssGeofencingIface->resume_geofence(geofenceId, monitorTransitions);
+ }
+ return Void();
+}
+
+Return<void> GnssGeofencing::removeGeofence(int32_t geofenceId) {
+ if (mGnssGeofencingIface == nullptr) {
+ ALOGE("%s: GnssGeofencing interface is not available", __func__);
+ } else {
+ mGnssGeofencingIface->remove_geofence_area(geofenceId);
+ }
+ return Void();
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gnss/1.0/default/GnssGeofencing.h b/gnss/1.0/default/GnssGeofencing.h
new file mode 100644
index 0000000..124b893
--- /dev/null
+++ b/gnss/1.0/default/GnssGeofencing.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef android_hardware_gnss_V1_0_GnssGeofencing_H_
+#define android_hardware_gnss_V1_0_GnssGeofencing_H_
+
+#include <ThreadCreationWrapper.h>
+#include <android/hardware/gnss/1.0/IGnssGeofencing.h>
+#include <hidl/Status.h>
+#include <hardware/gps.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_0::IGnssGeofenceCallback;
+using ::android::hardware::gnss::V1_0::IGnssGeofencing;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+/*
+ * Interface for GNSS Geofencing support. It also contains wrapper methods to allow
+ * methods from IGnssGeofenceCallback interface to be passed into the
+ * conventional implementation of the GNSS HAL.
+ */
+struct GnssGeofencing : public IGnssGeofencing {
+ GnssGeofencing(const GpsGeofencingInterface* gpsGeofencingIface);
+ ~GnssGeofencing();
+
+ /*
+ * Methods from ::android::hardware::gnss::V1_0::IGnssGeofencing follow.
+ * These declarations were generated from IGnssGeofencing.hal.
+ */
+ Return<void> setCallback(const sp<IGnssGeofenceCallback>& callback) override;
+ Return<void> addGeofence(int32_t geofenceId,
+ double latitudeDegrees,
+ double longitudeDegrees,
+ double radiusMeters,
+ IGnssGeofenceCallback::GeofenceTransition lastTransition,
+ int32_t monitorTransitions,
+ uint32_t notificationResponsivenessMs,
+ uint32_t unknownTimerMs) override;
+
+ Return<void> pauseGeofence(int32_t geofenceId) override;
+ Return<void> resumeGeofence(int32_t geofenceId, int32_t monitorTransitions) override;
+ Return<void> removeGeofence(int32_t geofenceId) override;
+
+ /*
+ * Callback methods to be passed into the conventional GNSS HAL by the default
+ * implementation. These methods are not part of the IGnssGeofencing base class.
+ */
+ static void gnssGfTransitionCb(int32_t geofence_id, GpsLocation* location,
+ int32_t transition, GpsUtcTime timestamp);
+ static void gnssGfStatusCb(int32_t status, GpsLocation* last_location);
+ static void gnssGfAddCb(int32_t geofence_id, int32_t status);
+ static void gnssGfRemoveCb(int32_t geofence_id, int32_t status);
+ static void gnssGfPauseCb(int32_t geofence_id, int32_t status);
+ static void gnssGfResumeCb(int32_t geofence_id, int32_t status);
+ static pthread_t createThreadCb(const char* name, void (*start)(void*), void* arg);
+
+ /*
+ * Holds function pointers to the callback methods.
+ */
+ static GpsGeofenceCallbacks sGnssGfCb;
+
+ private:
+ static std::vector<std::unique_ptr<ThreadFuncArgs>> sThreadFuncArgsList;
+ static sp<IGnssGeofenceCallback> mGnssGeofencingCbIface;
+ const GpsGeofencingInterface* mGnssGeofencingIface = nullptr;
+ static bool sInterfaceExists;
+};
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // android_hardware_gnss_V1_0_GnssGeofencing_H_
diff --git a/gnss/1.0/default/GnssMeasurement.cpp b/gnss/1.0/default/GnssMeasurement.cpp
new file mode 100644
index 0000000..9f8d7b5
--- /dev/null
+++ b/gnss/1.0/default/GnssMeasurement.cpp
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "GnssHAL_GnssMeasurementInterface"
+
+#include "GnssMeasurement.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+sp<IGnssMeasurementCallback> GnssMeasurement::sGnssMeasureCbIface = nullptr;
+GpsMeasurementCallbacks GnssMeasurement::sGnssMeasurementCbs = {
+ .size = sizeof(GpsMeasurementCallbacks),
+ .measurement_callback = gpsMeasurementCb,
+ .gnss_measurement_callback = gnssMeasurementCb
+};
+
+GnssMeasurement::GnssMeasurement(const GpsMeasurementInterface* gpsMeasurementIface)
+ : mGnssMeasureIface(gpsMeasurementIface) {}
+
+void GnssMeasurement::gnssMeasurementCb(LegacyGnssData* legacyGnssData) {
+ if (sGnssMeasureCbIface == nullptr) {
+ ALOGE("%s: GNSSMeasurement Callback Interface configured incorrectly", __func__);
+ return;
+ }
+
+ if (legacyGnssData == nullptr) {
+ ALOGE("%s: Invalid GnssData from GNSS HAL", __func__);
+ return;
+ }
+
+ IGnssMeasurementCallback::GnssData gnssData;
+ gnssData.measurementCount = std::min(legacyGnssData->measurement_count,
+ static_cast<size_t>(GnssMax::SVS_COUNT));
+
+ for (size_t i = 0; i < gnssData.measurementCount; i++) {
+ auto entry = legacyGnssData->measurements[i];
+ gnssData.measurements[i] = {
+ .flags = static_cast<IGnssMeasurementCallback::GnssMeasurementFlags>(entry.flags),
+ .svid = entry.svid,
+ .constellation = static_cast<GnssConstellationType>(entry.constellation),
+ .timeOffsetNs = entry.time_offset_ns,
+ .state = static_cast<IGnssMeasurementCallback::GnssMeasurementState>(entry.state),
+ .receivedSvTimeInNs = entry.received_sv_time_in_ns,
+ .receivedSvTimeUncertaintyInNs = entry.received_sv_time_uncertainty_in_ns,
+ .cN0DbHz = entry.c_n0_dbhz,
+ .pseudorangeRateMps = entry.pseudorange_rate_mps,
+ .pseudorangeRateUncertaintyMps = entry.pseudorange_rate_uncertainty_mps,
+ .accumulatedDeltaRangeState = static_cast<IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState>(
+ entry.accumulated_delta_range_state),
+ .accumulatedDeltaRangeM = entry.accumulated_delta_range_m,
+ .accumulatedDeltaRangeUncertaintyM = entry.accumulated_delta_range_uncertainty_m,
+ .carrierFrequencyHz = entry.carrier_frequency_hz,
+ .carrierCycles = entry.carrier_cycles,
+ .carrierPhase = entry.carrier_phase,
+ .carrierPhaseUncertainty = entry.carrier_phase_uncertainty,
+ .multipathIndicator = static_cast<IGnssMeasurementCallback::GnssMultipathIndicator>(
+ entry.multipath_indicator),
+ .snrDb = entry.snr_db
+ };
+ }
+
+ auto clockVal = legacyGnssData->clock;
+ gnssData.clock = {
+ .gnssClockFlags = static_cast<IGnssMeasurementCallback::GnssClockFlags>(clockVal.flags),
+ .leapSecond = clockVal.leap_second,
+ .timeNs = clockVal.time_ns,
+ .timeUncertaintyNs = clockVal.time_uncertainty_ns,
+ .fullBiasNs = clockVal.full_bias_ns,
+ .biasNs = clockVal.bias_ns,
+ .biasUncertaintyNs = clockVal.bias_uncertainty_ns,
+ .driftNsps = clockVal.drift_nsps,
+ .driftUncertaintyNsps = clockVal.drift_uncertainty_nsps,
+ .hwClockDiscontinuityCount = clockVal.hw_clock_discontinuity_count
+ };
+
+ sGnssMeasureCbIface->GnssMeasurementCb(gnssData);
+}
+
+/*
+ * The code in the following method has been moved here from GnssLocationProvider.
+ * It converts GpsData to GnssData. This code is no longer required in
+ * GnssLocationProvider since GpsData is deprecated and no longer part of the
+ * GNSS interface.
+ */
+void GnssMeasurement::gpsMeasurementCb(GpsData* gpsData) {
+ if (sGnssMeasureCbIface == nullptr) {
+ ALOGE("%s: GNSSMeasurement Callback Interface configured incorrectly", __func__);
+ return;
+ }
+
+ if (gpsData == nullptr) {
+ ALOGE("%s: Invalid GpsData from GNSS HAL", __func__);
+ return;
+ }
+
+ IGnssMeasurementCallback::GnssData gnssData;
+ gnssData.measurementCount = std::min(gpsData->measurement_count,
+ static_cast<size_t>(GnssMax::SVS_COUNT));
+
+
+ for (size_t i = 0; i < gnssData.measurementCount; i++) {
+ auto entry = gpsData->measurements[i];
+ gnssData.measurements[i].flags =
+ static_cast<IGnssMeasurementCallback::GnssMeasurementFlags>(
+ entry.flags);
+ gnssData.measurements[i].svid = static_cast<int32_t>(entry.prn);
+ if (entry.prn >= 1 && entry.prn <= 32) {
+ gnssData.measurements[i].constellation = GnssConstellationType::GPS;
+ } else {
+ gnssData.measurements[i].constellation =
+ GnssConstellationType::UNKNOWN;
+ }
+
+ gnssData.measurements[i].timeOffsetNs = entry.time_offset_ns;
+ gnssData.measurements[i].state =
+ static_cast<IGnssMeasurementCallback::GnssMeasurementState>(
+ entry.state);
+ gnssData.measurements[i].receivedSvTimeInNs = entry.received_gps_tow_ns;
+ gnssData.measurements[i].receivedSvTimeUncertaintyInNs =
+ entry.received_gps_tow_uncertainty_ns;
+ gnssData.measurements[i].cN0DbHz = entry.c_n0_dbhz;
+ gnssData.measurements[i].pseudorangeRateMps = entry.pseudorange_rate_mps;
+ gnssData.measurements[i].pseudorangeRateUncertaintyMps =
+ entry.pseudorange_rate_uncertainty_mps;
+ gnssData.measurements[i].accumulatedDeltaRangeState =
+ static_cast<IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState>(
+ entry.accumulated_delta_range_state);
+ gnssData.measurements[i].accumulatedDeltaRangeM =
+ entry.accumulated_delta_range_m;
+ gnssData.measurements[i].accumulatedDeltaRangeUncertaintyM =
+ entry.accumulated_delta_range_uncertainty_m;
+
+ if (entry.flags & GNSS_MEASUREMENT_HAS_CARRIER_FREQUENCY) {
+ gnssData.measurements[i].carrierFrequencyHz = entry.carrier_frequency_hz;
+ } else {
+ gnssData.measurements[i].carrierFrequencyHz = 0;
+ }
+
+ if (entry.flags & GNSS_MEASUREMENT_HAS_CARRIER_PHASE) {
+ gnssData.measurements[i].carrierPhase = entry.carrier_phase;
+ } else {
+ gnssData.measurements[i].carrierPhase = 0;
+ }
+
+ if (entry.flags & GNSS_MEASUREMENT_HAS_CARRIER_PHASE_UNCERTAINTY) {
+ gnssData.measurements[i].carrierPhaseUncertainty = entry.carrier_phase_uncertainty;
+ } else {
+ gnssData.measurements[i].carrierPhaseUncertainty = 0;
+ }
+
+ gnssData.measurements[i].multipathIndicator =
+ static_cast<IGnssMeasurementCallback::GnssMultipathIndicator>(
+ entry.multipath_indicator);
+
+ if (entry.flags & GNSS_MEASUREMENT_HAS_SNR) {
+ gnssData.measurements[i].snrDb = entry.snr_db;
+ } else {
+ gnssData.measurements[i].snrDb = 0;
+ }
+ }
+
+ auto clockVal = gpsData->clock;
+ static uint32_t discontinuity_count_to_handle_old_clock_type = 0;
+ auto flags = clockVal.flags;
+
+ gnssData.clock.leapSecond = clockVal.leap_second;
+ /*
+ * GnssClock only supports the more effective HW_CLOCK type, so type
+ * handling and documentation complexity has been removed. To convert the
+ * old GPS_CLOCK types (active only in a limited number of older devices),
+ * the GPS time information is handled as an always discontinuous HW clock,
+ * with the GPS time information put into the full_bias_ns instead - so that
+ * time_ns - full_bias_ns = local estimate of GPS time. Additionally, the
+ * sign of full_bias_ns and bias_ns has flipped between GpsClock &
+ * GnssClock, so that is also handled below.
+ */
+ switch (clockVal.type) {
+ case GPS_CLOCK_TYPE_UNKNOWN:
+ // Clock type unsupported.
+ ALOGE("Unknown clock type provided.");
+ break;
+ case GPS_CLOCK_TYPE_LOCAL_HW_TIME:
+ // Already local hardware time. No need to do anything.
+ break;
+ case GPS_CLOCK_TYPE_GPS_TIME:
+ // GPS time, need to convert.
+ flags |= GPS_CLOCK_HAS_FULL_BIAS;
+ clockVal.full_bias_ns = clockVal.time_ns;
+ clockVal.time_ns = 0;
+ gnssData.clock.hwClockDiscontinuityCount =
+ discontinuity_count_to_handle_old_clock_type++;
+ break;
+ }
+
+ gnssData.clock.timeNs = clockVal.time_ns;
+ gnssData.clock.timeUncertaintyNs = clockVal.time_uncertainty_ns;
+ /*
+ * Definition of sign for full_bias_ns & bias_ns has been changed since N,
+ * so flip signs here.
+ */
+ gnssData.clock.fullBiasNs = -(clockVal.full_bias_ns);
+ gnssData.clock.biasNs = -(clockVal.bias_ns);
+ gnssData.clock.biasUncertaintyNs = clockVal.bias_uncertainty_ns;
+ gnssData.clock.driftNsps = clockVal.drift_nsps;
+ gnssData.clock.driftUncertaintyNsps = clockVal.drift_uncertainty_nsps;
+ gnssData.clock.gnssClockFlags =
+ static_cast<IGnssMeasurementCallback::GnssClockFlags>(clockVal.flags);
+
+ sGnssMeasureCbIface->GnssMeasurementCb(gnssData);
+}
+
+// Methods from ::android::hardware::gnss::V1_0::IGnssMeasurement follow.
+Return<GnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallback(
+ const sp<IGnssMeasurementCallback>& callback) {
+ if (mGnssMeasureIface == nullptr) {
+ ALOGE("%s: GnssMeasure interface is unavailable", __func__);
+ return GnssMeasurementStatus::ERROR_GENERIC;
+ }
+ sGnssMeasureCbIface = callback;
+
+ return static_cast<GnssMeasurement::GnssMeasurementStatus>(
+ mGnssMeasureIface->init(&sGnssMeasurementCbs));
+}
+
+Return<void> GnssMeasurement::close() {
+ if (mGnssMeasureIface == nullptr) {
+ ALOGE("%s: GnssMeasure interface is unavailable", __func__);
+ } else {
+ mGnssMeasureIface->close();
+ }
+ return Void();
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gnss/1.0/default/GnssMeasurement.h b/gnss/1.0/default/GnssMeasurement.h
new file mode 100644
index 0000000..9ff1435
--- /dev/null
+++ b/gnss/1.0/default/GnssMeasurement.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef android_hardware_gnss_V1_0_GnssMeasurement_H_
+#define android_hardware_gnss_V1_0_GnssMeasurement_H_
+
+#include <ThreadCreationWrapper.h>
+#include <android/hardware/gnss/1.0/IGnssMeasurement.h>
+#include <hidl/Status.h>
+#include <hardware/gps.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_0::IGnssMeasurement;
+using ::android::hardware::gnss::V1_0::IGnssMeasurementCallback;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+using LegacyGnssData = ::GnssData;
+
+/*
+ * Extended interface for GNSS Measurements support. Also contains wrapper methods to allow methods
+ * from IGnssMeasurementCallback interface to be passed into the conventional implementation of the
+ * GNSS HAL.
+ */
+struct GnssMeasurement : public IGnssMeasurement {
+ GnssMeasurement(const GpsMeasurementInterface* gpsMeasurementIface);
+
+ /*
+ * Methods from ::android::hardware::gnss::V1_0::IGnssMeasurement follow.
+ * These declarations were generated from IGnssMeasurement.hal.
+ */
+ Return<GnssMeasurementStatus> setCallback(
+ const sp<IGnssMeasurementCallback>& callback) override;
+ Return<void> close() override;
+
+ /*
+ * Callback methods to be passed into the conventional GNSS HAL by the default
+ * implementation. These methods are not part of the IGnssMeasurement base class.
+ */
+ static void gnssMeasurementCb(LegacyGnssData* data);
+ /*
+ * Deprecated callback added for backward compatibity for devices that do
+ * not support GnssData measurements.
+ */
+ static void gpsMeasurementCb(GpsData* data);
+
+ /*
+ * Holds function pointers to the callback methods.
+ */
+ static GpsMeasurementCallbacks sGnssMeasurementCbs;
+
+ private:
+ const GpsMeasurementInterface* mGnssMeasureIface = nullptr;
+ static sp<IGnssMeasurementCallback> sGnssMeasureCbIface;
+};
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // android_hardware_gnss_V1_0_GnssMeasurement_H_
diff --git a/gnss/1.0/default/GnssNavigationMessage.cpp b/gnss/1.0/default/GnssNavigationMessage.cpp
new file mode 100644
index 0000000..edae938
--- /dev/null
+++ b/gnss/1.0/default/GnssNavigationMessage.cpp
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "GnssHAL_GnssNavigationMessageInterface"
+
+#include "GnssNavigationMessage.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+sp<IGnssNavigationMessageCallback> GnssNavigationMessage::sGnssNavigationMsgCbIface = nullptr;
+
+GpsNavigationMessageCallbacks GnssNavigationMessage::sGnssNavigationMessageCb = {
+ .size = sizeof(GpsNavigationMessageCallbacks),
+ .navigation_message_callback = nullptr,
+ .gnss_navigation_message_callback = gnssNavigationMessageCb
+};
+
+GnssNavigationMessage::GnssNavigationMessage(
+ const GpsNavigationMessageInterface* gpsNavigationMessageIface) :
+ mGnssNavigationMessageIface(gpsNavigationMessageIface) {}
+
+void GnssNavigationMessage::gnssNavigationMessageCb(LegacyGnssNavigationMessage* message) {
+ if (sGnssNavigationMsgCbIface == nullptr) {
+ ALOGE("%s: GnssNavigation Message Callback Interface configured incorrectly", __func__);
+ return;
+ }
+
+ if (message == nullptr) {
+ ALOGE("%s, received invalid GnssNavigationMessage from GNSS HAL", __func__);
+ return;
+ }
+
+ IGnssNavigationMessageCallback::GnssNavigationMessage navigationMsg;
+
+ navigationMsg.svid = message->svid;
+ navigationMsg.type =
+ static_cast<IGnssNavigationMessageCallback::GnssNavigationMessageType>(message->type);
+ navigationMsg.status =
+ static_cast<IGnssNavigationMessageCallback::NavigationMessageStatus>(message->status);
+ navigationMsg.messageId = message->message_id;
+ navigationMsg.submessageId = message->submessage_id;
+ navigationMsg.data.setToExternal(message->data, message->data_length);
+
+ sGnssNavigationMsgCbIface->gnssNavigationMessageCb(navigationMsg);
+}
+
+// Methods from ::android::hardware::gnss::V1_0::IGnssNavigationMessage follow.
+Return<GnssNavigationMessage::GnssNavigationMessageStatus> GnssNavigationMessage::setCallback(
+ const sp<IGnssNavigationMessageCallback>& callback) {
+ if (mGnssNavigationMessageIface == nullptr) {
+ ALOGE("%s: GnssNavigationMessage not available", __func__);
+ return GnssNavigationMessageStatus::ERROR_GENERIC;
+ }
+
+ sGnssNavigationMsgCbIface = callback;
+
+ return static_cast<GnssNavigationMessage::GnssNavigationMessageStatus>(
+ mGnssNavigationMessageIface->init(&sGnssNavigationMessageCb));
+}
+
+Return<void> GnssNavigationMessage::close() {
+ if (mGnssNavigationMessageIface == nullptr) {
+ ALOGE("%s: GnssNavigationMessage not available", __func__);
+ } else {
+ mGnssNavigationMessageIface->close();
+ }
+ return Void();
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gnss/1.0/default/GnssNavigationMessage.h b/gnss/1.0/default/GnssNavigationMessage.h
new file mode 100644
index 0000000..882854b
--- /dev/null
+++ b/gnss/1.0/default/GnssNavigationMessage.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef android_hardware_gnss_V1_0_GnssNavigationMessage_H_
+#define android_hardware_gnss_V1_0_GnssNavigationMessage_H_
+
+#include <android/hardware/gnss/1.0/IGnssNavigationMessage.h>
+#include <hidl/Status.h>
+#include <hardware/gps.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_0::IGnssNavigationMessage;
+using ::android::hardware::gnss::V1_0::IGnssNavigationMessageCallback;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+using LegacyGnssNavigationMessage = ::GnssNavigationMessage;
+
+/*
+ * Extended interface for GNSS navigation message reporting support. Also contains wrapper methods
+ * to allow methods from IGnssNavigationMessageCallback interface to be passed into the conventional
+ * implementation of the GNSS HAL.
+ */
+struct GnssNavigationMessage : public IGnssNavigationMessage {
+ GnssNavigationMessage(const GpsNavigationMessageInterface* gpsNavigationMessageIface);
+
+ /*
+ * Methods from ::android::hardware::gnss::V1_0::IGnssNavigationMessage follow.
+ * These declarations were generated from IGnssNavigationMessage.hal.
+ */
+ Return<GnssNavigationMessageStatus> setCallback(
+ const sp<IGnssNavigationMessageCallback>& callback) override;
+ Return<void> close() override;
+
+ /*
+ * Callback methods to be passed into the conventional GNSS HAL by the default implementation.
+ * These methods are not part of the IGnssNavigationMessage base class.
+ */
+ static void gnssNavigationMessageCb(LegacyGnssNavigationMessage* message);
+
+ /*
+ * Holds function pointers to the callback methods.
+ */
+ static GpsNavigationMessageCallbacks sGnssNavigationMessageCb;
+ private:
+ const GpsNavigationMessageInterface* mGnssNavigationMessageIface = nullptr;
+ static sp<IGnssNavigationMessageCallback> sGnssNavigationMsgCbIface;
+};
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // android_hardware_gnss_V1_0_GnssNavigationMessage_H_
diff --git a/gnss/1.0/default/GnssNi.cpp b/gnss/1.0/default/GnssNi.cpp
new file mode 100644
index 0000000..10af1f4
--- /dev/null
+++ b/gnss/1.0/default/GnssNi.cpp
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "GnssHAL_GnssNiInterface"
+
+#include "GnssNi.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+std::vector<std::unique_ptr<ThreadFuncArgs>> GnssNi::sThreadFuncArgsList;
+sp<IGnssNiCallback> GnssNi::sGnssNiCbIface = nullptr;
+bool GnssNi::sInterfaceExists = false;
+
+GpsNiCallbacks GnssNi::sGnssNiCb = {
+ .notify_cb = niNotifyCb,
+ .create_thread_cb = createThreadCb
+};
+
+GnssNi::GnssNi(const GpsNiInterface* gpsNiIface) : mGnssNiIface(gpsNiIface) {
+ /* Error out if an instance of the interface already exists. */
+ LOG_ALWAYS_FATAL_IF(sInterfaceExists);
+ sInterfaceExists = true;
+}
+
+GnssNi::~GnssNi() {
+ sThreadFuncArgsList.clear();
+}
+
+pthread_t GnssNi::createThreadCb(const char* name, void (*start)(void*), void* arg) {
+ return createPthread(name, start, arg, &sThreadFuncArgsList);
+}
+
+void GnssNi::niNotifyCb(GpsNiNotification* notification) {
+ if (sGnssNiCbIface == nullptr) {
+ ALOGE("%s: GNSS NI Callback Interface configured incorrectly", __func__);
+ return;
+ }
+
+ if (notification == nullptr) {
+ ALOGE("%s: Invalid GpsNotification callback from GNSS HAL", __func__);
+ return;
+ }
+
+ IGnssNiCallback::GnssNiNotification notificationGnss = {
+ .notificationId = notification->notification_id,
+ .niType = static_cast<IGnssNiCallback::GnssNiType>(notification->ni_type),
+ .notifyFlags =
+ static_cast<IGnssNiCallback::GnssNiNotifyFlags>(notification->notify_flags),
+ .timeoutSec = static_cast<uint32_t>(notification->timeout),
+ .defaultResponse =
+ static_cast<IGnssNiCallback::GnssUserResponseType>(notification->default_response),
+ .requestorId = notification->requestor_id,
+ .notificationMessage = notification->text,
+ .requestorIdEncoding =
+ static_cast<IGnssNiCallback::GnssNiEncodingType>(notification->requestor_id_encoding),
+ .notificationIdEncoding =
+ static_cast<IGnssNiCallback::GnssNiEncodingType>(notification->text_encoding)
+ };
+
+ sGnssNiCbIface->niNotifyCb(notificationGnss);
+}
+
+// Methods from ::android::hardware::gnss::V1_0::IGnssNi follow.
+Return<void> GnssNi::setCallback(const sp<IGnssNiCallback>& callback) {
+ if (mGnssNiIface == nullptr) {
+ ALOGE("%s: GnssNi interface is unavailable", __func__);
+ return Void();
+ }
+
+ sGnssNiCbIface = callback;
+
+ mGnssNiIface->init(&sGnssNiCb);
+ return Void();
+}
+
+Return<void> GnssNi::respond(int32_t notifId, IGnssNiCallback::GnssUserResponseType userResponse) {
+ if (mGnssNiIface == nullptr) {
+ ALOGE("%s: GnssNi interface is unavailable", __func__);
+ } else {
+ mGnssNiIface->respond(notifId, static_cast<GpsUserResponseType>(userResponse));
+ }
+ return Void();
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gnss/1.0/default/GnssNi.h b/gnss/1.0/default/GnssNi.h
new file mode 100644
index 0000000..fe850b1
--- /dev/null
+++ b/gnss/1.0/default/GnssNi.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef android_hardware_gnss_V1_0_GnssNi_H_
+#define android_hardware_gnss_V1_0_GnssNi_H_
+
+#include <ThreadCreationWrapper.h>
+#include <android/hardware/gnss/1.0/IGnssNi.h>
+#include <hidl/Status.h>
+#include <hardware/gps.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_0::IGnssNi;
+using ::android::hardware::gnss::V1_0::IGnssNiCallback;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+/*
+ * Extended interface for Network-initiated (NI) support. This interface is used to respond to
+ * NI notifications originating from the HAL. Also contains wrapper methods to allow methods from
+ * IGnssNiCallback interface to be passed into the conventional implementation of the GNSS HAL.
+ */
+struct GnssNi : public IGnssNi {
+ GnssNi(const GpsNiInterface* gpsNiIface);
+ ~GnssNi();
+
+ /*
+ * Methods from ::android::hardware::gnss::V1_0::IGnssNi follow.
+ * These declarations were generated from IGnssNi.hal.
+ */
+ Return<void> setCallback(const sp<IGnssNiCallback>& callback) override;
+ Return<void> respond(int32_t notifId,
+ IGnssNiCallback::GnssUserResponseType userResponse) override;
+
+ /*
+ * Callback methods to be passed into the conventional GNSS HAL by the default
+ * implementation. These methods are not part of the IGnssNi base class.
+ */
+ static pthread_t createThreadCb(const char* name, void (*start)(void*), void* arg);
+ static void niNotifyCb(GpsNiNotification* notification);
+
+ /*
+ * Holds function pointers to the callback methods.
+ */
+ static GpsNiCallbacks sGnssNiCb;
+
+ private:
+ const GpsNiInterface* mGnssNiIface = nullptr;
+ static sp<IGnssNiCallback> sGnssNiCbIface;
+ static std::vector<std::unique_ptr<ThreadFuncArgs>> sThreadFuncArgsList;
+ static bool sInterfaceExists;
+};
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // android_hardware_gnss_V1_0_GnssNi_H_
diff --git a/gnss/1.0/default/GnssUtils.cpp b/gnss/1.0/default/GnssUtils.cpp
new file mode 100644
index 0000000..9f7e356
--- /dev/null
+++ b/gnss/1.0/default/GnssUtils.cpp
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "GnssUtils.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+using android::hardware::gnss::V1_0::GnssLocation;
+
+GnssLocation convertToGnssLocation(GpsLocation* location) {
+ GnssLocation gnssLocation = {};
+ if (location != nullptr) {
+ gnssLocation = {
+ .gnssLocationFlags = location->flags,
+ .latitudeDegrees = location->latitude,
+ .longitudeDegrees = location->longitude,
+ .altitudeMeters = location->altitude,
+ .speedMetersPerSec = location->speed,
+ .bearingDegrees = location->bearing,
+ .accuracyMeters = location->accuracy,
+ .timestamp = location->timestamp
+ };
+ }
+
+ return gnssLocation;
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gnss/1.0/default/GnssUtils.h b/gnss/1.0/default/GnssUtils.h
new file mode 100644
index 0000000..fc2f547
--- /dev/null
+++ b/gnss/1.0/default/GnssUtils.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef android_hardware_gnss_V1_0_GnssUtil_H_
+#define android_hardware_gnss_V1_0_GnssUtil_H_
+
+#include <hardware/gps.h>
+#include <android/hardware/gnss/1.0/types.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+/*
+ * This method converts a GpsLocation struct to a GnssLocation
+ * struct.
+ */
+GnssLocation convertToGnssLocation(GpsLocation* location);
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif
diff --git a/gnss/1.0/default/GnssXtra.cpp b/gnss/1.0/default/GnssXtra.cpp
new file mode 100644
index 0000000..065bb33
--- /dev/null
+++ b/gnss/1.0/default/GnssXtra.cpp
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "GnssHAL_GnssXtraInterface"
+
+#include "GnssXtra.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+std::vector<std::unique_ptr<ThreadFuncArgs>> GnssXtra::sThreadFuncArgsList;
+sp<IGnssXtraCallback> GnssXtra::sGnssXtraCbIface = nullptr;
+bool GnssXtra::sInterfaceExists = false;
+
+GpsXtraCallbacks GnssXtra::sGnssXtraCb = {
+ .download_request_cb = gnssXtraDownloadRequestCb,
+ .create_thread_cb = createThreadCb,
+};
+
+GnssXtra::~GnssXtra() {
+ sThreadFuncArgsList.clear();
+}
+
+pthread_t GnssXtra::createThreadCb(const char* name, void (*start)(void*), void* arg) {
+ return createPthread(name, start, arg, &sThreadFuncArgsList);
+}
+
+GnssXtra::GnssXtra(const GpsXtraInterface* xtraIface) : mGnssXtraIface(xtraIface) {
+ /* Error out if an instance of the interface already exists. */
+ LOG_ALWAYS_FATAL_IF(sInterfaceExists);
+ sInterfaceExists = true;
+}
+
+void GnssXtra::gnssXtraDownloadRequestCb() {
+ if (sGnssXtraCbIface == nullptr) {
+ ALOGE("%s: GNSS Callback Interface configured incorrectly", __func__);
+ return;
+ }
+
+ sGnssXtraCbIface->downloadRequestCb();
+}
+
+// Methods from ::android::hardware::gnss::V1_0::IGnssXtra follow.
+Return<bool> GnssXtra::setCallback(const sp<IGnssXtraCallback>& callback) {
+ if (mGnssXtraIface == nullptr) {
+ ALOGE("%s: Gnss Xtra interface is unavailable", __func__);
+ return false;
+ }
+
+ sGnssXtraCbIface = callback;
+
+ return (mGnssXtraIface->init(&sGnssXtraCb) == 0);
+}
+
+Return<bool> GnssXtra::injectXtraData(const hidl_string& xtraData) {
+ if (mGnssXtraIface == nullptr) {
+ ALOGE("%s: Gnss Xtra interface is unavailable", __func__);
+ return false;
+ }
+
+ char* buf = new char[xtraData.size()];
+ const char* data = xtraData.c_str();
+
+ memcpy(buf, data, xtraData.size());
+
+ int ret = mGnssXtraIface->inject_xtra_data(buf, xtraData.size());
+ delete[] buf;
+ return (ret == 0);
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gnss/1.0/default/GnssXtra.h b/gnss/1.0/default/GnssXtra.h
new file mode 100644
index 0000000..7a0733a
--- /dev/null
+++ b/gnss/1.0/default/GnssXtra.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef android_hardware_gnss_V1_0_GnssXtra_H_
+#define android_hardware_gnss_V1_0_GnssXtra_H_
+
+#include <ThreadCreationWrapper.h>
+#include <android/hardware/gnss/1.0/IGnssXtra.h>
+#include <hardware/gps.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_0::IGnssXtra;
+using ::android::hardware::gnss::V1_0::IGnssXtraCallback;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+/*
+ * This interface is used by the GNSS HAL to request the framework to download XTRA data.
+ * Also contains wrapper methods to allow methods from IGnssXtraCallback interface to be passed
+ * into the conventional implementation of the GNSS HAL.
+ */
+struct GnssXtra : public IGnssXtra {
+ GnssXtra(const GpsXtraInterface* xtraIface);
+ ~GnssXtra();
+
+ /*
+ * Methods from ::android::hardware::gnss::V1_0::IGnssXtra follow.
+ * These declarations were generated from IGnssXtra.hal.
+ */
+ Return<bool> setCallback(const sp<IGnssXtraCallback>& callback) override;
+ Return<bool> injectXtraData(const hidl_string& xtraData) override;
+
+ /*
+ * Callback methods to be passed into the conventional GNSS HAL by the default implementation.
+ * These methods are not part of the IGnssXtra base class.
+ */
+ static pthread_t createThreadCb(const char* name, void (*start)(void*), void* arg);
+ static void gnssXtraDownloadRequestCb();
+
+ /*
+ * Holds function pointers to the callback methods.
+ */
+ static GpsXtraCallbacks sGnssXtraCb;
+
+ private:
+ const GpsXtraInterface* mGnssXtraIface = nullptr;
+ static sp<IGnssXtraCallback> sGnssXtraCbIface;
+ static std::vector<std::unique_ptr<ThreadFuncArgs>> sThreadFuncArgsList;
+ static bool sInterfaceExists;
+};
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // android_hardware_gnss_V1_0_GnssXtra_H_
diff --git a/gnss/1.0/default/ThreadCreationWrapper.cpp b/gnss/1.0/default/ThreadCreationWrapper.cpp
new file mode 100644
index 0000000..2a5638f
--- /dev/null
+++ b/gnss/1.0/default/ThreadCreationWrapper.cpp
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <ThreadCreationWrapper.h>
+
+void* threadFunc(void* arg) {
+ ThreadFuncArgs* threadArgs = reinterpret_cast<ThreadFuncArgs*>(arg);
+ threadArgs->fptr(threadArgs->args);
+ return nullptr;
+}
+
+pthread_t createPthread(const char* name,
+ void (*start)(void*),
+ void* arg, std::vector<std::unique_ptr<ThreadFuncArgs>> * listArgs) {
+ pthread_t threadId;
+ auto threadArgs = new ThreadFuncArgs(start, arg);
+ auto argPtr = std::unique_ptr<ThreadFuncArgs>(threadArgs);
+
+ listArgs->push_back(std::move(argPtr));
+
+ int ret = pthread_create(&threadId, nullptr, threadFunc, reinterpret_cast<void*>(
+ threadArgs));
+ if (ret != 0) {
+ ALOGE("pthread creation unsuccessful");
+ } else {
+ pthread_setname_np(threadId, name);
+ }
+ return threadId;
+}
diff --git a/gnss/1.0/default/ThreadCreationWrapper.h b/gnss/1.0/default/ThreadCreationWrapper.h
new file mode 100644
index 0000000..df0a9e4
--- /dev/null
+++ b/gnss/1.0/default/ThreadCreationWrapper.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_GNSS_THREADCREATIONWRAPPER_H
+#define ANDROID_HARDWARE_GNSS_THREADCREATIONWRAPPER_H
+
+#include <pthread.h>
+#include <vector>
+#include <cutils/log.h>
+
+typedef void (*threadEntryFunc)(void* ret);
+
+/*
+ * This class facilitates createThreadCb methods in various GNSS interfaces to wrap
+ * pthread_create() from libc since its function signature differs from what is required by the
+ * conventional GNSS HAL. The arguments passed to pthread_create() need to be on heap and not on
+ * the stack of createThreadCb.
+ */
+struct ThreadFuncArgs {
+ ThreadFuncArgs(void (*start)(void*), void* arg) : fptr(start), args(arg) {}
+
+ /* pointer to the function of type void()(void*) that needs to be wrapped */
+ threadEntryFunc fptr;
+ /* argument for fptr to be called with */
+ void* args;
+};
+
+/*
+ * This method is simply a wrapper. It is required since pthread_create() requires an entry
+ * function pointer of type void*()(void*) and the GNSS hal requires as input a function pointer of
+ * type void()(void*).
+ */
+void* threadFunc(void* arg);
+
+/*
+ * This method is called by createThreadCb with a pointer to the vector that
+ * holds the pointers to the thread arguments. The arg and start parameters are
+ * first used to create a ThreadFuncArgs object which is then saved in the
+ * listArgs parameters. The created ThreadFuncArgs object is then used to invoke
+ * threadFunc() method which in-turn invokes pthread_create.
+ */
+pthread_t createPthread(const char* name, void (*start)(void*), void* arg,
+ std::vector<std::unique_ptr<ThreadFuncArgs>> * listArgs);
+
+#endif
diff --git a/gnss/1.0/types.hal b/gnss/1.0/types.hal
index 3120648..ee35ca4 100644
--- a/gnss/1.0/types.hal
+++ b/gnss/1.0/types.hal
@@ -16,12 +16,9 @@
package android.hardware.gnss@1.0;
-enum ConstS32 : int32_t {
+enum GnssMax : uint32_t {
/** Maximum number of SVs for gnssSvStatusCb(). */
- GNSS_MAX_SVS = 64,
-
-/* Maximum number of Measurements in gnssMeasurementCb(). */
- GNSS_MAX_MEASUREMENT = 64,
+ SVS_COUNT = 64,
};
/* Milliseconds since January 1, 1970 */
@@ -32,7 +29,7 @@
*/
enum GnssConstellationType : uint8_t {
UNKNOWN = 0,
- GNSS = 1,
+ GPS = 1,
SBAS = 2,
GLONASS = 3,
QZSS = 4,
@@ -46,18 +43,18 @@
uint16_t gnssLocationFlags;
/* Represents latitude in degrees. */
- double latitude;
+ double latitudeDegrees;
/* Represents longitude in degrees. */
- double longitude;
+ double longitudeDegrees;
/*
* Represents altitude in meters above the WGS 84 reference ellipsoid.
*/
- double altitude;
+ double altitudeMeters;
/* Represents speed in meters per second. */
- float speedMetersperSec;
+ float speedMetersPerSec;
/* Represents heading in degrees. */
float bearingDegrees;