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