1 //
2 // Copyright (C) 2023 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 #include "host/commands/run_cvd/launch/webrtc_controller.h"
17
18 #include <android-base/logging.h>
19 #include <fruit/fruit.h>
20
21 #include "common/libs/fs/shared_buf.h"
22 #include "common/libs/fs/shared_fd.h"
23 #include "common/libs/transport/channel_sharedfd.h"
24 #include "common/libs/utils/result.h"
25 #include "google/rpc/code.pb.h"
26 #include "host/commands/run_cvd/launch/launch.h"
27 #include "webrtc_commands.pb.h"
28
29 namespace cuttlefish {
30 namespace {
31
IsSuccess(const webrtc::WebrtcCommandResponse & response)32 Result<void> IsSuccess(const webrtc::WebrtcCommandResponse& response) {
33 CF_EXPECT(response.has_status(), "Webrtc command response missing status?");
34 const auto& response_status = response.status();
35 CF_EXPECT_EQ(response_status.code(), google::rpc::Code::OK,
36 "Webrtc command failed: " << response_status.message());
37 return {};
38 }
39
40 } // namespace
41
42 using webrtc::WebrtcCommandRequest;
43 using webrtc::WebrtcCommandResponse;
44
ResultSetup()45 Result<void> WebRtcController::ResultSetup() {
46 LOG(DEBUG) << "Initializing the WebRTC command sockets.";
47 SharedFD host_socket;
48 CF_EXPECT(SharedFD::SocketPair(AF_LOCAL, SOCK_STREAM, 0, &client_socket_,
49 &host_socket),
50 client_socket_->StrError());
51
52 command_channel_.emplace(host_socket);
53 return {};
54 }
55
GetClientSocket() const56 SharedFD WebRtcController::GetClientSocket() const { return client_socket_; }
57
SendStartRecordingCommand()58 Result<void> WebRtcController::SendStartRecordingCommand() {
59 CF_EXPECT(command_channel_.has_value(), "Not initialized?");
60 WebrtcCommandRequest request;
61 request.mutable_start_recording_request();
62 WebrtcCommandResponse response =
63 CF_EXPECT(command_channel_->SendCommand(request));
64 CF_EXPECT(IsSuccess(response), "Failed to start recording.");
65 return {};
66 }
67
SendStopRecordingCommand()68 Result<void> WebRtcController::SendStopRecordingCommand() {
69 CF_EXPECT(command_channel_.has_value(), "Not initialized?");
70 WebrtcCommandRequest request;
71 request.mutable_stop_recording_request();
72 WebrtcCommandResponse response =
73 CF_EXPECT(command_channel_->SendCommand(request));
74 CF_EXPECT(IsSuccess(response), "Failed to stop recording.");
75 return {};
76 }
77
SendScreenshotDisplayCommand(int display_number,const std::string & screenshot_path)78 Result<void> WebRtcController::SendScreenshotDisplayCommand(
79 int display_number, const std::string& screenshot_path) {
80 CF_EXPECT(command_channel_.has_value(), "Not initialized?");
81 WebrtcCommandRequest request;
82 auto* screenshot_request = request.mutable_screenshot_display_request();
83 screenshot_request->set_display_number(display_number);
84 screenshot_request->set_screenshot_path(screenshot_path);
85 WebrtcCommandResponse response =
86 CF_EXPECT(command_channel_->SendCommand(request));
87 CF_EXPECT(IsSuccess(response), "Failed to screenshot display.");
88 return {};
89 }
90
WebRtcControllerComponent()91 fruit::Component<WebRtcController> WebRtcControllerComponent() {
92 return fruit::createComponent()
93 .addMultibinding<SetupFeature, WebRtcController>();
94 }
95
96 } // namespace cuttlefish
97