blob: 2a7cb74836964ad770484dc6b01c93921243e94a [file] [log] [blame]
Yuwei Huang5a84f9532019-02-20 18:29:011// Copyright 2019 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Yuwei Huangbdc4a972019-03-01 17:43:065#include "remoting/test/ftl_signaling_playground.h"
6
7#include <utility>
8
Yuwei Huang575c32ee2019-02-27 04:41:569#include "base/bind.h"
Yuwei Huangbdc4a972019-03-01 17:43:0610#include "base/bind_helpers.h"
Yuwei Huang5a84f9532019-02-20 18:29:0111#include "base/command_line.h"
Yuwei Huangbdc4a972019-03-01 17:43:0612#include "base/files/file_path.h"
Yuwei Huang5a84f9532019-02-20 18:29:0113#include "base/logging.h"
Yuwei Huangbdc4a972019-03-01 17:43:0614#include "base/path_service.h"
15#include "base/strings/stringprintf.h"
16#include "remoting/base/oauth_token_getter_impl.h"
Yuwei Huang5a84f9532019-02-20 18:29:0117#include "remoting/signaling/ftl_client.h"
Yuwei Huangbdc4a972019-03-01 17:43:0618#include "remoting/test/test_oauth_token_factory.h"
19
20namespace {
21
22constexpr char kSwitchNameHelp[] = "help";
23constexpr char kSwitchNameAuthCode[] = "code";
24
25// Reads a newline-terminated string from stdin.
26std::string ReadString() {
27 const int kMaxLen = 1024;
28 std::string str(kMaxLen, 0);
29 char* result = fgets(&str[0], kMaxLen, stdin);
30 if (!result)
31 return std::string();
32 size_t newline_index = str.find('\n');
33 if (newline_index != std::string::npos)
34 str[newline_index] = '\0';
35 str.resize(strlen(&str[0]));
36 return str;
37}
38
39// Read the value of |switch_name| from command line if it exists, otherwise
40// read from stdin.
41std::string ReadStringFromCommandLineOrStdin(const std::string& switch_name,
42 const std::string& read_prompt) {
43 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
44 if (command_line->HasSwitch(switch_name)) {
45 return command_line->GetSwitchValueASCII(switch_name);
46 }
47 printf("%s", read_prompt.c_str());
48 return ReadString();
49}
50
51} // namespace
Yuwei Huang5a84f9532019-02-20 18:29:0152
Yuwei Huang575c32ee2019-02-27 04:41:5653namespace remoting {
Yuwei Huang5a84f9532019-02-20 18:29:0154
Yuwei Huang575c32ee2019-02-27 04:41:5655FtlSignalingPlayground::FtlSignalingPlayground() = default;
56
57FtlSignalingPlayground::~FtlSignalingPlayground() = default;
58
Yuwei Huangbdc4a972019-03-01 17:43:0659bool FtlSignalingPlayground::ShouldPrintHelp() {
60 return base::CommandLine::ForCurrentProcess()->HasSwitch(kSwitchNameHelp);
61}
62
63void FtlSignalingPlayground::PrintHelp() {
64 printf("Usage: %s [--code=<auth-code>]\n",
65 base::CommandLine::ForCurrentProcess()
66 ->GetProgram()
67 .MaybeAsASCII()
68 .c_str());
69}
70
71void FtlSignalingPlayground::StartAndAuthenticate() {
72 DCHECK(!token_getter_factory_);
73 DCHECK(!token_getter_);
74 DCHECK(!client_);
75
76 static const std::string read_auth_code_prompt = base::StringPrintf(
77 "Please authenticate at:\n\n"
78 " %s\n\n"
79 "Enter the auth code: ",
80 TestOAuthTokenGetterFactory::GetAuthorizationCodeUri().c_str());
81 std::string auth_code = ReadStringFromCommandLineOrStdin(
82 kSwitchNameAuthCode, read_auth_code_prompt);
83
84 token_getter_factory_ = std::make_unique<TestOAuthTokenGetterFactory>();
85
86 // We can't get back the refresh token since we have first-party scope, so
87 // we are not trying to store it.
88 // TODO(yuweih): Consider storing the access token and reuse it until it is
89 // expired.
90 token_getter_ = token_getter_factory_->CreateFromIntermediateCredentials(
91 auth_code,
92 base::DoNothing::Repeatedly<const std::string&, const std::string&>());
93 client_ = std::make_unique<FtlClient>(token_getter_.get());
94}
95
Yuwei Huang575c32ee2019-02-27 04:41:5696void FtlSignalingPlayground::GetIceServer(base::OnceClosure on_done) {
Yuwei Huangbdc4a972019-03-01 17:43:0697 DCHECK(client_);
98 client_->GetIceServer(base::BindOnce(
Yuwei Huang575c32ee2019-02-27 04:41:5699 &FtlSignalingPlayground::OnGetIceServerResponse, std::move(on_done)));
100 VLOG(0) << "Running GetIceServer...";
101}
102
103// static
104void FtlSignalingPlayground::OnGetIceServerResponse(
105 base::OnceClosure on_done,
106 grpc::Status status,
107 const ftl::GetICEServerResponse& response) {
108 if (status.ok()) {
109 VLOG(0) << "Ice transport policy: "
110 << response.ice_config().ice_transport_policy();
111 for (const ftl::ICEServerList& server :
112 response.ice_config().ice_servers()) {
113 VLOG(0) << "ICE server:";
114 VLOG(0) << " hostname=" << server.hostname();
115 VLOG(0) << " username=" << server.username();
116 VLOG(0) << " credential=" << server.credential();
117 VLOG(0) << " max_rate_kbps=" << server.max_rate_kbps();
118 for (const std::string& url : server.urls()) {
119 VLOG(0) << " url=" << url;
120 }
121 }
122 } else {
Yuwei Huang5a84f9532019-02-20 18:29:01123 LOG(ERROR) << "RPC failed. Code=" << status.error_code() << ", "
124 << "Message=" << status.error_message();
125 if (status.error_code() == grpc::StatusCode::UNAVAILABLE) {
126 VLOG(0)
127 << "Set the GRPC_DEFAULT_SSL_ROOTS_FILE_PATH environment variable "
128 << "to third_party/grpc/src/etc/roots.pem if gRPC cannot locate the "
129 << "root certificates.";
130 }
Yuwei Huang5a84f9532019-02-20 18:29:01131 }
Yuwei Huang575c32ee2019-02-27 04:41:56132 std::move(on_done).Run();
133}
Yuwei Huang5a84f9532019-02-20 18:29:01134
Yuwei Huang575c32ee2019-02-27 04:41:56135} // namespace remoting