Clean up extension confirmation prompts and make them consistent between Views and...
[chromium-blink-merge.git] / remoting / test / app_remoting_test_driver_environment.cc
blob73dfda72d158e2dcbde12aa5ef09abddcf6c35c4
1 // Copyright 2015 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.
5 #include "remoting/test/app_remoting_test_driver_environment.h"
7 #include <map>
8 #include <string>
9 #include <vector>
11 #include "base/bind.h"
12 #include "base/callback_forward.h"
13 #include "base/logging.h"
14 #include "base/message_loop/message_loop.h"
15 #include "base/run_loop.h"
16 #include "base/strings/stringprintf.h"
17 #include "remoting/test/access_token_fetcher.h"
18 #include "remoting/test/refresh_token_store.h"
19 #include "remoting/test/remote_host_info.h"
21 namespace remoting {
22 namespace test {
24 AppRemotingTestDriverEnvironment* AppRemotingSharedData;
26 AppRemotingTestDriverEnvironment::AppRemotingTestDriverEnvironment(
27 const std::string& user_name,
28 const base::FilePath& refresh_token_file_path,
29 ServiceEnvironment service_environment)
30 : user_name_(user_name),
31 service_environment_(service_environment),
32 refresh_token_file_path_(refresh_token_file_path),
33 test_access_token_fetcher_(nullptr),
34 test_refresh_token_store_(nullptr),
35 test_remote_host_info_fetcher_(nullptr),
36 message_loop_(new base::MessageLoopForIO()) {
37 DCHECK(!user_name_.empty());
38 DCHECK(service_environment_ < kUnknownEnvironment);
40 PopulateApplicationNames();
41 PopulateApplicationDetailsMap();
44 AppRemotingTestDriverEnvironment::~AppRemotingTestDriverEnvironment() {
47 bool AppRemotingTestDriverEnvironment::Initialize(
48 const std::string& auth_code) {
49 if (!access_token_.empty()) {
50 return true;
53 // If a unit test has set |test_refresh_token_store_| then we should use it
54 // below. Note that we do not want to destroy the test object.
55 scoped_ptr<RefreshTokenStore> temporary_refresh_token_store;
56 RefreshTokenStore* refresh_token_store = test_refresh_token_store_;
57 if (!refresh_token_store) {
58 temporary_refresh_token_store =
59 RefreshTokenStore::OnDisk(user_name_, refresh_token_file_path_);
60 refresh_token_store = temporary_refresh_token_store.get();
63 // Check to see if we have a refresh token stored for this user.
64 refresh_token_ = refresh_token_store->FetchRefreshToken();
65 if (refresh_token_.empty()) {
66 // This isn't necessarily an error as this might be a first run scenario.
67 DVLOG(1) << "No refresh token stored for " << user_name_;
69 if (auth_code.empty()) {
70 // No token and no Auth code means no service connectivity, bail!
71 LOG(ERROR) << "Cannot retrieve an access token without a stored refresh"
72 << " token on disk or an auth_code passed into the tool";
73 return false;
77 if (!RetrieveAccessToken(auth_code)) {
78 // If we cannot retrieve an access token, then nothing is going to work and
79 // we should let the caller know that our object is not ready to be used.
80 return false;
83 return true;
86 bool AppRemotingTestDriverEnvironment::RefreshAccessToken() {
87 DCHECK(!refresh_token_.empty());
89 // Empty auth code is used when refreshing.
90 return RetrieveAccessToken(std::string());
93 bool AppRemotingTestDriverEnvironment::GetRemoteHostInfoForApplicationId(
94 const std::string& application_id,
95 RemoteHostInfo* remote_host_info) {
96 DCHECK(!application_id.empty());
97 DCHECK(remote_host_info);
99 if (access_token_.empty()) {
100 LOG(ERROR) << "RemoteHostInfo requested without a valid access token. "
101 << "Ensure the environment object has been initialized.";
102 return false;
105 base::RunLoop run_loop;
107 RemoteHostInfoCallback remote_host_info_fetch_callback = base::Bind(
108 &AppRemotingTestDriverEnvironment::OnRemoteHostInfoRetrieved,
109 base::Unretained(this), run_loop.QuitClosure(), remote_host_info);
111 // If a unit test has set |test_remote_host_info_fetcher_| then we should use
112 // it below. Note that we do not want to destroy the test object at the end
113 // of the function which is why we have the dance below.
114 scoped_ptr<RemoteHostInfoFetcher> temporary_remote_host_info_fetcher;
115 RemoteHostInfoFetcher* remote_host_info_fetcher =
116 test_remote_host_info_fetcher_;
117 if (!remote_host_info_fetcher) {
118 temporary_remote_host_info_fetcher.reset(new RemoteHostInfoFetcher());
119 remote_host_info_fetcher = temporary_remote_host_info_fetcher.get();
122 remote_host_info_fetcher->RetrieveRemoteHostInfo(
123 application_id, access_token_, service_environment_,
124 remote_host_info_fetch_callback);
126 run_loop.Run();
128 return remote_host_info->IsReadyForConnection();
131 void AppRemotingTestDriverEnvironment::ShowHostAvailability() {
132 const char kHostAvailabilityFormatString[] = "%-25s%-35s%-10s";
134 LOG(INFO) << base::StringPrintf(kHostAvailabilityFormatString,
135 "Application Name", "Application ID",
136 "Status");
138 for (const auto& application_name : application_names_) {
139 const RemoteApplicationDetails& application_details =
140 GetDetailsFromAppName(application_name);
142 RemoteHostInfo remote_host_info;
143 GetRemoteHostInfoForApplicationId(application_details.application_id,
144 &remote_host_info);
146 std::string status;
147 RemoteHostStatus remote_host_status = remote_host_info.remote_host_status;
148 if (remote_host_status == kRemoteHostStatusReady) {
149 status = "Ready :)";
150 } else if (remote_host_status == kRemoteHostStatusPending) {
151 status = "Pending :|";
152 } else {
153 status = "Unknown :(";
156 LOG(INFO) << base::StringPrintf(
157 kHostAvailabilityFormatString, application_name.c_str(),
158 application_details.application_id.c_str(), status.c_str());
162 const RemoteApplicationDetails&
163 AppRemotingTestDriverEnvironment::GetDetailsFromAppName(
164 const std::string& application_name) {
165 const auto map_pair_iterator =
166 application_details_map_.find(application_name);
167 DCHECK(map_pair_iterator != application_details_map_.end());
169 return map_pair_iterator->second;
172 void AppRemotingTestDriverEnvironment::SetAccessTokenFetcherForTest(
173 AccessTokenFetcher* access_token_fetcher) {
174 DCHECK(access_token_fetcher);
176 test_access_token_fetcher_ = access_token_fetcher;
179 void AppRemotingTestDriverEnvironment::SetRefreshTokenStoreForTest(
180 RefreshTokenStore* refresh_token_store) {
181 DCHECK(refresh_token_store);
183 test_refresh_token_store_ = refresh_token_store;
186 void AppRemotingTestDriverEnvironment::SetRemoteHostInfoFetcherForTest(
187 RemoteHostInfoFetcher* remote_host_info_fetcher) {
188 DCHECK(remote_host_info_fetcher);
190 test_remote_host_info_fetcher_ = remote_host_info_fetcher;
193 void AppRemotingTestDriverEnvironment::TearDown() {
194 // Letting the MessageLoop tear down during the test destructor results in
195 // errors after test completion, when the MessageLoop dtor touches the
196 // registered AtExitManager. The AtExitManager is torn down before the test
197 // destructor is executed, so we tear down the MessageLoop here, while it is
198 // still valid.
199 message_loop_.reset();
202 bool AppRemotingTestDriverEnvironment::RetrieveAccessToken(
203 const std::string& auth_code) {
204 base::RunLoop run_loop;
206 access_token_.clear();
208 AccessTokenCallback access_token_callback =
209 base::Bind(&AppRemotingTestDriverEnvironment::OnAccessTokenRetrieved,
210 base::Unretained(this), run_loop.QuitClosure());
212 // If a unit test has set |test_access_token_fetcher_| then we should use it
213 // below. Note that we do not want to destroy the test object at the end of
214 // the function which is why we have the dance below.
215 scoped_ptr<AccessTokenFetcher> temporary_access_token_fetcher;
216 AccessTokenFetcher* access_token_fetcher = test_access_token_fetcher_;
217 if (!access_token_fetcher) {
218 temporary_access_token_fetcher.reset(new AccessTokenFetcher());
219 access_token_fetcher = temporary_access_token_fetcher.get();
222 if (!auth_code.empty()) {
223 // If the user passed in an authcode, then use it to retrieve an
224 // updated access/refresh token.
225 access_token_fetcher->GetAccessTokenFromAuthCode(auth_code,
226 access_token_callback);
227 } else {
228 DCHECK(!refresh_token_.empty());
230 access_token_fetcher->GetAccessTokenFromRefreshToken(refresh_token_,
231 access_token_callback);
234 run_loop.Run();
236 // If we were using an auth_code and received a valid refresh token,
237 // then we want to store it locally. If we had an auth code and did not
238 // receive a refresh token, then we should let the user know and exit.
239 if (!auth_code.empty()) {
240 if (!refresh_token_.empty()) {
241 // If a unit test has set |test_refresh_token_store_| then we should use
242 // it below. Note that we do not want to destroy the test object.
243 scoped_ptr<RefreshTokenStore> temporary_refresh_token_store;
244 RefreshTokenStore* refresh_token_store = test_refresh_token_store_;
245 if (!refresh_token_store) {
246 temporary_refresh_token_store =
247 RefreshTokenStore::OnDisk(user_name_, refresh_token_file_path_);
248 refresh_token_store = temporary_refresh_token_store.get();
251 if (!refresh_token_store->StoreRefreshToken(refresh_token_)) {
252 // If we failed to persist the refresh token, then we should let the
253 // user sort out the issue before continuing.
254 return false;
256 } else {
257 LOG(ERROR) << "Failed to use AUTH CODE to retrieve a refresh token.\n"
258 << "Was the one-time use AUTH CODE used more than once?";
259 return false;
263 if (access_token_.empty()) {
264 LOG(ERROR) << "Failed to retrieve access token.";
265 return false;
268 return true;
271 void AppRemotingTestDriverEnvironment::OnAccessTokenRetrieved(
272 base::Closure done_closure,
273 const std::string& access_token,
274 const std::string& refresh_token) {
275 access_token_ = access_token;
276 refresh_token_ = refresh_token;
278 done_closure.Run();
281 void AppRemotingTestDriverEnvironment::OnRemoteHostInfoRetrieved(
282 base::Closure done_closure,
283 RemoteHostInfo* remote_host_info,
284 const RemoteHostInfo& retrieved_remote_host_info) {
285 DCHECK(remote_host_info);
287 *remote_host_info = retrieved_remote_host_info;
289 done_closure.Run();
292 } // namespace test
293 } // namespace remoting