0

Allow CRD clients to send a single mesage for keyboard combos

In order to invoke common platform tasks (send attention sequence
and lock workstation), CRD currently relies on injecting key events
on the client and picking them up on the host.  There is a listener
which tracks the current key events and then calls the platform API
once it sees the trigger.

The problem with this approach is if there is a stuck key (i.e. we
fail to send a key up event) then this functionality is broken.
While we should fix bugs which cause lost key events, we should also
look for ways to prevent issues like that from affecting other
features.

My change allows the client to send a single message to invoke an
action like LockWorkstation() or SendSAS() which will then be
executed in the user's session.  The change is targeted at the
Windows multi-process architecture but I've used interfaces to
allow for other platforms to use it (similar to how InputInjection
and the other event protos are used) if we decide to implement
it in the future.

This CL sets up the plumbing to get the request from the network
process to the desktop process on Windows.  There will be a
follow-up CL which adds the WebRTC data channel and ClientSession
integration.

Bug: 892434

Change-Id: Iedfe8c4778fbaacacc68754c6d24e7fd485b0407
Reviewed-on: https://chromium-review.googlesource.com/c/1266100
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
Reviewed-by: Jamie Walch <jamiewalch@chromium.org>
Commit-Queue: Joe Downing <joedow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#600463}
This commit is contained in:
Joe Downing
2018-10-17 17:47:30 +00:00
committed by Commit Bot
parent b90f388e94
commit 505ae0d04d
30 changed files with 406 additions and 14 deletions

