BatchingAPIClient.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. /* Copyright (c) 2017-2021, 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. #define LOG_NDEBUG 0
  30. #define LOG_TAG "LocSvc_BatchingAPIClient"
  31. #include <inttypes.h>
  32. #include <log_util.h>
  33. #include <loc_cfg.h>
  34. #include <thread>
  35. #include "LocationUtil.h"
  36. #include "BatchingAPIClient.h"
  37. #include "limits.h"
  38. namespace android {
  39. namespace hardware {
  40. namespace gnss {
  41. namespace V2_1 {
  42. namespace implementation {
  43. using ::android::hardware::gnss::V2_0::IGnssBatching;
  44. using ::android::hardware::gnss::V2_0::IGnssBatchingCallback;
  45. using ::android::hardware::gnss::V2_0::GnssLocation;
  46. static void convertBatchOption(const IGnssBatching::Options& in, LocationOptions& out,
  47. LocationCapabilitiesMask mask);
  48. BatchingAPIClient::BatchingAPIClient(const sp<V1_0::IGnssBatchingCallback>& callback) :
  49. LocationAPIClientBase(),
  50. mGnssBatchingCbIface(nullptr),
  51. mDefaultId(UINT_MAX),
  52. mLocationCapabilitiesMask(0),
  53. mGnssBatchingCbIface_2_0(nullptr)
  54. {
  55. LOC_LOGD("%s]: (%p)", __FUNCTION__, &callback);
  56. gnssUpdateCallbacks(callback);
  57. }
  58. BatchingAPIClient::BatchingAPIClient(const sp<V2_0::IGnssBatchingCallback>& callback) :
  59. LocationAPIClientBase(),
  60. mGnssBatchingCbIface(nullptr),
  61. mDefaultId(UINT_MAX),
  62. mLocationCapabilitiesMask(0),
  63. mGnssBatchingCbIface_2_0(nullptr)
  64. {
  65. LOC_LOGD("%s]: (%p)", __FUNCTION__, &callback);
  66. gnssUpdateCallbacks_2_0(callback);
  67. }
  68. BatchingAPIClient::~BatchingAPIClient()
  69. {
  70. LOC_LOGD("%s]: ()", __FUNCTION__);
  71. }
  72. int BatchingAPIClient::getBatchSize() {
  73. int batchSize = locAPIGetBatchSize();
  74. LOC_LOGd("batchSize: %d", batchSize);
  75. return batchSize;
  76. }
  77. void BatchingAPIClient::setCallbacks()
  78. {
  79. LocationCallbacks locationCallbacks;
  80. memset(&locationCallbacks, 0, sizeof(LocationCallbacks));
  81. locationCallbacks.size = sizeof(LocationCallbacks);
  82. locationCallbacks.trackingCb = nullptr;
  83. locationCallbacks.batchingCb = nullptr;
  84. locationCallbacks.batchingCb = [this](size_t count, Location* location,
  85. BatchingOptions batchOptions) {
  86. onBatchingCb(count, location, batchOptions);
  87. };
  88. locationCallbacks.geofenceBreachCb = nullptr;
  89. locationCallbacks.geofenceStatusCb = nullptr;
  90. locationCallbacks.gnssLocationInfoCb = nullptr;
  91. locationCallbacks.gnssNiCb = nullptr;
  92. locationCallbacks.gnssSvCb = nullptr;
  93. locationCallbacks.gnssNmeaCb = nullptr;
  94. locationCallbacks.gnssMeasurementsCb = nullptr;
  95. locAPISetCallbacks(locationCallbacks);
  96. }
  97. void BatchingAPIClient::gnssUpdateCallbacks(const sp<V1_0::IGnssBatchingCallback>& callback)
  98. {
  99. mMutex.lock();
  100. bool cbWasNull = (mGnssBatchingCbIface == nullptr);
  101. mGnssBatchingCbIface = callback;
  102. mGnssBatchingCbIface_2_0 = nullptr;
  103. mMutex.unlock();
  104. if (cbWasNull) {
  105. setCallbacks();
  106. }
  107. }
  108. void BatchingAPIClient::gnssUpdateCallbacks_2_0(const sp<V2_0::IGnssBatchingCallback>& callback)
  109. {
  110. mMutex.lock();
  111. bool cbWasNull = (mGnssBatchingCbIface_2_0 == nullptr);
  112. mGnssBatchingCbIface = nullptr;
  113. mGnssBatchingCbIface_2_0 = callback;
  114. mMutex.unlock();
  115. if (cbWasNull) {
  116. setCallbacks();
  117. }
  118. }
  119. int BatchingAPIClient::startSession(const IGnssBatching::Options& opts) {
  120. mMutex.lock();
  121. mState = STARTED;
  122. mMutex.unlock();
  123. LOC_LOGD("%s]: (%lld %d)", __FUNCTION__,
  124. static_cast<long long>(opts.periodNanos), static_cast<uint8_t>(opts.flags));
  125. int retVal = -1;
  126. LocationOptions options;
  127. convertBatchOption(opts, options, mLocationCapabilitiesMask);
  128. uint32_t mode = 0;
  129. if (opts.flags == static_cast<uint8_t>(IGnssBatching::Flag::WAKEUP_ON_FIFO_FULL)) {
  130. mode = SESSION_MODE_ON_FULL;
  131. }
  132. if (locAPIStartSession(mDefaultId, mode, options) == LOCATION_ERROR_SUCCESS) {
  133. retVal = 1;
  134. }
  135. return retVal;
  136. }
  137. int BatchingAPIClient::updateSessionOptions(const IGnssBatching::Options& opts)
  138. {
  139. LOC_LOGD("%s]: (%lld %d)", __FUNCTION__,
  140. static_cast<long long>(opts.periodNanos), static_cast<uint8_t>(opts.flags));
  141. int retVal = -1;
  142. LocationOptions options;
  143. convertBatchOption(opts, options, mLocationCapabilitiesMask);
  144. uint32_t mode = 0;
  145. if (opts.flags == static_cast<uint8_t>(IGnssBatching::Flag::WAKEUP_ON_FIFO_FULL)) {
  146. mode = SESSION_MODE_ON_FULL;
  147. }
  148. if (locAPIUpdateSessionOptions(mDefaultId, mode, options) == LOCATION_ERROR_SUCCESS) {
  149. retVal = 1;
  150. }
  151. return retVal;
  152. }
  153. int BatchingAPIClient::stopSession() {
  154. mMutex.lock();
  155. mState = STOPPING;
  156. mMutex.unlock();
  157. LOC_LOGD("%s]: ", __FUNCTION__);
  158. int retVal = -1;
  159. locAPIGetBatchedLocations(mDefaultId, SIZE_MAX);
  160. if (locAPIStopSession(mDefaultId) == LOCATION_ERROR_SUCCESS) {
  161. retVal = 1;
  162. }
  163. return retVal;
  164. }
  165. void BatchingAPIClient::getBatchedLocation(int last_n_locations)
  166. {
  167. LOC_LOGD("%s]: (%d)", __FUNCTION__, last_n_locations);
  168. locAPIGetBatchedLocations(mDefaultId, last_n_locations);
  169. }
  170. void BatchingAPIClient::flushBatchedLocations() {
  171. LOC_LOGD("%s]: ()", __FUNCTION__);
  172. uint32_t retVal = locAPIGetBatchedLocations(mDefaultId, SIZE_MAX);
  173. // when flush a stopped session or one doesn't exist, just report an empty batch.
  174. if (LOCATION_ERROR_ID_UNKNOWN == retVal) {
  175. BatchingOptions opt = {};
  176. ::std::thread thd(&BatchingAPIClient::onBatchingCb, this, 0, nullptr, opt);
  177. thd.detach();
  178. }
  179. }
  180. void BatchingAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask)
  181. {
  182. LOC_LOGD("%s]: (%" PRIu64 ")", __FUNCTION__, capabilitiesMask);
  183. mLocationCapabilitiesMask = capabilitiesMask;
  184. }
  185. void BatchingAPIClient::onBatchingCb(size_t count, Location* location,
  186. BatchingOptions /*batchOptions*/) {
  187. bool processReport = false;
  188. LOC_LOGd("(count: %zu)", count);
  189. mMutex.lock();
  190. // back to back stop() and flush() could bring twice onBatchingCb(). Each one might come first.
  191. // Combine them both (the first goes to cache, the second in location*) before report to FW
  192. switch (mState) {
  193. case STOPPING:
  194. mState = STOPPED;
  195. for (size_t i = 0; i < count; i++) {
  196. mBatchedLocationInCache.push_back(location[i]);
  197. }
  198. break;
  199. case STARTED:
  200. case STOPPED: // flush() always trigger report, even on a stopped session
  201. processReport = true;
  202. break;
  203. default:
  204. break;
  205. }
  206. // report location batch when in STARTED state or flush(), combined with cache in last stop()
  207. if (processReport) {
  208. auto gnssBatchingCbIface(mGnssBatchingCbIface);
  209. auto gnssBatchingCbIface_2_0(mGnssBatchingCbIface_2_0);
  210. size_t batchCacheCnt = mBatchedLocationInCache.size();
  211. LOC_LOGd("(batchCacheCnt: %zu)", batchCacheCnt);
  212. if (gnssBatchingCbIface_2_0 != nullptr) {
  213. hidl_vec<V2_0::GnssLocation> locationVec;
  214. if (count+batchCacheCnt > 0) {
  215. locationVec.resize(count+batchCacheCnt);
  216. for (size_t i = 0; i < batchCacheCnt; ++i) {
  217. convertGnssLocation(mBatchedLocationInCache[i], locationVec[i]);
  218. }
  219. for (size_t i = 0; i < count; i++) {
  220. convertGnssLocation(location[i], locationVec[i+batchCacheCnt]);
  221. }
  222. }
  223. auto r = gnssBatchingCbIface_2_0->gnssLocationBatchCb(locationVec);
  224. if (!r.isOk()) {
  225. LOC_LOGE("%s] Error from gnssLocationBatchCb 2_0 description=%s",
  226. __func__, r.description().c_str());
  227. }
  228. } else if (gnssBatchingCbIface != nullptr) {
  229. hidl_vec<V1_0::GnssLocation> locationVec;
  230. if (count+batchCacheCnt > 0) {
  231. locationVec.resize(count+batchCacheCnt);
  232. for (size_t i = 0; i < batchCacheCnt; ++i) {
  233. convertGnssLocation(mBatchedLocationInCache[i], locationVec[i]);
  234. }
  235. for (size_t i = 0; i < count; i++) {
  236. convertGnssLocation(location[i], locationVec[i+batchCacheCnt]);
  237. }
  238. }
  239. auto r = gnssBatchingCbIface->gnssLocationBatchCb(locationVec);
  240. if (!r.isOk()) {
  241. LOC_LOGE("%s] Error from gnssLocationBatchCb 1.0 description=%s",
  242. __func__, r.description().c_str());
  243. }
  244. }
  245. mBatchedLocationInCache.clear();
  246. }
  247. mMutex.unlock();
  248. }
  249. static void convertBatchOption(const IGnssBatching::Options& in, LocationOptions& out,
  250. LocationCapabilitiesMask mask)
  251. {
  252. memset(&out, 0, sizeof(LocationOptions));
  253. out.size = sizeof(LocationOptions);
  254. out.minInterval = (uint32_t)(in.periodNanos / 1000000L);
  255. out.minDistance = 0;
  256. out.mode = GNSS_SUPL_MODE_STANDALONE;
  257. if (mask & LOCATION_CAPABILITIES_GNSS_MSA_BIT)
  258. out.mode = GNSS_SUPL_MODE_MSA;
  259. if (mask & LOCATION_CAPABILITIES_GNSS_MSB_BIT)
  260. out.mode = GNSS_SUPL_MODE_MSB;
  261. }
  262. } // namespace implementation
  263. } // namespace V2_1
  264. } // namespace gnss
  265. } // namespace hardware
  266. } // namespace android