This source file includes following definitions.
- InjectSas
- event_handler_
- Connect
- Disconnect
- InjectSas
- OnConnected
- OnDisconnected
- NotifyConnected
- NotifyClosed
#include "remoting/host/win/rdp_client.h"
#include <windows.h>
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/logging.h"
#include "base/single_thread_task_runner.h"
#include "base/win/registry.h"
#include "net/base/ip_endpoint.h"
#include "remoting/base/typed_buffer.h"
#include "remoting/host/win/rdp_client_window.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
namespace remoting {
namespace {
const unsigned char kRdpLoopbackAddress[] = { 127, 0, 0, 2 };
const int kDefaultRdpPort = 3389;
const wchar_t kRdpPortKeyName[] = L"SYSTEM\\CurrentControlSet\\Control\\"
L"Terminal Server\\WinStations\\RDP-Tcp";
const wchar_t kRdpPortValueName[] = L"PortNumber";
}
class RdpClient::Core
: public base::RefCountedThreadSafe<Core>,
public RdpClientWindow::EventHandler {
public:
Core(
scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
RdpClient::EventHandler* event_handler);
void Connect(const webrtc::DesktopSize& screen_size,
const std::string& terminal_id);
void Disconnect();
void InjectSas();
virtual void OnConnected() OVERRIDE;
virtual void OnDisconnected() OVERRIDE;
private:
friend class base::RefCountedThreadSafe<Core>;
virtual ~Core();
void NotifyConnected();
void NotifyClosed();
scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_;
scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_;
RdpClient::EventHandler* event_handler_;
scoped_ptr<RdpClientWindow> rdp_client_window_;
scoped_refptr<Core> self_;
DISALLOW_COPY_AND_ASSIGN(Core);
};
RdpClient::RdpClient(
scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
const webrtc::DesktopSize& screen_size,
const std::string& terminal_id,
EventHandler* event_handler) {
DCHECK(caller_task_runner->BelongsToCurrentThread());
core_ = new Core(caller_task_runner, ui_task_runner, event_handler);
core_->Connect(screen_size, terminal_id);
}
RdpClient::~RdpClient() {
DCHECK(CalledOnValidThread());
core_->Disconnect();
}
void RdpClient::InjectSas() {
DCHECK(CalledOnValidThread());
core_->InjectSas();
}
RdpClient::Core::Core(
scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
RdpClient::EventHandler* event_handler)
: caller_task_runner_(caller_task_runner),
ui_task_runner_(ui_task_runner),
event_handler_(event_handler) {
}
void RdpClient::Core::Connect(const webrtc::DesktopSize& screen_size,
const std::string& terminal_id) {
if (!ui_task_runner_->BelongsToCurrentThread()) {
ui_task_runner_->PostTask(
FROM_HERE, base::Bind(&Core::Connect, this, screen_size, terminal_id));
return;
}
DCHECK(base::MessageLoopForUI::IsCurrent());
DCHECK(!rdp_client_window_);
DCHECK(!self_);
DWORD server_port;
base::win::RegKey key(HKEY_LOCAL_MACHINE, kRdpPortKeyName, KEY_READ);
if (!key.Valid() ||
(key.ReadValueDW(kRdpPortValueName, &server_port) != ERROR_SUCCESS)) {
server_port = kDefaultRdpPort;
}
net::IPAddressNumber server_address(
kRdpLoopbackAddress,
kRdpLoopbackAddress + arraysize(kRdpLoopbackAddress));
net::IPEndPoint server_endpoint(server_address, server_port);
rdp_client_window_.reset(new RdpClientWindow(server_endpoint, terminal_id,
this));
if (!rdp_client_window_->Connect(screen_size)) {
rdp_client_window_.reset();
NotifyClosed();
}
}
void RdpClient::Core::Disconnect() {
if (!ui_task_runner_->BelongsToCurrentThread()) {
ui_task_runner_->PostTask(FROM_HERE, base::Bind(&Core::Disconnect, this));
return;
}
event_handler_ = NULL;
if (rdp_client_window_) {
self_ = this;
rdp_client_window_->Disconnect();
}
}
void RdpClient::Core::InjectSas() {
if (!ui_task_runner_->BelongsToCurrentThread()) {
ui_task_runner_->PostTask(FROM_HERE, base::Bind(&Core::InjectSas, this));
return;
}
if (rdp_client_window_)
rdp_client_window_->InjectSas();
}
void RdpClient::Core::OnConnected() {
DCHECK(ui_task_runner_->BelongsToCurrentThread());
DCHECK(rdp_client_window_);
NotifyConnected();
}
void RdpClient::Core::OnDisconnected() {
DCHECK(ui_task_runner_->BelongsToCurrentThread());
DCHECK(rdp_client_window_);
NotifyClosed();
ui_task_runner_->DeleteSoon(FROM_HERE, rdp_client_window_.release());
self_ = NULL;
}
RdpClient::Core::~Core() {
DCHECK(!event_handler_);
DCHECK(!rdp_client_window_);
}
void RdpClient::Core::NotifyConnected() {
if (!caller_task_runner_->BelongsToCurrentThread()) {
caller_task_runner_->PostTask(
FROM_HERE, base::Bind(&Core::NotifyConnected, this));
return;
}
if (event_handler_)
event_handler_->OnRdpConnected();
}
void RdpClient::Core::NotifyClosed() {
if (!caller_task_runner_->BelongsToCurrentThread()) {
caller_task_runner_->PostTask(
FROM_HERE, base::Bind(&Core::NotifyClosed, this));
return;
}
if (event_handler_) {
RdpClient::EventHandler* event_handler = event_handler_;
event_handler_ = NULL;
event_handler->OnRdpClosed();
}
}
}