#include "remoting/host/host_user_interface.h"
#include "base/bind.h"
#include "remoting/host/chromoting_host.h"
#include "remoting/host/chromoting_host_context.h"
#include "remoting/host/disconnect_window.h"
#include "remoting/host/local_input_monitor.h"
namespace remoting {
HostUserInterface::HostUserInterface(ChromotingHostContext* context)
: host_(NULL),
context_(context),
is_monitoring_local_inputs_(false),
ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)),
weak_ptr_(weak_factory_.GetWeakPtr()) {
DCHECK(ui_task_runner()->BelongsToCurrentThread());
}
HostUserInterface::~HostUserInterface() {
DCHECK(ui_task_runner()->BelongsToCurrentThread());
MonitorLocalInputs(false);
ShowDisconnectWindow(false, std::string());
}
void HostUserInterface::Start(ChromotingHost* host,
const base::Closure& disconnect_callback) {
DCHECK(network_task_runner()->BelongsToCurrentThread());
DCHECK(host_ == NULL);
host_ = host;
disconnect_callback_ = disconnect_callback;
disconnect_window_ = DisconnectWindow::Create();
local_input_monitor_ = LocalInputMonitor::Create();
host_->AddStatusObserver(this);
}
void HostUserInterface::OnClientAuthenticated(const std::string& jid) {
DCHECK(network_task_runner()->BelongsToCurrentThread());
authenticated_jid_ = jid;
std::string username = jid.substr(0, jid.find('/'));
ui_task_runner()->PostTask(FROM_HERE, base::Bind(
&HostUserInterface::ProcessOnClientAuthenticated,
weak_ptr_, username));
}
void HostUserInterface::OnClientDisconnected(const std::string& jid) {
DCHECK(network_task_runner()->BelongsToCurrentThread());
if (jid == authenticated_jid_) {
ui_task_runner()->PostTask(FROM_HERE, base::Bind(
&HostUserInterface::ProcessOnClientDisconnected,
weak_ptr_));
}
}
void HostUserInterface::OnAccessDenied(const std::string& jid) {
}
void HostUserInterface::OnShutdown() {
DCHECK(network_task_runner()->BelongsToCurrentThread());
host_->RemoveStatusObserver(this);
host_ = NULL;
}
void HostUserInterface::OnDisconnectCallback() {
DCHECK(ui_task_runner()->BelongsToCurrentThread());
MonitorLocalInputs(false);
ShowDisconnectWindow(false, std::string());
DisconnectSession();
}
base::SingleThreadTaskRunner* HostUserInterface::network_task_runner() const {
return context_->network_task_runner();
}
base::SingleThreadTaskRunner* HostUserInterface::ui_task_runner() const {
return context_->ui_task_runner();
}
void HostUserInterface::DisconnectSession() const {
DCHECK(ui_task_runner()->BelongsToCurrentThread());
disconnect_callback_.Run();
}
void HostUserInterface::ProcessOnClientAuthenticated(
const std::string& username) {
DCHECK(ui_task_runner()->BelongsToCurrentThread());
MonitorLocalInputs(true);
ShowDisconnectWindow(true, username);
}
void HostUserInterface::ProcessOnClientDisconnected() {
DCHECK(ui_task_runner()->BelongsToCurrentThread());
MonitorLocalInputs(false);
ShowDisconnectWindow(false, std::string());
}
void HostUserInterface::StartForTest(
ChromotingHost* host,
const base::Closure& disconnect_callback,
scoped_ptr<DisconnectWindow> disconnect_window,
scoped_ptr<LocalInputMonitor> local_input_monitor) {
DCHECK(network_task_runner()->BelongsToCurrentThread());
DCHECK(host_ == NULL);
host_ = host;
disconnect_callback_ = disconnect_callback;
disconnect_window_ = disconnect_window.Pass();
local_input_monitor_ = local_input_monitor.Pass();
}
void HostUserInterface::MonitorLocalInputs(bool enable) {
DCHECK(ui_task_runner()->BelongsToCurrentThread());
if (enable != is_monitoring_local_inputs_) {
if (enable) {
local_input_monitor_->Start(host_, disconnect_callback_);
} else {
local_input_monitor_->Stop();
}
is_monitoring_local_inputs_ = enable;
}
}
void HostUserInterface::ShowDisconnectWindow(bool show,
const std::string& username) {
DCHECK(ui_task_runner()->BelongsToCurrentThread());
if (show) {
disconnect_window_->Show(
host_,
base::Bind(&HostUserInterface::OnDisconnectCallback, weak_ptr_),
username);
} else {
disconnect_window_->Hide();
}
}
}