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