• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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