blob: fe94070f3eb33f925dd6d7dd3e0e3e7991f063a8 [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 Huang2687b47f2019-04-01 20:57:085#include "remoting/test/ftl_services_playground.h"
Yuwei Huangbdc4a972019-03-01 17:43:066
Yuwei Huang30bac9e2019-03-01 21:28:147#include <inttypes.h>
Yuwei Huangaae881f2019-03-01 23:10:278#include <string>
Yuwei Huangbdc4a972019-03-01 17:43:069#include <utility>
Yuwei Huang98655b92019-03-04 23:41:4110#include <vector>
Yuwei Huangbdc4a972019-03-01 17:43:0611
Yuwei Huangaae881f2019-03-01 23:10:2712#include "base/base64.h"
Yuwei Huang575c32ee2019-02-27 04:41:5613#include "base/bind.h"
Yuwei Huangbdc4a972019-03-01 17:43:0614#include "base/bind_helpers.h"
Yuwei Huang5a84f9532019-02-20 18:29:0115#include "base/command_line.h"
Yuwei Huangbdc4a972019-03-01 17:43:0616#include "base/files/file_path.h"
Yuwei Huangaae881f2019-03-01 23:10:2717#include "base/guid.h"
Yuwei Huang5a84f9532019-02-20 18:29:0118#include "base/logging.h"
Yuwei Huangbdc4a972019-03-01 17:43:0619#include "base/path_service.h"
Yuwei Huang22e0b562019-03-27 20:54:2920#include "base/run_loop.h"
Yuwei Huangb8e1f2d2019-03-22 19:40:2621#include "base/task/post_task.h"
Yuwei Huang84b92a7c2019-04-16 22:25:0022#include "remoting/base/grpc_support/grpc_async_unary_request.h"
Yuwei Huangbdc4a972019-03-01 17:43:0623#include "remoting/base/oauth_token_getter_impl.h"
Yuwei Huangfeddf232020-07-28 00:27:4924#include "remoting/base/protobuf_http_status.h"
25#include "remoting/base/url_request_context_getter.h"
Yuwei Huang8dd1b7282019-05-03 02:12:4026#include "remoting/proto/ftl/v1/ftl_services.grpc.pb.h"
Yuwei Huang82c01892019-03-28 20:39:4027#include "remoting/signaling/ftl_grpc_context.h"
Yuwei Huang41ddec52019-04-02 02:08:1928#include "remoting/test/cli_util.h"
Yuwei Huang1cf68062019-04-11 23:28:4229#include "remoting/test/test_device_id_provider.h"
Yuwei Huang41ddec52019-04-02 02:08:1930#include "remoting/test/test_oauth_token_getter.h"
Yuwei Huang946cebd42019-03-04 22:14:2031#include "remoting/test/test_token_storage.h"
Yuwei Huangfeddf232020-07-28 00:27:4932#include "services/network/public/cpp/shared_url_loader_factory.h"
33#include "services/network/transitional_url_loader_factory_owner.h"
Yuwei Huangbdc4a972019-03-01 17:43:0634
35namespace {
36
37constexpr char kSwitchNameHelp[] = "help";
Yuwei Huang946cebd42019-03-04 22:14:2038constexpr char kSwitchNameUsername[] = "username";
39constexpr char kSwitchNameStoragePath[] = "storage-path";
Yuwei Huangfce958772019-03-30 00:18:1140constexpr char kSwitchNameNoAutoSignin[] = "no-auto-signin";
Yuwei Huangbdc4a972019-03-01 17:43:0641
Yuwei Huangfce958772019-03-30 00:18:1142bool NeedsManualSignin() {
43 return base::CommandLine::ForCurrentProcess()->HasSwitch(
44 kSwitchNameNoAutoSignin);
Yuwei Huangb8e1f2d2019-03-22 19:40:2645}
46
Yuwei Huangbdc4a972019-03-01 17:43:0647} // namespace
Yuwei Huang5a84f9532019-02-20 18:29:0148
Yuwei Huang575c32ee2019-02-27 04:41:5649namespace remoting {
Yuwei Huang5a84f9532019-02-20 18:29:0150
Jeremy Roman7c5cfabd2019-08-12 15:45:2751FtlServicesPlayground::FtlServicesPlayground() {}
Yuwei Huang575c32ee2019-02-27 04:41:5652
Yuwei Huang2687b47f2019-04-01 20:57:0853FtlServicesPlayground::~FtlServicesPlayground() = default;
Yuwei Huang575c32ee2019-02-27 04:41:5654
Yuwei Huang2687b47f2019-04-01 20:57:0855bool FtlServicesPlayground::ShouldPrintHelp() {
Yuwei Huangbdc4a972019-03-01 17:43:0656 return base::CommandLine::ForCurrentProcess()->HasSwitch(kSwitchNameHelp);
57}
58
Yuwei Huang2687b47f2019-04-01 20:57:0859void FtlServicesPlayground::PrintHelp() {
Yuwei Huang946cebd42019-03-04 22:14:2060 printf(
Yuwei Huang41ddec52019-04-02 02:08:1961 "Usage: %s [--no-auto-signin] [--auth-code=<auth-code>] "
Yuwei Huangfce958772019-03-30 00:18:1162 "[--storage-path=<storage-path>] [--username=<[email protected]>]\n",
Yuwei Huang946cebd42019-03-04 22:14:2063 base::CommandLine::ForCurrentProcess()
64 ->GetProgram()
65 .MaybeAsASCII()
66 .c_str());
Yuwei Huangbdc4a972019-03-01 17:43:0667}
68
Yuwei Huang2687b47f2019-04-01 20:57:0869void FtlServicesPlayground::StartAndAuthenticate() {
Yuwei Huang946cebd42019-03-04 22:14:2070 DCHECK(!storage_);
Yuwei Huangbdc4a972019-03-01 17:43:0671 DCHECK(!token_getter_);
Yuwei Huang82c01892019-03-28 20:39:4072 DCHECK(!executor_);
Yuwei Huangbdc4a972019-03-01 17:43:0673
Yuwei Huang946cebd42019-03-04 22:14:2074 base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
75 std::string username = cmd_line->GetSwitchValueASCII(kSwitchNameUsername);
76 base::FilePath storage_path =
77 cmd_line->GetSwitchValuePath(kSwitchNameStoragePath);
78 storage_ = test::TestTokenStorage::OnDisk(username, storage_path);
79
Yuwei Huang41ddec52019-04-02 02:08:1980 token_getter_ = std::make_unique<test::TestOAuthTokenGetter>(storage_.get());
81
Yuwei Huangfce958772019-03-30 00:18:1182 base::RunLoop run_loop;
Yuwei Huang41ddec52019-04-02 02:08:1983 token_getter_->Initialize(
84 base::BindOnce(&FtlServicesPlayground::ResetServices,
85 weak_factory_.GetWeakPtr(), run_loop.QuitClosure()));
Yuwei Huangfce958772019-03-30 00:18:1186 run_loop.Run();
Yuwei Huangaae881f2019-03-01 23:10:2787
88 StartLoop();
89}
90
Yuwei Huang2687b47f2019-04-01 20:57:0891void FtlServicesPlayground::StartLoop() {
Yuwei Huang41ddec52019-04-02 02:08:1992 std::vector<test::CommandOption> options{
93 {"GetIceServer", base::BindRepeating(&FtlServicesPlayground::GetIceServer,
94 weak_factory_.GetWeakPtr())},
95 {"PullMessages", base::BindRepeating(&FtlServicesPlayground::PullMessages,
96 weak_factory_.GetWeakPtr())},
97 {"ReceiveMessages",
98 base::BindRepeating(&FtlServicesPlayground::StartReceivingMessages,
99 weak_factory_.GetWeakPtr())},
100 {"SendMessage", base::BindRepeating(&FtlServicesPlayground::SendMessage,
101 weak_factory_.GetWeakPtr())}};
Yuwei Huangfce958772019-03-30 00:18:11102
Yuwei Huang41ddec52019-04-02 02:08:19103 if (NeedsManualSignin()) {
104 options.insert(
105 options.begin(),
106 {"SignInGaia", base::BindRepeating(&FtlServicesPlayground::SignInGaia,
107 weak_factory_.GetWeakPtr())});
Yuwei Huangaae881f2019-03-01 23:10:27108 }
Yuwei Huang41ddec52019-04-02 02:08:19109
Yuwei Huangfeddf232020-07-28 00:27:49110 auto url_request_context_getter =
111 base::MakeRefCounted<URLRequestContextGetter>(
112 base::ThreadTaskRunnerHandle::Get());
113 url_loader_factory_owner_ =
114 std::make_unique<network::TransitionalURLLoaderFactoryOwner>(
115 url_request_context_getter);
116
Yuwei Huang41ddec52019-04-02 02:08:19117 test::RunCommandOptionsLoop(options);
Yuwei Huangbdc4a972019-03-01 17:43:06118}
119
Yuwei Huang2687b47f2019-04-01 20:57:08120void FtlServicesPlayground::ResetServices(base::OnceClosure on_done) {
Yuwei Huang82c01892019-03-28 20:39:40121 executor_ = std::make_unique<GrpcAuthenticatedExecutor>(token_getter_.get());
122 peer_to_peer_stub_ = PeerToPeer::NewStub(FtlGrpcContext::CreateChannel());
123
124 registration_manager_ = std::make_unique<FtlRegistrationManager>(
Yuwei Huangfeddf232020-07-28 00:27:49125 token_getter_.get(), url_loader_factory_owner_->GetURLLoaderFactory(),
Yuwei Huang1cf68062019-04-11 23:28:42126 std::make_unique<test::TestDeviceIdProvider>(storage_.get()));
Yuwei Huang968994cb2019-03-21 00:55:27127
128 message_subscription_.reset();
Yuwei Huang82c01892019-03-28 20:39:40129 messaging_client_ = std::make_unique<FtlMessagingClient>(
Yuwei Huangfefd73352020-03-04 23:36:57130 token_getter_.get(), registration_manager_.get(), &signaling_tracker_);
Yuwei Huang968994cb2019-03-21 00:55:27131 message_subscription_ = messaging_client_->RegisterMessageCallback(
Yuwei Huang2687b47f2019-04-01 20:57:08132 base::BindRepeating(&FtlServicesPlayground::OnMessageReceived,
Yuwei Huang968994cb2019-03-21 00:55:27133 weak_factory_.GetWeakPtr()));
Yuwei Huangfce958772019-03-30 00:18:11134
135 if (NeedsManualSignin()) {
136 std::move(on_done).Run();
137 } else {
138 SignInGaia(std::move(on_done));
139 }
Yuwei Huang3f1fcd362019-03-11 20:27:17140}
141
Yuwei Huang2687b47f2019-04-01 20:57:08142void FtlServicesPlayground::GetIceServer(base::OnceClosure on_done) {
Yuwei Huang3f1fcd362019-03-11 20:27:17143 DCHECK(peer_to_peer_stub_);
144 VLOG(0) << "Running GetIceServer...";
Yuwei Huang82c01892019-03-28 20:39:40145 ftl::GetICEServerRequest request;
146 *request.mutable_header() = FtlGrpcContext::CreateRequestHeader();
147 auto grpc_request = CreateGrpcAsyncUnaryRequest(
Erik Jensen1ea01012020-07-27 21:35:06148 base::BindOnce(&PeerToPeer::StubInterface::AsyncGetICEServer,
Yuwei Huang3f1fcd362019-03-11 20:27:17149 base::Unretained(peer_to_peer_stub_.get())),
Yuwei Huang2071aeb2019-05-10 21:10:59150 request,
Yuwei Huang2687b47f2019-04-01 20:57:08151 base::BindOnce(&FtlServicesPlayground::OnGetIceServerResponse,
Yuwei Huang946cebd42019-03-04 22:14:20152 weak_factory_.GetWeakPtr(), std::move(on_done)));
Yuwei Huang2071aeb2019-05-10 21:10:59153 FtlGrpcContext::FillClientContext(grpc_request->context());
Yuwei Huang82c01892019-03-28 20:39:40154 executor_->ExecuteRpc(std::move(grpc_request));
Yuwei Huang575c32ee2019-02-27 04:41:56155}
156
Yuwei Huang2687b47f2019-04-01 20:57:08157void FtlServicesPlayground::OnGetIceServerResponse(
Yuwei Huang575c32ee2019-02-27 04:41:56158 base::OnceClosure on_done,
Yuwei Huang81bbc1a2019-03-08 20:46:06159 const grpc::Status& status,
Yuwei Huang575c32ee2019-02-27 04:41:56160 const ftl::GetICEServerResponse& response) {
Yuwei Huangfce958772019-03-30 00:18:11161 if (!status.ok()) {
162 HandleGrpcStatusError(std::move(on_done), status);
163 return;
164 }
165
166 printf("Ice transport policy: %s\n",
167 response.ice_config().ice_transport_policy().c_str());
168 for (const ftl::ICEServerList& server : response.ice_config().ice_servers()) {
169 printf(
170 "ICE server:\n"
171 " hostname=%s\n"
172 " username=%s\n"
173 " credential=%s\n"
174 " max_rate_kbps=%" PRId64 "\n",
175 server.hostname().c_str(), server.username().c_str(),
176 server.credential().c_str(), server.max_rate_kbps());
177 for (const std::string& url : server.urls()) {
178 printf(" url=%s\n", url.c_str());
Yuwei Huang575c32ee2019-02-27 04:41:56179 }
Yuwei Huangaae881f2019-03-01 23:10:27180 }
181 std::move(on_done).Run();
182}
183
Yuwei Huang2687b47f2019-04-01 20:57:08184void FtlServicesPlayground::SignInGaia(base::OnceClosure on_done) {
Yuwei Huange5b94452019-03-23 00:26:05185 DCHECK(registration_manager_);
Yuwei Huangaae881f2019-03-01 23:10:27186 VLOG(0) << "Running SignInGaia...";
Yuwei Huange5b94452019-03-23 00:26:05187 registration_manager_->SignInGaia(
Yuwei Huang2687b47f2019-04-01 20:57:08188 base::BindOnce(&FtlServicesPlayground::OnSignInGaiaResponse,
Yuwei Huang946cebd42019-03-04 22:14:20189 weak_factory_.GetWeakPtr(), std::move(on_done)));
Yuwei Huangaae881f2019-03-01 23:10:27190}
191
Yuwei Huangfeddf232020-07-28 00:27:49192void FtlServicesPlayground::OnSignInGaiaResponse(
193 base::OnceClosure on_done,
194 const ProtobufHttpStatus& status) {
Yuwei Huangfce958772019-03-30 00:18:11195 if (!status.ok()) {
Yuwei Huangfeddf232020-07-28 00:27:49196 // TODO(yuweih): Clean this up.
197 HandleGrpcStatusError(
198 std::move(on_done),
199 grpc::Status(static_cast<grpc::StatusCode>(status.error_code()),
200 status.error_message()));
Yuwei Huangfce958772019-03-30 00:18:11201 return;
Yuwei Huang98655b92019-03-04 23:41:41202 }
Yuwei Huangfce958772019-03-30 00:18:11203
204 std::string registration_id_base64;
205 base::Base64Encode(registration_manager_->GetRegistrationId(),
206 &registration_id_base64);
207 printf("Service signed in. registration_id(base64)=%s\n",
208 registration_id_base64.c_str());
Yuwei Huang98655b92019-03-04 23:41:41209 std::move(on_done).Run();
210}
211
Yuwei Huang2687b47f2019-04-01 20:57:08212void FtlServicesPlayground::PullMessages(base::OnceClosure on_done) {
Yuwei Huang968994cb2019-03-21 00:55:27213 DCHECK(messaging_client_);
Yuwei Huang98655b92019-03-04 23:41:41214 VLOG(0) << "Running PullMessages...";
Yuwei Huang3f1fcd362019-03-11 20:27:17215
Yuwei Huang968994cb2019-03-21 00:55:27216 messaging_client_->PullMessages(
Yuwei Huang2687b47f2019-04-01 20:57:08217 base::BindOnce(&FtlServicesPlayground::OnPullMessagesResponse,
Yuwei Huang98655b92019-03-04 23:41:41218 weak_factory_.GetWeakPtr(), std::move(on_done)));
219}
220
Yuwei Huang2687b47f2019-04-01 20:57:08221void FtlServicesPlayground::OnPullMessagesResponse(base::OnceClosure on_done,
222 const grpc::Status& status) {
Yuwei Huang98655b92019-03-04 23:41:41223 if (!status.ok()) {
Yuwei Huangfce958772019-03-30 00:18:11224 HandleGrpcStatusError(std::move(on_done), status);
225 return;
Yuwei Huang5a84f9532019-02-20 18:29:01226 }
Yuwei Huang575c32ee2019-02-27 04:41:56227 std::move(on_done).Run();
228}
Yuwei Huang5a84f9532019-02-20 18:29:01229
Yuwei Huang2687b47f2019-04-01 20:57:08230void FtlServicesPlayground::SendMessage(base::OnceClosure on_done) {
Yuwei Huang4de60092019-03-22 21:19:44231 DCHECK(messaging_client_);
232 VLOG(0) << "Running SendMessage...";
233
234 printf("Receiver ID: ");
Yuwei Huang41ddec52019-04-02 02:08:19235 std::string receiver_id = test::ReadString();
Yuwei Huang4de60092019-03-22 21:19:44236
237 printf("Receiver registration ID (base64, optional): ");
Yuwei Huang41ddec52019-04-02 02:08:19238 std::string registration_id_base64 = test::ReadString();
Yuwei Huang4de60092019-03-22 21:19:44239
240 std::string registration_id;
241 bool success = base::Base64Decode(registration_id_base64, &registration_id);
242 if (!success) {
243 fprintf(stderr, "Your input can't be base64 decoded.\n");
244 std::move(on_done).Run();
245 return;
246 }
247 DoSendMessage(receiver_id, registration_id, std::move(on_done), true);
248}
249
Yuwei Huang2687b47f2019-04-01 20:57:08250void FtlServicesPlayground::DoSendMessage(const std::string& receiver_id,
251 const std::string& registration_id,
252 base::OnceClosure on_done,
253 bool should_keep_running) {
Yuwei Huang4de60092019-03-22 21:19:44254 if (!should_keep_running) {
255 std::move(on_done).Run();
256 return;
257 }
258
259 printf("Message (enter nothing to quit): ");
Yuwei Huang41ddec52019-04-02 02:08:19260 std::string message = test::ReadString();
Yuwei Huang4de60092019-03-22 21:19:44261
262 if (message.empty()) {
263 std::move(on_done).Run();
264 return;
265 }
266
Yuwei Huang2687b47f2019-04-01 20:57:08267 auto on_continue = base::BindOnce(&FtlServicesPlayground::DoSendMessage,
Yuwei Huang4de60092019-03-22 21:19:44268 weak_factory_.GetWeakPtr(), receiver_id,
269 registration_id, std::move(on_done));
270
Yuwei Huang4c919d142019-04-05 17:05:49271 ftl::ChromotingMessage crd_message;
272 crd_message.mutable_xmpp()->set_stanza(message);
Yuwei Huang4de60092019-03-22 21:19:44273 messaging_client_->SendMessage(
Yuwei Huang4c919d142019-04-05 17:05:49274 receiver_id, registration_id, crd_message,
Yuwei Huang2687b47f2019-04-01 20:57:08275 base::BindOnce(&FtlServicesPlayground::OnSendMessageResponse,
Yuwei Huang4de60092019-03-22 21:19:44276 weak_factory_.GetWeakPtr(), std::move(on_continue)));
277}
278
Yuwei Huang2687b47f2019-04-01 20:57:08279void FtlServicesPlayground::OnSendMessageResponse(
Yuwei Huang4de60092019-03-22 21:19:44280 base::OnceCallback<void(bool)> on_continue,
281 const grpc::Status& status) {
282 if (!status.ok()) {
Yuwei Huangfce958772019-03-30 00:18:11283 HandleGrpcStatusError(base::BindOnce(std::move(on_continue), false),
284 status);
285 return;
Yuwei Huang4de60092019-03-22 21:19:44286 }
Yuwei Huangfce958772019-03-30 00:18:11287
288 printf("Message successfully sent.\n");
289 std::move(on_continue).Run(true);
Yuwei Huang4de60092019-03-22 21:19:44290}
291
Yuwei Huang2687b47f2019-04-01 20:57:08292void FtlServicesPlayground::StartReceivingMessages(base::OnceClosure on_done) {
Yuwei Huangb8e1f2d2019-03-22 19:40:26293 VLOG(0) << "Running StartReceivingMessages...";
Yuwei Huangce344e32019-04-05 19:31:29294 receive_messages_done_callback_ = std::move(on_done);
Yuwei Huangb8e1f2d2019-03-22 19:40:26295 messaging_client_->StartReceivingMessages(
Yuwei Huangce344e32019-04-05 19:31:29296 base::BindOnce(&FtlServicesPlayground::OnReceiveMessagesStreamReady,
297 weak_factory_.GetWeakPtr()),
298 base::BindOnce(&FtlServicesPlayground::OnReceiveMessagesStreamClosed,
299 weak_factory_.GetWeakPtr()));
Yuwei Huangb8e1f2d2019-03-22 19:40:26300}
301
Yuwei Huang2687b47f2019-04-01 20:57:08302void FtlServicesPlayground::StopReceivingMessages(base::OnceClosure on_done) {
Yuwei Huangb8e1f2d2019-03-22 19:40:26303 messaging_client_->StopReceivingMessages();
304 std::move(on_done).Run();
305}
306
Yuwei Huangc9bb46f2019-04-04 02:19:00307void FtlServicesPlayground::OnMessageReceived(
Yuwei Huang4ef50e732019-05-30 04:30:25308 const ftl::Id& sender_id,
Yuwei Huangc9bb46f2019-04-04 02:19:00309 const std::string& sender_registration_id,
Yuwei Huang4c919d142019-04-05 17:05:49310 const ftl::ChromotingMessage& message) {
311 std::string message_text = message.xmpp().stanza();
Yuwei Huang968994cb2019-03-21 00:55:27312 printf(
313 "Received message:\n"
314 " Sender ID=%s\n"
Yuwei Huangc9bb46f2019-04-04 02:19:00315 " Sender Registration ID=%s\n"
Yuwei Huang968994cb2019-03-21 00:55:27316 " Message=%s\n",
Yuwei Huang4ef50e732019-05-30 04:30:25317 sender_id.id().c_str(), sender_registration_id.c_str(),
318 message_text.c_str());
Yuwei Huang968994cb2019-03-21 00:55:27319}
320
Yuwei Huangce344e32019-04-05 19:31:29321void FtlServicesPlayground::OnReceiveMessagesStreamReady() {
322 printf("Started receiving messages. Press enter to stop streaming...\n");
323 test::WaitForEnterKey(base::BindOnce(
324 &FtlServicesPlayground::StopReceivingMessages, weak_factory_.GetWeakPtr(),
325 std::move(receive_messages_done_callback_)));
326}
327
328void FtlServicesPlayground::OnReceiveMessagesStreamClosed(
Yuwei Huangb8e1f2d2019-03-22 19:40:26329 const grpc::Status& status) {
Yuwei Huangce344e32019-04-05 19:31:29330 base::OnceClosure callback = std::move(receive_messages_done_callback_);
331 bool is_callback_null = callback.is_null();
332 if (is_callback_null) {
333 callback = base::DoNothing::Once();
334 }
Yuwei Huangb8e1f2d2019-03-22 19:40:26335 if (status.error_code() == grpc::StatusCode::CANCELLED) {
336 printf("ReceiveMessages stream canceled by client.\n");
Yuwei Huangce344e32019-04-05 19:31:29337 std::move(callback).Run();
Yuwei Huangb8e1f2d2019-03-22 19:40:26338 return;
339 }
Yuwei Huangfce958772019-03-30 00:18:11340
Yuwei Huangb8e1f2d2019-03-22 19:40:26341 if (!status.ok()) {
Yuwei Huangce344e32019-04-05 19:31:29342 HandleGrpcStatusError(std::move(callback), status);
343 } else {
344 printf("Stream closed by server.\n");
345 std::move(callback).Run();
Yuwei Huangb8e1f2d2019-03-22 19:40:26346 }
Yuwei Huangce344e32019-04-05 19:31:29347
348 if (is_callback_null) {
349 // Stream had been started and callback has been passed to wait for the
350 // enter key.
351 printf("Please press enter to continue...\n");
352 }
Yuwei Huangb8e1f2d2019-03-22 19:40:26353}
354
Yuwei Huang2687b47f2019-04-01 20:57:08355void FtlServicesPlayground::HandleGrpcStatusError(base::OnceClosure on_done,
356 const grpc::Status& status) {
Yuwei Huangfce958772019-03-30 00:18:11357 DCHECK(!status.ok());
358 if (status.error_code() == grpc::StatusCode::UNAUTHENTICATED) {
359 if (NeedsManualSignin()) {
360 printf(
361 "Request is unauthenticated. You should run SignInGaia first if "
362 "you haven't done so, otherwise your OAuth token might be expired. \n"
363 "Request for new OAuth token? [y/N]: ");
Yuwei Huangdc86bdf42019-04-18 19:14:10364 if (!test::ReadYNBool()) {
Yuwei Huangfce958772019-03-30 00:18:11365 std::move(on_done).Run();
366 return;
367 }
368 }
369 VLOG(0) << "Grpc request failed to authenticate. "
370 << "Trying to reauthenticate...";
Yuwei Huang41ddec52019-04-02 02:08:19371 token_getter_->ResetWithAuthenticationFlow(
372 base::BindOnce(&FtlServicesPlayground::ResetServices,
373 weak_factory_.GetWeakPtr(), std::move(on_done)));
Yuwei Huangfce958772019-03-30 00:18:11374 return;
375 }
376
377 fprintf(stderr, "RPC failed. Code=%d, Message=%s\n", status.error_code(),
378 status.error_message().c_str());
379 std::move(on_done).Run();
380}
381
Yuwei Huang575c32ee2019-02-27 04:41:56382} // namespace remoting