Yuwei Huang | 5a84f953 | 2019-02-20 18:29:01 | [diff] [blame] | 1 | // 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 Huang | bdc4a97 | 2019-03-01 17:43:06 | [diff] [blame^] | 5 | #include "remoting/test/ftl_signaling_playground.h" |
| 6 | |
| 7 | #include <utility> |
| 8 | |
Yuwei Huang | 575c32ee | 2019-02-27 04:41:56 | [diff] [blame] | 9 | #include "base/bind.h" |
Yuwei Huang | bdc4a97 | 2019-03-01 17:43:06 | [diff] [blame^] | 10 | #include "base/bind_helpers.h" |
Yuwei Huang | 5a84f953 | 2019-02-20 18:29:01 | [diff] [blame] | 11 | #include "base/command_line.h" |
Yuwei Huang | bdc4a97 | 2019-03-01 17:43:06 | [diff] [blame^] | 12 | #include "base/files/file_path.h" |
Yuwei Huang | 5a84f953 | 2019-02-20 18:29:01 | [diff] [blame] | 13 | #include "base/logging.h" |
Yuwei Huang | bdc4a97 | 2019-03-01 17:43:06 | [diff] [blame^] | 14 | #include "base/path_service.h" |
| 15 | #include "base/strings/stringprintf.h" |
| 16 | #include "remoting/base/oauth_token_getter_impl.h" |
Yuwei Huang | 5a84f953 | 2019-02-20 18:29:01 | [diff] [blame] | 17 | #include "remoting/signaling/ftl_client.h" |
Yuwei Huang | bdc4a97 | 2019-03-01 17:43:06 | [diff] [blame^] | 18 | #include "remoting/test/test_oauth_token_factory.h" |
| 19 | |
| 20 | namespace { |
| 21 | |
| 22 | constexpr char kSwitchNameHelp[] = "help"; |
| 23 | constexpr char kSwitchNameAuthCode[] = "code"; |
| 24 | |
| 25 | // Reads a newline-terminated string from stdin. |
| 26 | std::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. |
| 41 | std::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 Huang | 5a84f953 | 2019-02-20 18:29:01 | [diff] [blame] | 52 | |
Yuwei Huang | 575c32ee | 2019-02-27 04:41:56 | [diff] [blame] | 53 | namespace remoting { |
Yuwei Huang | 5a84f953 | 2019-02-20 18:29:01 | [diff] [blame] | 54 | |
Yuwei Huang | 575c32ee | 2019-02-27 04:41:56 | [diff] [blame] | 55 | FtlSignalingPlayground::FtlSignalingPlayground() = default; |
| 56 | |
| 57 | FtlSignalingPlayground::~FtlSignalingPlayground() = default; |
| 58 | |
Yuwei Huang | bdc4a97 | 2019-03-01 17:43:06 | [diff] [blame^] | 59 | bool FtlSignalingPlayground::ShouldPrintHelp() { |
| 60 | return base::CommandLine::ForCurrentProcess()->HasSwitch(kSwitchNameHelp); |
| 61 | } |
| 62 | |
| 63 | void FtlSignalingPlayground::PrintHelp() { |
| 64 | printf("Usage: %s [--code=<auth-code>]\n", |
| 65 | base::CommandLine::ForCurrentProcess() |
| 66 | ->GetProgram() |
| 67 | .MaybeAsASCII() |
| 68 | .c_str()); |
| 69 | } |
| 70 | |
| 71 | void 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 Huang | 575c32ee | 2019-02-27 04:41:56 | [diff] [blame] | 96 | void FtlSignalingPlayground::GetIceServer(base::OnceClosure on_done) { |
Yuwei Huang | bdc4a97 | 2019-03-01 17:43:06 | [diff] [blame^] | 97 | DCHECK(client_); |
| 98 | client_->GetIceServer(base::BindOnce( |
Yuwei Huang | 575c32ee | 2019-02-27 04:41:56 | [diff] [blame] | 99 | &FtlSignalingPlayground::OnGetIceServerResponse, std::move(on_done))); |
| 100 | VLOG(0) << "Running GetIceServer..."; |
| 101 | } |
| 102 | |
| 103 | // static |
| 104 | void 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 Huang | 5a84f953 | 2019-02-20 18:29:01 | [diff] [blame] | 123 | 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 Huang | 5a84f953 | 2019-02-20 18:29:01 | [diff] [blame] | 131 | } |
Yuwei Huang | 575c32ee | 2019-02-27 04:41:56 | [diff] [blame] | 132 | std::move(on_done).Run(); |
| 133 | } |
Yuwei Huang | 5a84f953 | 2019-02-20 18:29:01 | [diff] [blame] | 134 | |
Yuwei Huang | 575c32ee | 2019-02-27 04:41:56 | [diff] [blame] | 135 | } // namespace remoting |