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