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