1 /* Copyright (c) 2017, 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 static void convertBatchOption(const IGnssBatching::Options& in, LocationOptions& out,
49         LocationCapabilitiesMask mask);
50 
BatchingAPIClient(const sp<IGnssBatchingCallback> & callback)51 BatchingAPIClient::BatchingAPIClient(const sp<IGnssBatchingCallback>& callback) :
52     LocationAPIClientBase(),
53     mGnssBatchingCbIface(callback),
54     mDefaultId(UINT_MAX),
55     mLocationCapabilitiesMask(0)
56 {
57     LOC_LOGD("%s]: (%p)", __FUNCTION__, &callback);
58 
59     LocationCallbacks locationCallbacks;
60     memset(&locationCallbacks, 0, sizeof(LocationCallbacks));
61     locationCallbacks.size = sizeof(LocationCallbacks);
62 
63     locationCallbacks.trackingCb = nullptr;
64     locationCallbacks.batchingCb = nullptr;
65     if (mGnssBatchingCbIface != nullptr) {
66         locationCallbacks.batchingCb = [this](size_t count, Location* location,
67             BatchingOptions batchOptions) {
68             onBatchingCb(count, location, batchOptions);
69         };
70     }
71     locationCallbacks.geofenceBreachCb = nullptr;
72     locationCallbacks.geofenceStatusCb = nullptr;
73     locationCallbacks.gnssLocationInfoCb = nullptr;
74     locationCallbacks.gnssNiCb = nullptr;
75     locationCallbacks.gnssSvCb = nullptr;
76     locationCallbacks.gnssNmeaCb = nullptr;
77     locationCallbacks.gnssMeasurementsCb = nullptr;
78 
79     locAPISetCallbacks(locationCallbacks);
80 }
81 
~BatchingAPIClient()82 BatchingAPIClient::~BatchingAPIClient()
83 {
84     LOC_LOGD("%s]: ()", __FUNCTION__);
85 }
86 
getBatchSize()87 int BatchingAPIClient::getBatchSize()
88 {
89     LOC_LOGD("%s]: ()", __FUNCTION__);
90     return locAPIGetBatchSize();
91 }
92 
startSession(const IGnssBatching::Options & opts)93 int BatchingAPIClient::startSession(const IGnssBatching::Options& opts)
94 {
95     LOC_LOGD("%s]: (%lld %d)", __FUNCTION__,
96             static_cast<long long>(opts.periodNanos), static_cast<uint8_t>(opts.flags));
97     int retVal = -1;
98     LocationOptions options;
99     convertBatchOption(opts, options, mLocationCapabilitiesMask);
100     uint32_t mode = 0;
101     if (opts.flags == static_cast<uint8_t>(IGnssBatching::Flag::WAKEUP_ON_FIFO_FULL)) {
102         mode = SESSION_MODE_ON_FULL;
103     }
104     if (locAPIStartSession(mDefaultId, mode, options) == LOCATION_ERROR_SUCCESS) {
105         retVal = 1;
106     }
107     return retVal;
108 }
109 
updateSessionOptions(const IGnssBatching::Options & opts)110 int BatchingAPIClient::updateSessionOptions(const IGnssBatching::Options& opts)
111 {
112     LOC_LOGD("%s]: (%lld %d)", __FUNCTION__,
113             static_cast<long long>(opts.periodNanos), static_cast<uint8_t>(opts.flags));
114     int retVal = -1;
115     LocationOptions options;
116     convertBatchOption(opts, options, mLocationCapabilitiesMask);
117 
118     uint32_t mode = 0;
119     if (opts.flags == static_cast<uint8_t>(IGnssBatching::Flag::WAKEUP_ON_FIFO_FULL)) {
120         mode = SESSION_MODE_ON_FULL;
121     }
122     if (locAPIUpdateSessionOptions(mDefaultId, mode, options) == LOCATION_ERROR_SUCCESS) {
123         retVal = 1;
124     }
125     return retVal;
126 }
127 
stopSession()128 int BatchingAPIClient::stopSession()
129 {
130     LOC_LOGD("%s]: ", __FUNCTION__);
131     int retVal = -1;
132     if (locAPIStopSession(mDefaultId) == LOCATION_ERROR_SUCCESS) {
133         retVal = 1;
134     }
135     return retVal;
136 }
137 
getBatchedLocation(int last_n_locations)138 void BatchingAPIClient::getBatchedLocation(int last_n_locations)
139 {
140     LOC_LOGD("%s]: (%d)", __FUNCTION__, last_n_locations);
141     locAPIGetBatchedLocations(mDefaultId, last_n_locations);
142 }
143 
flushBatchedLocations()144 void BatchingAPIClient::flushBatchedLocations()
145 {
146     LOC_LOGD("%s]: ()", __FUNCTION__);
147     locAPIGetBatchedLocations(mDefaultId, SIZE_MAX);
148 }
149 
onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask)150 void BatchingAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask)
151 {
152     LOC_LOGD("%s]: (%02x)", __FUNCTION__, capabilitiesMask);
153     mLocationCapabilitiesMask = capabilitiesMask;
154 }
155 
onBatchingCb(size_t count,Location * location,BatchingOptions batchOptions)156 void BatchingAPIClient::onBatchingCb(size_t count, Location* location, BatchingOptions batchOptions)
157 {
158     LOC_LOGD("%s]: (count: %zu)", __FUNCTION__, count);
159     if (mGnssBatchingCbIface != nullptr && count > 0) {
160         hidl_vec<GnssLocation> locationVec;
161         locationVec.resize(count);
162         for (size_t i = 0; i < count; i++) {
163             convertGnssLocation(location[i], locationVec[i]);
164         }
165         auto r = mGnssBatchingCbIface->gnssLocationBatchCb(locationVec);
166         if (!r.isOk()) {
167             LOC_LOGE("%s] Error from gnssLocationBatchCb description=%s",
168                 __func__, r.description().c_str());
169         }
170     }
171 }
172 
convertBatchOption(const IGnssBatching::Options & in,LocationOptions & out,LocationCapabilitiesMask mask)173 static void convertBatchOption(const IGnssBatching::Options& in, LocationOptions& out,
174         LocationCapabilitiesMask mask)
175 {
176     memset(&out, 0, sizeof(LocationOptions));
177     out.size = sizeof(LocationOptions);
178     out.minInterval = (uint32_t)(in.periodNanos / 1000000L);
179     out.minDistance = 0;
180     out.mode = GNSS_SUPL_MODE_STANDALONE;
181     if (mask & LOCATION_CAPABILITIES_GNSS_MSA_BIT)
182         out.mode = GNSS_SUPL_MODE_MSA;
183     if (mask & LOCATION_CAPABILITIES_GNSS_MSB_BIT)
184         out.mode = GNSS_SUPL_MODE_MSB;
185 }
186 
187 }  // namespace implementation
188 }  // namespace V1_0
189 }  // namespace gnss
190 }  // namespace hardware
191 }  // namespace android
192