1 /* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of The Linux Foundation, nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29
30 #define LOG_NDEBUG 0
31 #define LOG_TAG "LocSvc_BatchingAPIClient"
32
33 #include <log_util.h>
34 #include <loc_cfg.h>
35
36 #include "LocationUtil.h"
37 #include "BatchingAPIClient.h"
38
39 #include "limits.h"
40
41
42 namespace android {
43 namespace hardware {
44 namespace gnss {
45 namespace V1_0 {
46 namespace implementation {
47
48 using ::android::hardware::gnss::V1_0::IGnssBatching;
49 using ::android::hardware::gnss::V1_0::IGnssBatchingCallback;
50 using ::android::hardware::gnss::V1_0::GnssLocation;
51
52 static void convertBatchOption(const IGnssBatching::Options& in, LocationOptions& out,
53 LocationCapabilitiesMask mask);
54
BatchingAPIClient(const sp<IGnssBatchingCallback> & callback)55 BatchingAPIClient::BatchingAPIClient(const sp<IGnssBatchingCallback>& callback) :
56 LocationAPIClientBase(),
57 mGnssBatchingCbIface(callback),
58 mDefaultId(UINT_MAX),
59 mLocationCapabilitiesMask(0)
60 {
61 LOC_LOGD("%s]: (%p)", __FUNCTION__, &callback);
62
63 LocationCallbacks locationCallbacks;
64 memset(&locationCallbacks, 0, sizeof(LocationCallbacks));
65 locationCallbacks.size = sizeof(LocationCallbacks);
66
67 locationCallbacks.trackingCb = nullptr;
68 locationCallbacks.batchingCb = nullptr;
69 if (mGnssBatchingCbIface != nullptr) {
70 locationCallbacks.batchingCb = [this](size_t count, Location* location,
71 BatchingOptions batchOptions) {
72 onBatchingCb(count, location, batchOptions);
73 };
74 }
75 locationCallbacks.geofenceBreachCb = nullptr;
76 locationCallbacks.geofenceStatusCb = nullptr;
77 locationCallbacks.gnssLocationInfoCb = nullptr;
78 locationCallbacks.gnssNiCb = nullptr;
79 locationCallbacks.gnssSvCb = nullptr;
80 locationCallbacks.gnssNmeaCb = nullptr;
81 locationCallbacks.gnssMeasurementsCb = nullptr;
82
83 locAPISetCallbacks(locationCallbacks);
84 }
85
~BatchingAPIClient()86 BatchingAPIClient::~BatchingAPIClient()
87 {
88 LOC_LOGD("%s]: ()", __FUNCTION__);
89 }
90
getBatchSize()91 int BatchingAPIClient::getBatchSize()
92 {
93 LOC_LOGD("%s]: ()", __FUNCTION__);
94 return locAPIGetBatchSize();
95 }
96
startSession(const IGnssBatching::Options & opts)97 int BatchingAPIClient::startSession(const IGnssBatching::Options& opts)
98 {
99 LOC_LOGD("%s]: (%lld %d)", __FUNCTION__,
100 static_cast<long long>(opts.periodNanos), static_cast<uint8_t>(opts.flags));
101 int retVal = -1;
102 LocationOptions options;
103 convertBatchOption(opts, options, mLocationCapabilitiesMask);
104 uint32_t mode = 0;
105 if (opts.flags == static_cast<uint8_t>(IGnssBatching::Flag::WAKEUP_ON_FIFO_FULL)) {
106 mode = SESSION_MODE_ON_FULL;
107 }
108 if (locAPIStartSession(mDefaultId, mode, options) == LOCATION_ERROR_SUCCESS) {
109 retVal = 1;
110 }
111 return retVal;
112 }
113
updateSessionOptions(const IGnssBatching::Options & opts)114 int BatchingAPIClient::updateSessionOptions(const IGnssBatching::Options& opts)
115 {
116 LOC_LOGD("%s]: (%lld %d)", __FUNCTION__,
117 static_cast<long long>(opts.periodNanos), static_cast<uint8_t>(opts.flags));
118 int retVal = -1;
119 LocationOptions options;
120 convertBatchOption(opts, options, mLocationCapabilitiesMask);
121
122 uint32_t mode = 0;
123 if (opts.flags == static_cast<uint8_t>(IGnssBatching::Flag::WAKEUP_ON_FIFO_FULL)) {
124 mode = SESSION_MODE_ON_FULL;
125 }
126 if (locAPIUpdateSessionOptions(mDefaultId, mode, options) == LOCATION_ERROR_SUCCESS) {
127 retVal = 1;
128 }
129 return retVal;
130 }
131
stopSession()132 int BatchingAPIClient::stopSession()
133 {
134 LOC_LOGD("%s]: ", __FUNCTION__);
135 int retVal = -1;
136 if (locAPIStopSession(mDefaultId) == LOCATION_ERROR_SUCCESS) {
137 retVal = 1;
138 }
139 return retVal;
140 }
141
getBatchedLocation(int last_n_locations)142 void BatchingAPIClient::getBatchedLocation(int last_n_locations)
143 {
144 LOC_LOGD("%s]: (%d)", __FUNCTION__, last_n_locations);
145 locAPIGetBatchedLocations(mDefaultId, last_n_locations);
146 }
147
flushBatchedLocations()148 void BatchingAPIClient::flushBatchedLocations()
149 {
150 LOC_LOGD("%s]: ()", __FUNCTION__);
151 locAPIGetBatchedLocations(mDefaultId, SIZE_MAX);
152 }
153
onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask)154 void BatchingAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask)
155 {
156 LOC_LOGD("%s]: (%02x)", __FUNCTION__, capabilitiesMask);
157 mLocationCapabilitiesMask = capabilitiesMask;
158 }
159
onBatchingCb(size_t count,Location * location,BatchingOptions)160 void BatchingAPIClient::onBatchingCb(size_t count, Location* location,
161 BatchingOptions /*batchOptions*/)
162 {
163 LOC_LOGD("%s]: (count: %zu)", __FUNCTION__, count);
164 if (mGnssBatchingCbIface != nullptr && count > 0) {
165 hidl_vec<GnssLocation> locationVec;
166 locationVec.resize(count);
167 for (size_t i = 0; i < count; i++) {
168 convertGnssLocation(location[i], locationVec[i]);
169 }
170 auto r = mGnssBatchingCbIface->gnssLocationBatchCb(locationVec);
171 if (!r.isOk()) {
172 LOC_LOGE("%s] Error from gnssLocationBatchCb description=%s",
173 __func__, r.description().c_str());
174 }
175 }
176 }
177
convertBatchOption(const IGnssBatching::Options & in,LocationOptions & out,LocationCapabilitiesMask mask)178 static void convertBatchOption(const IGnssBatching::Options& in, LocationOptions& out,
179 LocationCapabilitiesMask mask)
180 {
181 memset(&out, 0, sizeof(LocationOptions));
182 out.size = sizeof(LocationOptions);
183 out.minInterval = (uint32_t)(in.periodNanos / 1000000L);
184 out.minDistance = 0;
185 out.mode = GNSS_SUPL_MODE_STANDALONE;
186 if (mask & LOCATION_CAPABILITIES_GNSS_MSA_BIT)
187 out.mode = GNSS_SUPL_MODE_MSA;
188 if (mask & LOCATION_CAPABILITIES_GNSS_MSB_BIT)
189 out.mode = GNSS_SUPL_MODE_MSB;
190 }
191
192 } // namespace implementation
193 } // namespace V1_0
194 } // namespace gnss
195 } // namespace hardware
196 } // namespace android
197