Roll src/third_party/skia f559de4:94e5010
[chromium-blink-merge.git] / remoting / test / app_remoting_test_driver_environment.cc
blob902cd00dd0734eaa5abddf7094c0275d8b91caf7
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 DCHECK(!user_name_.empty());
35 DCHECK(service_environment < kUnknownEnvironment);
37 PopulateApplicationNames();
38 PopulateApplicationDetailsMap();
41 AppRemotingTestDriverEnvironment::~AppRemotingTestDriverEnvironment() {
44 bool AppRemotingTestDriverEnvironment::Initialize(
45 const std::string& auth_code) {
46 if (!access_token_.empty()) {
47 return true;
50 // If a unit test has set |test_refresh_token_store_| then we should use it
51 // below. Note that we do not want to destroy the test object.
52 scoped_ptr<RefreshTokenStore> temporary_refresh_token_store;
53 RefreshTokenStore* refresh_token_store = test_refresh_token_store_;
54 if (!refresh_token_store) {
55 temporary_refresh_token_store = RefreshTokenStore::OnDisk(user_name_);
56 refresh_token_store = temporary_refresh_token_store.get();
59 // Check to see if we have a refresh token stored for this user.
60 refresh_token_ = refresh_token_store->FetchRefreshToken();
61 if (refresh_token_.empty()) {
62 // This isn't necessarily an error as this might be a first run scenario.
63 DVLOG(1) << "No refresh token stored for " << user_name_;
65 if (auth_code.empty()) {
66 // No token and no Auth code means no service connectivity, bail!
67 LOG(ERROR) << "Cannot retrieve an access token without a stored refresh"
68 << " token on disk or an auth_code passed into the tool";
69 return false;
73 if (!RetrieveAccessToken(auth_code)) {
74 // If we cannot retrieve an access token, then nothing is going to work and
75 // we should let the caller know that our object is not ready to be used.
76 return false;
79 return true;
82 bool AppRemotingTestDriverEnvironment::RefreshAccessToken() {
83 DCHECK(!refresh_token_.empty());
85 // Empty auth code is used when refreshing.
86 return RetrieveAccessToken(std::string());
89 bool AppRemotingTestDriverEnvironment::GetRemoteHostInfoForApplicationId(
90 const std::string& application_id,
91 RemoteHostInfo* remote_host_info) {
92 DCHECK(!application_id.empty());
93 DCHECK(remote_host_info);
95 if (access_token_.empty()) {
96 LOG(ERROR) << "RemoteHostInfo requested without a valid access token. "
97 << "Ensure the environment object has been initialized.";
98 return false;
101 scoped_ptr<base::MessageLoopForIO> message_loop;
102 if (!base::MessageLoop::current()) {
103 // Create a temporary message loop if the current thread does not already
104 // have one so we can use its task runner for our network request.
105 message_loop.reset(new base::MessageLoopForIO);
108 base::RunLoop run_loop;
110 RemoteHostInfoCallback remote_host_info_fetch_callback = base::Bind(
111 &AppRemotingTestDriverEnvironment::OnRemoteHostInfoRetrieved,
112 base::Unretained(this), run_loop.QuitClosure(), remote_host_info);
114 // If a unit test has set |test_remote_host_info_fetcher_| then we should use
115 // it below. Note that we do not want to destroy the test object at the end
116 // of the function which is why we have the dance below.
117 scoped_ptr<RemoteHostInfoFetcher> temporary_remote_host_info_fetcher;
118 RemoteHostInfoFetcher* remote_host_info_fetcher =
119 test_remote_host_info_fetcher_;
120 if (!remote_host_info_fetcher) {
121 temporary_remote_host_info_fetcher.reset(new RemoteHostInfoFetcher());
122 remote_host_info_fetcher = temporary_remote_host_info_fetcher.get();
125 remote_host_info_fetcher->RetrieveRemoteHostInfo(
126 application_id, access_token_, service_environment_,
127 remote_host_info_fetch_callback);
129 run_loop.Run();
131 return remote_host_info->IsReadyForConnection();
134 void AppRemotingTestDriverEnvironment::ShowHostAvailability() {
135 const char kHostAvailabilityFormatString[] = "%-25s%-35s%-10s";
136 std::vector<std::string>::const_iterator it = application_names_.begin();
138 LOG(INFO) << base::StringPrintf(kHostAvailabilityFormatString,
139 "Application Name", "Application ID",
140 "Status");
142 while (it != application_names_.end()) {
143 std::string application_name = *it;
145 const RemoteApplicationDetails& application_details =
146 GetDetailsFromAppName(application_name);
148 RemoteHostInfo remote_host_info;
149 GetRemoteHostInfoForApplicationId(application_details.application_id,
150 &remote_host_info);
152 std::string status;
153 RemoteHostStatus remote_host_status = remote_host_info.remote_host_status;
154 if (remote_host_status == kRemoteHostStatusReady) {
155 status = "Ready :)";
156 } else if (remote_host_status == kRemoteHostStatusPending) {
157 status = "Pending :|";
158 } else {
159 status = "Unknown :(";
162 LOG(INFO) << base::StringPrintf(
163 kHostAvailabilityFormatString, application_name.c_str(),
164 application_details.application_id.c_str(), status.c_str());
166 ++it;
170 const RemoteApplicationDetails&
171 AppRemotingTestDriverEnvironment::GetDetailsFromAppName(
172 const std::string& application_name) {
173 std::map<std::string, RemoteApplicationDetails>::const_iterator
174 map_pair_iterator = application_details_map_.find(application_name);
175 DCHECK(map_pair_iterator != application_details_map_.end());
177 return map_pair_iterator->second;
180 void AppRemotingTestDriverEnvironment::SetAccessTokenFetcherForTest(
181 AccessTokenFetcher* access_token_fetcher) {
182 DCHECK(access_token_fetcher);
184 test_access_token_fetcher_ = access_token_fetcher;
187 void AppRemotingTestDriverEnvironment::SetRefreshTokenStoreForTest(
188 RefreshTokenStore* refresh_token_store) {
189 DCHECK(refresh_token_store);
191 test_refresh_token_store_ = refresh_token_store;
194 void AppRemotingTestDriverEnvironment::SetRemoteHostInfoFetcherForTest(
195 RemoteHostInfoFetcher* remote_host_info_fetcher) {
196 DCHECK(remote_host_info_fetcher);
198 test_remote_host_info_fetcher_ = remote_host_info_fetcher;
201 bool AppRemotingTestDriverEnvironment::RetrieveAccessToken(
202 const std::string& auth_code) {
203 scoped_ptr<base::MessageLoopForIO> message_loop;
205 if (!base::MessageLoop::current()) {
206 // Create a temporary message loop if the current thread does not already
207 // have one so we can use its task runner for our network request.
208 message_loop.reset(new base::MessageLoopForIO);
211 base::RunLoop run_loop;
213 access_token_.clear();
215 AccessTokenCallback access_token_callback =
216 base::Bind(&AppRemotingTestDriverEnvironment::OnAccessTokenRetrieved,
217 base::Unretained(this), run_loop.QuitClosure());
219 // If a unit test has set |test_access_token_fetcher_| then we should use it
220 // below. Note that we do not want to destroy the test object at the end of
221 // the function which is why we have the dance below.
222 scoped_ptr<AccessTokenFetcher> temporary_access_token_fetcher;
223 AccessTokenFetcher* access_token_fetcher = test_access_token_fetcher_;
224 if (!access_token_fetcher) {
225 temporary_access_token_fetcher.reset(new AccessTokenFetcher());
226 access_token_fetcher = temporary_access_token_fetcher.get();
229 if (!auth_code.empty()) {
230 // If the user passed in an authcode, then use it to retrieve an
231 // updated access/refresh token.
232 access_token_fetcher->GetAccessTokenFromAuthCode(auth_code,
233 access_token_callback);
234 } else {
235 DCHECK(!refresh_token_.empty());
237 access_token_fetcher->GetAccessTokenFromRefreshToken(refresh_token_,
238 access_token_callback);
241 run_loop.Run();
243 // If we were using an auth_code and received a valid refresh token,
244 // then we want to store it locally. If we had an auth code and did not
245 // receive a refresh token, then we should let the user know and exit.
246 if (!auth_code.empty()) {
247 if (!refresh_token_.empty()) {
248 // If a unit test has set |test_refresh_token_store_| then we should use
249 // it below. Note that we do not want to destroy the test object.
250 scoped_ptr<RefreshTokenStore> temporary_refresh_token_store;
251 RefreshTokenStore* refresh_token_store = test_refresh_token_store_;
252 if (!refresh_token_store) {
253 temporary_refresh_token_store = RefreshTokenStore::OnDisk(user_name_);
254 refresh_token_store = temporary_refresh_token_store.get();
257 if (!refresh_token_store->StoreRefreshToken(refresh_token_)) {
258 // If we failed to persist the refresh token, then we should let the
259 // user sort out the issue before continuing.
260 return false;
262 } else {
263 LOG(ERROR) << "Failed to use AUTH CODE to retrieve a refresh token.\n"
264 << "Was the one-time use AUTH CODE used more than once?";
265 return false;
269 if (access_token_.empty()) {
270 LOG(ERROR) << "Failed to retrieve access token.";
271 return false;
274 return true;
277 void AppRemotingTestDriverEnvironment::OnAccessTokenRetrieved(
278 base::Closure done_closure,
279 const std::string& access_token,
280 const std::string& refresh_token) {
281 access_token_ = access_token;
282 refresh_token_ = refresh_token;
284 done_closure.Run();
287 void AppRemotingTestDriverEnvironment::OnRemoteHostInfoRetrieved(
288 base::Closure done_closure,
289 RemoteHostInfo* remote_host_info,
290 const RemoteHostInfo& retrieved_remote_host_info) {
291 DCHECK(remote_host_info);
293 *remote_host_info = retrieved_remote_host_info;
295 done_closure.Run();
298 } // namespace test
299 } // namespace remoting