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 "remoting/client/plugin/chromoting_instance.h" | 5 #include "remoting/client/plugin/chromoting_instance.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 21 matching lines...) Expand all Loading... |
32 #include "remoting/client/chromoting_client.h" | 32 #include "remoting/client/chromoting_client.h" |
33 #include "remoting/client/frame_consumer_proxy.h" | 33 #include "remoting/client/frame_consumer_proxy.h" |
34 #include "remoting/client/plugin/pepper_audio_player.h" | 34 #include "remoting/client/plugin/pepper_audio_player.h" |
35 #include "remoting/client/plugin/pepper_input_handler.h" | 35 #include "remoting/client/plugin/pepper_input_handler.h" |
36 #include "remoting/client/plugin/pepper_port_allocator.h" | 36 #include "remoting/client/plugin/pepper_port_allocator.h" |
37 #include "remoting/client/plugin/pepper_view.h" | 37 #include "remoting/client/plugin/pepper_view.h" |
38 #include "remoting/client/plugin/pepper_xmpp_proxy.h" | 38 #include "remoting/client/plugin/pepper_xmpp_proxy.h" |
39 #include "remoting/client/rectangle_update_decoder.h" | 39 #include "remoting/client/rectangle_update_decoder.h" |
40 #include "remoting/protocol/connection_to_host.h" | 40 #include "remoting/protocol/connection_to_host.h" |
41 #include "remoting/protocol/host_stub.h" | 41 #include "remoting/protocol/host_stub.h" |
42 #include "remoting/protocol/input_event_tracker.h" | |
43 #include "remoting/protocol/libjingle_transport_factory.h" | 42 #include "remoting/protocol/libjingle_transport_factory.h" |
44 #include "remoting/protocol/mouse_input_filter.h" | |
45 | 43 |
46 // Windows defines 'PostMessage', so we have to undef it. | 44 // Windows defines 'PostMessage', so we have to undef it. |
47 #if defined(PostMessage) | 45 #if defined(PostMessage) |
48 #undef PostMessage | 46 #undef PostMessage |
49 #endif | 47 #endif |
50 | 48 |
51 namespace remoting { | 49 namespace remoting { |
52 | 50 |
53 namespace { | 51 namespace { |
54 | 52 |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
148 | 146 |
149 return true; | 147 return true; |
150 } | 148 } |
151 | 149 |
152 ChromotingInstance::ChromotingInstance(PP_Instance pp_instance) | 150 ChromotingInstance::ChromotingInstance(PP_Instance pp_instance) |
153 : pp::Instance(pp_instance), | 151 : pp::Instance(pp_instance), |
154 initialized_(false), | 152 initialized_(false), |
155 plugin_task_runner_( | 153 plugin_task_runner_( |
156 new PluginThreadTaskRunner(&plugin_thread_delegate_)), | 154 new PluginThreadTaskRunner(&plugin_thread_delegate_)), |
157 context_(plugin_task_runner_), | 155 context_(plugin_task_runner_), |
| 156 input_tracker_(&mouse_input_filter_), |
| 157 #if defined(OS_MACOSX) |
| 158 // On Mac we need an extra filter to inject missing keyup events. |
| 159 // See remoting/client/plugin/mac_key_event_processor.h for more details. |
| 160 mac_key_event_processor_(&input_tracker_), |
| 161 key_mapper_(&mac_key_event_processor_), |
| 162 #else |
| 163 key_mapper_(&input_tracker_), |
| 164 #endif |
| 165 input_handler_(&key_mapper_), |
158 weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { | 166 weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { |
159 RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE | PP_INPUTEVENT_CLASS_WHEEL); | 167 RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE | PP_INPUTEVENT_CLASS_WHEEL); |
160 RequestFilteringInputEvents(PP_INPUTEVENT_CLASS_KEYBOARD); | 168 RequestFilteringInputEvents(PP_INPUTEVENT_CLASS_KEYBOARD); |
161 | 169 |
162 // Resister this instance to handle debug log messsages. | 170 // Resister this instance to handle debug log messsages. |
163 RegisterLoggingInstance(); | 171 RegisterLoggingInstance(); |
164 | 172 |
165 // Send hello message. | 173 // Send hello message. |
166 scoped_ptr<base::DictionaryValue> data(new base::DictionaryValue()); | 174 scoped_ptr<base::DictionaryValue> data(new base::DictionaryValue()); |
167 data->SetInteger("apiVersion", kApiVersion); | 175 data->SetInteger("apiVersion", kApiVersion); |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
339 } | 347 } |
340 PauseVideo(pause); | 348 PauseVideo(pause); |
341 } | 349 } |
342 } | 350 } |
343 | 351 |
344 void ChromotingInstance::DidChangeView(const pp::View& view) { | 352 void ChromotingInstance::DidChangeView(const pp::View& view) { |
345 DCHECK(plugin_task_runner_->BelongsToCurrentThread()); | 353 DCHECK(plugin_task_runner_->BelongsToCurrentThread()); |
346 | 354 |
347 view_->SetView(view); | 355 view_->SetView(view); |
348 | 356 |
349 if (mouse_input_filter_.get()) { | 357 mouse_input_filter_.set_input_size(view_->get_view_size_dips()); |
350 mouse_input_filter_->set_input_size(view_->get_view_size_dips()); | |
351 } | |
352 } | 358 } |
353 | 359 |
354 bool ChromotingInstance::HandleInputEvent(const pp::InputEvent& event) { | 360 bool ChromotingInstance::HandleInputEvent(const pp::InputEvent& event) { |
355 DCHECK(plugin_task_runner_->BelongsToCurrentThread()); | 361 DCHECK(plugin_task_runner_->BelongsToCurrentThread()); |
356 | 362 |
357 if (!IsConnected()) | 363 if (!IsConnected()) |
358 return false; | 364 return false; |
359 | 365 |
360 // TODO(wez): When we have a good hook into Host dimensions changes, move | 366 // TODO(wez): When we have a good hook into Host dimensions changes, move |
361 // this there. | 367 // this there. |
362 // If |input_handler_| is valid, then |mouse_input_filter_| must also be | 368 mouse_input_filter_.set_output_size(view_->get_screen_size()); |
363 // since they are constructed together as part of the input pipeline | |
364 mouse_input_filter_->set_output_size(view_->get_screen_size()); | |
365 | 369 |
366 return input_handler_->HandleInputEvent(event); | 370 return input_handler_.HandleInputEvent(event); |
367 } | 371 } |
368 | 372 |
369 void ChromotingInstance::SetDesktopSize(const SkISize& size, | 373 void ChromotingInstance::SetDesktopSize(const SkISize& size, |
370 const SkIPoint& dpi) { | 374 const SkIPoint& dpi) { |
371 scoped_ptr<base::DictionaryValue> data(new base::DictionaryValue()); | 375 scoped_ptr<base::DictionaryValue> data(new base::DictionaryValue()); |
372 data->SetInteger("width", size.width()); | 376 data->SetInteger("width", size.width()); |
373 data->SetInteger("height", size.height()); | 377 data->SetInteger("height", size.height()); |
374 if (dpi.x()) | 378 if (dpi.x()) |
375 data->SetInteger("x_dpi", dpi.x()); | 379 data->SetInteger("x_dpi", dpi.x()); |
376 if (dpi.y()) | 380 if (dpi.y()) |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
469 | 473 |
470 jingle_glue::JingleThreadWrapper::EnsureForCurrentThread(); | 474 jingle_glue::JingleThreadWrapper::EnsureForCurrentThread(); |
471 | 475 |
472 host_connection_.reset(new protocol::ConnectionToHost(true)); | 476 host_connection_.reset(new protocol::ConnectionToHost(true)); |
473 scoped_ptr<AudioPlayer> audio_player(new PepperAudioPlayer(this)); | 477 scoped_ptr<AudioPlayer> audio_player(new PepperAudioPlayer(this)); |
474 client_.reset(new ChromotingClient(config, &context_, | 478 client_.reset(new ChromotingClient(config, &context_, |
475 host_connection_.get(), this, | 479 host_connection_.get(), this, |
476 rectangle_decoder_.get(), | 480 rectangle_decoder_.get(), |
477 audio_player.Pass())); | 481 audio_player.Pass())); |
478 | 482 |
479 // Construct the input pipeline | 483 // Connect the input pipeline to the protocol stub & initialize components. |
480 mouse_input_filter_.reset( | 484 mouse_input_filter_.set_input_stub(host_connection_->input_stub()); |
481 new protocol::MouseInputFilter(host_connection_->input_stub())); | 485 mouse_input_filter_.set_input_size(view_->get_view_size_dips()); |
482 mouse_input_filter_->set_input_size(view_->get_view_size_dips()); | |
483 input_tracker_.reset( | |
484 new protocol::InputEventTracker(mouse_input_filter_.get())); | |
485 | |
486 #if defined(OS_MACOSX) | |
487 // On Mac we need an extra filter to inject missing keyup events. | |
488 // See remoting/client/plugin/mac_key_event_processor.h for more details. | |
489 mac_key_event_processor_.reset( | |
490 new MacKeyEventProcessor(input_tracker_.get())); | |
491 key_mapper_.set_input_stub(mac_key_event_processor_.get()); | |
492 #else | |
493 key_mapper_.set_input_stub(input_tracker_.get()); | |
494 #endif | |
495 input_handler_.reset( | |
496 new PepperInputHandler(&key_mapper_)); | |
497 | 486 |
498 LOG(INFO) << "Connecting to " << config.host_jid | 487 LOG(INFO) << "Connecting to " << config.host_jid |
499 << ". Local jid: " << config.local_jid << "."; | 488 << ". Local jid: " << config.local_jid << "."; |
500 | 489 |
501 // Setup the XMPP Proxy. | 490 // Setup the XMPP Proxy. |
502 xmpp_proxy_ = new PepperXmppProxy( | 491 xmpp_proxy_ = new PepperXmppProxy( |
503 base::Bind(&ChromotingInstance::SendOutgoingIq, AsWeakPtr()), | 492 base::Bind(&ChromotingInstance::SendOutgoingIq, AsWeakPtr()), |
504 plugin_task_runner_, context_.main_task_runner()); | 493 plugin_task_runner_, context_.main_task_runner()); |
505 | 494 |
506 scoped_ptr<cricket::HttpPortAllocatorBase> port_allocator( | 495 scoped_ptr<cricket::HttpPortAllocatorBase> port_allocator( |
(...skipping 19 matching lines...) Expand all Loading... |
526 LOG(INFO) << "Disconnecting from host."; | 515 LOG(INFO) << "Disconnecting from host."; |
527 if (client_.get()) { | 516 if (client_.get()) { |
528 // TODO(sergeyu): Should we disconnect asynchronously? | 517 // TODO(sergeyu): Should we disconnect asynchronously? |
529 base::WaitableEvent done_event(true, false); | 518 base::WaitableEvent done_event(true, false); |
530 client_->Stop(base::Bind(&base::WaitableEvent::Signal, | 519 client_->Stop(base::Bind(&base::WaitableEvent::Signal, |
531 base::Unretained(&done_event))); | 520 base::Unretained(&done_event))); |
532 done_event.Wait(); | 521 done_event.Wait(); |
533 client_.reset(); | 522 client_.reset(); |
534 } | 523 } |
535 | 524 |
536 input_handler_.reset(); | 525 // Disconnect the input pipeline and teardown the connection. |
537 input_tracker_.reset(); | 526 mouse_input_filter_.set_input_stub(NULL); |
538 mouse_input_filter_.reset(); | |
539 host_connection_.reset(); | 527 host_connection_.reset(); |
540 } | 528 } |
541 | 529 |
542 void ChromotingInstance::OnIncomingIq(const std::string& iq) { | 530 void ChromotingInstance::OnIncomingIq(const std::string& iq) { |
543 xmpp_proxy_->OnIq(iq); | 531 xmpp_proxy_->OnIq(iq); |
544 } | 532 } |
545 | 533 |
546 void ChromotingInstance::ReleaseAllKeys() { | 534 void ChromotingInstance::ReleaseAllKeys() { |
547 if (IsConnected()) | 535 if (IsConnected()) |
548 input_tracker_->ReleaseAll(); | 536 input_tracker_.ReleaseAll(); |
549 } | 537 } |
550 | 538 |
551 void ChromotingInstance::InjectKeyEvent(const protocol::KeyEvent& event) { | 539 void ChromotingInstance::InjectKeyEvent(const protocol::KeyEvent& event) { |
552 // Inject after the KeyEventMapper, so the event won't get mapped or trapped. | 540 // Inject after the KeyEventMapper, so the event won't get mapped or trapped. |
553 if (IsConnected()) | 541 if (IsConnected()) |
554 input_tracker_->InjectKeyEvent(event); | 542 input_tracker_.InjectKeyEvent(event); |
555 } | 543 } |
556 | 544 |
557 void ChromotingInstance::RemapKey(uint32 in_usb_keycode, | 545 void ChromotingInstance::RemapKey(uint32 in_usb_keycode, |
558 uint32 out_usb_keycode) { | 546 uint32 out_usb_keycode) { |
559 key_mapper_.RemapKey(in_usb_keycode, out_usb_keycode); | 547 key_mapper_.RemapKey(in_usb_keycode, out_usb_keycode); |
560 } | 548 } |
561 | 549 |
562 void ChromotingInstance::TrapKey(uint32 usb_keycode, bool trap) { | 550 void ChromotingInstance::TrapKey(uint32 usb_keycode, bool trap) { |
563 key_mapper_.TrapKey(usb_keycode, trap); | 551 key_mapper_.TrapKey(usb_keycode, trap); |
564 } | 552 } |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
746 PostChromotingMessage("logDebugMessage", data.Pass()); | 734 PostChromotingMessage("logDebugMessage", data.Pass()); |
747 g_logging_to_plugin = false; | 735 g_logging_to_plugin = false; |
748 } | 736 } |
749 | 737 |
750 bool ChromotingInstance::IsConnected() { | 738 bool ChromotingInstance::IsConnected() { |
751 return host_connection_.get() && | 739 return host_connection_.get() && |
752 (host_connection_->state() == protocol::ConnectionToHost::CONNECTED); | 740 (host_connection_->state() == protocol::ConnectionToHost::CONNECTED); |
753 } | 741 } |
754 | 742 |
755 } // namespace remoting | 743 } // namespace remoting |
OLD | NEW |