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 | |
Yuwei Huang | 30bac9e | 2019-03-01 21:28:14 | [diff] [blame^] | 7 | #include <inttypes.h> |
Yuwei Huang | bdc4a97 | 2019-03-01 17:43:06 | [diff] [blame] | 8 | #include <utility> |
| 9 | |
Yuwei Huang | 575c32ee | 2019-02-27 04:41:56 | [diff] [blame] | 10 | #include "base/bind.h" |
Yuwei Huang | bdc4a97 | 2019-03-01 17:43:06 | [diff] [blame] | 11 | #include "base/bind_helpers.h" |
Yuwei Huang | 5a84f953 | 2019-02-20 18:29:01 | [diff] [blame] | 12 | #include "base/command_line.h" |
Yuwei Huang | bdc4a97 | 2019-03-01 17:43:06 | [diff] [blame] | 13 | #include "base/files/file_path.h" |
Yuwei Huang | 5a84f953 | 2019-02-20 18:29:01 | [diff] [blame] | 14 | #include "base/logging.h" |
Yuwei Huang | bdc4a97 | 2019-03-01 17:43:06 | [diff] [blame] | 15 | #include "base/path_service.h" |
| 16 | #include "base/strings/stringprintf.h" |
| 17 | #include "remoting/base/oauth_token_getter_impl.h" |
Yuwei Huang | 5a84f953 | 2019-02-20 18:29:01 | [diff] [blame] | 18 | #include "remoting/signaling/ftl_client.h" |
Yuwei Huang | bdc4a97 | 2019-03-01 17:43:06 | [diff] [blame] | 19 | #include "remoting/test/test_oauth_token_factory.h" |
| 20 | |
| 21 | namespace { |
| 22 | |
| 23 | constexpr char kSwitchNameHelp[] = "help"; |
| 24 | constexpr char kSwitchNameAuthCode[] = "code"; |
| 25 | |
| 26 | // Reads a newline-terminated string from stdin. |
| 27 | std::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. |
| 42 | std::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 Huang | 5a84f953 | 2019-02-20 18:29:01 | [diff] [blame] | 53 | |
Yuwei Huang | 575c32ee | 2019-02-27 04:41:56 | [diff] [blame] | 54 | namespace remoting { |
Yuwei Huang | 5a84f953 | 2019-02-20 18:29:01 | [diff] [blame] | 55 | |
Yuwei Huang | 575c32ee | 2019-02-27 04:41:56 | [diff] [blame] | 56 | FtlSignalingPlayground::FtlSignalingPlayground() = default; |
| 57 | |
| 58 | FtlSignalingPlayground::~FtlSignalingPlayground() = default; |
| 59 | |
Yuwei Huang | bdc4a97 | 2019-03-01 17:43:06 | [diff] [blame] | 60 | bool FtlSignalingPlayground::ShouldPrintHelp() { |
| 61 | return base::CommandLine::ForCurrentProcess()->HasSwitch(kSwitchNameHelp); |
| 62 | } |
| 63 | |
| 64 | void FtlSignalingPlayground::PrintHelp() { |
| 65 | printf("Usage: %s [--code=<auth-code>]\n", |
| 66 | base::CommandLine::ForCurrentProcess() |
| 67 | ->GetProgram() |
| 68 | .MaybeAsASCII() |
| 69 | .c_str()); |
| 70 | } |
| 71 | |
| 72 | void 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 Huang | 575c32ee | 2019-02-27 04:41:56 | [diff] [blame] | 97 | void FtlSignalingPlayground::GetIceServer(base::OnceClosure on_done) { |
Yuwei Huang | bdc4a97 | 2019-03-01 17:43:06 | [diff] [blame] | 98 | DCHECK(client_); |
| 99 | client_->GetIceServer(base::BindOnce( |
Yuwei Huang | 575c32ee | 2019-02-27 04:41:56 | [diff] [blame] | 100 | &FtlSignalingPlayground::OnGetIceServerResponse, std::move(on_done))); |
| 101 | VLOG(0) << "Running GetIceServer..."; |
| 102 | } |
| 103 | |
| 104 | // static |
| 105 | void FtlSignalingPlayground::OnGetIceServerResponse( |
| 106 | base::OnceClosure on_done, |
| 107 | grpc::Status status, |
| 108 | const ftl::GetICEServerResponse& response) { |
| 109 | if (status.ok()) { |
Yuwei Huang | 30bac9e | 2019-03-01 21:28:14 | [diff] [blame^] | 110 | printf("Ice transport policy: %s\n", |
| 111 | response.ice_config().ice_transport_policy().c_str()); |
Yuwei Huang | 575c32ee | 2019-02-27 04:41:56 | [diff] [blame] | 112 | for (const ftl::ICEServerList& server : |
| 113 | response.ice_config().ice_servers()) { |
Yuwei Huang | 30bac9e | 2019-03-01 21:28:14 | [diff] [blame^] | 114 | 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 Huang | 575c32ee | 2019-02-27 04:41:56 | [diff] [blame] | 122 | for (const std::string& url : server.urls()) { |
Yuwei Huang | 30bac9e | 2019-03-01 21:28:14 | [diff] [blame^] | 123 | printf(" url=%s\n", url.c_str()); |
Yuwei Huang | 575c32ee | 2019-02-27 04:41:56 | [diff] [blame] | 124 | } |
| 125 | } |
| 126 | } else { |
Yuwei Huang | 5a84f953 | 2019-02-20 18:29:01 | [diff] [blame] | 127 | 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 Huang | 5a84f953 | 2019-02-20 18:29:01 | [diff] [blame] | 135 | } |
Yuwei Huang | 575c32ee | 2019-02-27 04:41:56 | [diff] [blame] | 136 | std::move(on_done).Run(); |
| 137 | } |
Yuwei Huang | 5a84f953 | 2019-02-20 18:29:01 | [diff] [blame] | 138 | |
Yuwei Huang | 575c32ee | 2019-02-27 04:41:56 | [diff] [blame] | 139 | } // namespace remoting |