1 /* Copyright (c) 2017-2019, 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 <inttypes.h>
34 #include <log_util.h>
35 #include <loc_cfg.h>
36
37 #include "LocationUtil.h"
38 #include "BatchingAPIClient.h"
39
40 #include "limits.h"
41
42
43 namespace android {
44 namespace hardware {
45 namespace gnss {
46 namespace V2_0 {
47 namespace implementation {
48
49 using ::android::hardware::gnss::V2_0::IGnssBatching;
50 using ::android::hardware::gnss::V2_0::IGnssBatchingCallback;
51 using ::android::hardware::gnss::V2_0::GnssLocation;
52
53 static void convertBatchOption(const IGnssBatching::Options& in, LocationOptions& out,
54 LocationCapabilitiesMask mask);
55
BatchingAPIClient(const sp<V1_0::IGnssBatchingCallback> & callback)56 BatchingAPIClient::BatchingAPIClient(const sp<V1_0::IGnssBatchingCallback>& callback) :
57 LocationAPIClientBase(),
58 mGnssBatchingCbIface(nullptr),
59 mDefaultId(UINT_MAX),
60 mLocationCapabilitiesMask(0),
61 mGnssBatchingCbIface_2_0(nullptr)
62 {
63 LOC_LOGD("%s]: (%p)", __FUNCTION__, &callback);
64
65 gnssUpdateCallbacks(callback);
66 }
67
BatchingAPIClient(const sp<V2_0::IGnssBatchingCallback> & callback)68 BatchingAPIClient::BatchingAPIClient(const sp<V2_0::IGnssBatchingCallback>& callback) :
69 LocationAPIClientBase(),
70 mGnssBatchingCbIface(nullptr),
71 mDefaultId(UINT_MAX),
72 mLocationCapabilitiesMask(0),
73 mGnssBatchingCbIface_2_0(nullptr)
74 {
75 LOC_LOGD("%s]: (%p)", __FUNCTION__, &callback);
76
77 gnssUpdateCallbacks_2_0(callback);
78 }
79
~BatchingAPIClient()80 BatchingAPIClient::~BatchingAPIClient()
81 {
82 LOC_LOGD("%s]: ()", __FUNCTION__);
83 }
84
getBatchSize()85 int BatchingAPIClient::getBatchSize()
86 {
87 LOC_LOGD("%s]: ()", __FUNCTION__);
88 return locAPIGetBatchSize();
89 }
90
setCallbacks()91 void BatchingAPIClient::setCallbacks()
92 {
93 LocationCallbacks locationCallbacks;
94 memset(&locationCallbacks, 0, sizeof(LocationCallbacks));
95 locationCallbacks.size = sizeof(LocationCallbacks);
96
97 locationCallbacks.trackingCb = nullptr;
98 locationCallbacks.batchingCb = nullptr;
99 locationCallbacks.batchingCb = [this](size_t count, Location* location,
100 BatchingOptions batchOptions) {
101 onBatchingCb(count, location, batchOptions);
102 };
103 locationCallbacks.geofenceBreachCb = nullptr;
104 locationCallbacks.geofenceStatusCb = nullptr;
105 locationCallbacks.gnssLocationInfoCb = nullptr;
106 locationCallbacks.gnssNiCb = nullptr;
107 locationCallbacks.gnssSvCb = nullptr;
108 locationCallbacks.gnssNmeaCb = nullptr;
109 locationCallbacks.gnssMeasurementsCb = nullptr;
110
111 locAPISetCallbacks(locationCallbacks);
112 }
113
gnssUpdateCallbacks(const sp<V1_0::IGnssBatchingCallback> & callback)114 void BatchingAPIClient::gnssUpdateCallbacks(const sp<V1_0::IGnssBatchingCallback>& callback)
115 {
116 mMutex.lock();
117 mGnssBatchingCbIface = callback;
118 mMutex.unlock();
119
120 if (mGnssBatchingCbIface != nullptr) {
121 setCallbacks();
122 }
123 }
124
gnssUpdateCallbacks_2_0(const sp<V2_0::IGnssBatchingCallback> & callback)125 void BatchingAPIClient::gnssUpdateCallbacks_2_0(const sp<V2_0::IGnssBatchingCallback>& callback)
126 {
127 mMutex.lock();
128 mGnssBatchingCbIface_2_0 = callback;
129 mMutex.unlock();
130
131 if (mGnssBatchingCbIface_2_0 != nullptr) {
132 setCallbacks();
133 }
134 }
135
startSession(const IGnssBatching::Options & opts)136 int BatchingAPIClient::startSession(const IGnssBatching::Options& opts)
137 {
138 LOC_LOGD("%s]: (%lld %d)", __FUNCTION__,
139 static_cast<long long>(opts.periodNanos), static_cast<uint8_t>(opts.flags));
140 int retVal = -1;
141 LocationOptions options;
142 convertBatchOption(opts, options, mLocationCapabilitiesMask);
143 uint32_t mode = 0;
144 if (opts.flags == static_cast<uint8_t>(IGnssBatching::Flag::WAKEUP_ON_FIFO_FULL)) {
145 mode = SESSION_MODE_ON_FULL;
146 }
147 if (locAPIStartSession(mDefaultId, mode, options) == LOCATION_ERROR_SUCCESS) {
148 retVal = 1;
149 }
150 return retVal;
151 }
152
updateSessionOptions(const IGnssBatching::Options & opts)153 int BatchingAPIClient::updateSessionOptions(const IGnssBatching::Options& opts)
154 {
155 LOC_LOGD("%s]: (%lld %d)", __FUNCTION__,
156 static_cast<long long>(opts.periodNanos), static_cast<uint8_t>(opts.flags));
157 int retVal = -1;
158 LocationOptions options;
159 convertBatchOption(opts, options, mLocationCapabilitiesMask);
160
161 uint32_t mode = 0;
162 if (opts.flags == static_cast<uint8_t>(IGnssBatching::Flag::WAKEUP_ON_FIFO_FULL)) {
163 mode = SESSION_MODE_ON_FULL;
164 }
165 if (locAPIUpdateSessionOptions(mDefaultId, mode, options) == LOCATION_ERROR_SUCCESS) {
166 retVal = 1;
167 }
168 return retVal;
169 }
170
stopSession()171 int BatchingAPIClient::stopSession()
172 {
173 LOC_LOGD("%s]: ", __FUNCTION__);
174 int retVal = -1;
175 if (locAPIStopSession(mDefaultId) == LOCATION_ERROR_SUCCESS) {
176 retVal = 1;
177 }
178 return retVal;
179 }
180
getBatchedLocation(int last_n_locations)181 void BatchingAPIClient::getBatchedLocation(int last_n_locations)
182 {
183 LOC_LOGD("%s]: (%d)", __FUNCTION__, last_n_locations);
184 locAPIGetBatchedLocations(mDefaultId, last_n_locations);
185 }
186
flushBatchedLocations()187 void BatchingAPIClient::flushBatchedLocations()
188 {
189 LOC_LOGD("%s]: ()", __FUNCTION__);
190 locAPIGetBatchedLocations(mDefaultId, SIZE_MAX);
191 }
192
onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask)193 void BatchingAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask)
194 {
195 LOC_LOGD("%s]: (%" PRIu64 ")", __FUNCTION__, capabilitiesMask);
196 mLocationCapabilitiesMask = capabilitiesMask;
197 }
198
onBatchingCb(size_t count,Location * location,BatchingOptions)199 void BatchingAPIClient::onBatchingCb(size_t count, Location* location,
200 BatchingOptions /*batchOptions*/)
201 {
202 mMutex.lock();
203 auto gnssBatchingCbIface(mGnssBatchingCbIface);
204 auto gnssBatchingCbIface_2_0(mGnssBatchingCbIface_2_0);
205 mMutex.unlock();
206
207 LOC_LOGD("%s]: (count: %zu)", __FUNCTION__, count);
208 if (gnssBatchingCbIface_2_0 != nullptr && count > 0) {
209 hidl_vec<V2_0::GnssLocation> locationVec;
210 locationVec.resize(count);
211 for (size_t i = 0; i < count; i++) {
212 convertGnssLocation(location[i], locationVec[i]);
213 }
214 auto r = gnssBatchingCbIface_2_0->gnssLocationBatchCb(locationVec);
215 if (!r.isOk()) {
216 LOC_LOGE("%s] Error from gnssLocationBatchCb 2.0 description=%s",
217 __func__, r.description().c_str());
218 }
219 } else if (gnssBatchingCbIface != nullptr && count > 0) {
220 hidl_vec<V1_0::GnssLocation> locationVec;
221 locationVec.resize(count);
222 for (size_t i = 0; i < count; i++) {
223 convertGnssLocation(location[i], locationVec[i]);
224 }
225 auto r = gnssBatchingCbIface->gnssLocationBatchCb(locationVec);
226 if (!r.isOk()) {
227 LOC_LOGE("%s] Error from gnssLocationBatchCb 1.0 description=%s",
228 __func__, r.description().c_str());
229 }
230 }
231 }
232
convertBatchOption(const IGnssBatching::Options & in,LocationOptions & out,LocationCapabilitiesMask mask)233 static void convertBatchOption(const IGnssBatching::Options& in, LocationOptions& out,
234 LocationCapabilitiesMask mask)
235 {
236 memset(&out, 0, sizeof(LocationOptions));
237 out.size = sizeof(LocationOptions);
238 out.minInterval = (uint32_t)(in.periodNanos / 1000000L);
239 out.minDistance = 0;
240 out.mode = GNSS_SUPL_MODE_STANDALONE;
241 if (mask & LOCATION_CAPABILITIES_GNSS_MSA_BIT)
242 out.mode = GNSS_SUPL_MODE_MSA;
243 if (mask & LOCATION_CAPABILITIES_GNSS_MSB_BIT)
244 out.mode = GNSS_SUPL_MODE_MSB;
245 }
246
247 } // namespace implementation
248 } // namespace V2_0
249 } // namespace gnss
250 } // namespace hardware
251 } // namespace android
252