GnssAutoPowerHandler.cpp 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. /*
  2. * Copyright (c) 2021 The Linux Foundation. All rights reserved.
  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. #define LOG_TAG "LocSvc_GnssAutoPowerHandler"
  29. #include <log_util.h>
  30. #include <gps_extended_c.h>
  31. #include <utils/Mutex.h>
  32. #include "GnssAutoPowerHandler.h"
  33. #include "android-base/macros.h"
  34. #include <VehicleUtils.h>
  35. #include <chrono>
  36. #include <thread>
  37. using android::Mutex;
  38. // Power state report
  39. constexpr int32_t POWER_STATE_WAIT_FOR_VHAL =
  40. static_cast<int32_t>(VehicleApPowerStateReport::WAIT_FOR_VHAL);
  41. constexpr int32_t POWER_STATE_DEEP_SLEEP_ENTRY =
  42. static_cast<int32_t>(VehicleApPowerStateReport::DEEP_SLEEP_ENTRY);
  43. constexpr int32_t POWER_STATE_DEEP_SLEEP_EXIT =
  44. static_cast<int32_t>(VehicleApPowerStateReport::DEEP_SLEEP_EXIT);
  45. constexpr int32_t POWER_STATE_SHUTDOWN_POSTPONE =
  46. static_cast<int32_t>(VehicleApPowerStateReport::SHUTDOWN_POSTPONE);
  47. constexpr int32_t POWER_STATE_SHUTDOWN_START =
  48. static_cast<int32_t>(VehicleApPowerStateReport::SHUTDOWN_START);
  49. constexpr int32_t POWER_STATE_ON =
  50. static_cast<int32_t>(VehicleApPowerStateReport::ON);
  51. constexpr int32_t POWER_STATE_SHUTDOWN_PREPARE =
  52. static_cast<int32_t>(VehicleApPowerStateReport::SHUTDOWN_PREPARE);
  53. constexpr int32_t POWER_STATE_SHUTDOWN_CANCELLED =
  54. static_cast<int32_t>(VehicleApPowerStateReport::SHUTDOWN_CANCELLED);
  55. static GnssAutoPowerHandler* sGnssAutoPowerHandler = nullptr;
  56. /*VHidlDeathRecipient Implementation*/
  57. void GnssAutoPowerHandler::VHidlDeathRecipient::serviceDied(uint64_t cookie, const wp<IBase>& who) {
  58. mHandler->handleVHidlDeath(cookie, who);
  59. }
  60. void GnssAutoPowerHandler::sendPowerEventToLocCtrlApi(PowerStateType intPowerState) {
  61. if (NULL == mLocationControlApi)
  62. mLocationControlApi = LocationControlAPI::getInstance();
  63. if (NULL != mLocationControlApi)
  64. mLocationControlApi->powerStateEvent(intPowerState);
  65. }
  66. void GnssAutoPowerHandler::initializeGnssAutoPower() {
  67. bool retVal = false;
  68. do {
  69. retVal = connectToVhal();
  70. if (true != retVal) {
  71. LOC_LOGw("Could not connect to VHAL");
  72. }
  73. //Sleep for 10ms for VHAL service to come-up before trying again.
  74. std::this_thread::sleep_for(std::chrono::milliseconds(50));
  75. } while (false == retVal);
  76. }
  77. GnssAutoPowerHandler::GnssAutoPowerHandler():
  78. mVHidlDeathRecipient(new VHidlDeathRecipient(this)),
  79. mLocationControlApi(LocationControlAPI::getInstance()) {
  80. sGnssAutoPowerHandler = this;
  81. std::thread subscriptionThread ( [this]() {
  82. initializeGnssAutoPower();
  83. });
  84. subscriptionThread.detach();
  85. }
  86. GnssAutoPowerHandler::~GnssAutoPowerHandler(){
  87. }
  88. bool GnssAutoPowerHandler::subscribeToVhal() {
  89. bool returnVal = false;
  90. constexpr int32_t prop = static_cast<int32_t>(VehicleProperty::AP_POWER_STATE_REPORT);
  91. if (!isPropertySupported(prop)) {
  92. LOC_LOGW("Vehicle property(%d) is not supported by VHAL.", prop);
  93. return returnVal;
  94. }
  95. VehiclePropValue propValue{
  96. .prop = prop,
  97. };
  98. sp<IVehicle> vhalService;
  99. {
  100. Mutex::Autolock lock(mMutex);
  101. vhalService = mVhalService;
  102. }
  103. StatusCode status;
  104. vhalService->get(propValue, [&status, &propValue](StatusCode s, const
  105. VehiclePropValue& value) {
  106. status = s;
  107. propValue = value;
  108. });
  109. if (status != StatusCode::OK) {
  110. LOC_LOGW("Failed to get vehicle property(%d) value.", prop);
  111. return returnVal;
  112. }
  113. handleGnssAutoPowerEvent(propValue.value.int32Values[0]);
  114. // Subscribe to AP_POWER_STATE_REPORT.
  115. SubscribeOptions reqVhalProperties[] = {
  116. {.propId = prop, .flags = SubscribeFlags::EVENTS_FROM_ANDROID},
  117. };
  118. hidl_vec<SubscribeOptions> options;
  119. options.setToExternal(reqVhalProperties, arraysize(reqVhalProperties));
  120. status = vhalService->subscribe(this, options);
  121. if (status != StatusCode::OK) {
  122. LOC_LOGW("%s], Failed to subscribe to vehicle property(%d).", __FUNCTION__, prop);
  123. } else {
  124. returnVal = true;
  125. }
  126. return returnVal;
  127. } //GnssAutoPowerHandler::subscribeToVhal
  128. bool GnssAutoPowerHandler::isPropertySupported(int32_t prop) {
  129. if (mSupportedProperties.count(prop) > 0) {
  130. return mSupportedProperties[prop];
  131. }
  132. StatusCode status;
  133. hidl_vec<int32_t> props = {prop};
  134. sp<IVehicle> vhalService;
  135. {
  136. Mutex::Autolock lock(mMutex);
  137. vhalService = mVhalService;
  138. }
  139. vhalService->getPropConfigs(props,
  140. [&status](StatusCode s,
  141. hidl_vec<VehiclePropConfig>) {
  142. status = s;
  143. });
  144. mSupportedProperties[prop] = (status == StatusCode::OK);
  145. return mSupportedProperties[prop];
  146. }
  147. bool GnssAutoPowerHandler::connectToVhal(void) {
  148. bool returnValue = false;
  149. {
  150. Mutex::Autolock lock(mMutex);
  151. if (mVhalService.get() != nullptr) {
  152. return true;
  153. }
  154. }
  155. // Get a vehicle HAL instance.
  156. sp<IVehicle> vhalService = IVehicle::tryGetService();
  157. if (vhalService.get() == nullptr) {
  158. LOC_LOGe("Unable to connect to VHAL Service.");
  159. return returnValue;
  160. }
  161. auto ret = vhalService->linkToDeath(mVHidlDeathRecipient, /*cookie=*/0x03);
  162. if (!ret.isOk() || ret == false) {
  163. LOC_LOGw("Failed to connect to VHAL. VHAL is dead.");
  164. return returnValue;
  165. }
  166. {
  167. Mutex::Autolock lock(mMutex);
  168. mVhalService = vhalService;
  169. }
  170. LOC_LOGi("Connected to VHAL");
  171. returnValue = subscribeToVhal();
  172. return returnValue;
  173. }//initializeGnssAutoPower
  174. void GnssAutoPowerHandler::handleGnssAutoPowerEvent(int32_t powerState) {
  175. bool retVal = false;
  176. LOC_LOGd("Power State: %d", powerState);
  177. switch (powerState) {
  178. case POWER_STATE_SHUTDOWN_PREPARE:
  179. LOC_LOGi("Suspend GNSS sessions.");
  180. sendPowerEventToLocCtrlApi(POWER_STATE_SUSPEND);
  181. break;
  182. case POWER_STATE_DEEP_SLEEP_EXIT:
  183. case POWER_STATE_SHUTDOWN_CANCELLED:
  184. LOC_LOGi("Resume GNSS Sessions.");
  185. sendPowerEventToLocCtrlApi(POWER_STATE_RESUME);
  186. break;
  187. default:
  188. break;
  189. }//switch
  190. } //GnssAutoPowerHandler::handleGnssAutoPowerEvent
  191. void GnssAutoPowerHandler::handleVHidlDeath(uint64_t cookie, const wp<IBase>& who) {
  192. {
  193. LOC_LOGE("%s] VHAL service died. cookie: %llu, who: %p",
  194. __FUNCTION__, static_cast<unsigned long long>(cookie), &who);
  195. Mutex::Autolock lock(mMutex);
  196. if (mVhalService.get() != nullptr) {
  197. mVhalService->unlinkToDeath(mVHidlDeathRecipient);
  198. mVhalService = nullptr;
  199. }
  200. }
  201. (void) cookie;
  202. //TBD: To re-connect to VHAL service
  203. } //handleVHidlDeath
  204. /*Overrides*/
  205. Return<void> GnssAutoPowerHandler::onPropertyEvent(const hidl_vec<VehiclePropValue>& ) {
  206. return Return<void>();
  207. }
  208. Return<void> GnssAutoPowerHandler::onPropertySet(const VehiclePropValue& propValue) {
  209. if (propValue.prop == static_cast<int32_t>(VehicleProperty::AP_POWER_STATE_REPORT))
  210. {
  211. int32_t powerState = propValue.value.int32Values[0];
  212. handleGnssAutoPowerEvent(powerState);
  213. }
  214. return Return<void>();
  215. }
  216. Return<void> GnssAutoPowerHandler::onPropertySetError(StatusCode status, int32_t propId,
  217. int32_t areaId) {
  218. (void)status;
  219. (void)propId;
  220. (void)areaId;
  221. return Return<void>();
  222. }
  223. GnssAutoPowerHandler* GnssAutoPowerHandler::getGnssAutoPowerHandler() {
  224. if (nullptr == sGnssAutoPowerHandler) {
  225. GnssAutoPowerHandler *autoPwrHandler;
  226. autoPwrHandler = new GnssAutoPowerHandler();
  227. }
  228. return sGnssAutoPowerHandler;
  229. }
  230. extern "C" void initGnssAutoPowerHandler(void){
  231. GnssAutoPowerHandler::getGnssAutoPowerHandler();
  232. }