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