blob: 3ca052aff744558975a7e40d7461eaa8bb082d24 [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
Yuwei Huang30bac9e2019-03-01 21:28:147#include <inttypes.h>
Yuwei Huangbdc4a972019-03-01 17:43:068#include <utility>
9
Yuwei Huang575c32ee2019-02-27 04:41:5610#include "base/bind.h"
Yuwei Huangbdc4a972019-03-01 17:43:0611#include "base/bind_helpers.h"
Yuwei Huang5a84f9532019-02-20 18:29:0112#include "base/command_line.h"
Yuwei Huangbdc4a972019-03-01 17:43:0613#include "base/files/file_path.h"
Yuwei Huang5a84f9532019-02-20 18:29:0114#include "base/logging.h"
Yuwei Huangbdc4a972019-03-01 17:43:0615#include "base/path_service.h"
16#include "base/strings/stringprintf.h"
17#include "remoting/base/oauth_token_getter_impl.h"
Yuwei Huang5a84f9532019-02-20 18:29:0118#include "remoting/signaling/ftl_client.h"
Yuwei Huangbdc4a972019-03-01 17:43:0619#include "remoting/test/test_oauth_token_factory.h"
20
21namespace {
22
23constexpr char kSwitchNameHelp[] = "help";
24constexpr char kSwitchNameAuthCode[] = "code";
25
26// Reads a newline-terminated string from stdin.
27std::string ReadString() {
28 const int kMaxLen = 1024;
29 std::string str(kMaxLen, 0);
30 char* result = fgets(&str[0], kMaxLen, stdin);
31 if (!result)
32 return std::string();
33 size_t newline_index = str.find('\n');
34 if (newline_index != std::string::npos)
35 str[newline_index] = '\0';
36 str.resize(strlen(&str[0]));
37 return str;
38}
39
40// Read the value of |switch_name| from command line if it exists, otherwise
41// read from stdin.
42std::string ReadStringFromCommandLineOrStdin(const std::string& switch_name,
43 const std::string& read_prompt) {
44 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
45 if (command_line->HasSwitch(switch_name)) {
46 return command_line->GetSwitchValueASCII(switch_name);
47 }
48 printf("%s", read_prompt.c_str());
49 return ReadString();
50}
51
52} // namespace
Yuwei Huang5a84f9532019-02-20 18:29:0153
Yuwei Huang575c32ee2019-02-27 04:41:5654namespace remoting {
Yuwei Huang5a84f9532019-02-20 18:29:0155
Yuwei Huang575c32ee2019-02-27 04:41:5656FtlSignalingPlayground::FtlSignalingPlayground() = default;
57
58FtlSignalingPlayground::~FtlSignalingPlayground() = default;
59
Yuwei Huangbdc4a972019-03-01 17:43:0660bool FtlSignalingPlayground::ShouldPrintHelp() {
61 return base::CommandLine::ForCurrentProcess()->HasSwitch(kSwitchNameHelp);
62}
63
64void FtlSignalingPlayground::PrintHelp() {
65 printf("Usage: %s [--code=<auth-code>]\n",
66 base::CommandLine::ForCurrentProcess()
67 ->GetProgram()
68 .MaybeAsASCII()
69 .c_str());
70}
71
72void FtlSignalingPlayground::StartAndAuthenticate() {
73 DCHECK(!token_getter_factory_);
74 DCHECK(!token_getter_);
75 DCHECK(!client_);
76
77 static const std::string read_auth_code_prompt = base::StringPrintf(
78 "Please authenticate at:\n\n"
79 " %s\n\n"
80 "Enter the auth code: ",
81 TestOAuthTokenGetterFactory::GetAuthorizationCodeUri().c_str());
82 std::string auth_code = ReadStringFromCommandLineOrStdin(
83 kSwitchNameAuthCode, read_auth_code_prompt);
84
85 token_getter_factory_ = std::make_unique<TestOAuthTokenGetterFactory>();
86
87 // We can't get back the refresh token since we have first-party scope, so
88 // we are not trying to store it.
89 // TODO(yuweih): Consider storing the access token and reuse it until it is
90 // expired.
91 token_getter_ = token_getter_factory_->CreateFromIntermediateCredentials(
92 auth_code,
93 base::DoNothing::Repeatedly<const std::string&, const std::string&>());
94 client_ = std::make_unique<FtlClient>(token_getter_.get());
95}
96
Yuwei Huang575c32ee2019-02-27 04:41:5697void FtlSignalingPlayground::GetIceServer(base::OnceClosure on_done) {
Yuwei Huangbdc4a972019-03-01 17:43:0698 DCHECK(client_);
99 client_->GetIceServer(base::BindOnce(
Yuwei Huang575c32ee2019-02-27 04:41:56100 &FtlSignalingPlayground::OnGetIceServerResponse, std::move(on_done)));
101 VLOG(0) << "Running GetIceServer...";
102}
103
104// static
105void FtlSignalingPlayground::OnGetIceServerResponse(
106 base::OnceClosure on_done,
107 grpc::Status status,
108 const ftl::GetICEServerResponse& response) {
109 if (status.ok()) {
Yuwei Huang30bac9e2019-03-01 21:28:14110 printf("Ice transport policy: %s\n",
111 response.ice_config().ice_transport_policy().c_str());
Yuwei Huang575c32ee2019-02-27 04:41:56112 for (const ftl::ICEServerList& server :
113 response.ice_config().ice_servers()) {
Yuwei Huang30bac9e2019-03-01 21:28:14114 printf(
115 "ICE server:\n"
116 " hostname=%s\n"
117 " username=%s\n"
118 " credential=%s\n"
119 " max_rate_kbps=%" PRId64 "\n",
120 server.hostname().c_str(), server.username().c_str(),
121 server.credential().c_str(), server.max_rate_kbps());
Yuwei Huang575c32ee2019-02-27 04:41:56122 for (const std::string& url : server.urls()) {
Yuwei Huang30bac9e2019-03-01 21:28:14123 printf(" url=%s\n", url.c_str());
Yuwei Huang575c32ee2019-02-27 04:41:56124 }
125 }
126 } else {
Yuwei Huang5a84f9532019-02-20 18:29:01127 LOG(ERROR) << "RPC failed. Code=" << status.error_code() << ", "
128 << "Message=" << status.error_message();
129 if (status.error_code() == grpc::StatusCode::UNAVAILABLE) {
130 VLOG(0)
131 << "Set the GRPC_DEFAULT_SSL_ROOTS_FILE_PATH environment variable "
132 << "to third_party/grpc/src/etc/roots.pem if gRPC cannot locate the "
133 << "root certificates.";
134 }
Yuwei Huang5a84f9532019-02-20 18:29:01135 }
Yuwei Huang575c32ee2019-02-27 04:41:56136 std::move(on_done).Run();
137}
Yuwei Huang5a84f9532019-02-20 18:29:01138
Yuwei Huang575c32ee2019-02-27 04:41:56139} // namespace remoting