OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/message_loop.h" | 5 #include "base/message_loop.h" |
6 #include "remoting/base/constants.h" | 6 #include "remoting/base/constants.h" |
| 7 #include "remoting/host/audio_capturer.h" |
7 #include "remoting/host/client_session.h" | 8 #include "remoting/host/client_session.h" |
| 9 #include "remoting/host/desktop_environment.h" |
8 #include "remoting/host/host_mock_objects.h" | 10 #include "remoting/host/host_mock_objects.h" |
9 #include "remoting/protocol/protocol_mock_objects.h" | 11 #include "remoting/protocol/protocol_mock_objects.h" |
10 #include "testing/gtest/include/gtest/gtest.h" | 12 #include "testing/gtest/include/gtest/gtest.h" |
11 | 13 |
12 namespace remoting { | 14 namespace remoting { |
13 | 15 |
14 using protocol::MockClipboardStub; | 16 using protocol::MockClipboardStub; |
15 using protocol::MockConnectionToClient; | 17 using protocol::MockConnectionToClient; |
16 using protocol::MockConnectionToClientEventHandler; | 18 using protocol::MockConnectionToClientEventHandler; |
17 using protocol::MockHostStub; | 19 using protocol::MockHostStub; |
18 using protocol::MockInputStub; | 20 using protocol::MockInputStub; |
19 using protocol::MockSession; | 21 using protocol::MockSession; |
| 22 using protocol::SessionConfig; |
20 | 23 |
21 using testing::_; | 24 using testing::_; |
| 25 using testing::AnyNumber; |
22 using testing::DeleteArg; | 26 using testing::DeleteArg; |
23 using testing::InSequence; | 27 using testing::InSequence; |
24 using testing::Return; | 28 using testing::Return; |
25 using testing::ReturnRef; | 29 using testing::ReturnRef; |
26 | 30 |
27 class ClientSessionTest : public testing::Test { | 31 class ClientSessionTest : public testing::Test { |
28 public: | 32 public: |
29 ClientSessionTest() {} | 33 ClientSessionTest() {} |
30 | 34 |
31 virtual void SetUp() OVERRIDE { | 35 virtual void SetUp() OVERRIDE { |
| 36 message_loop_proxy_ = base::MessageLoopProxy::current(); |
| 37 |
| 38 EXPECT_CALL(context_, ui_task_runner()) |
| 39 .Times(AnyNumber()) |
| 40 .WillRepeatedly(Return(message_loop_proxy_.get())); |
| 41 EXPECT_CALL(context_, capture_task_runner()) |
| 42 .Times(AnyNumber()) |
| 43 .WillRepeatedly(Return(message_loop_proxy_.get())); |
| 44 EXPECT_CALL(context_, encode_task_runner()) |
| 45 .Times(AnyNumber()) |
| 46 .WillRepeatedly(Return(message_loop_proxy_.get())); |
| 47 EXPECT_CALL(context_, network_task_runner()) |
| 48 .Times(AnyNumber()) |
| 49 .WillRepeatedly(Return(message_loop_proxy_.get())); |
| 50 |
32 client_jid_ = "user@domain/rest-of-jid"; | 51 client_jid_ = "user@domain/rest-of-jid"; |
33 | 52 |
| 53 event_executor_ = new MockEventExecutor(); |
| 54 EXPECT_CALL(*event_executor_, StartPtr(_)); |
| 55 EXPECT_CALL(*event_executor_, StopAndDeleteMock()); |
| 56 |
| 57 capturer_ = new MockVideoFrameCapturer(); |
| 58 EXPECT_CALL(*capturer_, Start(_)); |
| 59 EXPECT_CALL(*capturer_, Stop()); |
| 60 EXPECT_CALL(*capturer_, InvalidateRegion(_)).Times(AnyNumber()); |
| 61 EXPECT_CALL(*capturer_, CaptureInvalidRegion(_)).Times(AnyNumber()); |
| 62 |
| 63 scoped_ptr<DesktopEnvironment> desktop_environment(new DesktopEnvironment( |
| 64 scoped_ptr<AudioCapturer>(NULL), |
| 65 scoped_ptr<EventExecutor>(event_executor_), |
| 66 scoped_ptr<VideoFrameCapturer>(capturer_))); |
| 67 |
34 // Set up a large default screen size that won't affect most tests. | 68 // Set up a large default screen size that won't affect most tests. |
35 default_screen_size_.set(1000, 1000); | 69 default_screen_size_.set(1000, 1000); |
36 EXPECT_CALL(capturer_, size_most_recent()) | 70 EXPECT_CALL(*capturer_, size_most_recent()) |
37 .WillRepeatedly(ReturnRef(default_screen_size_)); | 71 .WillRepeatedly(ReturnRef(default_screen_size_)); |
38 | 72 |
| 73 session_config_ = SessionConfig::GetDefault(); |
| 74 |
39 protocol::MockSession* session = new MockSession(); | 75 protocol::MockSession* session = new MockSession(); |
| 76 EXPECT_CALL(*session, config()).WillRepeatedly(ReturnRef(session_config_)); |
40 EXPECT_CALL(*session, jid()).WillRepeatedly(ReturnRef(client_jid_)); | 77 EXPECT_CALL(*session, jid()).WillRepeatedly(ReturnRef(client_jid_)); |
41 EXPECT_CALL(*session, SetEventHandler(_)); | 78 EXPECT_CALL(*session, SetEventHandler(_)); |
42 EXPECT_CALL(*session, Close()); | 79 EXPECT_CALL(*session, Close()); |
43 scoped_ptr<protocol::ConnectionToClient> connection( | 80 scoped_ptr<protocol::ConnectionToClient> connection( |
44 new protocol::ConnectionToClient(session)); | 81 new protocol::ConnectionToClient(session)); |
45 connection_ = connection.get(); | 82 connection_ = connection.get(); |
| 83 |
46 client_session_.reset(new ClientSession( | 84 client_session_.reset(new ClientSession( |
47 &session_event_handler_, connection.Pass(), | 85 &session_event_handler_, |
48 &host_clipboard_stub_, &host_input_stub_, &capturer_, | 86 context_.capture_task_runner(), |
| 87 context_.encode_task_runner(), |
| 88 context_.network_task_runner(), |
| 89 connection.Pass(), |
| 90 desktop_environment.Pass(), |
49 base::TimeDelta())); | 91 base::TimeDelta())); |
50 } | 92 } |
51 | 93 |
52 virtual void TearDown() OVERRIDE { | 94 virtual void TearDown() OVERRIDE { |
53 client_session_.reset(); | 95 // MockClientSessionEventHandler won't trigger StopAndDelete, so fake it. |
| 96 client_session_.release()->StopAndDelete(); |
54 // Run message loop before destroying because protocol::Session is | 97 // Run message loop before destroying because protocol::Session is |
55 // destroyed asynchronously. | 98 // destroyed asynchronously. |
56 message_loop_.RunAllPending(); | 99 message_loop_.RunAllPending(); |
57 } | 100 } |
58 | 101 |
59 protected: | 102 protected: |
60 void DisconnectClientSession() { | 103 void DisconnectClientSession() { |
61 client_session_->Disconnect(); | 104 client_session_->Disconnect(); |
62 // MockSession won't trigger OnConnectionClosed, so fake it. | 105 // MockSession won't trigger OnConnectionClosed, so fake it. |
63 client_session_->OnConnectionClosed(client_session_->connection(), | 106 client_session_->OnConnectionClosed(client_session_->connection(), |
64 protocol::OK); | 107 protocol::OK); |
65 } | 108 } |
66 | 109 |
| 110 MockChromotingHostContext context_; |
| 111 scoped_refptr<base::MessageLoopProxy> message_loop_proxy_; |
67 SkISize default_screen_size_; | 112 SkISize default_screen_size_; |
68 MessageLoop message_loop_; | 113 MessageLoop message_loop_; |
69 std::string client_jid_; | 114 std::string client_jid_; |
70 MockHostStub host_stub_; | 115 MockHostStub host_stub_; |
71 MockClipboardStub host_clipboard_stub_; | 116 MockEventExecutor* event_executor_; |
72 MockInputStub host_input_stub_; | 117 MockVideoFrameCapturer* capturer_; |
73 MockVideoFrameCapturer capturer_; | |
74 MockClientSessionEventHandler session_event_handler_; | 118 MockClientSessionEventHandler session_event_handler_; |
75 scoped_ptr<ClientSession> client_session_; | 119 scoped_ptr<ClientSession> client_session_; |
| 120 SessionConfig session_config_; |
76 | 121 |
77 // ClientSession owns |connection_| but tests need it to inject fake events. | 122 // ClientSession owns |connection_| but tests need it to inject fake events. |
78 protocol::ConnectionToClient* connection_; | 123 protocol::ConnectionToClient* connection_; |
79 }; | 124 }; |
80 | 125 |
81 MATCHER_P2(EqualsClipboardEvent, m, d, "") { | 126 MATCHER_P2(EqualsClipboardEvent, m, d, "") { |
82 return (strcmp(arg.mime_type().c_str(), m) == 0 && | 127 return (strcmp(arg.mime_type().c_str(), m) == 0 && |
83 memcmp(arg.data().data(), d, arg.data().size()) == 0); | 128 memcmp(arg.data().data(), d, arg.data().size()) == 0); |
84 } | 129 } |
85 | 130 |
86 TEST_F(ClientSessionTest, ClipboardStubFilter) { | 131 TEST_F(ClientSessionTest, ClipboardStubFilter) { |
87 protocol::ClipboardEvent clipboard_event1; | 132 protocol::ClipboardEvent clipboard_event1; |
88 clipboard_event1.set_mime_type(kMimeTypeTextUtf8); | 133 clipboard_event1.set_mime_type(kMimeTypeTextUtf8); |
89 clipboard_event1.set_data("a"); | 134 clipboard_event1.set_data("a"); |
90 | 135 |
91 protocol::ClipboardEvent clipboard_event2; | 136 protocol::ClipboardEvent clipboard_event2; |
92 clipboard_event2.set_mime_type(kMimeTypeTextUtf8); | 137 clipboard_event2.set_mime_type(kMimeTypeTextUtf8); |
93 clipboard_event2.set_data("b"); | 138 clipboard_event2.set_data("b"); |
94 | 139 |
95 protocol::ClipboardEvent clipboard_event3; | 140 protocol::ClipboardEvent clipboard_event3; |
96 clipboard_event3.set_mime_type(kMimeTypeTextUtf8); | 141 clipboard_event3.set_mime_type(kMimeTypeTextUtf8); |
97 clipboard_event3.set_data("c"); | 142 clipboard_event3.set_data("c"); |
98 | 143 |
99 InSequence s; | 144 InSequence s; |
100 EXPECT_CALL(session_event_handler_, OnSessionAuthenticated(_)); | 145 EXPECT_CALL(session_event_handler_, OnSessionAuthenticated(_)); |
101 EXPECT_CALL(session_event_handler_, OnSessionChannelsConnected(_)); | 146 EXPECT_CALL(session_event_handler_, OnSessionChannelsConnected(_)); |
102 EXPECT_CALL(host_clipboard_stub_, InjectClipboardEvent(EqualsClipboardEvent( | 147 EXPECT_CALL(*event_executor_, InjectClipboardEvent(EqualsClipboardEvent( |
103 kMimeTypeTextUtf8, "b"))); | 148 kMimeTypeTextUtf8, "b"))); |
104 EXPECT_CALL(session_event_handler_, OnSessionClosed(_)); | 149 EXPECT_CALL(session_event_handler_, OnSessionClosed(_)); |
105 | 150 |
106 // This event should not get through to the clipboard stub, | 151 // This event should not get through to the clipboard stub, |
107 // because the client isn't authenticated yet. | 152 // because the client isn't authenticated yet. |
108 connection_->clipboard_stub()->InjectClipboardEvent(clipboard_event1); | 153 connection_->clipboard_stub()->InjectClipboardEvent(clipboard_event1); |
109 client_session_->OnConnectionAuthenticated(client_session_->connection()); | 154 client_session_->OnConnectionAuthenticated(client_session_->connection()); |
110 client_session_->OnConnectionChannelsConnected(client_session_->connection()); | 155 client_session_->OnConnectionChannelsConnected(client_session_->connection()); |
111 // This event should get through to the clipboard stub. | 156 // This event should get through to the clipboard stub. |
112 connection_->clipboard_stub()->InjectClipboardEvent(clipboard_event2); | 157 connection_->clipboard_stub()->InjectClipboardEvent(clipboard_event2); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 mouse_event2.set_x(200); | 198 mouse_event2.set_x(200); |
154 mouse_event2.set_y(201); | 199 mouse_event2.set_y(201); |
155 | 200 |
156 protocol::MouseEvent mouse_event3; | 201 protocol::MouseEvent mouse_event3; |
157 mouse_event3.set_x(300); | 202 mouse_event3.set_x(300); |
158 mouse_event3.set_y(301); | 203 mouse_event3.set_y(301); |
159 | 204 |
160 InSequence s; | 205 InSequence s; |
161 EXPECT_CALL(session_event_handler_, OnSessionAuthenticated(_)); | 206 EXPECT_CALL(session_event_handler_, OnSessionAuthenticated(_)); |
162 EXPECT_CALL(session_event_handler_, OnSessionChannelsConnected(_)); | 207 EXPECT_CALL(session_event_handler_, OnSessionChannelsConnected(_)); |
163 EXPECT_CALL(host_input_stub_, InjectKeyEvent(EqualsKeyEvent(2, true))); | 208 EXPECT_CALL(*event_executor_, InjectKeyEvent(EqualsKeyEvent(2, true))); |
164 EXPECT_CALL(host_input_stub_, InjectKeyEvent(EqualsKeyEvent(2, false))); | 209 EXPECT_CALL(*event_executor_, InjectKeyEvent(EqualsKeyEvent(2, false))); |
165 EXPECT_CALL(host_input_stub_, InjectMouseEvent(EqualsMouseEvent(200, 201))); | 210 EXPECT_CALL(*event_executor_, InjectMouseEvent(EqualsMouseEvent(200, 201))); |
166 EXPECT_CALL(session_event_handler_, OnSessionClosed(_)); | 211 EXPECT_CALL(session_event_handler_, OnSessionClosed(_)); |
167 | 212 |
168 // These events should not get through to the input stub, | 213 // These events should not get through to the input stub, |
169 // because the client isn't authenticated yet. | 214 // because the client isn't authenticated yet. |
170 connection_->input_stub()->InjectKeyEvent(key_event1); | 215 connection_->input_stub()->InjectKeyEvent(key_event1); |
171 connection_->input_stub()->InjectMouseEvent(mouse_event1); | 216 connection_->input_stub()->InjectMouseEvent(mouse_event1); |
172 client_session_->OnConnectionAuthenticated(client_session_->connection()); | 217 client_session_->OnConnectionAuthenticated(client_session_->connection()); |
173 client_session_->OnConnectionChannelsConnected(client_session_->connection()); | 218 client_session_->OnConnectionChannelsConnected(client_session_->connection()); |
174 // These events should get through to the input stub. | 219 // These events should get through to the input stub. |
175 connection_->input_stub()->InjectKeyEvent(key_event2_down); | 220 connection_->input_stub()->InjectKeyEvent(key_event2_down); |
(...skipping 13 matching lines...) Expand all Loading... |
189 protocol::MouseEvent mouse_event2; | 234 protocol::MouseEvent mouse_event2; |
190 mouse_event2.set_x(200); | 235 mouse_event2.set_x(200); |
191 mouse_event2.set_y(201); | 236 mouse_event2.set_y(201); |
192 protocol::MouseEvent mouse_event3; | 237 protocol::MouseEvent mouse_event3; |
193 mouse_event3.set_x(300); | 238 mouse_event3.set_x(300); |
194 mouse_event3.set_y(301); | 239 mouse_event3.set_y(301); |
195 | 240 |
196 InSequence s; | 241 InSequence s; |
197 EXPECT_CALL(session_event_handler_, OnSessionAuthenticated(_)); | 242 EXPECT_CALL(session_event_handler_, OnSessionAuthenticated(_)); |
198 EXPECT_CALL(session_event_handler_, OnSessionChannelsConnected(_)); | 243 EXPECT_CALL(session_event_handler_, OnSessionChannelsConnected(_)); |
199 EXPECT_CALL(host_input_stub_, InjectMouseEvent(EqualsMouseEvent(100, 101))); | 244 EXPECT_CALL(*event_executor_, InjectMouseEvent(EqualsMouseEvent(100, 101))); |
200 EXPECT_CALL(host_input_stub_, InjectMouseEvent(EqualsMouseEvent(200, 201))); | 245 EXPECT_CALL(*event_executor_, InjectMouseEvent(EqualsMouseEvent(200, 201))); |
201 EXPECT_CALL(session_event_handler_, OnSessionClosed(_)); | 246 EXPECT_CALL(session_event_handler_, OnSessionClosed(_)); |
202 | 247 |
203 client_session_->OnConnectionAuthenticated(client_session_->connection()); | 248 client_session_->OnConnectionAuthenticated(client_session_->connection()); |
204 client_session_->OnConnectionChannelsConnected(client_session_->connection()); | 249 client_session_->OnConnectionChannelsConnected(client_session_->connection()); |
205 // This event should get through to the input stub. | 250 // This event should get through to the input stub. |
206 connection_->input_stub()->InjectMouseEvent(mouse_event1); | 251 connection_->input_stub()->InjectMouseEvent(mouse_event1); |
207 // This one should too because the local event echoes the remote one. | 252 // This one should too because the local event echoes the remote one. |
208 client_session_->LocalMouseMoved(SkIPoint::Make(mouse_event1.x(), | 253 client_session_->LocalMouseMoved(SkIPoint::Make(mouse_event1.x(), |
209 mouse_event1.y())); | 254 mouse_event1.y())); |
210 connection_->input_stub()->InjectMouseEvent(mouse_event2); | 255 connection_->input_stub()->InjectMouseEvent(mouse_event2); |
(...skipping 15 matching lines...) Expand all Loading... |
226 key2.set_pressed(true); | 271 key2.set_pressed(true); |
227 key2.set_keycode(2); | 272 key2.set_keycode(2); |
228 | 273 |
229 protocol::MouseEvent mousedown; | 274 protocol::MouseEvent mousedown; |
230 mousedown.set_button(protocol::MouseEvent::BUTTON_LEFT); | 275 mousedown.set_button(protocol::MouseEvent::BUTTON_LEFT); |
231 mousedown.set_button_down(true); | 276 mousedown.set_button_down(true); |
232 | 277 |
233 InSequence s; | 278 InSequence s; |
234 EXPECT_CALL(session_event_handler_, OnSessionAuthenticated(_)); | 279 EXPECT_CALL(session_event_handler_, OnSessionAuthenticated(_)); |
235 EXPECT_CALL(session_event_handler_, OnSessionChannelsConnected(_)); | 280 EXPECT_CALL(session_event_handler_, OnSessionChannelsConnected(_)); |
236 EXPECT_CALL(host_input_stub_, InjectKeyEvent(EqualsKeyEvent(1, true))); | 281 EXPECT_CALL(*event_executor_, InjectKeyEvent(EqualsKeyEvent(1, true))); |
237 EXPECT_CALL(host_input_stub_, InjectKeyEvent(EqualsKeyEvent(2, true))); | 282 EXPECT_CALL(*event_executor_, InjectKeyEvent(EqualsKeyEvent(2, true))); |
238 EXPECT_CALL(host_input_stub_, InjectMouseEvent(EqualsMouseButtonEvent( | 283 EXPECT_CALL(*event_executor_, InjectMouseEvent(EqualsMouseButtonEvent( |
239 protocol::MouseEvent::BUTTON_LEFT, true))); | 284 protocol::MouseEvent::BUTTON_LEFT, true))); |
240 EXPECT_CALL(host_input_stub_, InjectKeyEvent(EqualsKeyEvent(1, false))); | 285 EXPECT_CALL(*event_executor_, InjectKeyEvent(EqualsKeyEvent(1, false))); |
241 EXPECT_CALL(host_input_stub_, InjectKeyEvent(EqualsKeyEvent(2, false))); | 286 EXPECT_CALL(*event_executor_, InjectKeyEvent(EqualsKeyEvent(2, false))); |
242 EXPECT_CALL(host_input_stub_, InjectMouseEvent(EqualsMouseButtonEvent( | 287 EXPECT_CALL(*event_executor_, InjectMouseEvent(EqualsMouseButtonEvent( |
243 protocol::MouseEvent::BUTTON_LEFT, false))); | 288 protocol::MouseEvent::BUTTON_LEFT, false))); |
244 EXPECT_CALL(session_event_handler_, OnSessionClosed(_)); | 289 EXPECT_CALL(session_event_handler_, OnSessionClosed(_)); |
245 | 290 |
246 client_session_->OnConnectionAuthenticated(client_session_->connection()); | 291 client_session_->OnConnectionAuthenticated(client_session_->connection()); |
247 client_session_->OnConnectionChannelsConnected(client_session_->connection()); | 292 client_session_->OnConnectionChannelsConnected(client_session_->connection()); |
248 | 293 |
249 connection_->input_stub()->InjectKeyEvent(key1); | 294 connection_->input_stub()->InjectKeyEvent(key1); |
250 connection_->input_stub()->InjectKeyEvent(key2); | 295 connection_->input_stub()->InjectKeyEvent(key2); |
251 connection_->input_stub()->InjectMouseEvent(mousedown); | 296 connection_->input_stub()->InjectMouseEvent(mousedown); |
252 | 297 |
253 DisconnectClientSession(); | 298 DisconnectClientSession(); |
254 } | 299 } |
255 | 300 |
256 TEST_F(ClientSessionTest, ClampMouseEvents) { | 301 TEST_F(ClientSessionTest, ClampMouseEvents) { |
257 SkISize screen(SkISize::Make(200, 100)); | 302 SkISize screen(SkISize::Make(200, 100)); |
258 EXPECT_CALL(capturer_, size_most_recent()) | 303 EXPECT_CALL(*capturer_, size_most_recent()) |
259 .WillRepeatedly(ReturnRef(screen)); | 304 .WillRepeatedly(ReturnRef(screen)); |
260 | 305 |
261 EXPECT_CALL(session_event_handler_, OnSessionAuthenticated(_)); | 306 EXPECT_CALL(session_event_handler_, OnSessionAuthenticated(_)); |
262 EXPECT_CALL(session_event_handler_, OnSessionChannelsConnected(_)); | 307 EXPECT_CALL(session_event_handler_, OnSessionChannelsConnected(_)); |
263 EXPECT_CALL(session_event_handler_, OnSessionClosed(_)); | 308 EXPECT_CALL(session_event_handler_, OnSessionClosed(_)); |
264 | 309 |
265 client_session_->OnConnectionAuthenticated(client_session_->connection()); | 310 client_session_->OnConnectionAuthenticated(client_session_->connection()); |
266 client_session_->OnConnectionChannelsConnected(client_session_->connection()); | 311 client_session_->OnConnectionChannelsConnected(client_session_->connection()); |
267 | 312 |
268 int input_x[3] = { -999, 100, 999 }; | 313 int input_x[3] = { -999, 100, 999 }; |
269 int expected_x[3] = { 0, 100, 199 }; | 314 int expected_x[3] = { 0, 100, 199 }; |
270 int input_y[3] = { -999, 50, 999 }; | 315 int input_y[3] = { -999, 50, 999 }; |
271 int expected_y[3] = { 0, 50, 99 }; | 316 int expected_y[3] = { 0, 50, 99 }; |
272 | 317 |
273 protocol::MouseEvent event; | 318 protocol::MouseEvent event; |
274 for (int j = 0; j < 3; j++) { | 319 for (int j = 0; j < 3; j++) { |
275 for (int i = 0; i < 3; i++) { | 320 for (int i = 0; i < 3; i++) { |
276 event.set_x(input_x[i]); | 321 event.set_x(input_x[i]); |
277 event.set_y(input_y[j]); | 322 event.set_y(input_y[j]); |
278 EXPECT_CALL(host_input_stub_, InjectMouseEvent(EqualsMouseEvent( | 323 EXPECT_CALL(*event_executor_, InjectMouseEvent(EqualsMouseEvent( |
279 expected_x[i], expected_y[j]))); | 324 expected_x[i], expected_y[j]))); |
280 connection_->input_stub()->InjectMouseEvent(event); | 325 connection_->input_stub()->InjectMouseEvent(event); |
281 } | 326 } |
282 } | 327 } |
283 | 328 |
284 DisconnectClientSession(); | 329 DisconnectClientSession(); |
285 } | 330 } |
286 | 331 |
287 } // namespace remoting | 332 } // namespace remoting |
OLD | NEW |