Re-enable blink_perf.canvas on Windows
[chromium-blink-merge.git] / remoting / test / app_remoting_test_driver_environment.cc
blob9bb04bd610fa8759d3a9f16560dea8e31d78dc6d
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 ServiceEnvironment service_environment)
29 : user_name_(user_name),
30 service_environment_(service_environment),
31 test_access_token_fetcher_(nullptr),
32 test_refresh_token_store_(nullptr),
33 test_remote_host_info_fetcher_(nullptr),
34 message_loop_(new base::MessageLoopForIO()) {
35 DCHECK(!user_name_.empty());
36 DCHECK(service_environment < kUnknownEnvironment);
38 PopulateApplicationNames();
39 PopulateApplicationDetailsMap();
42 AppRemotingTestDriverEnvironment::~AppRemotingTestDriverEnvironment() {
45 bool AppRemotingTestDriverEnvironment::Initialize(
46 const std::string& auth_code) {
47 if (!access_token_.empty()) {
48 return true;
51 // If a unit test has set |test_refresh_token_store_| then we should use it
52 // below. Note that we do not want to destroy the test object.
53 scoped_ptr<RefreshTokenStore> temporary_refresh_token_store;
54 RefreshTokenStore* refresh_token_store = test_refresh_token_store_;
55 if (!refresh_token_store) {
56 temporary_refresh_token_store = RefreshTokenStore::OnDisk(user_name_);
57 refresh_token_store = temporary_refresh_token_store.get();
60 // Check to see if we have a refresh token stored for this user.
61 refresh_token_ = refresh_token_store->FetchRefreshToken();
62 if (refresh_token_.empty()) {
63 // This isn't necessarily an error as this might be a first run scenario.
64 DVLOG(1) << "No refresh token stored for " << user_name_;
66 if (auth_code.empty()) {
67 // No token and no Auth code means no service connectivity, bail!
68 LOG(ERROR) << "Cannot retrieve an access token without a stored refresh"
69 << " token on disk or an auth_code passed into the tool";
70 return false;
74 if (!RetrieveAccessToken(auth_code)) {
75 // If we cannot retrieve an access token, then nothing is going to work and
76 // we should let the caller know that our object is not ready to be used.
77 return false;
80 return true;
83 bool AppRemotingTestDriverEnvironment::RefreshAccessToken() {
84 DCHECK(!refresh_token_.empty());
86 // Empty auth code is used when refreshing.
87 return RetrieveAccessToken(std::string());
90 bool AppRemotingTestDriverEnvironment::GetRemoteHostInfoForApplicationId(
91 const std::string& application_id,
92 RemoteHostInfo* remote_host_info) {
93 DCHECK(!application_id.empty());
94 DCHECK(remote_host_info);
96 if (access_token_.empty()) {
97 LOG(ERROR) << "RemoteHostInfo requested without a valid access token. "
98 << "Ensure the environment object has been initialized.";
99 return false;
102 base::RunLoop run_loop;
104 RemoteHostInfoCallback remote_host_info_fetch_callback = base::Bind(
105 &AppRemotingTestDriverEnvironment::OnRemoteHostInfoRetrieved,
106 base::Unretained(this), run_loop.QuitClosure(), remote_host_info);
108 // If a unit test has set |test_remote_host_info_fetcher_| then we should use
109 // it below. Note that we do not want to destroy the test object at the end
110 // of the function which is why we have the dance below.
111 scoped_ptr<RemoteHostInfoFetcher> temporary_remote_host_info_fetcher;
112 RemoteHostInfoFetcher* remote_host_info_fetcher =
113 test_remote_host_info_fetcher_;
114 if (!remote_host_info_fetcher) {
115 temporary_remote_host_info_fetcher.reset(new RemoteHostInfoFetcher());
116 remote_host_info_fetcher = temporary_remote_host_info_fetcher.get();
119 remote_host_info_fetcher->RetrieveRemoteHostInfo(
120 application_id, access_token_, service_environment_,
121 remote_host_info_fetch_callback);
123 run_loop.Run();
125 return remote_host_info->IsReadyForConnection();
128 void AppRemotingTestDriverEnvironment::ShowHostAvailability() {
129 const char kHostAvailabilityFormatString[] = "%-25s%-35s%-10s";
131 LOG(INFO) << base::StringPrintf(kHostAvailabilityFormatString,
132 "Application Name", "Application ID",
133 "Status");
135 for (const auto& application_name : application_names_) {
136 const RemoteApplicationDetails& application_details =
137 GetDetailsFromAppName(application_name);
139 RemoteHostInfo remote_host_info;
140 GetRemoteHostInfoForApplicationId(application_details.application_id,
141 &remote_host_info);
143 std::string status;
144 RemoteHostStatus remote_host_status = remote_host_info.remote_host_status;
145 if (remote_host_status == kRemoteHostStatusReady) {
146 status = "Ready :)";
147 } else if (remote_host_status == kRemoteHostStatusPending) {
148 status = "Pending :|";
149 } else {
150 status = "Unknown :(";
153 LOG(INFO) << base::StringPrintf(
154 kHostAvailabilityFormatString, application_name.c_str(),
155 application_details.application_id.c_str(), status.c_str());
159 const RemoteApplicationDetails&
160 AppRemotingTestDriverEnvironment::GetDetailsFromAppName(
161 const std::string& application_name) {
162 const auto map_pair_iterator =
163 application_details_map_.find(application_name);
164 DCHECK(map_pair_iterator != application_details_map_.end());
166 return map_pair_iterator->second;
169 void AppRemotingTestDriverEnvironment::SetAccessTokenFetcherForTest(
170 AccessTokenFetcher* access_token_fetcher) {
171 DCHECK(access_token_fetcher);
173 test_access_token_fetcher_ = access_token_fetcher;
176 void AppRemotingTestDriverEnvironment::SetRefreshTokenStoreForTest(
177 RefreshTokenStore* refresh_token_store) {
178 DCHECK(refresh_token_store);
180 test_refresh_token_store_ = refresh_token_store;
183 void AppRemotingTestDriverEnvironment::SetRemoteHostInfoFetcherForTest(
184 RemoteHostInfoFetcher* remote_host_info_fetcher) {
185 DCHECK(remote_host_info_fetcher);
187 test_remote_host_info_fetcher_ = remote_host_info_fetcher;
190 void AppRemotingTestDriverEnvironment::TearDown() {
191 // Letting the MessageLoop tear down during the test destructor results in
192 // errors after test completion, when the MessageLoop dtor touches the
193 // registered AtExitManager. The AtExitManager is torn down before the test
194 // destructor is executed, so we tear down the MessageLoop here, while it is
195 // still valid.
196 message_loop_.reset();
199 bool AppRemotingTestDriverEnvironment::RetrieveAccessToken(
200 const std::string& auth_code) {
201 base::RunLoop run_loop;
203 access_token_.clear();
205 AccessTokenCallback access_token_callback =
206 base::Bind(&AppRemotingTestDriverEnvironment::OnAccessTokenRetrieved,
207 base::Unretained(this), run_loop.QuitClosure());
209 // If a unit test has set |test_access_token_fetcher_| then we should use it
210 // below. Note that we do not want to destroy the test object at the end of
211 // the function which is why we have the dance below.
212 scoped_ptr<AccessTokenFetcher> temporary_access_token_fetcher;
213 AccessTokenFetcher* access_token_fetcher = test_access_token_fetcher_;
214 if (!access_token_fetcher) {
215 temporary_access_token_fetcher.reset(new AccessTokenFetcher());
216 access_token_fetcher = temporary_access_token_fetcher.get();
219 if (!auth_code.empty()) {
220 // If the user passed in an authcode, then use it to retrieve an
221 // updated access/refresh token.
222 access_token_fetcher->GetAccessTokenFromAuthCode(auth_code,
223 access_token_callback);
224 } else {
225 DCHECK(!refresh_token_.empty());
227 access_token_fetcher->GetAccessTokenFromRefreshToken(refresh_token_,
228 access_token_callback);
231 run_loop.Run();
233 // If we were using an auth_code and received a valid refresh token,
234 // then we want to store it locally. If we had an auth code and did not
235 // receive a refresh token, then we should let the user know and exit.
236 if (!auth_code.empty()) {
237 if (!refresh_token_.empty()) {
238 // If a unit test has set |test_refresh_token_store_| then we should use
239 // it below. Note that we do not want to destroy the test object.
240 scoped_ptr<RefreshTokenStore> temporary_refresh_token_store;
241 RefreshTokenStore* refresh_token_store = test_refresh_token_store_;
242 if (!refresh_token_store) {
243 temporary_refresh_token_store = RefreshTokenStore::OnDisk(user_name_);
244 refresh_token_store = temporary_refresh_token_store.get();
247 if (!refresh_token_store->StoreRefreshToken(refresh_token_)) {
248 // If we failed to persist the refresh token, then we should let the
249 // user sort out the issue before continuing.
250 return false;
252 } else {
253 LOG(ERROR) << "Failed to use AUTH CODE to retrieve a refresh token.\n"
254 << "Was the one-time use AUTH CODE used more than once?";
255 return false;
259 if (access_token_.empty()) {
260 LOG(ERROR) << "Failed to retrieve access token.";
261 return false;
264 return true;
267 void AppRemotingTestDriverEnvironment::OnAccessTokenRetrieved(
268 base::Closure done_closure,
269 const std::string& access_token,
270 const std::string& refresh_token) {
271 access_token_ = access_token;
272 refresh_token_ = refresh_token;
274 done_closure.Run();
277 void AppRemotingTestDriverEnvironment::OnRemoteHostInfoRetrieved(
278 base::Closure done_closure,
279 RemoteHostInfo* remote_host_info,
280 const RemoteHostInfo& retrieved_remote_host_info) {
281 DCHECK(remote_host_info);
283 *remote_host_info = retrieved_remote_host_info;
285 done_closure.Run();
288 } // namespace test
289 } // namespace remoting