CapoDetector.cpp 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. /*
  2. * Copyright 2022 Google LLC. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "CapoDetector.h"
  17. #include <google/protobuf/message.h>
  18. #include <google/protobuf/io/coded_stream.h>
  19. #include <google/protobuf/io/zero_copy_stream_impl.h>
  20. #include <log/log.h>
  21. #ifdef LOG_TAG
  22. #undef LOG_TAG
  23. #define LOG_TAG "CapoDetector"
  24. #endif
  25. namespace android {
  26. namespace chre {
  27. namespace { // anonymous namespace for file-local definitions
  28. /**
  29. * Called when onConnected() to send NanoappList request.
  30. */
  31. void requestNanoappList(SocketClient &client) {
  32. flatbuffers::FlatBufferBuilder builder;
  33. HostProtocolHost::encodeNanoappListRequest(builder);
  34. if (!client.sendMessage(builder.GetBufferPointer(), builder.GetSize())) {
  35. ALOGE("Failed to send NanoappList request");
  36. }
  37. }
  38. } // namespace
  39. /**
  40. * Called when initializing connection with CHRE socket.
  41. */
  42. sp<CapoDetector> CapoDetector::start() {
  43. sp<CapoDetector> listener = new CapoDetector();
  44. if (!listener->connectInBackground(kChreSocketName, listener)) {
  45. ALOGE("Couldn't connect to CHRE socket");
  46. return nullptr;
  47. }
  48. ALOGI("%s connect to CHRE socket.", __func__);
  49. return listener;
  50. }
  51. /**
  52. * Called when the socket is successfully (re-)connected.
  53. * Reset the position and try to send NanoappList request.
  54. */
  55. void CapoDetector::onConnected() {
  56. flatbuffers::FlatBufferBuilder builder;
  57. // Reset the last position type.
  58. last_position_type_ = capo::PositionType::UNKNOWN;
  59. requestNanoappList(*this);
  60. }
  61. /**
  62. * Called when we have failed to (re-)connect the socket after many attempts
  63. * and are giving up.
  64. */
  65. void CapoDetector::onConnectionAborted() {
  66. ALOGE("%s, Capo Aborting Connection!", __func__);
  67. }
  68. /**
  69. * Invoked when the socket is disconnected, and this connection loss was not
  70. * the result of an explicit call to disconnect().
  71. * Reset the position while disconnecting.
  72. */
  73. void CapoDetector::onDisconnected() {
  74. last_position_type_ = capo::PositionType::UNKNOWN;
  75. }
  76. /**
  77. * Decode unix socket msgs to CHRE messages, and call the appropriate
  78. * callback depending on the CHRE message.
  79. */
  80. void CapoDetector::onMessageReceived(const void *data, size_t length) {
  81. if (!HostProtocolHost::decodeMessageFromChre(data, length, *this)) {
  82. ALOGE("Failed to decode message");
  83. }
  84. }
  85. /**
  86. * Listen for messages from capo nanoapp and handle the message.
  87. */
  88. void CapoDetector::handleNanoappMessage(const fbs::NanoappMessageT &message) {
  89. ALOGI("%s, Id %" PRIu64 ", type %d, size %d", __func__, message.app_id, message.message_type,
  90. static_cast<int>(message.message.size()));
  91. // Exclude the message with unmatched nanoapp id.
  92. if (message.app_id != kCapoNanoappId)
  93. return;
  94. // Handle the message with message_type.
  95. switch (message.message_type) {
  96. case capo::MessageType::ACK_NOTIFICATION: {
  97. capo::AckNotification gd;
  98. gd.set_notification_type(static_cast<capo::NotificationType>(message.message[1]));
  99. ALOGD("%s, get notification event from capo nanoapp, type %d", __func__,
  100. gd.notification_type());
  101. break;
  102. }
  103. case capo::MessageType::POSITION_DETECTED: {
  104. capo::PositionDetected gd;
  105. gd.set_position_type(static_cast<capo::PositionType>(message.message[1]));
  106. ALOGD("%s, get position event from capo nanoapp, type %d", __func__,
  107. gd.position_type());
  108. // Callback to function while getting carried position event.
  109. if (callback_func_ != nullptr) {
  110. last_position_type_ = gd.position_type();
  111. ALOGD("%s, sent position type %d to callback function", __func__,
  112. last_position_type_);
  113. callback_func_(last_position_type_);
  114. }
  115. break;
  116. }
  117. default:
  118. ALOGE("%s, get invalid message, type: %" PRIu32 ", from capo nanoapp.", __func__,
  119. message.message_type);
  120. break;
  121. }
  122. }
  123. /**
  124. * Handle the response of a NanoappList request.
  125. * Ensure that capo nanoapp is running.
  126. */
  127. void CapoDetector::handleNanoappListResponse(const fbs::NanoappListResponseT &response) {
  128. for (const std::unique_ptr<fbs::NanoappListEntryT> &nanoapp : response.nanoapps) {
  129. if (nanoapp->app_id == kCapoNanoappId) {
  130. if (nanoapp->enabled)
  131. enable();
  132. else
  133. ALOGE("Capo nanoapp not enabled");
  134. return;
  135. }
  136. }
  137. ALOGE("Capo nanoapp not found");
  138. }
  139. /**
  140. * Send enabling message to the nanoapp.
  141. */
  142. void CapoDetector::enable() {
  143. // Create CHRE message with serialized message
  144. flatbuffers::FlatBufferBuilder builder, config_builder, force_builder;
  145. auto config_data = std::make_unique<capo::ConfigureDetector_ConfigData>();
  146. auto msg = std::make_unique<capo::ConfigureDetector>();
  147. config_data->set_still_time_threshold_nanosecond(mCapoDetectorMDParameters.still_time_threshold_ns);
  148. config_data->set_window_width_nanosecond(mCapoDetectorMDParameters.window_width_ns);
  149. config_data->set_motion_confidence_threshold(mCapoDetectorMDParameters.motion_confidence_threshold);
  150. config_data->set_still_confidence_threshold(mCapoDetectorMDParameters.still_confidence_threshold);
  151. config_data->set_var_threshold(mCapoDetectorMDParameters.var_threshold);
  152. config_data->set_var_threshold_delta(mCapoDetectorMDParameters.var_threshold_delta);
  153. msg->set_allocated_config_data(config_data.release());
  154. auto pb_size = msg->ByteSizeLong();
  155. auto pb_data = std::make_unique<uint8_t[]>(pb_size);
  156. if (!msg->SerializeToArray(pb_data.get(), pb_size)) {
  157. ALOGE("Failed to serialize message.");
  158. }
  159. ALOGI("Configuring CapoDetector");
  160. // Configure the detector from host-side
  161. android::chre::HostProtocolHost::encodeNanoappMessage(
  162. config_builder, getNanoppAppId(), capo::MessageType::CONFIGURE_DETECTOR, getHostEndPoint(),
  163. pb_data.get(), pb_size);
  164. ALOGI("Sending capo config message to Nanoapp, %" PRIu32 " bytes", config_builder.GetSize());
  165. if (!sendMessage(config_builder.GetBufferPointer(), config_builder.GetSize())) {
  166. ALOGE("Failed to send config event for capo nanoapp");
  167. }
  168. ALOGI("Enabling CapoDetector");
  169. android::chre::HostProtocolHost::encodeNanoappMessage(
  170. builder, getNanoppAppId(), capo::MessageType::ENABLE_DETECTOR, getHostEndPoint(),
  171. /*messageData*/ nullptr, /*messageDataLenbuffer*/ 0);
  172. ALOGI("Sending enable message to Nanoapp, %" PRIu32 " bytes", builder.GetSize());
  173. if (!sendMessage(builder.GetBufferPointer(), builder.GetSize())) {
  174. ALOGE("Failed to send enable event for capo nanoapp");
  175. }
  176. ALOGI("Forcing CapoDetector to update state");
  177. // Force an updated state upon connection
  178. android::chre::HostProtocolHost::encodeNanoappMessage(
  179. force_builder, getNanoppAppId(), capo::MessageType::FORCE_UPDATE, getHostEndPoint(),
  180. /*messageData*/ nullptr, /*messageDataLenbuffer*/ 0);
  181. ALOGI("Sending force-update message to Nanoapp, %" PRIu32 " bytes", force_builder.GetSize());
  182. if (!sendMessage(force_builder.GetBufferPointer(), force_builder.GetSize())) {
  183. ALOGE("Failed to send force-update event for capo nanoapp");
  184. }
  185. }
  186. } // namespace chre
  187. } // namespace android