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/commands/run_cvd/launch/grpc_socket_creator.h"
28 #include "host/commands/run_cvd/launch/log_tee_creator.h"
29 #include "host/libs/config/command_source.h"
30 #include "host/libs/config/cuttlefish_config.h"
31 #include "host/libs/config/known_paths.h"
32
33 namespace cuttlefish {
34 namespace {
35
36 class WmediumdServer : public CommandSource {
37 public:
INJECT(WmediumdServer (const CuttlefishConfig & config,const CuttlefishConfig::InstanceSpecific & instance,LogTeeCreator & log_tee,GrpcSocketCreator & grpc_socket))38 INJECT(WmediumdServer(const CuttlefishConfig& config,
39 const CuttlefishConfig::InstanceSpecific& instance,
40 LogTeeCreator& log_tee, GrpcSocketCreator& grpc_socket))
41 : config_(config),
42 instance_(instance),
43 log_tee_(log_tee),
44 grpc_socket_(grpc_socket) {}
45
46 // CommandSource
Commands()47 Result<std::vector<MonitorCommand>> Commands() override {
48 Command cmd(WmediumdBinary());
49 cmd.AddParameter("-u", config_.vhost_user_mac80211_hwsim());
50 cmd.AddParameter("-a", config_.wmediumd_api_server_socket());
51 cmd.AddParameter("-c", config_path_);
52
53 cmd.AddParameter("--grpc_uds_path=", grpc_socket_.CreateGrpcSocket(Name()));
54
55 std::vector<MonitorCommand> commands;
56 commands.emplace_back(std::move(log_tee_.CreateLogTee(cmd, "wmediumd")));
57 commands.emplace_back(std::move(cmd));
58 return commands;
59 }
60
61 // SetupFeature
Name() const62 std::string Name() const override { return "WmediumdServer"; }
Enabled() const63 bool Enabled() const override {
64 return instance_.start_wmediumd();
65 }
66
67 private:
Dependencies() const68 std::unordered_set<SetupFeature*> Dependencies() const override { return {}; }
ResultSetup()69 Result<void> ResultSetup() override {
70 // If wmediumd configuration is given, use it
71 if (!config_.wmediumd_config().empty()) {
72 config_path_ = config_.wmediumd_config();
73 return {};
74 }
75 // Otherwise, generate wmediumd configuration using the current wifi mac
76 // prefix before start
77 config_path_ = instance_.PerInstanceInternalPath("wmediumd.cfg");
78 Command gen_config_cmd(WmediumdGenConfigBinary());
79 gen_config_cmd.AddParameter("-o", config_path_);
80 gen_config_cmd.AddParameter("-p", instance_.wifi_mac_prefix());
81
82 int success = gen_config_cmd.Start().Wait();
83 CF_EXPECT(success == 0, "Unable to run " << gen_config_cmd.Executable()
84 << ". Exited with status "
85 << success);
86 return {};
87 }
88
89 const CuttlefishConfig& config_;
90 const CuttlefishConfig::InstanceSpecific& instance_;
91 LogTeeCreator& log_tee_;
92 GrpcSocketCreator& grpc_socket_;
93 std::string config_path_;
94 };
95
96 // SetupFeature class for waiting wmediumd server to be settled.
97 // This class is used by the instance that does not launches wmediumd.
98 // TODO(b/276832089) remove this when run_env implementation is completed.
99 class ValidateWmediumdService : public SetupFeature {
100 public:
INJECT(ValidateWmediumdService (const CuttlefishConfig & config,const CuttlefishConfig::InstanceSpecific & instance))101 INJECT(ValidateWmediumdService(
102 const CuttlefishConfig& config,
103 const CuttlefishConfig::InstanceSpecific& instance))
104 : config_(config), instance_(instance) {}
Name() const105 std::string Name() const override { return "ValidateWmediumdService"; }
Enabled() const106 bool Enabled() const override {
107 return config_.virtio_mac80211_hwsim() && !instance_.start_wmediumd();
108 }
109
110 private:
Dependencies() const111 std::unordered_set<SetupFeature*> Dependencies() const override { return {}; }
ResultSetup()112 Result<void> ResultSetup() override {
113 CF_EXPECT(WaitForUnixSocket(config_.wmediumd_api_server_socket(), 30));
114 CF_EXPECT(WaitForUnixSocket(config_.vhost_user_mac80211_hwsim(), 30));
115
116 return {};
117 }
118
119 private:
120 const CuttlefishConfig& config_;
121 const CuttlefishConfig::InstanceSpecific& instance_;
122 };
123
124 } // namespace
125
126 fruit::Component<fruit::Required<const CuttlefishConfig,
127 const CuttlefishConfig::InstanceSpecific,
128 LogTeeCreator, GrpcSocketCreator>>
WmediumdServerComponent()129 WmediumdServerComponent() {
130 return fruit::createComponent()
131 .addMultibinding<CommandSource, WmediumdServer>()
132 .addMultibinding<SetupFeature, WmediumdServer>()
133 .addMultibinding<SetupFeature, ValidateWmediumdService>();
134 }
135
136 } // namespace cuttlefish
137