blob: e380810d2094deac7d6f368dd1b084d6439f81da [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "remoting/host/input_monitor/local_input_monitor.h"
#include <utility>
#include "base/bind.h"
#include "base/callback.h"
#include "base/memory/ref_counted.h"
#include "base/single_thread_task_runner.h"
#include "remoting/host/client_session_control.h"
#include "remoting/host/input_monitor/local_hotkey_input_monitor.h"
#include "remoting/host/input_monitor/local_keyboard_input_monitor.h"
#include "remoting/host/input_monitor/local_pointer_input_monitor.h"
namespace remoting {
namespace {
class LocalInputMonitorImpl : public LocalInputMonitor {
public:
LocalInputMonitorImpl(
scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> input_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner);
~LocalInputMonitorImpl() override;
// LocalInputMonitor implementation.
void StartMonitoringForClientSession(
base::WeakPtr<ClientSessionControl> client_session_control) override;
void StartMonitoring(PointerMoveCallback on_pointer_input,
base::RepeatingClosure on_keyboard_input,
base::RepeatingClosure on_error) override;
private:
void OnMonitoringStarted();
scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_;
scoped_refptr<base::SingleThreadTaskRunner> input_task_runner_;
scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_;
std::unique_ptr<LocalHotkeyInputMonitor> hotkey_input_monitor_;
std::unique_ptr<LocalKeyboardInputMonitor> keyboard_input_monitor_;
std::unique_ptr<LocalPointerInputMonitor> pointer_input_monitor_;
// Indicates whether the instance is actively monitoring local input.
bool monitoring_ = false;
DISALLOW_COPY_AND_ASSIGN(LocalInputMonitorImpl);
};
LocalInputMonitorImpl::LocalInputMonitorImpl(
scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> input_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner)
: caller_task_runner_(caller_task_runner),
input_task_runner_(input_task_runner),
ui_task_runner_(ui_task_runner) {}
LocalInputMonitorImpl::~LocalInputMonitorImpl() {
// LocalInputMonitor sub-classes expect to be torn down on the caller thread.
if (!caller_task_runner_->BelongsToCurrentThread()) {
if (hotkey_input_monitor_)
caller_task_runner_->DeleteSoon(FROM_HERE,
hotkey_input_monitor_.release());
if (keyboard_input_monitor_)
caller_task_runner_->DeleteSoon(FROM_HERE,
keyboard_input_monitor_.release());
if (pointer_input_monitor_)
caller_task_runner_->DeleteSoon(FROM_HERE,
pointer_input_monitor_.release());
}
caller_task_runner_ = nullptr;
}
void LocalInputMonitorImpl::StartMonitoringForClientSession(
base::WeakPtr<ClientSessionControl> client_session_control) {
DCHECK(!monitoring_);
hotkey_input_monitor_ = LocalHotkeyInputMonitor::Create(
caller_task_runner_, input_task_runner_, ui_task_runner_,
base::BindOnce(&ClientSessionControl::DisconnectSession,
client_session_control, protocol::OK));
pointer_input_monitor_ = LocalPointerInputMonitor::Create(
caller_task_runner_, input_task_runner_, ui_task_runner_,
base::BindRepeating(&ClientSessionControl::OnLocalPointerMoved,
client_session_control),
base::BindOnce(&ClientSessionControl::DisconnectSession,
client_session_control, protocol::OK));
OnMonitoringStarted();
}
void LocalInputMonitorImpl::StartMonitoring(
PointerMoveCallback on_pointer_input,
base::RepeatingClosure on_keyboard_input,
base::RepeatingClosure on_error) {
DCHECK(!monitoring_);
DCHECK(on_error);
DCHECK(on_pointer_input || on_keyboard_input);
if (on_pointer_input) {
pointer_input_monitor_ = LocalPointerInputMonitor::Create(
caller_task_runner_, input_task_runner_, ui_task_runner_,
std::move(on_pointer_input), base::BindOnce(on_error));
}
if (on_keyboard_input) {
keyboard_input_monitor_ = LocalKeyboardInputMonitor::Create(
caller_task_runner_, input_task_runner_, ui_task_runner_,
std::move(on_keyboard_input), base::BindOnce(on_error));
}
OnMonitoringStarted();
}
void LocalInputMonitorImpl::OnMonitoringStarted() {
monitoring_ = true;
// We don't need these after we've provided them to the per-input monitors.
// Note: we want to keep |caller_task_runner_| as we use it to ensure the
// underlying input monitors are released on the appropriate thread.
input_task_runner_ = nullptr;
ui_task_runner_ = nullptr;
}
} // namespace
std::unique_ptr<LocalInputMonitor> LocalInputMonitor::Create(
scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> input_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) {
return std::make_unique<LocalInputMonitorImpl>(
caller_task_runner, input_task_runner, ui_task_runner);
}
} // namespace remoting