1 /*
2 * Copyright (C) 2020 The Android Open Source Project
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
17 #define LOG_TAG "ConnectionObserver"
18
19 #include "host/frontend/webrtc/connection_observer.h"
20
21 #include <linux/input.h>
22
23 #include <chrono>
24 #include <map>
25 #include <string>
26 #include <thread>
27 #include <vector>
28
29 #include <json/json.h>
30
31 #include <android-base/logging.h>
32 #include <android-base/parsedouble.h>
33 #include <gflags/gflags.h>
34
35 #include "common/libs/fs/shared_buf.h"
36 #include "common/libs/utils/json.h"
37 #include "common/libs/utils/result.h"
38 #include "host/frontend/webrtc/adb_handler.h"
39 #include "host/frontend/webrtc/bluetooth_handler.h"
40 #include "host/frontend/webrtc/gpx_locations_handler.h"
41 #include "host/frontend/webrtc/kml_locations_handler.h"
42 #include "host/frontend/webrtc/libdevice/camera_controller.h"
43 #include "host/frontend/webrtc/libdevice/lights_observer.h"
44 #include "host/frontend/webrtc/location_handler.h"
45 #include "host/libs/config/config_utils.h"
46 #include "host/libs/config/cuttlefish_config.h"
47 #include "host/libs/input_connector/input_connector.h"
48 #include "host/libs/vm_manager/crosvm_display_controller.h"
49
50 namespace cuttlefish {
51
52 /**
53 * connection observer implementation for regular android mode.
54 * i.e. when it is not in the confirmation UI mode (or TEE),
55 * the control flow will fall back to this ConnectionObserverForAndroid
56 */
57 class ConnectionObserverImpl : public webrtc_streaming::ConnectionObserver {
58 public:
ConnectionObserverImpl(std::unique_ptr<InputConnector::EventSink> input_events_sink,KernelLogEventsHandler & kernel_log_events_handler,std::map<std::string,SharedFD> commands_to_custom_action_servers,std::weak_ptr<DisplayHandler> display_handler,CameraController * camera_controller,webrtc_streaming::SensorsHandler & sensors_handler,std::shared_ptr<webrtc_streaming::LightsObserver> lights_observer)59 ConnectionObserverImpl(
60 std::unique_ptr<InputConnector::EventSink> input_events_sink,
61 KernelLogEventsHandler &kernel_log_events_handler,
62 std::map<std::string, SharedFD> commands_to_custom_action_servers,
63 std::weak_ptr<DisplayHandler> display_handler,
64 CameraController *camera_controller,
65 webrtc_streaming::SensorsHandler &sensors_handler,
66 std::shared_ptr<webrtc_streaming::LightsObserver> lights_observer)
67 : input_events_sink_(std::move(input_events_sink)),
68 kernel_log_events_handler_(kernel_log_events_handler),
69 commands_to_custom_action_servers_(commands_to_custom_action_servers),
70 weak_display_handler_(display_handler),
71 camera_controller_(camera_controller),
72 sensors_handler_(sensors_handler),
73 lights_observer_(lights_observer) {}
~ConnectionObserverImpl()74 virtual ~ConnectionObserverImpl() {
75 auto display_handler = weak_display_handler_.lock();
76 if (display_handler) {
77 display_handler->RemoveDisplayClient();
78 }
79 if (kernel_log_subscription_id_ != -1) {
80 kernel_log_events_handler_.Unsubscribe(kernel_log_subscription_id_);
81 }
82 }
83
OnConnected()84 void OnConnected() override {
85 auto display_handler = weak_display_handler_.lock();
86 if (display_handler) {
87 display_handler->AddDisplayClient();
88 }
89 SendLastFrameAsync(/*all displays*/ std::nullopt);
90 }
91
OnMouseMoveEvent(int x,int y)92 Result<void> OnMouseMoveEvent(int x, int y) override {
93 CF_EXPECT(input_events_sink_->SendMouseMoveEvent(x, y));
94 return {};
95 }
96
OnMouseButtonEvent(int button,bool down)97 Result<void> OnMouseButtonEvent(int button, bool down) override {
98 CF_EXPECT(input_events_sink_->SendMouseButtonEvent(button, down));
99 return {};
100 }
101
OnMouseWheelEvent(int pixels)102 Result<void> OnMouseWheelEvent(int pixels) override {
103 CF_EXPECT(input_events_sink_->SendMouseWheelEvent(pixels));
104 return {};
105 }
106
OnTouchEvent(const std::string & device_label,int x,int y,bool down)107 Result<void> OnTouchEvent(const std::string &device_label, int x, int y,
108 bool down) override {
109 CF_EXPECT(input_events_sink_->SendTouchEvent(device_label, x, y, down));
110 return {};
111 }
112
OnMultiTouchEvent(const std::string & device_label,Json::Value id,Json::Value x,Json::Value y,bool down,int size)113 Result<void> OnMultiTouchEvent(const std::string &device_label,
114 Json::Value id, Json::Value x, Json::Value y,
115 bool down, int size) {
116 std::vector<MultitouchSlot> slots(size);
117 for (int i = 0; i < size; i++) {
118 slots[i].id = id[i].asInt();
119 slots[i].x = x[i].asInt();
120 slots[i].y = y[i].asInt();
121 }
122 CF_EXPECT(
123 input_events_sink_->SendMultiTouchEvent(device_label, slots, down));
124 return {};
125 }
126
OnKeyboardEvent(uint16_t code,bool down)127 Result<void> OnKeyboardEvent(uint16_t code, bool down) override {
128 CF_EXPECT(input_events_sink_->SendKeyboardEvent(code, down));
129 return {};
130 }
131
OnRotaryWheelEvent(int pixels)132 Result<void> OnRotaryWheelEvent(int pixels) {
133 CF_EXPECT(input_events_sink_->SendRotaryEvent(pixels));
134 return {};
135 }
136
OnSwitchEvent(uint16_t code,bool state)137 Result<void> OnSwitchEvent(uint16_t code, bool state) {
138 CF_EXPECT(input_events_sink_->SendSwitchesEvent(code, state));
139 return {};
140 }
141
OnAdbChannelOpen(std::function<bool (const uint8_t *,size_t)> adb_message_sender)142 void OnAdbChannelOpen(std::function<bool(const uint8_t *, size_t)>
143 adb_message_sender) override {
144 LOG(VERBOSE) << "Adb Channel open";
145 adb_handler_.reset(new webrtc_streaming::AdbHandler(
146 CuttlefishConfig::Get()->ForDefaultInstance().adb_ip_and_port(),
147 adb_message_sender));
148 }
OnAdbMessage(const uint8_t * msg,size_t size)149 void OnAdbMessage(const uint8_t *msg, size_t size) override {
150 adb_handler_->handleMessage(msg, size);
151 }
OnControlChannelOpen(std::function<bool (const Json::Value)> control_message_sender)152 void OnControlChannelOpen(
153 std::function<bool(const Json::Value)> control_message_sender) override {
154 LOG(VERBOSE) << "Control Channel open";
155 if (camera_controller_) {
156 camera_controller_->SetMessageSender(control_message_sender);
157 }
158 kernel_log_subscription_id_ =
159 kernel_log_events_handler_.AddSubscriber(control_message_sender);
160 }
161
OnLidStateChange(bool lid_open)162 Result<void> OnLidStateChange(bool lid_open) override {
163 // InputManagerService treats a value of 0 as open and 1 as closed, so
164 // invert the lid_switch_open value that is sent to the input device.
165 CF_EXPECT(OnSwitchEvent(SW_LID, !lid_open));
166 return {};
167 }
OnHingeAngleChange(int)168 void OnHingeAngleChange(int /*hinge_angle*/) override {
169 // TODO(b/181157794) Propagate hinge angle sensor data using a custom
170 // Sensor HAL.
171 }
OnPowerButton(bool button_down)172 Result<void> OnPowerButton(bool button_down) override {
173 CF_EXPECT(OnKeyboardEvent(KEY_POWER, button_down));
174 return {};
175 }
OnBackButton(bool button_down)176 Result<void> OnBackButton(bool button_down) override {
177 CF_EXPECT(OnKeyboardEvent(KEY_BACK, button_down));
178 return {};
179 }
OnHomeButton(bool button_down)180 Result<void> OnHomeButton(bool button_down) override {
181 CF_EXPECT(OnKeyboardEvent(KEY_HOMEPAGE, button_down));
182 return {};
183 }
OnMenuButton(bool button_down)184 Result<void> OnMenuButton(bool button_down) override {
185 CF_EXPECT(OnKeyboardEvent(KEY_MENU, button_down));
186 return {};
187 }
OnVolumeDownButton(bool button_down)188 Result<void> OnVolumeDownButton(bool button_down) override {
189 CF_EXPECT(OnKeyboardEvent(KEY_VOLUMEDOWN, button_down));
190 return {};
191 }
OnVolumeUpButton(bool button_down)192 Result<void> OnVolumeUpButton(bool button_down) override {
193 CF_EXPECT(OnKeyboardEvent(KEY_VOLUMEUP, button_down));
194 return {};
195 }
OnCustomActionButton(const std::string & command,const std::string & button_state)196 void OnCustomActionButton(const std::string &command,
197 const std::string &button_state) override {
198 if (commands_to_custom_action_servers_.find(command) !=
199 commands_to_custom_action_servers_.end()) {
200 // Simple protocol for commands forwarded to action servers:
201 // - Always 128 bytes
202 // - Format: command:button_state
203 // - Example: my_button:down
204 std::string action_server_message = command + ":" + button_state;
205 WriteAll(commands_to_custom_action_servers_[command],
206 action_server_message.c_str(), 128);
207 } else {
208 LOG(WARNING) << "Unsupported control command: " << command << " ("
209 << button_state << ")";
210 }
211 }
212
OnBluetoothChannelOpen(std::function<bool (const uint8_t *,size_t)> bluetooth_message_sender)213 void OnBluetoothChannelOpen(std::function<bool(const uint8_t *, size_t)>
214 bluetooth_message_sender) override {
215 LOG(VERBOSE) << "Bluetooth channel open";
216 auto config = CuttlefishConfig::Get();
217 CHECK(config) << "Failed to get config";
218 bluetooth_handler_.reset(new webrtc_streaming::BluetoothHandler(
219 config->rootcanal_test_port(), bluetooth_message_sender));
220 }
221
OnBluetoothMessage(const uint8_t * msg,size_t size)222 void OnBluetoothMessage(const uint8_t *msg, size_t size) override {
223 bluetooth_handler_->handleMessage(msg, size);
224 }
225
OnSensorsChannelOpen(std::function<bool (const uint8_t *,size_t)> sensors_message_sender)226 void OnSensorsChannelOpen(std::function<bool(const uint8_t *, size_t)>
227 sensors_message_sender) override {
228 sensors_subscription_id =
229 sensors_handler_.Subscribe(sensors_message_sender);
230 LOG(VERBOSE) << "Sensors channel open";
231 }
232
OnSensorsChannelClosed()233 void OnSensorsChannelClosed() override {
234 sensors_handler_.UnSubscribe(sensors_subscription_id);
235 }
236
OnSensorsMessage(const uint8_t * msg,size_t size)237 void OnSensorsMessage(const uint8_t *msg, size_t size) override {
238 std::string msgstr(msg, msg + size);
239 std::vector<std::string> xyz = android::base::Split(msgstr, " ");
240
241 if (xyz.size() != 3) {
242 LOG(WARNING) << "Invalid rotation angles: Expected 3, received "
243 << xyz.size();
244 return;
245 }
246
247 double x, y, z;
248 CHECK(android::base::ParseDouble(xyz.at(0), &x))
249 << "X rotation value must be a double";
250 CHECK(android::base::ParseDouble(xyz.at(1), &y))
251 << "Y rotation value must be a double";
252 CHECK(android::base::ParseDouble(xyz.at(2), &z))
253 << "Z rotation value must be a double";
254 sensors_handler_.HandleMessage(x, y, z);
255 }
256
OnLightsChannelOpen(std::function<bool (const Json::Value &)> lights_message_sender)257 void OnLightsChannelOpen(
258 std::function<bool(const Json::Value &)> lights_message_sender) override {
259 LOG(DEBUG) << "Lights channel open";
260
261 lights_subscription_id_ =
262 lights_observer_->Subscribe(lights_message_sender);
263 }
264
OnLightsChannelClosed()265 void OnLightsChannelClosed() override {
266 lights_observer_->Unsubscribe(lights_subscription_id_);
267 }
268
OnLocationChannelOpen(std::function<bool (const uint8_t *,size_t)> location_message_sender)269 void OnLocationChannelOpen(std::function<bool(const uint8_t *, size_t)>
270 location_message_sender) override {
271 LOG(VERBOSE) << "Location channel open";
272 auto config = CuttlefishConfig::Get();
273 CHECK(config) << "Failed to get config";
274 location_handler_.reset(
275 new webrtc_streaming::LocationHandler(location_message_sender));
276 }
OnLocationMessage(const uint8_t * msg,size_t size)277 void OnLocationMessage(const uint8_t *msg, size_t size) override {
278 std::string msgstr(msg, msg + size);
279
280 std::vector<std::string> inputs = android::base::Split(msgstr, ",");
281
282 if (inputs.size() != 3) {
283 LOG(WARNING) << "Invalid location length , length = " << inputs.size();
284 return;
285 }
286
287 float longitude = std::stod(inputs.at(0));
288 float latitude = std::stod(inputs.at(1));
289 float elevation = std::stod(inputs.at(2));
290 location_handler_->HandleMessage(longitude, latitude, elevation);
291 }
292
OnKmlLocationsChannelOpen(std::function<bool (const uint8_t *,size_t)> kml_locations_message_sender)293 void OnKmlLocationsChannelOpen(std::function<bool(const uint8_t *, size_t)>
294 kml_locations_message_sender) override {
295 LOG(VERBOSE) << "Kml Locations channel open";
296 auto config = CuttlefishConfig::Get();
297 CHECK(config) << "Failed to get config";
298 kml_locations_handler_.reset(new webrtc_streaming::KmlLocationsHandler(
299 kml_locations_message_sender));
300 }
OnKmlLocationsMessage(const uint8_t * msg,size_t size)301 void OnKmlLocationsMessage(const uint8_t *msg, size_t size) override {
302 kml_locations_handler_->HandleMessage(msg, size);
303 }
304
OnGpxLocationsChannelOpen(std::function<bool (const uint8_t *,size_t)> gpx_locations_message_sender)305 void OnGpxLocationsChannelOpen(std::function<bool(const uint8_t *, size_t)>
306 gpx_locations_message_sender) override {
307 LOG(VERBOSE) << "Gpx Locations channel open";
308 auto config = CuttlefishConfig::Get();
309 CHECK(config) << "Failed to get config";
310 gpx_locations_handler_.reset(new webrtc_streaming::GpxLocationsHandler(
311 gpx_locations_message_sender));
312 }
OnGpxLocationsMessage(const uint8_t * msg,size_t size)313 void OnGpxLocationsMessage(const uint8_t *msg, size_t size) override {
314 gpx_locations_handler_->HandleMessage(msg, size);
315 }
316
OnCameraControlMsg(const Json::Value & msg)317 void OnCameraControlMsg(const Json::Value &msg) override {
318 if (camera_controller_) {
319 camera_controller_->HandleMessage(msg);
320 } else {
321 LOG(VERBOSE) << "Camera control message received but no camera "
322 "controller is available";
323 }
324 }
325
OnDisplayControlMsg(const Json::Value & msg)326 void OnDisplayControlMsg(const Json::Value &msg) override {
327 static constexpr const char kRefreshDisplay[] = "refresh_display";
328 if (!msg.isMember(kRefreshDisplay)) {
329 LOG(ERROR) << "Unknown display control command.";
330 return;
331 }
332 const auto display_number_json = msg[kRefreshDisplay];
333 if (!display_number_json.isInt()) {
334 LOG(ERROR) << "Invalid display control command.";
335 return;
336 }
337 const auto display_number =
338 static_cast<uint32_t>(display_number_json.asInt());
339 LOG(VERBOSE) << "Refresh display " << display_number;
340 SendLastFrameAsync(display_number);
341 }
342
OnDisplayAddMsg(const Json::Value & msg)343 void OnDisplayAddMsg(const Json::Value &msg) override {
344 auto result = HandleDisplayAddMessage(msg);
345 if (!result.ok()) {
346 LOG(ERROR) << result.error().FormatForEnv();
347 }
348 }
349
HandleDisplayAddMessage(const Json::Value & msg)350 Result<void> HandleDisplayAddMessage(const Json::Value &msg) {
351 auto width = CF_EXPECT(GetValue<int>(msg, {"width"}));
352 auto height = CF_EXPECT(GetValue<int>(msg, {"height"}));
353 auto dpi = CF_EXPECT(GetValue<int>(msg, {"dpi"}));
354 auto refresh_rate_hz = CF_EXPECT(GetValue<int>(msg, {"refresh_rate_hz"}));
355
356 auto display_config = CuttlefishConfig::DisplayConfig{
357 .width = width,
358 .height = height,
359 .dpi = dpi,
360 .refresh_rate_hz = refresh_rate_hz,
361 };
362
363 auto crosvm_display_conroller =
364 CF_EXPECT(vm_manager::GetCrosvmDisplayController());
365
366 int const instance_num = cuttlefish::GetInstance();
367 CF_EXPECT(crosvm_display_conroller.Add(instance_num, {display_config}));
368
369 return {};
370 }
371
OnDisplayRemoveMsg(const Json::Value & msg)372 void OnDisplayRemoveMsg(const Json::Value &msg) override {
373 auto result = HandleDisplayRemoveMessage(msg);
374 if (!result.ok()) {
375 LOG(ERROR) << result.error().FormatForEnv();
376 }
377 }
378
HandleDisplayRemoveMessage(const Json::Value & msg)379 Result<void> HandleDisplayRemoveMessage(const Json::Value &msg) {
380 auto display_id = CF_EXPECT(GetValue<std::string>(msg, {"display_id"}));
381
382 auto crosvm_display_conroller =
383 CF_EXPECT(vm_manager::GetCrosvmDisplayController());
384
385 int const instance_num = cuttlefish::GetInstance();
386 CF_EXPECT(crosvm_display_conroller.Remove(instance_num, {display_id}));
387
388 return {};
389 }
390
OnCameraData(const std::vector<char> & data)391 void OnCameraData(const std::vector<char> &data) override {
392 if (camera_controller_) {
393 camera_controller_->HandleMessage(data);
394 } else {
395 LOG(VERBOSE)
396 << "Camera data received but no camera controller is available";
397 }
398 }
399
400 private:
SendLastFrameAsync(std::optional<uint32_t> display_number)401 void SendLastFrameAsync(std::optional<uint32_t> display_number) {
402 auto display_handler = weak_display_handler_.lock();
403 if (display_handler) {
404 std::thread th([this, display_number]() {
405 // The encoder in libwebrtc won't drop 5 consecutive frames due to frame
406 // size, so we make sure at least 5 frames are sent every time a client
407 // connects to ensure they receive at least one.
408 constexpr int kNumFrames = 5;
409 constexpr int kMillisPerFrame = 16;
410 for (int i = 0; i < kNumFrames; ++i) {
411 auto display_handler = weak_display_handler_.lock();
412 display_handler->SendLastFrame(display_number);
413
414 if (i < kNumFrames - 1) {
415 std::this_thread::sleep_for(
416 std::chrono::milliseconds(kMillisPerFrame));
417 }
418 }
419 });
420 th.detach();
421 }
422 }
423
424 std::unique_ptr<InputConnector::EventSink> input_events_sink_;
425 KernelLogEventsHandler &kernel_log_events_handler_;
426 int kernel_log_subscription_id_ = -1;
427 std::shared_ptr<webrtc_streaming::AdbHandler> adb_handler_;
428 std::shared_ptr<webrtc_streaming::BluetoothHandler> bluetooth_handler_;
429 std::shared_ptr<webrtc_streaming::LocationHandler> location_handler_;
430 std::shared_ptr<webrtc_streaming::KmlLocationsHandler> kml_locations_handler_;
431 std::shared_ptr<webrtc_streaming::GpxLocationsHandler> gpx_locations_handler_;
432 std::map<std::string, SharedFD> commands_to_custom_action_servers_;
433 std::weak_ptr<DisplayHandler> weak_display_handler_;
434 CameraController *camera_controller_;
435 webrtc_streaming::SensorsHandler& sensors_handler_;
436 std::shared_ptr<webrtc_streaming::LightsObserver> lights_observer_;
437 int sensors_subscription_id = -1;
438 int lights_subscription_id_ = -1;
439 };
440
CfConnectionObserverFactory(InputConnector & input_connector,KernelLogEventsHandler & kernel_log_events_handler,webrtc_streaming::SensorsHandler & sensors_handler,std::shared_ptr<webrtc_streaming::LightsObserver> lights_observer)441 CfConnectionObserverFactory::CfConnectionObserverFactory(
442 InputConnector &input_connector,
443 KernelLogEventsHandler &kernel_log_events_handler,
444 webrtc_streaming::SensorsHandler &sensors_handler,
445 std::shared_ptr<webrtc_streaming::LightsObserver> lights_observer)
446 : input_connector_(input_connector),
447 kernel_log_events_handler_(kernel_log_events_handler),
448 sensors_handler_(sensors_handler),
449 lights_observer_(lights_observer) {}
450
451 std::shared_ptr<webrtc_streaming::ConnectionObserver>
CreateObserver()452 CfConnectionObserverFactory::CreateObserver() {
453 return std::shared_ptr<webrtc_streaming::ConnectionObserver>(
454 new ConnectionObserverImpl(
455 input_connector_.CreateSink(), kernel_log_events_handler_,
456 commands_to_custom_action_servers_, weak_display_handler_,
457 camera_controller_, sensors_handler_, lights_observer_));
458 }
459
AddCustomActionServer(SharedFD custom_action_server_fd,const std::vector<std::string> & commands)460 void CfConnectionObserverFactory::AddCustomActionServer(
461 SharedFD custom_action_server_fd,
462 const std::vector<std::string> &commands) {
463 for (const std::string &command : commands) {
464 LOG(DEBUG) << "Action server is listening to command: " << command;
465 commands_to_custom_action_servers_[command] = custom_action_server_fd;
466 }
467 }
468
SetDisplayHandler(std::weak_ptr<DisplayHandler> display_handler)469 void CfConnectionObserverFactory::SetDisplayHandler(
470 std::weak_ptr<DisplayHandler> display_handler) {
471 weak_display_handler_ = display_handler;
472 }
473
SetCameraHandler(CameraController * controller)474 void CfConnectionObserverFactory::SetCameraHandler(
475 CameraController *controller) {
476 camera_controller_ = controller;
477 }
478 } // namespace cuttlefish
479