diff --git a/base/cvd/cuttlefish/common/libs/sensors/sensors.h b/base/cvd/cuttlefish/common/libs/sensors/sensors.h index 789830d76d4..527a866d07b 100644 --- a/base/cvd/cuttlefish/common/libs/sensors/sensors.h +++ b/base/cvd/cuttlefish/common/libs/sensors/sensors.h @@ -57,6 +57,7 @@ inline constexpr char OUTER_DELIM = ' '; inline constexpr int kUpdateRotationVec = 0; inline constexpr int kGetSensorsData = 1; inline constexpr int kUpdateHal = 2; +inline constexpr int kUpdateLowLatencyOffBodyDetect = 3; using SensorsCmd = int; diff --git a/base/cvd/cuttlefish/host/commands/sensors_simulator/main.cpp b/base/cvd/cuttlefish/host/commands/sensors_simulator/main.cpp index 046aaa5e6da..5e6185d2662 100644 --- a/base/cvd/cuttlefish/host/commands/sensors_simulator/main.cpp +++ b/base/cvd/cuttlefish/host/commands/sensors_simulator/main.cpp @@ -79,6 +79,12 @@ Result ProcessWebrtcRequest(transport::SharedFdChannel& channel, "Can't send request for cmd: " << cmd); break; } + case kUpdateLowLatencyOffBodyDetect: { + double value; + CF_EXPECT(static_cast(ss >> value), kReqMisFormatted); + sensors_simulator.UpdateLowLatencyOffBodyDetect(value); + break; + } default: { return CF_ERR("Unsupported cmd: " << cmd); } diff --git a/base/cvd/cuttlefish/host/commands/sensors_simulator/sensors_hal_proxy.cpp b/base/cvd/cuttlefish/host/commands/sensors_simulator/sensors_hal_proxy.cpp index 9b408ff222b..1b81eb8a7d8 100644 --- a/base/cvd/cuttlefish/host/commands/sensors_simulator/sensors_hal_proxy.cpp +++ b/base/cvd/cuttlefish/host/commands/sensors_simulator/sensors_hal_proxy.cpp @@ -32,7 +32,8 @@ static constexpr uint32_t kIntervalMs = 1000; static constexpr SensorsMask kContinuousModeSensors = (1 << kAccelerationId) | (1 << kGyroscopeId) | (1 << kMagneticId) | (1 << kPressureId) | (1 << kUncalibGyroscopeId) | - (1 << kUncalibAccelerationId) | (1 << kLightId); + (1 << kUncalibAccelerationId) | (1 << kLightId) | + (1 << kSensorHandleLowLatencyOffBodyDetect); Result SensorIdToName(int id) { switch (id) { diff --git a/base/cvd/cuttlefish/host/commands/sensors_simulator/sensors_simulator.cpp b/base/cvd/cuttlefish/host/commands/sensors_simulator/sensors_simulator.cpp index 8e4f644c44f..f7218c72e69 100644 --- a/base/cvd/cuttlefish/host/commands/sensors_simulator/sensors_simulator.cpp +++ b/base/cvd/cuttlefish/host/commands/sensors_simulator/sensors_simulator.cpp @@ -37,7 +37,8 @@ inline double ToRadians(double x) { return x * M_PI / 180; } // Check if a given sensor id provides scalar data static bool IsScalarSensor(int id) { return (id == kTemperatureId) || (id == kProximityId) || (id == kLightId) || - (id == kPressureId) || (id == kHumidityId) || (id == kHingeAngle0Id); + (id == kPressureId) || (id == kHumidityId) || (id == kHingeAngle0Id) || + (id == kSensorHandleLowLatencyOffBodyDetect); } // Calculate the rotation matrix of the pitch, roll, and yaw angles. @@ -134,6 +135,10 @@ void SensorsSimulator::RefreshSensors(double x, double y, double z) { sensors_data_[kUncalibMagneticId].v = mgn_update; } +void SensorsSimulator::UpdateLowLatencyOffBodyDetect(double value) { + sensors_data_[kSensorHandleLowLatencyOffBodyDetect].f = value; +} + std::string SensorsSimulator::GetSensorsData(const SensorsMask mask) { std::stringstream sensors_msg; std::lock_guard lock(sensors_data_mtx_); diff --git a/base/cvd/cuttlefish/host/commands/sensors_simulator/sensors_simulator.h b/base/cvd/cuttlefish/host/commands/sensors_simulator/sensors_simulator.h index e0a26620257..b3a7cd3cf45 100644 --- a/base/cvd/cuttlefish/host/commands/sensors_simulator/sensors_simulator.h +++ b/base/cvd/cuttlefish/host/commands/sensors_simulator/sensors_simulator.h @@ -39,6 +39,7 @@ class SensorsSimulator { SensorsSimulator(bool is_auto); // Update sensor values based on new rotation status. void RefreshSensors(double x, double y, double z); + void UpdateLowLatencyOffBodyDetect(double value); // Return a string with serialized sensors data in ascending order of // sensor id. A bitmask is used to specify which sensors to include. diff --git a/base/cvd/cuttlefish/host/frontend/webrtc/connection_observer.cpp b/base/cvd/cuttlefish/host/frontend/webrtc/connection_observer.cpp index 3a813239e77..7e248f947b2 100644 --- a/base/cvd/cuttlefish/host/frontend/webrtc/connection_observer.cpp +++ b/base/cvd/cuttlefish/host/frontend/webrtc/connection_observer.cpp @@ -246,22 +246,13 @@ class ConnectionObserverImpl : public webrtc_streaming::ConnectionObserver { void OnSensorsMessage(const uint8_t *msg, size_t size) override { std::string msgstr(msg, msg + size); - std::vector xyz = android::base::Split(msgstr, " "); - if (xyz.size() != 3) { - LOG(WARNING) << "Invalid rotation angles: Expected 3, received " - << xyz.size(); - return; + if (msgstr.rfind(kOnSensorLowLatencyOffBodyDetectCmd, 0) == 0) { + auto payload = msgstr.substr(kOnSensorLowLatencyOffBodyDetectCmd.size()); + HandleLowLatencyOffBodySensorMessage(payload); + } else { + HandleRotationSensorMessage(msgstr); } - - double x, y, z; - CHECK(android::base::ParseDouble(xyz.at(0), &x)) - << "X rotation value must be a double"; - CHECK(android::base::ParseDouble(xyz.at(1), &y)) - << "Y rotation value must be a double"; - CHECK(android::base::ParseDouble(xyz.at(2), &z)) - << "Z rotation value must be a double"; - sensors_handler_.HandleMessage(x, y, z); } void OnLightsChannelOpen( @@ -431,6 +422,40 @@ class ConnectionObserverImpl : public webrtc_streaming::ConnectionObserver { } } + void HandleRotationSensorMessage(const std::string &msg) { + std::vector xyz = android::base::Split(msg, " "); + + if (xyz.size() != 3) { + LOG(WARNING) << "Invalid rotation angles: Expected 3, received " + << xyz.size(); + return; + } + + double x, y, z; + if (!android::base::ParseDouble(xyz.at(0), &x)) { + LOG(ERROR) << "X rotation value must be a double"; + return; + } + if (!android::base::ParseDouble(xyz.at(1), &y)) { + LOG(ERROR) << "Y rotation value must be a double"; + return; + } + if (!android::base::ParseDouble(xyz.at(2), &z)) { + LOG(ERROR) << "Z rotation value must be a double"; + return; + } + sensors_handler_.HandleMessage(x, y, z); + } + + void HandleLowLatencyOffBodySensorMessage(const std::string &msg) { + double value; + if (!android::base::ParseDouble(msg, &value)) { + LOG(ERROR) << "Low latency off body value must be double"; + return; + } + sensors_handler_.HandleLowLatencyOffBodyDetectMessage(value); + } + std::unique_ptr input_events_sink_; KernelLogEventsHandler &kernel_log_events_handler_; int kernel_log_subscription_id_ = -1; @@ -446,6 +471,8 @@ class ConnectionObserverImpl : public webrtc_streaming::ConnectionObserver { std::shared_ptr lights_observer_; int sensors_subscription_id = -1; int lights_subscription_id_ = -1; + static constexpr std::string_view kOnSensorLowLatencyOffBodyDetectCmd = + "low-latency-off-body-detect:"; }; CfConnectionObserverFactory::CfConnectionObserverFactory( diff --git a/base/cvd/cuttlefish/host/frontend/webrtc/sensors_handler.cpp b/base/cvd/cuttlefish/host/frontend/webrtc/sensors_handler.cpp index 8b32e5594e8..2e8462e46ed 100644 --- a/base/cvd/cuttlefish/host/frontend/webrtc/sensors_handler.cpp +++ b/base/cvd/cuttlefish/host/frontend/webrtc/sensors_handler.cpp @@ -57,6 +57,20 @@ Result SensorsHandler::RefreshSensors(const double x, const double y, return {}; } +Result SensorsHandler::RefreshLowLatencyOffBodyDetect( + const double value) { + auto msg = std::to_string(value); + auto size = msg.size(); + auto cmd = sensors::kUpdateLowLatencyOffBodyDetect; + auto request = CF_EXPECT(transport::CreateMessage(cmd, size), + "Failed to allocate message for cmd: " + << cmd << " with size: " << size << " bytes. "); + std::memcpy(request->payload, msg.data(), size); + CF_EXPECT(channel_.SendRequest(*request), + "Can't send request for cmd: " << cmd); + return {}; +} + Result SensorsHandler::GetSensorsData() { auto msg = std::to_string(kUiSupportedSensors); auto size = msg.size(); @@ -88,6 +102,16 @@ void SensorsHandler::HandleMessage(const double x, const double y, const double UpdateSensorsUi(); } +void SensorsHandler::HandleLowLatencyOffBodyDetectMessage(double value) { + auto refresh_result = RefreshLowLatencyOffBodyDetect(value); + if (!refresh_result.ok()) { + LOG(ERROR) << "Failed to refresh low latency off body detect: " + << refresh_result.error().FormatForEnv(); + return; + } + UpdateSensorsUi(); +} + int SensorsHandler::Subscribe(std::function send_to_client) { int subscriber_id = ++last_client_channel_id_; { diff --git a/base/cvd/cuttlefish/host/frontend/webrtc/sensors_handler.h b/base/cvd/cuttlefish/host/frontend/webrtc/sensors_handler.h index d91ecb17d12..517c7a0e6aa 100644 --- a/base/cvd/cuttlefish/host/frontend/webrtc/sensors_handler.h +++ b/base/cvd/cuttlefish/host/frontend/webrtc/sensors_handler.h @@ -31,11 +31,13 @@ struct SensorsHandler { SensorsHandler(SharedFD sensors_fd); ~SensorsHandler(); void HandleMessage(const double x, const double y, const double z); + void HandleLowLatencyOffBodyDetectMessage(double value); int Subscribe(std::function send_to_client); void UnSubscribe(int subscriber_id); private: Result RefreshSensors(const double x, const double y, const double z); + Result RefreshLowLatencyOffBodyDetect(const double value); Result GetSensorsData(); void UpdateSensorsUi(); std::unordered_map> client_channels_;