diff options
author | alexeypa@chromium.org <alexeypa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-11 23:01:45 +0000 |
---|---|---|
committer | alexeypa@chromium.org <alexeypa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-11 23:01:45 +0000 |
commit | c3041a1ecdbaf632afccdc3643b887e0f1d80693 (patch) | |
tree | 390cd64c70edaae88ccbad4faf867c2c5031b110 /remoting | |
parent | b388e926b70990b6be241c3c81281725ac0bca35 (diff) | |
download | chromium_src-c3041a1ecdbaf632afccdc3643b887e0f1d80693.zip chromium_src-c3041a1ecdbaf632afccdc3643b887e0f1d80693.tar.gz chromium_src-c3041a1ecdbaf632afccdc3643b887e0f1d80693.tar.bz2 |
Chromoting: the Me2me host (on Mac and Windows) now presents a notification on the console allowing a user to disconnect an incoming session.
BUG=127321,127322
Review URL: https://chromiumcodereview.appspot.com/10384127
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@136698 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting')
-rw-r--r-- | remoting/host/chromoting_host_unittest.cc | 17 | ||||
-rw-r--r-- | remoting/host/continue_window_win.cc | 6 | ||||
-rw-r--r-- | remoting/host/disconnect_window.h | 10 | ||||
-rw-r--r-- | remoting/host/disconnect_window_linux.cc | 17 | ||||
-rw-r--r-- | remoting/host/disconnect_window_mac.h | 7 | ||||
-rw-r--r-- | remoting/host/disconnect_window_mac.mm | 26 | ||||
-rw-r--r-- | remoting/host/disconnect_window_win.cc | 33 | ||||
-rw-r--r-- | remoting/host/host_mock_objects.h | 3 | ||||
-rw-r--r-- | remoting/host/host_ui.rc (renamed from remoting/host/plugin/host_plugin.rc) | 204 | ||||
-rw-r--r-- | remoting/host/host_ui_resource.h (renamed from remoting/host/plugin/host_plugin_resource.h) | 8 | ||||
-rw-r--r-- | remoting/host/host_user_interface.cc | 150 | ||||
-rw-r--r-- | remoting/host/host_user_interface.h | 105 | ||||
-rw-r--r-- | remoting/host/it2me_host_user_interface.cc | 189 | ||||
-rw-r--r-- | remoting/host/it2me_host_user_interface.h | 84 | ||||
-rw-r--r-- | remoting/host/plugin/host_script_object.cc | 11 | ||||
-rw-r--r-- | remoting/host/remoting_me2me_host.cc | 47 | ||||
-rw-r--r-- | remoting/host/simple_host_process.cc | 7 | ||||
-rw-r--r-- | remoting/remoting.gyp | 26 |
18 files changed, 597 insertions, 353 deletions
diff --git a/remoting/host/chromoting_host_unittest.cc b/remoting/host/chromoting_host_unittest.cc index 78401ee..b2b1bae 100644 --- a/remoting/host/chromoting_host_unittest.cc +++ b/remoting/host/chromoting_host_unittest.cc @@ -100,9 +100,10 @@ class ChromotingHostTest : public testing::Test { disconnect_window_ = new MockDisconnectWindow(); continue_window_ = new MockContinueWindow(); local_input_monitor_ = new MockLocalInputMonitor(); - it2me_host_user_interface_.reset(new It2MeHostUserInterface(host_, - &context_)); - it2me_host_user_interface_->InitFrom( + it2me_host_user_interface_.reset(new It2MeHostUserInterface(&context_)); + it2me_host_user_interface_->StartForTest( + host_, + base::Bind(&ChromotingHost::Shutdown, host_, base::Closure()), scoped_ptr<DisconnectWindow>(disconnect_window_), scoped_ptr<ContinueWindow>(continue_window_), scoped_ptr<LocalInputMonitor>(local_input_monitor_)); @@ -274,7 +275,7 @@ TEST_F(ChromotingHostTest, DISABLED_Connect) { // then execute the done task. { InSequence s; - EXPECT_CALL(*disconnect_window_, Show(_, _)) + EXPECT_CALL(*disconnect_window_, Show(_, _, _)) .Times(0); EXPECT_CALL(video_stub_, ProcessVideoPacketPtr(_, _)) .WillOnce(DoAll( @@ -297,7 +298,7 @@ TEST_F(ChromotingHostTest, DISABLED_Reconnect) { // connection. { InSequence s; - EXPECT_CALL(*disconnect_window_, Show(_, _)) + EXPECT_CALL(*disconnect_window_, Show(_, _, _)) .Times(0); EXPECT_CALL(video_stub_, ProcessVideoPacketPtr(_, _)) .WillOnce(DoAll( @@ -321,7 +322,7 @@ TEST_F(ChromotingHostTest, DISABLED_Reconnect) { // Connect the client again. { InSequence s; - EXPECT_CALL(*disconnect_window_, Show(_, _)) + EXPECT_CALL(*disconnect_window_, Show(_, _, _)) .Times(0); EXPECT_CALL(video_stub_, ProcessVideoPacketPtr(_, _)) .WillOnce(DoAll( @@ -346,7 +347,7 @@ TEST_F(ChromotingHostTest, DISABLED_ConnectTwice) { // connection. { InSequence s; - EXPECT_CALL(*disconnect_window_, Show(_, _)) + EXPECT_CALL(*disconnect_window_, Show(_, _, _)) .Times(0); EXPECT_CALL(video_stub_, ProcessVideoPacketPtr(_, _)) .WillOnce(DoAll( @@ -356,7 +357,7 @@ TEST_F(ChromotingHostTest, DISABLED_ConnectTwice) { &ChromotingHostTest::SimulateClientConnection, 1, true)), RunDoneTask())) .RetiresOnSaturation(); - EXPECT_CALL(*disconnect_window_, Show(_, _)) + EXPECT_CALL(*disconnect_window_, Show(_, _, _)) .Times(0); EXPECT_CALL(video_stub_, ProcessVideoPacketPtr(_, _)) .Times(AnyNumber()); diff --git a/remoting/host/continue_window_win.cc b/remoting/host/continue_window_win.cc index c62289b..8e81439 100644 --- a/remoting/host/continue_window_win.cc +++ b/remoting/host/continue_window_win.cc @@ -10,9 +10,7 @@ #include "base/logging.h" #include "base/utf_string_conversions.h" #include "remoting/host/chromoting_host.h" -// TODO(wez): The DisconnectWindow isn't plugin-specific, so shouldn't have -// a dependency on the plugin's resource header. -#include "remoting/host/plugin/host_plugin_resource.h" +#include "remoting/host/host_ui_resource.h" // TODO(garykac): Lots of duplicated code in this file and // disconnect_window_win.cc. These global floating windows are temporary so @@ -127,7 +125,7 @@ void ContinueWindowWin::Hide() { void ContinueWindowWin::EndDialog() { if (hwnd_) { - ::EndDialog(hwnd_, 0); + ::DestroyWindow(hwnd_); hwnd_ = NULL; } } diff --git a/remoting/host/disconnect_window.h b/remoting/host/disconnect_window.h index e5345ed..f55a90b 100644 --- a/remoting/host/disconnect_window.h +++ b/remoting/host/disconnect_window.h @@ -7,6 +7,7 @@ #include <string> +#include "base/callback.h" #include "base/memory/scoped_ptr.h" namespace remoting { @@ -20,10 +21,17 @@ class DisconnectWindow { kMaximumConnectedNameWidthInPixels = 400 }; + // DisconnectCallback is called when the user clicks on the Disconnect button + // to disconnect the session. This callback is provided as a parameter to the + // Show() method, and will be triggered on the UI thread. + typedef base::Callback<void(void)> DisconnectCallback; + virtual ~DisconnectWindow() {} // Show the disconnect window allowing the user to shut down |host|. - virtual void Show(ChromotingHost* host, const std::string& username) = 0; + virtual void Show(ChromotingHost* host, + const DisconnectCallback& disconnect_callback, + const std::string& username) = 0; // Hide the disconnect window. virtual void Hide() = 0; diff --git a/remoting/host/disconnect_window_linux.cc b/remoting/host/disconnect_window_linux.cc index 5a1f0aa..057986b 100644 --- a/remoting/host/disconnect_window_linux.cc +++ b/remoting/host/disconnect_window_linux.cc @@ -23,6 +23,7 @@ class DisconnectWindowLinux : public DisconnectWindow { virtual ~DisconnectWindowLinux(); virtual void Show(ChromotingHost* host, + const DisconnectCallback& disconnect_callback, const std::string& username) OVERRIDE; virtual void Hide() OVERRIDE; @@ -36,7 +37,7 @@ class DisconnectWindowLinux : public DisconnectWindow { void CreateWindow(const UiStrings& ui_strings); - ChromotingHost* host_; + DisconnectCallback disconnect_callback_; GtkWidget* disconnect_window_; GtkWidget* message_; GtkWidget* button_; @@ -50,8 +51,7 @@ class DisconnectWindowLinux : public DisconnectWindow { }; DisconnectWindowLinux::DisconnectWindowLinux() - : host_(NULL), - disconnect_window_(NULL), + : disconnect_window_(NULL), current_width_(0), current_height_(0) { } @@ -130,8 +130,9 @@ void DisconnectWindowLinux::CreateWindow(const UiStrings& ui_strings) { } void DisconnectWindowLinux::Show(ChromotingHost* host, + const DisconnectCallback& disconnect_callback, const std::string& username) { - host_ = host; + disconnect_callback_ = disconnect_callback; CreateWindow(host->ui_strings()); string16 text = ReplaceStringPlaceholders( @@ -148,16 +149,16 @@ void DisconnectWindowLinux::Hide() { } void DisconnectWindowLinux::OnClicked(GtkWidget* button) { - CHECK(host_); + CHECK(!disconnect_callback_.is_null()); - host_->Shutdown(base::Closure()); + disconnect_callback_.Run(); Hide(); } gboolean DisconnectWindowLinux::OnDelete(GtkWidget* window, GdkEvent* event) { - CHECK(host_); + CHECK(!disconnect_callback_.is_null()); - host_->Shutdown(base::Closure()); + disconnect_callback_.Run(); Hide(); return TRUE; diff --git a/remoting/host/disconnect_window_mac.h b/remoting/host/disconnect_window_mac.h index 8014b4e..779650d 100644 --- a/remoting/host/disconnect_window_mac.h +++ b/remoting/host/disconnect_window_mac.h @@ -1,9 +1,12 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// 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. #import <Cocoa/Cocoa.h> +#include "base/callback.h" +#include "remoting/host/disconnect_window.h" + namespace remoting { class ChromotingHost; } @@ -13,12 +16,14 @@ class ChromotingHost; @interface DisconnectWindowController : NSWindowController { @private remoting::ChromotingHost* host_; + base::Closure disconnect_callback_; NSString* username_; IBOutlet NSTextField* connectedToField_; IBOutlet NSButton* disconnectButton_; } - (id)initWithHost:(remoting::ChromotingHost*)host + callback:(const base::Closure&)disconnect_callback username:(NSString*)username; - (IBAction)stopSharing:(id)sender; @end diff --git a/remoting/host/disconnect_window_mac.mm b/remoting/host/disconnect_window_mac.mm index bccd31c..58fa041 100644 --- a/remoting/host/disconnect_window_mac.mm +++ b/remoting/host/disconnect_window_mac.mm @@ -19,7 +19,8 @@ class DisconnectWindowMac : public remoting::DisconnectWindow { DisconnectWindowMac(); virtual ~DisconnectWindowMac(); - virtual void Show(remoting::ChromotingHost* host, + virtual void Show(ChromotingHost* host, + const base::Closure& disconnect_callback, const std::string& username) OVERRIDE; virtual void Hide() OVERRIDE; @@ -37,12 +38,14 @@ DisconnectWindowMac::~DisconnectWindowMac() { [window_controller_ close]; } -void DisconnectWindowMac::Show(remoting::ChromotingHost* host, +void DisconnectWindowMac::Show(ChromotingHost* host, + const base::Closure& disconnect_callback, const std::string& username) { CHECK(window_controller_ == nil); NSString* nsUsername = base::SysUTF8ToNSString(username); window_controller_ = [[DisconnectWindowController alloc] initWithHost:host + callback:disconnect_callback username:nsUsername]; [window_controller_ showWindow:nil]; } @@ -61,23 +64,17 @@ scoped_ptr<DisconnectWindow> DisconnectWindow::Create() { } // namespace remoting @interface DisconnectWindowController() -@property (nonatomic, assign) remoting::ChromotingHost* host; -@property (nonatomic, copy) NSString* username; - - (BOOL)isRToL; - @end @implementation DisconnectWindowController - -@synthesize host = host_; -@synthesize username = username_; - - (id)initWithHost:(remoting::ChromotingHost*)host + callback:(const base::Closure&)disconnect_callback username:(NSString*)username { self = [super initWithWindowNibName:@"disconnect_window"]; if (self) { host_ = host; + disconnect_callback_ = disconnect_callback; username_ = [username copy]; } return self; @@ -89,9 +86,8 @@ scoped_ptr<DisconnectWindow> DisconnectWindow::Create() { } - (IBAction)stopSharing:(id)sender { - if (self.host) { - self.host->Shutdown(base::Closure()); - self.host = NULL; + if (host_ != NULL && !disconnect_callback_.is_null()) { + disconnect_callback_.Run(); } } @@ -104,14 +100,14 @@ scoped_ptr<DisconnectWindow> DisconnectWindow::Create() { } - (void)close { - self.host = NULL; + host_ = NULL; [super close]; } - (void)windowDidLoad { string16 text = ReplaceStringPlaceholders( host_->ui_strings().disconnect_message, - base::SysNSStringToUTF16(self.username), + base::SysNSStringToUTF16(username_), NULL); [connectedToField_ setStringValue:base::SysUTF16ToNSString(text)]; diff --git a/remoting/host/disconnect_window_win.cc b/remoting/host/disconnect_window_win.cc index 42e703f..06434a8 100644 --- a/remoting/host/disconnect_window_win.cc +++ b/remoting/host/disconnect_window_win.cc @@ -14,9 +14,7 @@ #include "base/win/scoped_hdc.h" #include "base/win/scoped_select_object.h" #include "remoting/host/chromoting_host.h" -// TODO(wez): The DisconnectWindow isn't plugin-specific, so shouldn't have -// a dependency on the plugin's resource header. -#include "remoting/host/plugin/host_plugin_resource.h" +#include "remoting/host/host_ui_resource.h" #include "remoting/host/ui_strings.h" // TODO(garykac): Lots of duplicated code in this file and @@ -39,7 +37,8 @@ class DisconnectWindowWin : public DisconnectWindow { DisconnectWindowWin(); virtual ~DisconnectWindowWin(); - virtual void Show(remoting::ChromotingHost* host, + virtual void Show(ChromotingHost* host, + const DisconnectCallback& disconnect_callback, const std::string& username) OVERRIDE; virtual void Hide() OVERRIDE; @@ -50,10 +49,10 @@ private: BOOL OnDialogMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); void ShutdownHost(); - void EndDialog(int result); + void EndDialog(); void SetStrings(const UiStrings& strings, const std::string& username); - remoting::ChromotingHost* host_; + DisconnectCallback disconnect_callback_; HWND hwnd_; bool has_hotkey_; base::win::ScopedGDIObject<HPEN> border_pen_; @@ -62,15 +61,14 @@ private: }; DisconnectWindowWin::DisconnectWindowWin() - : host_(NULL), - hwnd_(NULL), + : hwnd_(NULL), has_hotkey_(false), border_pen_(CreatePen(PS_SOLID, 5, RGB(0.13 * 255, 0.69 * 255, 0.11 * 255))) { } DisconnectWindowWin::~DisconnectWindowWin() { - EndDialog(0); + EndDialog(); } BOOL CALLBACK DisconnectWindowWin::DialogProc(HWND hwnd, UINT msg, @@ -100,8 +98,8 @@ BOOL DisconnectWindowWin::OnDialogMessage(HWND hwnd, UINT msg, case WM_COMMAND: switch (LOWORD(wParam)) { case IDC_DISCONNECT: + EndDialog(); ShutdownHost(); - EndDialog(LOWORD(wParam)); return TRUE; } return FALSE; @@ -113,8 +111,8 @@ BOOL DisconnectWindowWin::OnDialogMessage(HWND hwnd, UINT msg, // Handle the disconnect hot-key. case WM_HOTKEY: + EndDialog(); ShutdownHost(); - EndDialog(0); return TRUE; // Let the window be draggable by its client area by responding @@ -143,9 +141,10 @@ BOOL DisconnectWindowWin::OnDialogMessage(HWND hwnd, UINT msg, } void DisconnectWindowWin::Show(ChromotingHost* host, + const DisconnectCallback& disconnect_callback, const std::string& username) { CHECK(!hwnd_); - host_ = host; + disconnect_callback_ = disconnect_callback; // Load the dialog resource so that we can modify the RTL flags if necessary. // This is taken from chrome/default_plugin/install_dialog.cc @@ -203,8 +202,8 @@ void DisconnectWindowWin::Show(ChromotingHost* host, } void DisconnectWindowWin::ShutdownHost() { - CHECK(host_); - host_->Shutdown(base::Closure()); + CHECK(!disconnect_callback_.is_null()); + disconnect_callback_.Run(); } static int GetControlTextWidth(HWND control) { @@ -275,17 +274,17 @@ void DisconnectWindowWin::SetStrings(const UiStrings& strings, } void DisconnectWindowWin::Hide() { - EndDialog(0); + EndDialog(); } -void DisconnectWindowWin::EndDialog(int result) { +void DisconnectWindowWin::EndDialog() { if (has_hotkey_) { UnregisterHotKey(hwnd_, DISCONNECT_HOTKEY_ID); has_hotkey_ = false; } if (hwnd_) { - ::EndDialog(hwnd_, result); + ::DestroyWindow(hwnd_); hwnd_ = NULL; } } diff --git a/remoting/host/host_mock_objects.h b/remoting/host/host_mock_objects.h index abb19d52..ce65273 100644 --- a/remoting/host/host_mock_objects.h +++ b/remoting/host/host_mock_objects.h @@ -53,7 +53,8 @@ class MockDisconnectWindow : public DisconnectWindow { MockDisconnectWindow(); virtual ~MockDisconnectWindow(); - MOCK_METHOD2(Show, void(remoting::ChromotingHost* host, + MOCK_METHOD3(Show, void(remoting::ChromotingHost* host, + const DisconnectCallback& disconnect_callback, const std::string& username)); MOCK_METHOD0(Hide, void()); }; diff --git a/remoting/host/plugin/host_plugin.rc b/remoting/host/host_ui.rc index 612e051..a15a5cc 100644 --- a/remoting/host/plugin/host_plugin.rc +++ b/remoting/host/host_ui.rc @@ -1,102 +1,102 @@ -// Microsoft Visual C++ generated resource script.
-//
-#include "host_plugin_resource.h"
-
-#define APSTUDIO_READONLY_SYMBOLS
-/////////////////////////////////////////////////////////////////////////////
-//
-// Generated from the TEXTINCLUDE 2 resource.
-//
-#include "winres.h"
-#include "constants.h"
-
-/////////////////////////////////////////////////////////////////////////////
-#undef APSTUDIO_READONLY_SYMBOLS
-
-/////////////////////////////////////////////////////////////////////////////
-// English (U.S.) resources
-
-#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
-#ifdef _WIN32
-LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
-#pragma code_page(1252)
-#endif //_WIN32
-
-#ifdef APSTUDIO_INVOKED
-/////////////////////////////////////////////////////////////////////////////
-//
-// TEXTINCLUDE
-//
-
-1 TEXTINCLUDE
-BEGIN
- "host_plugin_resource.h\0"
-END
-
-2 TEXTINCLUDE
-BEGIN
- "#include ""winres.h""\r\n"
- "#include ""constants.h""\r\n"
- "\0"
-END
-
-#endif // APSTUDIO_INVOKED
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Dialog
-//
-
-IDD_DISCONNECT DIALOGEX 0, 0, 145, 24
-STYLE DS_SETFONT | WS_POPUP
-EXSTYLE WS_EX_TOPMOST | WS_EX_TOOLWINDOW
-FONT 9, "Microsoft Sans Serif", 400, 0, 0x0
-BEGIN
- DEFPUSHBUTTON "kDisconnectButton",IDC_DISCONNECT,68,5,70,14
- LTEXT "kSharingWith",IDC_DISCONNECT_SHARINGWITH,18,7,43,8
- CONTROL "",IDC_STATIC,"Static",SS_ETCHEDVERT,6,6,1,12
- CONTROL "",IDC_STATIC,"Static",SS_ETCHEDVERT,8,6,1,12
-END
-
-IDD_CONTINUE DIALOGEX 0, 0, 221, 58
-STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION
-EXSTYLE WS_EX_TOPMOST | WS_EX_TOOLWINDOW
-CAPTION "kTitle"
-FONT 8, "MS Shell Dlg", 400, 0, 0x1
-BEGIN
- DEFPUSHBUTTON "kDefault",IDC_CONTINUE_DEFAULT,116,38,98,14
- LTEXT "kMessage",IDC_CONTINUE_MESSAGE,7,7,207,30
- PUSHBUTTON "kCancel",IDC_CONTINUE_CANCEL,7,38,98,14
-END
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// DESIGNINFO
-//
-
-#ifdef APSTUDIO_INVOKED
-GUIDELINES DESIGNINFO
-BEGIN
- IDD_DISCONNECT, DIALOG
- BEGIN
- VERTGUIDE, 20
- BOTTOMMARGIN, 23
- END
-
- IDD_CONTINUE, DIALOG
- BEGIN
- LEFTMARGIN, 7
- RIGHTMARGIN, 214
- VERTGUIDE, 105
- VERTGUIDE, 116
- VERTGUIDE, 203
- TOPMARGIN, 7
- BOTTOMMARGIN, 52
- END
-END
-#endif // APSTUDIO_INVOKED
-
-#endif // English (U.S.) resources
-/////////////////////////////////////////////////////////////////////////////
+// Microsoft Visual C++ generated resource script. +// +#include "host_ui_resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "winres.h" +#include "constants.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "host_ui_resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""winres.h""\r\n" + "#include ""constants.h""\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_DISCONNECT DIALOGEX 0, 0, 145, 24 +STYLE DS_SETFONT | WS_POPUP +EXSTYLE WS_EX_TOPMOST | WS_EX_TOOLWINDOW +FONT 9, "Microsoft Sans Serif", 400, 0, 0x0 +BEGIN + DEFPUSHBUTTON "kDisconnectButton",IDC_DISCONNECT,68,5,70,14 + LTEXT "kSharingWith",IDC_DISCONNECT_SHARINGWITH,18,7,43,8 + CONTROL "",IDC_STATIC,"Static",SS_ETCHEDVERT,6,6,1,12 + CONTROL "",IDC_STATIC,"Static",SS_ETCHEDVERT,8,6,1,12 +END + +IDD_CONTINUE DIALOGEX 0, 0, 221, 58 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION +EXSTYLE WS_EX_TOPMOST | WS_EX_TOOLWINDOW +CAPTION "kTitle" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + DEFPUSHBUTTON "kDefault",IDC_CONTINUE_DEFAULT,116,38,98,14 + LTEXT "kMessage",IDC_CONTINUE_MESSAGE,7,7,207,30 + PUSHBUTTON "kCancel",IDC_CONTINUE_CANCEL,7,38,98,14 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_DISCONNECT, DIALOG + BEGIN + VERTGUIDE, 20 + BOTTOMMARGIN, 23 + END + + IDD_CONTINUE, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 214 + VERTGUIDE, 105 + VERTGUIDE, 116 + VERTGUIDE, 203 + TOPMARGIN, 7 + BOTTOMMARGIN, 52 + END +END +#endif // APSTUDIO_INVOKED + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// diff --git a/remoting/host/plugin/host_plugin_resource.h b/remoting/host/host_ui_resource.h index de91dab..6704a27 100644 --- a/remoting/host/plugin/host_plugin_resource.h +++ b/remoting/host/host_ui_resource.h @@ -1,6 +1,10 @@ +// 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. + //{{NO_DEPENDENCIES}} // Microsoft Visual C++ generated include file. -// Used by host_plugin.rc +// Used by host_ui.rc // #define IDD_DISCONNECT 101 #define IDD_CONTINUE 102 @@ -12,7 +16,7 @@ #define IDC_CONTINUE_CANCEL 1007 // Next default values for new objects -// +// #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 103 diff --git a/remoting/host/host_user_interface.cc b/remoting/host/host_user_interface.cc new file mode 100644 index 0000000..0009ea0 --- /dev/null +++ b/remoting/host/host_user_interface.cc @@ -0,0 +1,150 @@ +// 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/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), + ui_thread_proxy_(context->ui_message_loop()) { +} + +HostUserInterface::~HostUserInterface() { + DCHECK(ui_message_loop()->BelongsToCurrentThread()); + + MonitorLocalInputs(false); + ShowDisconnectWindow(false, std::string()); + + ui_thread_proxy_.Detach(); +} + +void HostUserInterface::Start(ChromotingHost* host, + const base::Closure& disconnect_callback) { + DCHECK(network_message_loop()->BelongsToCurrentThread()); + DCHECK(host_ == NULL); + DCHECK(disconnect_callback_.is_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) { + authenticated_jid_ = jid; + + std::string username = jid.substr(0, jid.find('/')); + ui_thread_proxy_.PostTask(FROM_HERE, base::Bind( + &HostUserInterface::ProcessOnClientAuthenticated, + base::Unretained(this), username)); +} + +void HostUserInterface::OnClientDisconnected(const std::string& jid) { + if (jid == authenticated_jid_) { + ui_thread_proxy_.PostTask(FROM_HERE, base::Bind( + &HostUserInterface::ProcessOnClientDisconnected, + base::Unretained(this))); + } +} + +void HostUserInterface::OnAccessDenied(const std::string& jid) { +} + +void HostUserInterface::OnShutdown() { + // Host status observers must be removed on the network thread, so + // it must happen here instead of in the destructor. + host_->RemoveStatusObserver(this); + host_ = NULL; + disconnect_callback_ = base::Closure(); +} + +void HostUserInterface::OnDisconnectCallback() { + DCHECK(ui_message_loop()->BelongsToCurrentThread()); + DCHECK(!disconnect_callback_.is_null()); + + MonitorLocalInputs(false); + ShowDisconnectWindow(false, std::string()); + disconnect_callback_.Run(); +} + +base::MessageLoopProxy* HostUserInterface::network_message_loop() const { + return context_->network_message_loop(); +} +base::MessageLoopProxy* HostUserInterface::ui_message_loop() const { + return context_->ui_message_loop(); +} + +void HostUserInterface::DisconnectSession() const { + return disconnect_callback_.Run(); +} + +void HostUserInterface::ProcessOnClientAuthenticated( + const std::string& username) { + DCHECK(ui_message_loop()->BelongsToCurrentThread()); + + MonitorLocalInputs(true); + ShowDisconnectWindow(true, username); +} + +void HostUserInterface::ProcessOnClientDisconnected() { + DCHECK(ui_message_loop()->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_message_loop()->BelongsToCurrentThread()); + DCHECK(host_ == NULL); + DCHECK(disconnect_callback_.is_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_message_loop()->BelongsToCurrentThread()); + + if (enable != is_monitoring_local_inputs_) { + if (enable) { + local_input_monitor_->Start(host_); + } else { + local_input_monitor_->Stop(); + } + is_monitoring_local_inputs_ = enable; + } +} + +void HostUserInterface::ShowDisconnectWindow(bool show, + const std::string& username) { + DCHECK(ui_message_loop()->BelongsToCurrentThread()); + + if (show) { + disconnect_window_->Show( + host_, + base::Bind(&HostUserInterface::OnDisconnectCallback, + base::Unretained(this)), + username); + } else { + disconnect_window_->Hide(); + } +} + +} // namespace remoting diff --git a/remoting/host/host_user_interface.h b/remoting/host/host_user_interface.h new file mode 100644 index 0000000..9c2729e --- /dev/null +++ b/remoting/host/host_user_interface.h @@ -0,0 +1,105 @@ +// 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_HOST_USER_INTERFACE_H_ +#define REMOTING_HOST_HOST_USER_INTERFACE_H_ + +#include <string> + +#include "base/basictypes.h" +#include "base/callback.h" +#include "base/compiler_specific.h" +#include "base/memory/scoped_ptr.h" + +#include "remoting/base/scoped_thread_proxy.h" +#include "remoting/host/host_status_observer.h" + +namespace remoting { + +class ChromotingHost; +class ChromotingHostContext; +class DisconnectWindow; +class LocalInputMonitor; +class SignalStrategy; + +class HostUserInterface : public HostStatusObserver { + public: + HostUserInterface(ChromotingHostContext* context); + virtual ~HostUserInterface(); + + virtual void Start(ChromotingHost* host, + const base::Closure& disconnect_callback); + + // HostStatusObserver implementation. These methods will be called from the + // network thread. + virtual void OnClientAuthenticated(const std::string& jid) OVERRIDE; + virtual void OnClientDisconnected(const std::string& jid) OVERRIDE; + virtual void OnAccessDenied(const std::string& jid) OVERRIDE; + virtual void OnShutdown() OVERRIDE; + + protected: + const std::string& get_authenticated_jid() const { + return authenticated_jid_; + } + ChromotingHost* get_host() const { return host_; } + + // Message loop accessors. + base::MessageLoopProxy* network_message_loop() const; + base::MessageLoopProxy* ui_message_loop() const; + + // Invokes the session disconnect callback passed to Start(). + void DisconnectSession() const; + + virtual void ProcessOnClientAuthenticated(const std::string& username); + virtual void ProcessOnClientDisconnected(); + + // Used by unit-tests as an alternative to Start() so that mock versions of + // internal objects can be used. + void StartForTest( + ChromotingHost* host, + const base::Closure& disconnect_callback, + scoped_ptr<DisconnectWindow> disconnect_window, + scoped_ptr<LocalInputMonitor> local_input_monitor); + + private: + // Invoked from the UI thread when the user clicks on the Disconnect button + // to disconnect the session. + void OnDisconnectCallback(); + + void MonitorLocalInputs(bool enable); + + // Show or hide the Disconnect window on the UI thread. If |show| is false, + // hide the window, ignoring the |username| parameter. + void ShowDisconnectWindow(bool show, const std::string& username); + + // The JID of the currently-authenticated user (or an empty string if no user + // is connected). + std::string authenticated_jid_; + + ChromotingHost* host_; + + // Host context used to make sure operations are run on the correct thread. + // This is owned by the ChromotingHost. + ChromotingHostContext* context_; + + // Used to ask the host to disconnect the session. + base::Closure disconnect_callback_; + + // Provide a user interface allowing the host user to close the connection. + scoped_ptr<DisconnectWindow> disconnect_window_; + + // Monitor local inputs to allow remote inputs to be blocked while the local + // user is trying to do something. + scoped_ptr<LocalInputMonitor> local_input_monitor_; + + bool is_monitoring_local_inputs_; + + ScopedThreadProxy ui_thread_proxy_; + + DISALLOW_COPY_AND_ASSIGN(HostUserInterface); +}; + +} // namespace remoting + +#endif // REMOTING_HOST_HOST_USER_INTERFACE_H_ diff --git a/remoting/host/it2me_host_user_interface.cc b/remoting/host/it2me_host_user_interface.cc index 758bafa..c39f6d3 100644 --- a/remoting/host/it2me_host_user_interface.cc +++ b/remoting/host/it2me_host_user_interface.cc @@ -11,6 +11,17 @@ #include "remoting/host/disconnect_window.h" #include "remoting/host/local_input_monitor.h" +namespace { + +// Milliseconds before the continue window is shown. +static const int kContinueWindowShowTimeoutMs = 10 * 60 * 1000; + +// Milliseconds before the continue window is automatically dismissed and +// the connection is closed. +static const int kContinueWindowHideTimeoutMs = 60 * 1000; + +} // namespace + namespace remoting { class It2MeHostUserInterface::TimerTask { @@ -27,151 +38,115 @@ class It2MeHostUserInterface::TimerTask { }; -It2MeHostUserInterface::It2MeHostUserInterface(ChromotingHost* host, - ChromotingHostContext* context) - : host_(host), - context_(context), - is_monitoring_local_inputs_(false), - ui_thread_proxy_(context->ui_message_loop()) { +It2MeHostUserInterface::It2MeHostUserInterface(ChromotingHostContext* context) + : HostUserInterface(context) { } It2MeHostUserInterface::~It2MeHostUserInterface() { -} + DCHECK(ui_message_loop()->BelongsToCurrentThread()); -void It2MeHostUserInterface::Init() { - InitFrom(DisconnectWindow::Create(), - ContinueWindow::Create(), - LocalInputMonitor::Create()); + ShowContinueWindow(false); + StartContinueWindowTimer(false); } -void It2MeHostUserInterface::InitFrom( - scoped_ptr<DisconnectWindow> disconnect_window, - scoped_ptr<ContinueWindow> continue_window, - scoped_ptr<LocalInputMonitor> monitor) { - disconnect_window_ = disconnect_window.Pass(); - continue_window_ = continue_window.Pass(); - local_input_monitor_ = monitor.Pass(); - host_->AddStatusObserver(this); +void It2MeHostUserInterface::Start(ChromotingHost* host, + const base::Closure& disconnect_callback) { + DCHECK(network_message_loop()->BelongsToCurrentThread()); + + HostUserInterface::Start(host, disconnect_callback); + continue_window_ = ContinueWindow::Create(); } void It2MeHostUserInterface::OnClientAuthenticated(const std::string& jid) { - if (!authenticated_jid_.empty()) { + if (!get_authenticated_jid().empty()) { // If we already authenticated another client then one of the // connections may be an attacker, so both are suspect and we have // to reject the second connection and shutdown the host. - host_->RejectAuthenticatingClient(); - context_->network_message_loop()->PostTask(FROM_HERE, base::Bind( - &ChromotingHost::Shutdown, host_, base::Closure())); - return; - } - - authenticated_jid_ = jid; - - std::string username = jid.substr(0, jid.find('/')); - ui_thread_proxy_.PostTask(FROM_HERE, base::Bind( - &It2MeHostUserInterface::ProcessOnClientAuthenticated, - base::Unretained(this), username)); -} - -void It2MeHostUserInterface::OnClientDisconnected(const std::string& jid) { - if (jid == authenticated_jid_) { - ui_thread_proxy_.PostTask(FROM_HERE, base::Bind( - &It2MeHostUserInterface::ProcessOnClientDisconnected, - base::Unretained(this))); + get_host()->RejectAuthenticatingClient(); + network_message_loop()->PostTask(FROM_HERE, base::Bind( + &ChromotingHost::Shutdown, get_host(), base::Closure())); + } else { + HostUserInterface::OnClientAuthenticated(jid); } } -void It2MeHostUserInterface::OnAccessDenied(const std::string& jid) { -} - -void It2MeHostUserInterface::OnShutdown() { - // Host status observers must be removed on the network thread, so - // it must happen here instead of in the destructor. - host_->RemoveStatusObserver(this); -} - -void It2MeHostUserInterface::Shutdown() { - DCHECK(context_->ui_message_loop()->BelongsToCurrentThread()); - - MonitorLocalInputs(false); - ShowDisconnectWindow(false, std::string()); - ShowContinueWindow(false); - StartContinueWindowTimer(false); - - ui_thread_proxy_.Detach(); -} - void It2MeHostUserInterface::ProcessOnClientAuthenticated( const std::string& username) { - DCHECK(context_->ui_message_loop()->BelongsToCurrentThread()); + DCHECK(ui_message_loop()->BelongsToCurrentThread()); - MonitorLocalInputs(true); - ShowDisconnectWindow(true, username); + HostUserInterface::ProcessOnClientAuthenticated(username); StartContinueWindowTimer(true); } void It2MeHostUserInterface::ProcessOnClientDisconnected() { - DCHECK(context_->ui_message_loop()->BelongsToCurrentThread()); + DCHECK(ui_message_loop()->BelongsToCurrentThread()); - MonitorLocalInputs(false); - ShowDisconnectWindow(false, std::string()); + HostUserInterface::ProcessOnClientDisconnected(); ShowContinueWindow(false); StartContinueWindowTimer(false); } -void It2MeHostUserInterface::MonitorLocalInputs(bool enable) { - DCHECK(context_->ui_message_loop()->BelongsToCurrentThread()); +void It2MeHostUserInterface::StartForTest( + ChromotingHost* host, + const base::Closure& disconnect_callback, + scoped_ptr<DisconnectWindow> disconnect_window, + scoped_ptr<ContinueWindow> continue_window, + scoped_ptr<LocalInputMonitor> local_input_monitor) { + HostUserInterface::StartForTest(host, disconnect_callback, + disconnect_window.Pass(), + local_input_monitor.Pass()); + continue_window_ = continue_window.Pass(); +} - if (enable == is_monitoring_local_inputs_) - return; - if (enable) { - local_input_monitor_->Start(host_); +void It2MeHostUserInterface::ContinueSession(bool continue_session) { + DCHECK(ui_message_loop()->BelongsToCurrentThread()); + + if (continue_session) { + get_host()->PauseSession(false); + timer_task_.reset(); + StartContinueWindowTimer(true); } else { - local_input_monitor_->Stop(); + DisconnectSession(); } - is_monitoring_local_inputs_ = enable; } -void It2MeHostUserInterface::ShowDisconnectWindow(bool show, - const std::string& username) { - DCHECK(context_->ui_message_loop()->BelongsToCurrentThread()); +void It2MeHostUserInterface::OnContinueWindowTimer() { + DCHECK(ui_message_loop()->BelongsToCurrentThread()); - if (show) { - disconnect_window_->Show(host_, username); - } else { - disconnect_window_->Hide(); - } + get_host()->PauseSession(true); + ShowContinueWindow(true); + + timer_task_.reset(new TimerTask( + ui_message_loop(), + base::Bind(&It2MeHostUserInterface::OnShutdownHostTimer, + base::Unretained(this)), + kContinueWindowHideTimeoutMs)); +} + +void It2MeHostUserInterface::OnShutdownHostTimer() { + DCHECK(ui_message_loop()->BelongsToCurrentThread()); + + ShowContinueWindow(false); + DisconnectSession(); } void It2MeHostUserInterface::ShowContinueWindow(bool show) { - DCHECK(context_->ui_message_loop()->BelongsToCurrentThread()); + DCHECK(ui_message_loop()->BelongsToCurrentThread()); if (show) { - continue_window_->Show(host_, base::Bind( + continue_window_->Show(get_host(), base::Bind( &It2MeHostUserInterface::ContinueSession, base::Unretained(this))); } else { continue_window_->Hide(); } } -void It2MeHostUserInterface::ContinueSession(bool continue_session) { - DCHECK(context_->ui_message_loop()->BelongsToCurrentThread()); - - if (continue_session) { - host_->PauseSession(false); - timer_task_.reset(); - StartContinueWindowTimer(true); - } else { - host_->Shutdown(base::Closure()); - } -} - void It2MeHostUserInterface::StartContinueWindowTimer(bool start) { - DCHECK(context_->ui_message_loop()->BelongsToCurrentThread()); + DCHECK(ui_message_loop()->BelongsToCurrentThread()); if (start) { timer_task_.reset(new TimerTask( - context_->ui_message_loop(), + ui_message_loop(), base::Bind(&It2MeHostUserInterface::OnContinueWindowTimer, base::Unretained(this)), kContinueWindowShowTimeoutMs)); @@ -180,24 +155,4 @@ void It2MeHostUserInterface::StartContinueWindowTimer(bool start) { } } -void It2MeHostUserInterface::OnContinueWindowTimer() { - DCHECK(context_->ui_message_loop()->BelongsToCurrentThread()); - - host_->PauseSession(true); - ShowContinueWindow(true); - - timer_task_.reset(new TimerTask( - context_->ui_message_loop(), - base::Bind(&It2MeHostUserInterface::OnShutdownHostTimer, - base::Unretained(this)), - kContinueWindowHideTimeoutMs)); -} - -void It2MeHostUserInterface::OnShutdownHostTimer() { - DCHECK(context_->ui_message_loop()->BelongsToCurrentThread()); - - ShowContinueWindow(false); - host_->Shutdown(base::Closure()); -} - } // namespace remoting diff --git a/remoting/host/it2me_host_user_interface.h b/remoting/host/it2me_host_user_interface.h index 897ddd7..b054c65 100644 --- a/remoting/host/it2me_host_user_interface.h +++ b/remoting/host/it2me_host_user_interface.h @@ -8,110 +8,68 @@ #include <string> #include "base/basictypes.h" +#include "base/callback.h" #include "base/compiler_specific.h" #include "base/memory/scoped_ptr.h" -#include "remoting/base/scoped_thread_proxy.h" -#include "remoting/host/host_status_observer.h" - -// Milliseconds before the continue window is shown. -static const int kContinueWindowShowTimeoutMs = 10 * 60 * 1000; - -// Milliseconds before the continue window is automatically dismissed and -// the connection is closed. -static const int kContinueWindowHideTimeoutMs = 60 * 1000; +#include "remoting/host/host_user_interface.h" namespace remoting { -class ChromotingHost; -class ChromotingHostContext; class ContinueWindow; -class DisconnectWindow; -class LocalInputMonitor; -class SignalStrategy; // This class implements the IT2Me-specific parts of the ChromotingHost: // Disconnect and Continue window popups. // IT2Me-specific handling of multiple connection attempts. -class It2MeHostUserInterface : public HostStatusObserver { +class It2MeHostUserInterface : public HostUserInterface { public: - It2MeHostUserInterface(ChromotingHost* host, ChromotingHostContext* context); + It2MeHostUserInterface(ChromotingHostContext* context); virtual ~It2MeHostUserInterface(); - void Init(); + virtual void Start(ChromotingHost* host, + const base::Closure& disconnect_callback) OVERRIDE; // HostStatusObserver implementation. These methods will be called from the // network thread. virtual void OnClientAuthenticated(const std::string& jid) OVERRIDE; - virtual void OnClientDisconnected(const std::string& jid) OVERRIDE; - virtual void OnAccessDenied(const std::string& jid) OVERRIDE; - virtual void OnShutdown() OVERRIDE; - // Shuts down the object and all its resources synchronously. Must - // be called on the UI thread. - void Shutdown(); + protected: + virtual void ProcessOnClientAuthenticated( + const std::string& username) OVERRIDE; + virtual void ProcessOnClientDisconnected() OVERRIDE; private: class TimerTask; - // Allow ChromotingHostTest::SetUp() to call InitFrom(). + // Allow ChromotingHostTest::SetUp() to call StartForTest(). friend class ChromotingHostTest; - // Used by unit-tests as an alternative to Init() so that mock versions of + // Used by unit-tests as an alternative to Start() so that mock versions of // internal objects can be used. - void InitFrom(scoped_ptr<DisconnectWindow> disconnect_window, - scoped_ptr<ContinueWindow> continue_window, - scoped_ptr<LocalInputMonitor> monitor); - - void ProcessOnClientAuthenticated(const std::string& username); - void ProcessOnClientDisconnected(); - - void MonitorLocalInputs(bool enable); - - // Show or hide the Disconnect window on the UI thread. If |show| is false, - // hide the window, ignoring the |username| parameter. - void ShowDisconnectWindow(bool show, const std::string& username); - - // Show or hide the Continue Sharing window on the UI thread. - void ShowContinueWindow(bool show); + void StartForTest( + ChromotingHost* host, + const base::Closure& disconnect_callback, + scoped_ptr<DisconnectWindow> disconnect_window, + scoped_ptr<ContinueWindow> continue_window, + scoped_ptr<LocalInputMonitor> local_input_monitor); // Called by the ContinueWindow implementation (on the UI thread) when the // user dismisses the Continue prompt. void ContinueSession(bool continue_session); - - void StartContinueWindowTimer(bool start); - void OnContinueWindowTimer(); void OnShutdownHostTimer(); - ChromotingHost* host_; - - // Host context used to make sure operations are run on the correct thread. - // This is owned by the ChromotingHost. - ChromotingHostContext* context_; - - // Provide a user interface allowing the host user to close the connection. - scoped_ptr<DisconnectWindow> disconnect_window_; + // Show or hide the Continue Sharing window on the UI thread. + void ShowContinueWindow(bool show); + void StartContinueWindowTimer(bool start); // Provide a user interface requiring the user to periodically re-confirm // the connection. scoped_ptr<ContinueWindow> continue_window_; - // Monitor local inputs to allow remote inputs to be blocked while the local - // user is trying to do something. - scoped_ptr<LocalInputMonitor> local_input_monitor_; - - bool is_monitoring_local_inputs_; - // Timer controlling the "continue session" dialog. scoped_ptr<TimerTask> timer_task_; - ScopedThreadProxy ui_thread_proxy_; - - // The JID of the currently-authenticated user (or an empty string if no user - // is connected). - std::string authenticated_jid_; - DISALLOW_COPY_AND_ASSIGN(It2MeHostUserInterface); }; diff --git a/remoting/host/plugin/host_script_object.cc b/remoting/host/plugin/host_script_object.cc index 83f201f..fd3fa55 100644 --- a/remoting/host/plugin/host_script_object.cc +++ b/remoting/host/plugin/host_script_object.cc @@ -98,9 +98,7 @@ HostNPScriptObject::~HostNPScriptObject() { // Shutdown It2MeHostUserInterface first so that it doesn't try to post // tasks on the UI thread while we are stopping the host. - if (it2me_host_user_interface_.get()) { - it2me_host_user_interface_->Shutdown(); - } + it2me_host_user_interface_.reset(); HostLogHandler::UnregisterLoggingScriptObject(this); @@ -561,9 +559,12 @@ void HostNPScriptObject::FinishConnectNetworkThread( host_->AddStatusObserver(this); log_to_server_.reset( new LogToServer(host_, ServerLogEntry::IT2ME, signal_strategy_.get())); + base::Closure disconnect_callback = base::Bind( + &ChromotingHost::Shutdown, base::Unretained(host_.get()), + base::Closure()); it2me_host_user_interface_.reset( - new It2MeHostUserInterface(host_.get(), host_context_.get())); - it2me_host_user_interface_->Init(); + new It2MeHostUserInterface(host_context_.get())); + it2me_host_user_interface_->Start(host_.get(), disconnect_callback); { base::AutoLock auto_lock(ui_strings_lock_); diff --git a/remoting/host/remoting_me2me_host.cc b/remoting/host/remoting_me2me_host.cc index cf732e3..bb7a7ea 100644 --- a/remoting/host/remoting_me2me_host.cc +++ b/remoting/host/remoting_me2me_host.cc @@ -4,10 +4,6 @@ // // This file implements a standalone host process for Me2Me. -#if defined(OS_WIN) -#include <windows.h> -#endif - #include <string> #include "base/at_exit.h" @@ -36,6 +32,7 @@ #include "remoting/host/heartbeat_sender.h" #include "remoting/host/host_config.h" #include "remoting/host/host_event_logger.h" +#include "remoting/host/host_user_interface.h" #include "remoting/host/json_host_config.h" #include "remoting/host/log_to_server.h" #include "remoting/host/policy_hack/nat_policy.h" @@ -46,6 +43,10 @@ #if defined(OS_MACOSX) #include "remoting/host/sighup_listener_mac.h" #endif +// N.B. OS_WIN is defined by including src/base headers. +#if defined(OS_WIN) +#include <commctrl.h> +#endif #if defined(TOOLKIT_GTK) #include "ui/gfx/gtk_util.h" #endif @@ -198,6 +199,10 @@ class HostProcess return kInvalidHostConfigurationExitCode; } +#if defined(OS_MACOSX) || defined(OS_WIN) + host_user_interface_.reset(new HostUserInterface(context_.get())); +#endif + StartWatchingNatPolicy(); #if defined(OS_MACOSX) || defined(OS_WIN) @@ -208,6 +213,10 @@ class HostProcess #endif message_loop_.Run(); +#if defined(OS_MACOSX) || defined(OS_WIN) + host_user_interface_.reset(); +#endif + base::WaitableEvent done_event(true, false); nat_policy_->StopWatching(&done_event); done_event.Wait(); @@ -381,6 +390,12 @@ class HostProcess new LogToServer(host_, ServerLogEntry::ME2ME, signal_strategy_.get())); host_event_logger_ = HostEventLogger::Create(host_, kApplicationName); +#if defined(OS_MACOSX) || defined(OS_WIN) + host_user_interface_->Start( + host_, + base::Bind(&HostProcess::OnRestartHostRequest, base::Unretained(this))); +#endif + host_->Start(); CreateAuthenticatorFactory(); @@ -390,6 +405,16 @@ class HostProcess Shutdown(kInvalidOauthCredentialsExitCode); } + // Invoked from when the user uses the Disconnect windows to terminate + // the sessions. + void OnRestartHostRequest() { + DCHECK(message_loop_.message_loop_proxy()->BelongsToCurrentThread()); + + context_->network_message_loop()->PostTask( + FROM_HERE, + base::Bind(&HostProcess::RestartHost, base::Unretained(this))); + } + void RestartHost() { DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); @@ -473,6 +498,11 @@ class HostProcess scoped_ptr<HeartbeatSender> heartbeat_sender_; scoped_ptr<LogToServer> log_to_server_; scoped_ptr<HostEventLogger> host_event_logger_; + +#if defined(OS_MACOSX) || defined(OS_WIN) + scoped_ptr<HostUserInterface> host_user_interface_; +#endif + scoped_refptr<ChromotingHost> host_; int exit_code_; @@ -517,11 +547,20 @@ int main(int argc, char** argv) { } #if defined(OS_WIN) +HMODULE g_hModule = NULL; int CALLBACK WinMain(HINSTANCE instance, HINSTANCE previous_instance, LPSTR command_line, int show_command) { + g_hModule = instance; + + // Register and initialize common controls. + INITCOMMONCONTROLSEX info; + info.dwSize = sizeof(info); + info.dwICC = ICC_STANDARD_CLASSES; + InitCommonControlsEx(&info); + // CommandLine::Init() ignores the passed |argc| and |argv| on Windows getting // the command line from GetCommandLineW(), so we can safely pass NULL here. return main(0, NULL); diff --git a/remoting/host/simple_host_process.cc b/remoting/host/simple_host_process.cc index 932f32e..2548741 100644 --- a/remoting/host/simple_host_process.cc +++ b/remoting/host/simple_host_process.cc @@ -235,9 +235,10 @@ class SimpleHost : public HeartbeatSender::Listener { log_to_server_.reset(new LogToServer(host_, mode, signal_strategy_.get())); if (is_it2me_) { - it2me_host_user_interface_.reset( - new It2MeHostUserInterface(host_, &context_)); - it2me_host_user_interface_->Init(); + it2me_host_user_interface_.reset(new It2MeHostUserInterface(&context_)); + it2me_host_user_interface_->Start( + host_, + base::Bind(&ChromotingHost::Shutdown, host_, base::Closure())); } if (protocol_config_.get()) { diff --git a/remoting/remoting.gyp b/remoting/remoting.gyp index 4ffaf97..05f5ddb 100644 --- a/remoting/remoting.gyp +++ b/remoting/remoting.gyp @@ -857,6 +857,9 @@ 'sources': [ 'host/branding.cc', 'host/branding.h', + 'host/host_ui_resource.h', + 'host/host_user_interface.cc', + 'host/host_user_interface.h', 'host/it2me_host_user_interface.cc', 'host/it2me_host_user_interface.h', 'host/plugin/daemon_controller.h', @@ -868,7 +871,6 @@ 'host/plugin/host_log_handler.cc', 'host/plugin/host_log_handler.h', 'host/plugin/host_plugin.cc', - 'host/plugin/host_plugin_resource.h', 'host/plugin/host_plugin_utils.cc', 'host/plugin/host_plugin_utils.h', 'host/plugin/host_script_object.cc', @@ -919,8 +921,8 @@ '<(INTERMEDIATE_DIR)', ], 'sources': [ + 'host/host_ui.rc', 'host/plugin/host_plugin.def', - 'host/plugin/host_plugin.rc', '<(SHARED_INTERMEDIATE_DIR)/remoting/host_plugin_version.rc' ], }], @@ -1302,6 +1304,8 @@ 'host/disconnect_window_mac.h', 'host/disconnect_window_mac.mm', 'host/disconnect_window_win.cc', + 'host/host_user_interface.cc', + 'host/host_user_interface.h', 'host/it2me_host_user_interface.cc', 'host/it2me_host_user_interface.h', 'host/simple_host_process.cc', @@ -1331,6 +1335,8 @@ 'host/branding.cc', 'host/branding.h', 'host/host_event_logger.h', + 'host/host_user_interface.cc', + 'host/host_user_interface.h', 'host/sighup_listener_mac.cc', 'host/sighup_listener_mac.h', 'host/remoting_me2me_host.cc', @@ -1360,6 +1366,7 @@ 'INFOPLIST_PREPROCESSOR_DEFINITIONS': 'VERSION_FULL="<(version_full)" VERSION_SHORT="<(version_short)" BUNDLE_ID="<(host_bundle_id)" COPYRIGHT_BY="<(copyright_by)"', }, 'mac_bundle_resources': [ + 'host/disconnect_window.xib', 'host/remoting_me2me_host.icns', 'host/remoting_me2me_host-Info.plist', ], @@ -1374,6 +1381,7 @@ ], 'sources': [ 'host/host_event_logger_win.cc', + 'host/host_ui.rc', 'host/remoting_host_messages.mc', '<(SHARED_INTERMEDIATE_DIR)/remoting/remoting_me2me_host_version.rc' ], @@ -1399,8 +1407,20 @@ 'message': 'Running message compiler on <(RULE_INPUT_PATH).', }, ], + 'link_settings': { + 'libraries': [ + '-lcomctl32.lib', + ], + }, 'msvs_settings': { 'VCLinkerTool': { + 'AdditionalOptions': [ + "\"/manifestdependency:type='win32' " + "name='Microsoft.Windows.Common-Controls' " + "version='6.0.0.0' " + "processorArchitecture='*' " + "publicKeyToken='6595b64144ccf1df' language='*'\"", + ], # 2 == /SUBSYSTEM:WINDOWS 'SubSystem': '2', }, @@ -1666,6 +1686,8 @@ 'host/host_key_pair_unittest.cc', 'host/host_mock_objects.cc', 'host/host_mock_objects.h', + 'host/host_user_interface.cc', + 'host/host_user_interface.h', 'host/it2me_host_user_interface.cc', 'host/it2me_host_user_interface.h', 'host/json_host_config_unittest.cc', |