@ -54,6 +54,8 @@ process_version("remoting_version") {
# stripping code.
static_library("host") {
sources = [
"action_executor.cc",
"action_executor.h",
"audio_capturer.cc",
"audio_capturer.h",
"audio_capturer_chromeos.cc",
@ -189,6 +191,8 @@ static_library("host") {
"input_injector_mac.cc",
"input_injector_win.cc",
"input_injector_x11.cc",
"ipc_action_executor.cc",
"ipc_action_executor.h",
"ipc_audio_capturer.cc",
"ipc_audio_capturer.h",
"ipc_constants.cc",

@ -0,0 +1,18 @@
// 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/action_executor.h"
namespace remoting {
// static
std::unique_ptr<ActionExecutor> ActionExecutor::Create() {
return nullptr;
}
ActionExecutor::ActionExecutor() = default;
ActionExecutor::~ActionExecutor() = default;
} // namespace remoting

@ -0,0 +1,38 @@
// 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.
#ifndef REMOTING_HOST_ACTION_EXECUTOR_H_
#define REMOTING_HOST_ACTION_EXECUTOR_H_
#include <memory>
#include "base/macros.h"
namespace remoting {
namespace protocol {
class ActionRequest;
} // namespace protocol
class ActionExecutor {
public:
virtual ~ActionExecutor();
// Creates an action executor for the current platform / host architecture.
static std::unique_ptr<ActionExecutor> Create();
// Implementations must never assume the presence of any |request| fields,
// nor assume that their contents are valid.
virtual void ExecuteAction(const protocol::ActionRequest& request) = 0;
protected:
ActionExecutor();
private:
DISALLOW_COPY_AND_ASSIGN(ActionExecutor);
};
} // namespace remoting
#endif // REMOTING_HOST_ACTION_EXECUTOR_H_

@ -8,6 +8,7 @@
#include "base/logging.h"
#include "base/single_thread_task_runner.h"
#include "build/build_config.h"
#include "remoting/host/action_executor.h"
#include "remoting/host/audio_capturer.h"
#include "remoting/host/client_session_control.h"
#include "remoting/host/desktop_capturer_proxy.h"
@ -34,6 +35,15 @@ BasicDesktopEnvironment::~BasicDesktopEnvironment() {
DCHECK(caller_task_runner_->BelongsToCurrentThread());
}
std::unique_ptr<ActionExecutor>
BasicDesktopEnvironment::CreateActionExecutor() {
DCHECK(caller_task_runner_->BelongsToCurrentThread());
// Connection mode derivations (It2Me/Me2Me) should override this method and
// return an executor instance if applicable.
return nullptr;
}
std::unique_ptr<AudioCapturer> BasicDesktopEnvironment::CreateAudioCapturer() {
DCHECK(caller_task_runner_->BelongsToCurrentThread());

@ -37,6 +37,7 @@ class BasicDesktopEnvironment : public DesktopEnvironment {
~BasicDesktopEnvironment() override;
// DesktopEnvironment implementation.
std::unique_ptr<ActionExecutor> CreateActionExecutor() override;
std::unique_ptr<AudioCapturer> CreateAudioCapturer() override;
std::unique_ptr<InputInjector> CreateInputInjector() override;
std::unique_ptr<ScreenControls> CreateScreenControls() override;

@ -14,6 +14,7 @@
#include "remoting/host/chromoting_param_traits.h"
#include "remoting/host/desktop_environment_options.h"
#include "remoting/host/screen_resolution.h"
#include "remoting/proto/action.pb.h"
#include "remoting/proto/process_stats.pb.h"
#include "remoting/protocol/errors.h"
#include "remoting/protocol/transport.h"
@ -244,6 +245,10 @@ IPC_MESSAGE_CONTROL1(ChromotingNetworkDesktopMsg_InjectTouchEvent,
IPC_MESSAGE_CONTROL1(ChromotingNetworkDesktopMsg_SetScreenResolution,
remoting::ScreenResolution /* resolution */)
// Carries an action request event from the client to the desktop session agent.
IPC_MESSAGE_CONTROL1(ChromotingNetworkDesktopMsg_ExecuteActionRequest,
remoting::protocol::ActionRequest /* request */)
//---------------------------------------------------------------------
// Chromoting messages sent from the remote_security_key process to the
// network process.

@ -322,5 +322,34 @@ void ParamTraits<remoting::protocol::AggregatedProcessResourceUsage>::Log(
l->append(")");
}
// static
void ParamTraits<remoting::protocol::ActionRequest>::Write(
base::Pickle* m,
const param_type& p) {
std::string serialized_action_request;
bool result = p.SerializeToString(&serialized_action_request);
DCHECK(result);
m->WriteString(serialized_action_request);
}
// static
bool ParamTraits<remoting::protocol::ActionRequest>::Read(
const base::Pickle* m,
base::PickleIterator* iter,
param_type* p) {
std::string serialized_action_request;
if (!iter->ReadString(&serialized_action_request))
return false;
return p->ParseFromString(serialized_action_request);
}
// static
void ParamTraits<remoting::protocol::ActionRequest>::Log(const param_type& p,
std::string* l) {
l->append(base::StringPrintf("ActionRequest action: %d, id: %u", p.action(),
p.request_id()));
}
} // namespace IPC

@ -11,6 +11,7 @@
#include "net/base/ip_endpoint.h"
#include "remoting/host/desktop_environment_options.h"
#include "remoting/host/screen_resolution.h"
#include "remoting/proto/action.pb.h"
#include "remoting/proto/process_stats.pb.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
@ -98,6 +99,16 @@ struct ParamTraits<remoting::protocol::AggregatedProcessResourceUsage> {
static void Log(const param_type& p, std::string* l);
};
template <>
struct ParamTraits<remoting::protocol::ActionRequest> {
typedef remoting::protocol::ActionRequest param_type;
static void Write(base::Pickle* m, const param_type& p);
static bool Read(const base::Pickle* m,
base::PickleIterator* iter,
param_type* p);
static void Log(const param_type& p, std::string* l);
};
} // namespace IPC
#endif // REMOTING_HOST_CHROMOTING_PARAM_TRAITS_H_

@ -21,6 +21,7 @@ class MouseCursorMonitor;
namespace remoting {
class ActionExecutor;
class AudioCapturer;
class ClientSessionControl;
class FileProxyWrapper;
@ -35,6 +36,7 @@ class DesktopEnvironment {
// Factory methods used to create audio/video capturers, event executor, and
// screen controls object for a particular desktop environment.
virtual std::unique_ptr<ActionExecutor> CreateActionExecutor() = 0;
virtual std::unique_ptr<AudioCapturer> CreateAudioCapturer() = 0;
virtual std::unique_ptr<InputInjector> CreateInputInjector() = 0;
virtual std::unique_ptr<ScreenControls> CreateScreenControls() = 0;

@ -19,6 +19,7 @@
#include "ipc/ipc_message_macros.h"
#include "remoting/base/auto_thread_task_runner.h"
#include "remoting/base/constants.h"
#include "remoting/host/action_executor.h"
#include "remoting/host/audio_capturer.h"
#include "remoting/host/chromoting_messages.h"
#include "remoting/host/desktop_environment.h"
@ -27,6 +28,7 @@
#include "remoting/host/remote_input_filter.h"
#include "remoting/host/screen_controls.h"
#include "remoting/host/screen_resolution.h"
#include "remoting/proto/action.pb.h"
#include "remoting/proto/audio.pb.h"
#include "remoting/proto/control.pb.h"
#include "remoting/proto/event.pb.h"
@ -188,6 +190,8 @@ bool DesktopSessionAgent::OnMessageReceived(const IPC::Message& message) {
OnInjectMouseEvent)
IPC_MESSAGE_HANDLER(ChromotingNetworkDesktopMsg_InjectTouchEvent,
OnInjectTouchEvent)
IPC_MESSAGE_HANDLER(ChromotingNetworkDesktopMsg_ExecuteActionRequest,
OnExecuteActionRequestEvent)
IPC_MESSAGE_HANDLER(ChromotingNetworkDesktopMsg_SetScreenResolution,
SetScreenResolution)
IPC_MESSAGE_HANDLER(ChromotingNetworkToAnyMsg_StartProcessStatsReport,
@ -289,6 +293,8 @@ void DesktopSessionAgent::OnStartSessionAgent(
// Create the input injector.
input_injector_ = desktop_environment_->CreateInputInjector();
action_executor_ = desktop_environment_->CreateActionExecutor();
// Hook up the input filter.
input_tracker_.reset(new protocol::InputEventTracker(input_injector_.get()));
remote_input_filter_.reset(new RemoteInputFilter(input_tracker_.get()));
@ -431,6 +437,7 @@ void DesktopSessionAgent::Stop() {
input_tracker_.reset();
desktop_environment_.reset();
action_executor_.reset();
input_injector_.reset();
screen_controls_.reset();
@ -541,6 +548,13 @@ void DesktopSessionAgent::OnInjectTouchEvent(
remote_input_filter_->InjectTouchEvent(event);
}
void DesktopSessionAgent::OnExecuteActionRequestEvent(
const protocol::ActionRequest& request) {
DCHECK(caller_task_runner_->BelongsToCurrentThread());
action_executor_->ExecuteAction(request);
}
void DesktopSessionAgent::SetScreenResolution(
const ScreenResolution& resolution) {
DCHECK(caller_task_runner_->BelongsToCurrentThread());

@ -35,6 +35,7 @@ class Message;
namespace remoting {
class ActionExecutor;
class AudioCapturer;
class AudioPacket;
class AutoThreadTaskRunner;
@ -47,6 +48,7 @@ class ScreenControls;
class ScreenResolution;
namespace protocol {
class ActionRequest;
class InputEventTracker;
} // namespace protocol
@ -135,6 +137,7 @@ class DesktopSessionAgent
void OnInjectTextEvent(const std::string& serialized_event);
void OnInjectMouseEvent(const std::string& serialized_event);
void OnInjectTouchEvent(const std::string& serialized_event);
void OnExecuteActionRequestEvent(const protocol::ActionRequest& request);
// Handles ChromotingNetworkDesktopMsg_SetScreenResolution request from
// the client.
@ -180,6 +183,9 @@ class DesktopSessionAgent
// The DesktopEnvironment instance used by this agent.
std::unique_ptr<DesktopEnvironment> desktop_environment_;
// Executes action request events.
std::unique_ptr<ActionExecutor> action_executor_;
// Executes keyboard, mouse and clipboard events.
std::unique_ptr<InputInjector> input_injector_;

@ -23,6 +23,7 @@
#include "remoting/host/client_session.h"
#include "remoting/host/client_session_control.h"
#include "remoting/host/desktop_session_connector.h"
#include "remoting/host/ipc_action_executor.h"
#include "remoting/host/ipc_audio_capturer.h"
#include "remoting/host/ipc_input_injector.h"
#include "remoting/host/ipc_mouse_cursor_monitor.h"
@ -105,6 +106,12 @@ DesktopSessionProxy::DesktopSessionProxy(
DCHECK(caller_task_runner_->BelongsToCurrentThread());
}
std::unique_ptr<ActionExecutor> DesktopSessionProxy::CreateActionExecutor() {
DCHECK(caller_task_runner_->BelongsToCurrentThread());
return std::make_unique<IpcActionExecutor>(this);
}
std::unique_ptr<AudioCapturer> DesktopSessionProxy::CreateAudioCapturer() {
DCHECK(caller_task_runner_->BelongsToCurrentThread());
@ -398,6 +405,13 @@ void DesktopSessionProxy::SetScreenResolution(
new ChromotingNetworkDesktopMsg_SetScreenResolution(screen_resolution_));
}
void DesktopSessionProxy::ExecuteAction(
const protocol::ActionRequest& request) {
DCHECK(caller_task_runner_->BelongsToCurrentThread());
SendToDesktop(new ChromotingNetworkDesktopMsg_ExecuteActionRequest(request));
}
DesktopSessionProxy::~DesktopSessionProxy() {
DCHECK(caller_task_runner_->BelongsToCurrentThread());

@ -17,6 +17,7 @@
#include "base/sequenced_task_runner_helpers.h"
#include "ipc/ipc_channel_handle.h"
#include "ipc/ipc_listener.h"
#include "remoting/host/action_executor.h"
#include "remoting/host/audio_capturer.h"
#include "remoting/host/desktop_environment.h"
#include "remoting/host/screen_resolution.h"
@ -79,6 +80,7 @@ class DesktopSessionProxy
const DesktopEnvironmentOptions& options);
// Mirrors DesktopEnvironment.
std::unique_ptr<ActionExecutor> CreateActionExecutor();
std::unique_ptr<AudioCapturer> CreateAudioCapturer();
std::unique_ptr<InputInjector> CreateInputInjector();
std::unique_ptr<ScreenControls> CreateScreenControls();
@ -132,6 +134,9 @@ class DesktopSessionProxy
// API used to implement the SessionController interface.
void SetScreenResolution(const ScreenResolution& resolution);
// API used to implement the ActionExecutor interface.
void ExecuteAction(const protocol::ActionRequest& request);
uint32_t desktop_session_id() const { return desktop_session_id_; }
private:

@ -64,6 +64,10 @@ FakeDesktopEnvironment::FakeDesktopEnvironment(
FakeDesktopEnvironment::~FakeDesktopEnvironment() = default;
// DesktopEnvironment implementation.
std::unique_ptr<ActionExecutor> FakeDesktopEnvironment::CreateActionExecutor() {
return nullptr;
}
std::unique_ptr<AudioCapturer> FakeDesktopEnvironment::CreateAudioCapturer() {
return nullptr;
}

@ -12,6 +12,7 @@
#include "base/macros.h"
#include "base/single_thread_task_runner.h"
#include "remoting/host/action_executor.h"
#include "remoting/host/desktop_environment.h"
#include "remoting/host/desktop_environment_options.h"
#include "remoting/host/fake_mouse_cursor_monitor.h"
@ -91,6 +92,7 @@ class FakeDesktopEnvironment : public DesktopEnvironment {
const DesktopEnvironmentOptions& options() const;
// DesktopEnvironment implementation.
std::unique_ptr<ActionExecutor> CreateActionExecutor() override;
std::unique_ptr<AudioCapturer> CreateAudioCapturer() override;
std::unique_ptr<InputInjector> CreateInputInjector() override;
std::unique_ptr<ScreenControls> CreateScreenControls() override;

@ -25,6 +25,10 @@ MockDesktopEnvironment::MockDesktopEnvironment() = default;
MockDesktopEnvironment::~MockDesktopEnvironment() = default;
std::unique_ptr<ActionExecutor> MockDesktopEnvironment::CreateActionExecutor() {
return base::WrapUnique(CreateActionExecutorPtr());
}
std::unique_ptr<AudioCapturer> MockDesktopEnvironment::CreateAudioCapturer() {
return base::WrapUnique(CreateAudioCapturerPtr());
}

@ -11,6 +11,7 @@
#include "base/macros.h"
#include "net/base/ip_endpoint.h"
#include "remoting/host/action_executor.h"
#include "remoting/host/chromoting_host_context.h"
#include "remoting/host/client_session.h"
#include "remoting/host/client_session_control.h"
@ -38,6 +39,7 @@ class MockDesktopEnvironment : public DesktopEnvironment {
MockDesktopEnvironment();
~MockDesktopEnvironment() override;
MOCK_METHOD0(CreateActionExecutorPtr, ActionExecutor*());
MOCK_METHOD0(CreateAudioCapturerPtr, AudioCapturer*());
MOCK_METHOD0(CreateInputInjectorPtr, InputInjector*());
MOCK_METHOD0(CreateScreenControlsPtr, ScreenControls*());
@ -49,6 +51,7 @@ class MockDesktopEnvironment : public DesktopEnvironment {
MOCK_CONST_METHOD0(GetDesktopSessionId, uint32_t());
// DesktopEnvironment implementation.
std::unique_ptr<ActionExecutor> CreateActionExecutor() override;
std::unique_ptr<AudioCapturer> CreateAudioCapturer() override;
std::unique_ptr<InputInjector> CreateInputInjector() override;
std::unique_ptr<ScreenControls> CreateScreenControls() override;

@ -0,0 +1,23 @@
// 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/ipc_action_executor.h"
#include <utility>
#include "remoting/host/desktop_session_proxy.h"
namespace remoting {
IpcActionExecutor::IpcActionExecutor(
scoped_refptr<DesktopSessionProxy> desktop_session_proxy)
: desktop_session_proxy_(desktop_session_proxy) {}
IpcActionExecutor::~IpcActionExecutor() = default;
void IpcActionExecutor::ExecuteAction(const protocol::ActionRequest& request) {
desktop_session_proxy_->ExecuteAction(request);
}
} // namespace remoting

@ -0,0 +1,37 @@
// 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.
#ifndef REMOTING_HOST_IPC_ACTION_EXECUTOR_H_
#define REMOTING_HOST_IPC_ACTION_EXECUTOR_H_
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "remoting/host/action_executor.h"
#include "remoting/proto/action.pb.h"
namespace remoting {
class DesktopSessionProxy;
// Routes ActionExecutor calls though the IPC channel to the desktop session
// agent running in the desktop integration process.
class IpcActionExecutor : public ActionExecutor {
public:
explicit IpcActionExecutor(
scoped_refptr<DesktopSessionProxy> desktop_session_proxy);
~IpcActionExecutor() override;
// ActionStub interface.
void ExecuteAction(const protocol::ActionRequest& request) override;
private:
// Wraps the IPC channel to the desktop process.
scoped_refptr<DesktopSessionProxy> desktop_session_proxy_;
DISALLOW_COPY_AND_ASSIGN(IpcActionExecutor);
};
} // namespace remoting
#endif // REMOTING_HOST_IPC_ACTION_EXECUTOR_H_

@ -13,6 +13,7 @@
#include "build/build_config.h"
#include "ipc/ipc_channel_handle.h"
#include "ipc/ipc_sender.h"
#include "remoting/host/action_executor.h"
#include "remoting/host/audio_capturer.h"
#include "remoting/host/chromoting_messages.h"
#include "remoting/host/client_session_control.h"
@ -42,6 +43,10 @@ IpcDesktopEnvironment::IpcDesktopEnvironment(
IpcDesktopEnvironment::~IpcDesktopEnvironment() = default;
std::unique_ptr<ActionExecutor> IpcDesktopEnvironment::CreateActionExecutor() {
return desktop_session_proxy_->CreateActionExecutor();
}
std::unique_ptr<AudioCapturer> IpcDesktopEnvironment::CreateAudioCapturer() {
return desktop_session_proxy_->CreateAudioCapturer();
}

@ -49,6 +49,7 @@ class IpcDesktopEnvironment : public DesktopEnvironment {
~IpcDesktopEnvironment() override;
// DesktopEnvironment implementation.
std::unique_ptr<ActionExecutor> CreateActionExecutor() override;
std::unique_ptr<AudioCapturer> CreateAudioCapturer() override;
std::unique_ptr<InputInjector> CreateInputInjector() override;
std::unique_ptr<ScreenControls> CreateScreenControls() override;

@ -11,6 +11,7 @@
#include "base/single_thread_task_runner.h"
#include "build/build_config.h"
#include "remoting/base/logging.h"
#include "remoting/host/action_executor.h"
#include "remoting/host/client_session_control.h"
#include "remoting/host/curtain_mode.h"
#include "remoting/host/desktop_resizer.h"
@ -35,6 +36,13 @@ Me2MeDesktopEnvironment::~Me2MeDesktopEnvironment() {
DCHECK(caller_task_runner()->BelongsToCurrentThread());
}
std::unique_ptr<ActionExecutor>
Me2MeDesktopEnvironment::CreateActionExecutor() {
DCHECK(caller_task_runner()->BelongsToCurrentThread());
return ActionExecutor::Create();
}
std::unique_ptr<ScreenControls>
Me2MeDesktopEnvironment::CreateScreenControls() {
DCHECK(caller_task_runner()->BelongsToCurrentThread());

@ -22,6 +22,7 @@ class Me2MeDesktopEnvironment : public BasicDesktopEnvironment {
~Me2MeDesktopEnvironment() override;
// DesktopEnvironment interface.
std::unique_ptr<ActionExecutor> CreateActionExecutor() override;
std::unique_ptr<ScreenControls> CreateScreenControls() override;
std::string GetCapabilities() const override;

@ -96,6 +96,8 @@ source_set("win") {
"rdp_client_window.h",
"security_descriptor.cc",
"security_descriptor.h",
"session_action_executor.cc",
"session_action_executor.h",
"session_desktop_environment.cc",
"session_desktop_environment.h",
"session_input_injector.cc",

@ -0,0 +1,45 @@
// 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/win/session_action_executor.h"
#include "base/bind.h"
#include "base/callback.h"
#include "base/location.h"
#include "base/macros.h"
#include "base/single_thread_task_runner.h"
#include "remoting/proto/action.pb.h"
namespace remoting {
using protocol::ActionRequest;
SessionActionExecutor::SessionActionExecutor(
scoped_refptr<base::SingleThreadTaskRunner> execute_action_task_runner,
const base::RepeatingClosure& inject_sas,
const base::RepeatingClosure& lock_workstation)
: execute_action_task_runner_(execute_action_task_runner),
inject_sas_(inject_sas),
lock_workstation_(lock_workstation) {}
SessionActionExecutor::~SessionActionExecutor() = default;
void SessionActionExecutor::ExecuteAction(const ActionRequest& request) {
DCHECK(request.has_action());
switch (request.action()) {
case protocol::ActionRequest::SEND_ATTENTION_SEQUENCE:
execute_action_task_runner_->PostTask(FROM_HERE, inject_sas_);
break;
case protocol::ActionRequest::LOCK_WORKSTATION:
execute_action_task_runner_->PostTask(FROM_HERE, lock_workstation_);
break;
default:
NOTREACHED() << "Unknown action type: " << request.action();
}
}
} // namespace remoting

@ -0,0 +1,48 @@
// 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.
#ifndef REMOTING_HOST_WIN_SESSION_ACTION_EXECUTOR_H_
#define REMOTING_HOST_WIN_SESSION_ACTION_EXECUTOR_H_
#include <memory>
#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "remoting/host/action_executor.h"
namespace base {
class SingleThreadTaskRunner;
} // namespace base
namespace remoting {
class SessionActionExecutor : public ActionExecutor {
public:
// |inject_sas| and |lock_workstation| are invoked on
// |execute_action_task_runner|.
SessionActionExecutor(
scoped_refptr<base::SingleThreadTaskRunner> execute_action_task_runner,
const base::RepeatingClosure& inject_sas,
const base::RepeatingClosure& lock_workstation);
~SessionActionExecutor() override;
// ActionExecutor implementation.
void ExecuteAction(const protocol::ActionRequest& request) override;
private:
scoped_refptr<base::SingleThreadTaskRunner> execute_action_task_runner_;
// Injects the Secure Attention Sequence.
base::RepeatingClosure inject_sas_;
// Locks the current session.
base::RepeatingClosure lock_workstation_;
DISALLOW_COPY_AND_ASSIGN(SessionActionExecutor);
};
} // namespace remoting
#endif // REMOTING_HOST_WIN_SESSION_ACTION_EXECUTOR_H_

@ -9,15 +9,25 @@
#include "base/logging.h"
#include "base/single_thread_task_runner.h"
#include "remoting/host/action_executor.h"
#include "remoting/host/audio_capturer.h"
#include "remoting/host/input_injector.h"
#include "remoting/host/screen_controls.h"
#include "remoting/host/win/session_action_executor.h"
#include "remoting/host/win/session_input_injector.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_capturer.h"
namespace remoting {
SessionDesktopEnvironment::~SessionDesktopEnvironment() {}
SessionDesktopEnvironment::~SessionDesktopEnvironment() = default;
std::unique_ptr<ActionExecutor>
SessionDesktopEnvironment::CreateActionExecutor() {
DCHECK(caller_task_runner()->BelongsToCurrentThread());
return std::make_unique<SessionActionExecutor>(
caller_task_runner(), inject_sas_, lock_workstation_);
}
std::unique_ptr<InputInjector>
SessionDesktopEnvironment::CreateInputInjector() {
@ -36,8 +46,8 @@ SessionDesktopEnvironment::SessionDesktopEnvironment(
scoped_refptr<base::SingleThreadTaskRunner> input_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
ui::SystemInputInjectorFactory* system_input_injector_factory,
const base::Closure& inject_sas,
const base::Closure& lock_workstation,
const base::RepeatingClosure& inject_sas,
const base::RepeatingClosure& lock_workstation,
const DesktopEnvironmentOptions& options)
: Me2MeDesktopEnvironment(caller_task_runner,
video_capture_task_runner,
@ -54,8 +64,8 @@ SessionDesktopEnvironmentFactory::SessionDesktopEnvironmentFactory(
scoped_refptr<base::SingleThreadTaskRunner> input_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
ui::SystemInputInjectorFactory* system_input_injector_factory,
const base::Closure& inject_sas,
const base::Closure& lock_workstation)
const base::RepeatingClosure& inject_sas,
const base::RepeatingClosure& lock_workstation)
: Me2MeDesktopEnvironmentFactory(caller_task_runner,
video_capture_task_runner,
input_task_runner,
@ -66,7 +76,7 @@ SessionDesktopEnvironmentFactory::SessionDesktopEnvironmentFactory(
DCHECK(caller_task_runner->BelongsToCurrentThread());
}
SessionDesktopEnvironmentFactory::~SessionDesktopEnvironmentFactory() {}
SessionDesktopEnvironmentFactory::~SessionDesktopEnvironmentFactory() = default;
std::unique_ptr<DesktopEnvironment> SessionDesktopEnvironmentFactory::Create(
base::WeakPtr<ClientSessionControl> client_session_control,

@ -21,6 +21,7 @@ class SessionDesktopEnvironment : public Me2MeDesktopEnvironment {
~SessionDesktopEnvironment() override;
// DesktopEnvironment implementation.
std::unique_ptr<ActionExecutor> CreateActionExecutor() override;
std::unique_ptr<InputInjector> CreateInputInjector() override;
private:
@ -31,15 +32,15 @@ class SessionDesktopEnvironment : public Me2MeDesktopEnvironment {
scoped_refptr<base::SingleThreadTaskRunner> input_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
ui::SystemInputInjectorFactory* system_input_injector_factory,
const base::Closure& inject_sas,
const base::Closure& lock_workstation,
const base::RepeatingClosure& inject_sas,
const base::RepeatingClosure& lock_workstation,
const DesktopEnvironmentOptions& options);
// Used to ask the daemon to inject Secure Attention Sequence.
base::Closure inject_sas_;
base::RepeatingClosure inject_sas_;
// Used to lock the workstation for the current session.
base::Closure lock_workstation_;
base::RepeatingClosure lock_workstation_;
DISALLOW_COPY_AND_ASSIGN(SessionDesktopEnvironment);
};
@ -53,8 +54,8 @@ class SessionDesktopEnvironmentFactory : public Me2MeDesktopEnvironmentFactory {
scoped_refptr<base::SingleThreadTaskRunner> input_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
ui::SystemInputInjectorFactory* system_input_injector_factory,
const base::Closure& inject_sas,
const base::Closure& lock_workstation);
const base::RepeatingClosure& inject_sas,
const base::RepeatingClosure& lock_workstation);
~SessionDesktopEnvironmentFactory() override;
// DesktopEnvironmentFactory implementation.
@ -64,10 +65,10 @@ class SessionDesktopEnvironmentFactory : public Me2MeDesktopEnvironmentFactory {
private:
// Used to ask the daemon to inject Secure Attention Sequence.
base::Closure inject_sas_;
base::RepeatingClosure inject_sas_;
// Used to lock the workstation for the current session.
base::Closure lock_workstation_;
base::RepeatingClosure lock_workstation_;
DISALLOW_COPY_AND_ASSIGN(SessionDesktopEnvironmentFactory);
};

@ -13,6 +13,7 @@ group("proto_lite") {
proto_library("proto") {
sources = [
"action.proto",
"audio.proto",
"control.proto",
"event.proto",

@ -0,0 +1,40 @@
syntax = "proto2";
option optimize_for = LITE_RUNTIME;
package remoting.protocol;
// Next Id: 3
message ActionRequest {
enum Action {
SEND_ATTENTION_SEQUENCE = 1;
LOCK_WORKSTATION = 2;
}
optional Action action = 1;
// Identifies an individual request so a response can be sent at a later time
// to indicate whether the action succeeded.
optional uint32 request_id = 2;
}
// Next Id: 4
message ActionResponse {
// The ID of the action request this response was generated for.
optional uint32 request_id = 1;
enum ReturnCode {
ACTION_SUCCESS = 1;
ACTION_ERROR = 2;
}
optional ReturnCode code = 2;
// ErrorCode field is populated if |code()| indicates an error occurred.
enum ErrorCode {
// The action supplied is not known.
UNKNOWN_ACTION_ERROR = 1;
// The action supplied is not supported by the platform or connection mode.
UNSUPPORTED_ACTION_ERROR = 2;
}
optional ErrorCode error = 3;
}