1 //
2 // Copyright (C) 2019 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/launch.h"
17
18 #include <string>
19 #include <unordered_set>
20 #include <utility>
21 #include <vector>
22
23 #include <fruit/fruit.h>
24
25 #include "common/libs/utils/files.h"
26 #include "common/libs/utils/result.h"
27 #include "host/libs/config/command_source.h"
28 #include "host/libs/config/known_paths.h"
29
30 namespace cuttlefish {
31 namespace {
32
33 class GnssGrpcProxyServer : public CommandSource {
34 public:
INJECT(GnssGrpcProxyServer (const CuttlefishConfig::InstanceSpecific & instance,GrpcSocketCreator & grpc_socket))35 INJECT(GnssGrpcProxyServer(const CuttlefishConfig::InstanceSpecific& instance,
36 GrpcSocketCreator& grpc_socket))
37 : instance_(instance), grpc_socket_(grpc_socket) {}
38
39 // CommandSource
Commands()40 Result<std::vector<MonitorCommand>> Commands() override {
41 Command gnss_grpc_proxy_cmd(GnssGrpcProxyBinary());
42 const unsigned gnss_grpc_proxy_server_port =
43 instance_.gnss_grpc_proxy_server_port();
44 gnss_grpc_proxy_cmd.AddParameter("--gnss_in_fd=", gnss_grpc_proxy_in_wr_);
45 gnss_grpc_proxy_cmd.AddParameter("--gnss_out_fd=", gnss_grpc_proxy_out_rd_);
46 gnss_grpc_proxy_cmd.AddParameter("--fixed_location_in_fd=",
47 fixed_location_grpc_proxy_in_wr_);
48 gnss_grpc_proxy_cmd.AddParameter("--fixed_location_out_fd=",
49 fixed_location_grpc_proxy_out_rd_);
50 gnss_grpc_proxy_cmd.AddParameter("--gnss_grpc_port=",
51 gnss_grpc_proxy_server_port);
52 gnss_grpc_proxy_cmd.AddParameter("--gnss_grpc_socket=",
53 grpc_socket_.CreateGrpcSocket(Name()));
54 if (!instance_.gnss_file_path().empty()) {
55 // If path is provided, proxy will start as local mode.
56 gnss_grpc_proxy_cmd.AddParameter("--gnss_file_path=",
57 instance_.gnss_file_path());
58 }
59 if (!instance_.fixed_location_file_path().empty()) {
60 gnss_grpc_proxy_cmd.AddParameter("--fixed_location_file_path=",
61 instance_.fixed_location_file_path());
62 }
63 std::vector<MonitorCommand> commands;
64 commands.emplace_back(std::move(gnss_grpc_proxy_cmd));
65 return commands;
66 }
67
68 // SetupFeature
Name() const69 std::string Name() const override { return "GnssGrpcProxyServer"; }
Enabled() const70 bool Enabled() const override {
71 return instance_.enable_gnss_grpc_proxy() &&
72 FileExists(GnssGrpcProxyBinary());
73 }
74
75 private:
Dependencies() const76 std::unordered_set<SetupFeature*> Dependencies() const override { return {}; }
ResultSetup()77 Result<void> ResultSetup() override {
78 std::vector<SharedFD> fifos;
79 std::vector<std::string> fifo_paths = {
80 instance_.PerInstanceInternalPath("gnsshvc_fifo_vm.in"),
81 instance_.PerInstanceInternalPath("gnsshvc_fifo_vm.out"),
82 instance_.PerInstanceInternalPath("locationhvc_fifo_vm.in"),
83 instance_.PerInstanceInternalPath("locationhvc_fifo_vm.out"),
84 };
85 for (const auto& path : fifo_paths) {
86 unlink(path.c_str());
87 CF_EXPECT(mkfifo(path.c_str(), 0660) == 0, "Could not create " << path);
88 auto fd = SharedFD::Open(path, O_RDWR);
89 CF_EXPECT(fd->IsOpen(),
90 "Could not open " << path << ": " << fd->StrError());
91 fifos.push_back(fd);
92 }
93
94 gnss_grpc_proxy_in_wr_ = fifos[0];
95 gnss_grpc_proxy_out_rd_ = fifos[1];
96 fixed_location_grpc_proxy_in_wr_ = fifos[2];
97 fixed_location_grpc_proxy_out_rd_ = fifos[3];
98 return {};
99 }
100
101 private:
102 const CuttlefishConfig::InstanceSpecific& instance_;
103 SharedFD gnss_grpc_proxy_in_wr_;
104 SharedFD gnss_grpc_proxy_out_rd_;
105 SharedFD fixed_location_grpc_proxy_in_wr_;
106 SharedFD fixed_location_grpc_proxy_out_rd_;
107 GrpcSocketCreator& grpc_socket_;
108 };
109
110 } // namespace
111
112 fruit::Component<fruit::Required<const CuttlefishConfig::InstanceSpecific,
113 GrpcSocketCreator>>
GnssGrpcProxyServerComponent()114 GnssGrpcProxyServerComponent() {
115 return fruit::createComponent()
116 .addMultibinding<CommandSource, GnssGrpcProxyServer>()
117 .addMultibinding<SetupFeature, GnssGrpcProxyServer>();
118 }
119
120 } // namespace cuttlefish
121