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_latency_test_fixture.h"
7 #include "base/logging.h"
8 #include "base/run_loop.h"
9 #include "base/thread_task_runner_handle.h"
10 #include "base/timer/timer.h"
11 #include "remoting/proto/event.pb.h"
12 #include "remoting/protocol/input_stub.h"
13 #include "remoting/protocol/usb_key_codes.h"
14 #include "remoting/test/app_remoting_connection_helper.h"
15 #include "remoting/test/app_remoting_test_driver_environment.h"
16 #include "remoting/test/rgb_value.h"
17 #include "remoting/test/test_chromoting_client.h"
18 #include "remoting/test/test_video_renderer.h"
23 AppRemotingLatencyTestFixture::AppRemotingLatencyTestFixture()
24 : timer_(new base::Timer(true, false)) {
25 // NOTE: Derived fixture must initialize application details in constructor.
28 AppRemotingLatencyTestFixture::~AppRemotingLatencyTestFixture() {
31 void AppRemotingLatencyTestFixture::SetUp() {
32 scoped_ptr
<TestVideoRenderer
> test_video_renderer(new TestVideoRenderer());
33 test_video_renderer_
= test_video_renderer
->GetWeakPtr();
35 scoped_ptr
<TestChromotingClient
> test_chromoting_client(
36 new TestChromotingClient(test_video_renderer
.Pass()));
38 test_chromoting_client
->AddRemoteConnectionObserver(this);
40 connection_helper_
.reset(
41 new AppRemotingConnectionHelper(GetApplicationDetails()));
42 connection_helper_
->Initialize(test_chromoting_client
.Pass());
44 if (!connection_helper_
->StartConnection()) {
45 LOG(ERROR
) << "Remote host connection could not be established.";
49 if (!PrepareApplicationForTesting()) {
50 LOG(ERROR
) << "Unable to prepare application for testing.";
55 void AppRemotingLatencyTestFixture::TearDown() {
56 // Only reset application state when remote host connection is established.
57 if (connection_helper_
->ConnectionIsReadyForTest()) {
58 ResetApplicationState();
61 connection_helper_
->test_chromoting_client()->RemoveRemoteConnectionObserver(
63 connection_helper_
.reset();
66 WaitForImagePatternMatchCallback
67 AppRemotingLatencyTestFixture::SetExpectedImagePattern(
68 const webrtc::DesktopRect
& expected_rect
,
69 const RGBValue
& expected_color
) {
70 scoped_ptr
<base::RunLoop
> run_loop(new base::RunLoop());
72 test_video_renderer_
->ExpectAverageColorInRect(expected_rect
, expected_color
,
73 run_loop
->QuitClosure());
75 return base::Bind(&AppRemotingLatencyTestFixture::WaitForImagePatternMatch
,
76 base::Unretained(this), base::Passed(&run_loop
));
79 void AppRemotingLatencyTestFixture::SaveFrameDataToDisk(
80 bool save_frame_data_to_disk
) {
81 test_video_renderer_
->SaveFrameDataToDisk(save_frame_data_to_disk
);
84 bool AppRemotingLatencyTestFixture::WaitForImagePatternMatch(
85 scoped_ptr
<base::RunLoop
> run_loop
,
86 const base::TimeDelta
& max_wait_time
) {
88 DCHECK(!timer_
->IsRunning());
90 timer_
->Start(FROM_HERE
, max_wait_time
, run_loop
->QuitClosure());
94 // Image pattern is matched if we stopped because of the reply not the timer.
95 bool image_pattern_is_matched
= (timer_
->IsRunning());
99 return image_pattern_is_matched
;
102 void AppRemotingLatencyTestFixture::HostMessageReceived(
103 const protocol::ExtensionMessage
& message
) {
104 if (!host_message_received_callback_
.is_null()) {
105 host_message_received_callback_
.Run(message
);
109 void AppRemotingLatencyTestFixture::PressKey(uint32_t usb_keycode
,
111 remoting::protocol::KeyEvent event
;
112 event
.set_usb_keycode(usb_keycode
);
113 event
.set_pressed(pressed
);
114 connection_helper_
->input_stub()->InjectKeyEvent(event
);
117 void AppRemotingLatencyTestFixture::PressAndReleaseKey(uint32_t usb_keycode
) {
118 PressKey(usb_keycode
, true);
119 PressKey(usb_keycode
, false);
122 void AppRemotingLatencyTestFixture::PressAndReleaseKeyCombination(
123 const std::vector
<uint32_t>& usb_keycodes
) {
124 for (std::vector
<uint32_t>::const_iterator iter
= usb_keycodes
.begin();
125 iter
!= usb_keycodes
.end(); ++iter
) {
126 PressKey(*iter
, true);
128 for (std::vector
<uint32_t>::const_reverse_iterator iter
=
129 usb_keycodes
.rbegin();
130 iter
!= usb_keycodes
.rend(); ++iter
) {
131 PressKey(*iter
, false);
135 void AppRemotingLatencyTestFixture::SetHostMessageReceivedCallback(
136 const HostMessageReceivedCallback
& host_message_received_callback
) {
137 host_message_received_callback_
= host_message_received_callback
;
140 void AppRemotingLatencyTestFixture::ResetHostMessageReceivedCallback() {
141 host_message_received_callback_
.Reset();
144 void AppRemotingLatencyTestFixture::ResetApplicationState() {
145 DCHECK(!timer_
->IsRunning());
146 DCHECK(!run_loop_
|| !run_loop_
->running());
148 // Give the app some time to settle before reseting to initial state.
149 run_loop_
.reset(new base::RunLoop());
150 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
151 FROM_HERE
, run_loop_
->QuitClosure(), base::TimeDelta::FromSeconds(1));
154 // Press Alt + F4 and wait for amount of time for the input to be delivered
156 std::vector
<uint32_t> usb_keycodes
;
157 usb_keycodes
.push_back(kUsbLeftAlt
);
158 usb_keycodes
.push_back(kUsbF4
);
159 PressAndReleaseKeyCombination(usb_keycodes
);
161 run_loop_
.reset(new base::RunLoop());
162 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
163 FROM_HERE
, run_loop_
->QuitClosure(), base::TimeDelta::FromSeconds(2));
166 // Press 'N' to choose not save and wait for 1 second for the input to be
167 // delivered and processed.
168 PressAndReleaseKey(kUsbN
);
170 run_loop_
.reset(new base::RunLoop());
171 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
172 FROM_HERE
, run_loop_
->QuitClosure(), base::TimeDelta::FromSeconds(2));
178 } // namespace remoting