summaryrefslogtreecommitdiffstats
path: root/remoting/host/win
diff options
context:
space:
mode:
authoralexeypa@chromium.org <alexeypa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-09-08 09:52:34 +0000
committeralexeypa@chromium.org <alexeypa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-09-08 09:52:34 +0000
commit4c35f73337302284aaa503dc2d6b2172623687b5 (patch)
tree35d32d1c06d8c8fd2b87ffbe0587d1509c5ac6eb /remoting/host/win
parentdd29cd42928c96b849ab5b832fbe78e1cd1cd9ef (diff)
downloadchromium_src-4c35f73337302284aaa503dc2d6b2172623687b5.zip
chromium_src-4c35f73337302284aaa503dc2d6b2172623687b5.tar.gz
chromium_src-4c35f73337302284aaa503dc2d6b2172623687b5.tar.bz2
[Chromoting] Refactoring DesktopEnvironment and moving screen/audio recorders to ClientSession.
This CL changes the way screen/audio recorders and event executors are managed. New DesktopEnvironmentFactory class is now used by ChromotingHost's owner to specify the kind of desktop environment (or virtual terminal) to be used by the host. Screen/audio recorders and event executors now owned by the ClientSession instance, so there is a separate set of recorders and stubs exists for each authenticated client session. Clients sessions can now be torn dowsn in parallel with the host shuttting down. This is the 2nd attempt to land this change. This version includes: - |ClientSession| objects are torn down asynchronously now. - |ChromotingHost| now waits until all connections are torn down before deleting the session manager. BUG=134694 TEST=remoting_unittests Review URL: https://chromiumcodereview.appspot.com/10911152 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@155574 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting/host/win')
-rw-r--r--remoting/host/win/session_desktop_environment_factory.cc38
-rw-r--r--remoting/host/win/session_desktop_environment_factory.h26
-rw-r--r--remoting/host/win/session_event_executor.cc156
-rw-r--r--remoting/host/win/session_event_executor.h69
4 files changed, 289 insertions, 0 deletions
diff --git a/remoting/host/win/session_desktop_environment_factory.cc b/remoting/host/win/session_desktop_environment_factory.cc
new file mode 100644
index 0000000..b90ef33
--- /dev/null
+++ b/remoting/host/win/session_desktop_environment_factory.cc
@@ -0,0 +1,38 @@
+// Copyright (c) 2012 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_desktop_environment_factory.h"
+
+#include "remoting/host/audio_capturer.h"
+#include "remoting/host/chromoting_host_context.h"
+#include "remoting/host/desktop_environment.h"
+#include "remoting/host/event_executor.h"
+#include "remoting/host/video_frame_capturer.h"
+#include "remoting/host/win/session_event_executor.h"
+
+namespace remoting {
+
+SessionDesktopEnvironmentFactory::SessionDesktopEnvironmentFactory() {
+}
+
+SessionDesktopEnvironmentFactory::~SessionDesktopEnvironmentFactory() {
+}
+
+scoped_ptr<DesktopEnvironment> SessionDesktopEnvironmentFactory::Create(
+ ChromotingHostContext* context) {
+ scoped_ptr<AudioCapturer> audio_capturer = AudioCapturer::Create();
+ scoped_ptr<EventExecutor> event_executor = EventExecutor::Create(
+ context->desktop_task_runner(),
+ context->ui_task_runner());
+ event_executor.reset(new SessionEventExecutorWin(
+ context->desktop_task_runner(),
+ event_executor.Pass()));
+ scoped_ptr<VideoFrameCapturer> video_capturer(VideoFrameCapturer::Create());
+ return scoped_ptr<DesktopEnvironment>(new DesktopEnvironment(
+ audio_capturer.Pass(),
+ event_executor.Pass(),
+ video_capturer.Pass()));
+}
+
+} // namespace remoting
diff --git a/remoting/host/win/session_desktop_environment_factory.h b/remoting/host/win/session_desktop_environment_factory.h
new file mode 100644
index 0000000..6f71230
--- /dev/null
+++ b/remoting/host/win/session_desktop_environment_factory.h
@@ -0,0 +1,26 @@
+// Copyright (c) 2012 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_DESKTOP_ENVIRONMENT_FACTORY_H_
+#define REMOTING_HOST_WIN_SESSION_DESKTOP_ENVIRONMENT_FACTORY_H_
+
+#include "remoting/host/desktop_environment_factory.h"
+
+namespace remoting {
+
+class SessionDesktopEnvironmentFactory : public DesktopEnvironmentFactory {
+ public:
+ SessionDesktopEnvironmentFactory();
+ virtual ~SessionDesktopEnvironmentFactory();
+
+ virtual scoped_ptr<DesktopEnvironment> Create(
+ ChromotingHostContext* context) OVERRIDE;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(SessionDesktopEnvironmentFactory);
+};
+
+} // namespace remoting
+
+#endif // REMOTING_HOST_WIN_SESSION_DESKTOP_ENVIRONMENT_FACTORY_H_
diff --git a/remoting/host/win/session_event_executor.cc b/remoting/host/win/session_event_executor.cc
new file mode 100644
index 0000000..027aef0
--- /dev/null
+++ b/remoting/host/win/session_event_executor.cc
@@ -0,0 +1,156 @@
+// Copyright (c) 2012 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_event_executor.h"
+
+#include <string>
+
+#include "base/bind.h"
+#include "base/compiler_specific.h"
+#include "base/location.h"
+#include "base/single_thread_task_runner.h"
+#include "base/win/windows_version.h"
+#include "remoting/host/sas_injector.h"
+#include "remoting/host/win/desktop.h"
+#include "remoting/proto/event.pb.h"
+
+namespace {
+
+const uint32 kUsbLeftControl = 0x0700e0;
+const uint32 kUsbRightControl = 0x0700e4;
+const uint32 kUsbLeftAlt = 0x0700e2;
+const uint32 kUsbRightAlt = 0x0700e6;
+const uint32 kUsbDelete = 0x07004c;
+
+bool CheckCtrlAndAltArePressed(const std::set<uint32>& pressed_keys) {
+ size_t ctrl_keys = pressed_keys.count(kUsbLeftControl) +
+ pressed_keys.count(kUsbRightControl);
+ size_t alt_keys = pressed_keys.count(kUsbLeftAlt) +
+ pressed_keys.count(kUsbRightAlt);
+ return ctrl_keys != 0 && alt_keys != 0 &&
+ (ctrl_keys + alt_keys == pressed_keys.size());
+}
+
+} // namespace
+
+namespace remoting {
+
+using protocol::ClipboardEvent;
+using protocol::MouseEvent;
+using protocol::KeyEvent;
+
+SessionEventExecutorWin::SessionEventExecutorWin(
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
+ scoped_ptr<EventExecutor> nested_executor)
+ : nested_executor_(nested_executor.Pass()),
+ task_runner_(main_task_runner),
+ ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)),
+ weak_ptr_(weak_ptr_factory_.GetWeakPtr()) {
+ // Let |weak_ptr_| be used on the |task_runner_| thread.
+ // |weak_ptr_| and |weak_ptr_factory_| share a ThreadChecker, so the
+ // following line affects both of them.
+ weak_ptr_factory_.DetachFromThread();
+}
+
+SessionEventExecutorWin::~SessionEventExecutorWin() {
+}
+
+void SessionEventExecutorWin::Start(
+ scoped_ptr<protocol::ClipboardStub> client_clipboard) {
+ if (!task_runner_->BelongsToCurrentThread()) {
+ task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&SessionEventExecutorWin::Start,
+ weak_ptr_, base::Passed(&client_clipboard)));
+ return;
+ }
+
+ nested_executor_->Start(client_clipboard.Pass());
+}
+
+void SessionEventExecutorWin::StopAndDelete() {
+ if (!task_runner_->BelongsToCurrentThread()) {
+ task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&SessionEventExecutorWin::StopAndDelete,
+ weak_ptr_));
+ return;
+ }
+
+ nested_executor_.release()->StopAndDelete();
+ delete this;
+}
+
+void SessionEventExecutorWin::InjectClipboardEvent(
+ const ClipboardEvent& event) {
+ if (!task_runner_->BelongsToCurrentThread()) {
+ task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&SessionEventExecutorWin::InjectClipboardEvent,
+ weak_ptr_, event));
+ return;
+ }
+
+ nested_executor_->InjectClipboardEvent(event);
+}
+
+void SessionEventExecutorWin::InjectKeyEvent(const KeyEvent& event) {
+ if (!task_runner_->BelongsToCurrentThread()) {
+ task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&SessionEventExecutorWin::InjectKeyEvent,
+ weak_ptr_, event));
+ return;
+ }
+
+ // HostEventDispatcher should drop events lacking the pressed field.
+ DCHECK(event.has_pressed());
+
+ if (event.has_usb_keycode()) {
+ if (event.pressed()) {
+ // Simulate secure attention sequence if Ctrl-Alt-Del was just pressed.
+ if (event.usb_keycode() == kUsbDelete &&
+ CheckCtrlAndAltArePressed(pressed_keys_)) {
+ VLOG(3) << "Sending Secure Attention Sequence to console";
+
+ if (sas_injector_.get() == NULL)
+ sas_injector_ = SasInjector::Create();
+ sas_injector_->InjectSas();
+ }
+
+ pressed_keys_.insert(event.usb_keycode());
+ } else {
+ pressed_keys_.erase(event.usb_keycode());
+ }
+ }
+
+ SwitchToInputDesktop();
+ nested_executor_->InjectKeyEvent(event);
+}
+
+void SessionEventExecutorWin::InjectMouseEvent(const MouseEvent& event) {
+ if (!task_runner_->BelongsToCurrentThread()) {
+ task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&SessionEventExecutorWin::InjectMouseEvent,
+ weak_ptr_, event));
+ return;
+ }
+
+ SwitchToInputDesktop();
+ nested_executor_->InjectMouseEvent(event);
+}
+
+void SessionEventExecutorWin::SwitchToInputDesktop() {
+ // Switch to the desktop receiving user input if different from the current
+ // one.
+ scoped_ptr<Desktop> input_desktop = Desktop::GetInputDesktop();
+ if (input_desktop.get() != NULL && !desktop_.IsSame(*input_desktop)) {
+ // If SetThreadDesktop() fails, the thread is still assigned a desktop.
+ // So we can continue capture screen bits, just from a diffected desktop.
+ desktop_.SetThreadDesktop(input_desktop.Pass());
+ }
+}
+
+} // namespace remoting
diff --git a/remoting/host/win/session_event_executor.h b/remoting/host/win/session_event_executor.h
new file mode 100644
index 0000000..118238d
--- /dev/null
+++ b/remoting/host/win/session_event_executor.h
@@ -0,0 +1,69 @@
+// Copyright (c) 2012 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_EVENT_EXECUTOR_H_
+#define REMOTING_HOST_WIN_SESSION_EVENT_EXECUTOR_H_
+
+#include <set>
+
+#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
+#include "remoting/host/event_executor.h"
+#include "remoting/host/win/scoped_thread_desktop.h"
+
+namespace base {
+class SingleThreadTaskRunner;
+} // namespace base
+
+namespace remoting {
+
+class SasInjector;
+
+class SessionEventExecutorWin : public EventExecutor {
+ public:
+ SessionEventExecutorWin(
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
+ scoped_ptr<EventExecutor> nested_executor);
+ ~SessionEventExecutorWin();
+
+ // EventExecutor implementation.
+ virtual void Start(
+ scoped_ptr<protocol::ClipboardStub> client_clipboard) OVERRIDE;
+ virtual void StopAndDelete() OVERRIDE;
+
+ // protocol::ClipboardStub implementation.
+ virtual void InjectClipboardEvent(
+ const protocol::ClipboardEvent& event) OVERRIDE;
+
+ // protocol::InputStub implementation.
+ virtual void InjectKeyEvent(const protocol::KeyEvent& event) OVERRIDE;
+ virtual void InjectMouseEvent(const protocol::MouseEvent& event) OVERRIDE;
+
+ private:
+ // Switches to the desktop receiving a user input if different from
+ // the current one.
+ void SwitchToInputDesktop();
+
+ // Pointer to the next event executor.
+ scoped_ptr<EventExecutor> nested_executor_;
+
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+
+ ScopedThreadDesktop desktop_;
+
+ scoped_ptr<SasInjector> sas_injector_;
+
+ // Keys currently pressed by the client, used to detect Ctrl-Alt-Del.
+ std::set<uint32> pressed_keys_;
+
+ base::WeakPtrFactory<SessionEventExecutorWin> weak_ptr_factory_;
+ base::WeakPtr<SessionEventExecutorWin> weak_ptr_;
+
+ DISALLOW_COPY_AND_ASSIGN(SessionEventExecutorWin);
+};
+
+} // namespace remoting
+
+#endif // REMOTING_HOST_WIN_SESSION_EVENT_EXECUTOR_H_