1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file. 4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "remoting/host/host_window_proxy.h" 6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/bind.h" 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/location.h" 9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/logging.h" 10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/single_thread_task_runner.h" 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "remoting/host/client_session_control.h" 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h" 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace remoting { 15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Runs an instance of |HostWindow| on the |ui_task_runner_| thread. 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class HostWindowProxy::Core 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : public base::RefCountedThreadSafe<Core>, 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public ClientSessionControl { 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Core(scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, 22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<HostWindow> host_window); 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Starts |host_window_| on the |ui_task_runner_| thread. 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void Start(const base::WeakPtr<ClientSessionControl>& client_session_control); 27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Destroys |host_window_| on the |ui_task_runner_| thread. 29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void Stop(); 30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private: 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) friend class base::RefCountedThreadSafe<Core>; 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual ~Core(); 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Start() and Stop() equivalents called on the |ui_task_runner_| thread. 36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void StartOnUiThread(const std::string& client_jid); 37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void StopOnUiThread(); 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // ClientSessionControl interface. 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual const std::string& client_jid() const OVERRIDE; 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void DisconnectSession() OVERRIDE; 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void OnLocalMouseMoved( 435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const webrtc::DesktopVector& position) OVERRIDE; 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void SetDisableInputs(bool disable_inputs) OVERRIDE; 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Task runner on which public methods of this class must be called. 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_; 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Task runner on which |host_window_| is running. 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_; 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Stores the client's JID so it can be read on the |ui_task_runner_| thread. 53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string client_jid_; 54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Used to notify the caller about the local user's actions on 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // the |caller_task_runner| thread. 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::WeakPtr<ClientSessionControl> client_session_control_; 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The wrapped |HostWindow| instance running on the |ui_task_runner_| thread. 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<HostWindow> host_window_; 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Used to create the control pointer passed to |host_window_|. 63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::WeakPtrFactory<ClientSessionControl> weak_factory_; 64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(Core); 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)HostWindowProxy::HostWindowProxy( 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<HostWindow> host_window) { 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(caller_task_runner->BelongsToCurrentThread()); 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Detach |host_window| from the calling thread so that |Core| could run it on 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // the |ui_task_runner_| thread. 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) host_window->DetachFromThread(); 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) core_ = new Core(caller_task_runner, ui_task_runner, host_window.Pass()); 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)HostWindowProxy::~HostWindowProxy() { 81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(CalledOnValidThread()); 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) core_->Stop(); 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void HostWindowProxy::Start( 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::WeakPtr<ClientSessionControl>& client_session_control) { 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(CalledOnValidThread()); 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) core_->Start(client_session_control); 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)HostWindowProxy::Core::Core( 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<HostWindow> host_window) 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : caller_task_runner_(caller_task_runner), 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ui_task_runner_(ui_task_runner), 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) host_window_(host_window.Pass()), 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) weak_factory_(this) { 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(caller_task_runner->BelongsToCurrentThread()); 102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void HostWindowProxy::Core::Start( 105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::WeakPtr<ClientSessionControl>& client_session_control) { 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(caller_task_runner_->BelongsToCurrentThread()); 107868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!client_session_control_.get()); 108868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(client_session_control.get()); 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) client_session_control_ = client_session_control; 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ui_task_runner_->PostTask( 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, base::Bind(&Core::StartOnUiThread, this, 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) client_session_control->client_jid())); 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void HostWindowProxy::Core::Stop() { 117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(caller_task_runner_->BelongsToCurrentThread()); 118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ui_task_runner_->PostTask(FROM_HERE, base::Bind(&Core::StopOnUiThread, this)); 120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)HostWindowProxy::Core::~Core() { 123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!host_window_); 124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void HostWindowProxy::Core::StartOnUiThread(const std::string& client_jid) { 127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(ui_task_runner_->BelongsToCurrentThread()); 128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(client_jid_.empty()); 129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) client_jid_ = client_jid; 131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) host_window_->Start(weak_factory_.GetWeakPtr()); 132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void HostWindowProxy::Core::StopOnUiThread() { 135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(ui_task_runner_->BelongsToCurrentThread()); 136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) host_window_.reset(); 138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const std::string& HostWindowProxy::Core::client_jid() const { 141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(ui_task_runner_->BelongsToCurrentThread()); 142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return client_jid_; 144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void HostWindowProxy::Core::DisconnectSession() { 147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!caller_task_runner_->BelongsToCurrentThread()) { 148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) caller_task_runner_->PostTask(FROM_HERE, 149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&Core::DisconnectSession, this)); 150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 153868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (client_session_control_.get()) 154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) client_session_control_->DisconnectSession(); 155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void HostWindowProxy::Core::OnLocalMouseMoved( 1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const webrtc::DesktopVector& position) { 159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!caller_task_runner_->BelongsToCurrentThread()) { 160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) caller_task_runner_->PostTask( 161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, base::Bind(&Core::OnLocalMouseMoved, this, position)); 162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 165868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (client_session_control_.get()) 166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) client_session_control_->OnLocalMouseMoved(position); 167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void HostWindowProxy::Core::SetDisableInputs(bool disable_inputs) { 170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!caller_task_runner_->BelongsToCurrentThread()) { 171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) caller_task_runner_->PostTask( 172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, base::Bind(&Core::SetDisableInputs, this, disable_inputs)); 173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 176868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (client_session_control_.get()) 177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) client_session_control_->SetDisableInputs(disable_inputs); 178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace remoting 181