Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(138)

Side by Side Diff: remoting/test/app_remoting_connected_client_fixture.cc

Issue 1008043003: Adding Test Fixture for initial test cases for the App Remoting Test Driver. Also includes the pub… (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressing 2nd round of feedback Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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.
4
5 #include "remoting/test/app_remoting_connected_client_fixture.h"
6
7 #include "base/json/json_reader.h"
8 #include "base/logging.h"
9 #include "base/run_loop.h"
10 #include "base/thread_task_runner_handle.h"
11 #include "base/timer/timer.h"
12 #include "base/values.h"
13 #include "remoting/protocol/host_stub.h"
14 #include "remoting/test/app_remoting_test_driver_environment.h"
15 #include "remoting/test/remote_application_details.h"
16 #include "remoting/test/test_chromoting_client.h"
17
18 namespace {
19 const int kDefaultDPI = 96;
20 const int kDefaultWidth = 1024;
21 const int kDefaultHeight = 768;
22
23 const char kHostProcessWindowTitle[] = "Host Process";
24
25 void SimpleHostMessageHandler(
26 const std::string& target_message_type,
27 const std::string& target_message_data,
28 const base::Closure& done_closure,
29 bool* message_received,
30 const remoting::protocol::ExtensionMessage& message) {
31 if (message.type() == target_message_type &&
32 message.data() == target_message_data) {
33 *message_received = true;
34 done_closure.Run();
35 }
36 }
37 } // namespace
38
39 namespace remoting {
40 namespace test {
41
42 AppRemotingConnectedClientFixture::AppRemotingConnectedClientFixture()
43 : application_details_(
44 AppRemotingSharedData->GetDetailsFromAppName(GetParam())),
45 connection_is_ready_for_tests_(false),
46 timer_(new base::Timer(true, false)) {
47 }
48
49 AppRemotingConnectedClientFixture::~AppRemotingConnectedClientFixture() {
50 }
51
52 void AppRemotingConnectedClientFixture::SetUp() {
53 message_loop_.reset(new base::MessageLoopForIO);
54
55 client_.reset(new TestChromotingClient());
56 client_->AddRemoteConnectionObserver(this);
57
58 StartConnection();
59
60 if (!connection_is_ready_for_tests_) {
61 FAIL() << "Remote host connection could not be established.";
62 client_->EndConnection();
63 }
64 }
65
66 void AppRemotingConnectedClientFixture::TearDown() {
67 // |client_| must be destroyed before |message_loop_| as some of its
68 // members are destroyed via DeleteSoon on the message loop's TaskRunner.
69 client_->RemoveRemoteConnectionObserver(this);
70 client_.reset();
71
72 base::RunLoop().RunUntilIdle();
73
74 message_loop_.reset();
75 }
76
77 bool AppRemotingConnectedClientFixture::VerifyResponseForSimpleHostMessage(
78 const std::string& message_request_title,
79 const std::string& message_response_title,
80 const std::string& message_payload,
81 const base::TimeDelta& max_wait_time) {
82 DCHECK(thread_checker_.CalledOnValidThread());
83
84 bool message_received = false;
85
86 DCHECK(!run_loop_ || !run_loop_->running());
87 run_loop_.reset(new base::RunLoop());
88
89 host_message_received_callback_ =
90 base::Bind(&SimpleHostMessageHandler, message_response_title,
91 message_payload, run_loop_->QuitClosure(), &message_received);
92
93 protocol::ExtensionMessage message;
94 message.set_type(message_request_title);
95 message.set_data(message_payload);
96 client_->host_stub()->DeliverClientMessage(message);
97
98 DCHECK(!timer_->IsRunning());
99 timer_->Start(FROM_HERE, max_wait_time, run_loop_->QuitClosure());
100
101 run_loop_->Run();
102 timer_->Stop();
103
104 host_message_received_callback_.Reset();
105
106 return message_received;
107 }
108
109 void AppRemotingConnectedClientFixture::StartConnection() {
110 DCHECK(thread_checker_.CalledOnValidThread());
111
112 RemoteHostInfo remote_host_info;
113 remoting::test::AppRemotingSharedData->GetRemoteHostInfoForApplicationId(
114 application_details_.application_id, &remote_host_info);
115
116 if (!remote_host_info.IsReadyForConnection()) {
117 LOG(ERROR) << "Remote Host is unavailable for connections.";
118 return;
119 }
120
121 DCHECK(!run_loop_ || !run_loop_->running());
122 run_loop_.reset(new base::RunLoop());
123
124 // We will wait up to 30 seconds to complete the remote connection and for the
125 // main application window to become visible.
126 DCHECK(!timer_->IsRunning());
127 timer_->Start(FROM_HERE, base::TimeDelta::FromSeconds(30),
128 run_loop_->QuitClosure());
129
130 client_->StartConnection(AppRemotingSharedData->user_name(),
131 AppRemotingSharedData->access_token(),
132 remote_host_info);
133
134 run_loop_->Run();
135 timer_->Stop();
136 }
137
138 void AppRemotingConnectedClientFixture::ConnectionStateChanged(
139 protocol::ConnectionToHost::State state,
140 protocol::ErrorCode error_code) {
141 DCHECK(thread_checker_.CalledOnValidThread());
142
143 // If the connection is closed or failed then mark the connection as closed
144 // and quit the current RunLoop if it exists.
145 if (state == protocol::ConnectionToHost::CLOSED ||
146 state == protocol::ConnectionToHost::FAILED ||
147 error_code != protocol::OK) {
148 connection_is_ready_for_tests_ = false;
149
150 if (run_loop_) {
151 run_loop_->Quit();
152 }
153 }
154 }
155
156 void AppRemotingConnectedClientFixture::ConnectionReady(bool ready) {
157 DCHECK(thread_checker_.CalledOnValidThread());
158
159 if (ready) {
160 SendClientConnectionDetailsToHost();
161 } else {
162 // We will only get called here with a false value for |ready| if the video
163 // renderer encounters an error.
164 connection_is_ready_for_tests_ = false;
165
166 if (run_loop_) {
167 run_loop_->Quit();
168 }
169 }
170 }
171
172 void AppRemotingConnectedClientFixture::HostMessageReceived(
173 const protocol::ExtensionMessage& message) {
174 DCHECK(thread_checker_.CalledOnValidThread());
175
176 // If a callback is not registered, then the message is passed to a default
177 // handler for the class based on the message type.
178 if (!host_message_received_callback_.is_null()) {
179 host_message_received_callback_.Run(message);
180 } else if (message.type() == "onWindowAdded") {
181 HandleOnWindowAddedMessage(message);
182 } else {
183 DVLOG(2) << "HostMessage not handled by HostMessageReceived().";
184 DVLOG(2) << "type: " << message.type();
185 DVLOG(2) << "data: " << message.data();
186 }
187 }
188
189 void AppRemotingConnectedClientFixture::SendClientConnectionDetailsToHost() {
190 // First send an access token which will be used for Google Drive access.
191 protocol::ExtensionMessage message;
192 message.set_type("accessToken");
193 message.set_data(AppRemotingSharedData->access_token());
194
195 DVLOG(1) << "Sending access token to host";
196 client_->host_stub()->DeliverClientMessage(message);
197
198 // Next send the host a description of the client screen size.
199 protocol::ClientResolution client_resolution;
200 client_resolution.set_width(kDefaultWidth);
201 client_resolution.set_height(kDefaultHeight);
202 client_resolution.set_x_dpi(kDefaultDPI);
203 client_resolution.set_y_dpi(kDefaultDPI);
204 client_resolution.set_dips_width(kDefaultWidth);
205 client_resolution.set_dips_height(kDefaultHeight);
206
207 DVLOG(1) << "Sending ClientResolution details to host";
208 client_->host_stub()->NotifyClientResolution(client_resolution);
209
210 // Finally send a message to start sending us video packets.
211 protocol::VideoControl video_control;
212 video_control.set_enable(true);
213
214 DVLOG(1) << "Sending enable VideoControl message to host";
215 client_->host_stub()->ControlVideo(video_control);
216 }
217
218 void AppRemotingConnectedClientFixture::HandleOnWindowAddedMessage(
219 const remoting::protocol::ExtensionMessage& message) {
220 DCHECK_EQ(message.type(), "onWindowAdded");
221
222 const base::DictionaryValue* message_data = nullptr;
223 scoped_ptr<base::Value> host_message(base::JSONReader::Read(message.data()));
224 if (!host_message.get() || !host_message->GetAsDictionary(&message_data)) {
225 LOG(ERROR) << "onWindowAdded message received was not valid JSON.";
226 if (run_loop_) {
227 run_loop_->Quit();
228 }
229 return;
230 }
231
232 std::string current_window_title;
233 message_data->GetString("title", &current_window_title);
234 if (current_window_title == kHostProcessWindowTitle) {
235 LOG(ERROR) << "Host Process Window is visible, this likely means that the "
236 << "underlying application is in a bad state, YMMV.";
237 }
238
239 std::string main_window_title = application_details_.main_window_title;
240 if (current_window_title.find_first_of(main_window_title) == 0) {
241 connection_is_ready_for_tests_ = true;
242
243 if (timer_->IsRunning()) {
244 timer_->Stop();
245 }
246
247 DCHECK(run_loop_);
248 // Now that the main window is visible, give the app some time to settle
249 // before signaling that it is ready to run tests.
250 timer_->Start(FROM_HERE, base::TimeDelta::FromSeconds(2),
251 run_loop_->QuitClosure());
252 }
253 }
254
255 } // namespace test
256 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/test/app_remoting_connected_client_fixture.h ('k') | remoting/test/app_remoting_test_driver.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698