| Index: remoting/host/disconnect_window_win.cc
|
| diff --git a/remoting/host/disconnect_window_win.cc b/remoting/host/disconnect_window_win.cc
|
| index effe964cdb2b14f2e31eedde3884b79ac595bcb3..173ad46020f36773c06cd21a99c40f9b81c4e30c 100644
|
| --- a/remoting/host/disconnect_window_win.cc
|
| +++ b/remoting/host/disconnect_window_win.cc
|
| @@ -2,24 +2,23 @@
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| -#include "remoting/host/disconnect_window.h"
|
| -
|
| #include <windows.h>
|
|
|
| +#include "base/bind.h"
|
| #include "base/compiler_specific.h"
|
| #include "base/logging.h"
|
| #include "base/process_util.h"
|
| +#include "base/single_thread_task_runner.h"
|
| #include "base/string_util.h"
|
| #include "base/utf_string_conversions.h"
|
| #include "base/win/scoped_gdi_object.h"
|
| #include "base/win/scoped_hdc.h"
|
| #include "base/win/scoped_select_object.h"
|
| +#include "remoting/host/host_window.h"
|
| #include "remoting/host/ui_strings.h"
|
| #include "remoting/host/win/core_resource.h"
|
|
|
| -// TODO(garykac): Lots of duplicated code in this file and
|
| -// continue_window_win.cc. If we need to expand this then we should
|
| -// create a class with the shared code.
|
| +namespace remoting {
|
|
|
| namespace {
|
|
|
| @@ -32,28 +31,30 @@ const size_t kMaxSharingWithTextLength = 100;
|
| const wchar_t kShellTrayWindowName[] = L"Shell_TrayWnd";
|
| const int kWindowBorderRadius = 14;
|
|
|
| -} // namespace anonymous
|
| -
|
| -namespace remoting {
|
| -
|
| -class DisconnectWindowWin : public DisconnectWindow {
|
| +class DisconnectWindowWin : public HostWindow::Core {
|
| public:
|
| - explicit DisconnectWindowWin(const UiStrings* ui_strings);
|
| + DisconnectWindowWin(
|
| + scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
|
| + scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
|
| + const base::Closure& disconnect_callback,
|
| + const std::string& username,
|
| + const UiStrings& ui_strings);
|
| +
|
| + protected:
|
| + friend class base::RefCountedThreadSafe<Core>;
|
| virtual ~DisconnectWindowWin();
|
|
|
| - // DisconnectWindow interface.
|
| - virtual bool Show(const base::Closure& disconnect_callback,
|
| - const std::string& username) OVERRIDE;
|
| - virtual void Hide() OVERRIDE;
|
| + // HostWindow::Core overrides.
|
| + virtual void StartOnUiThread() OVERRIDE;
|
| + virtual void StopOnUiThread() OVERRIDE;
|
|
|
| -private:
|
| static INT_PTR CALLBACK DialogProc(HWND hwnd, UINT message, WPARAM wparam,
|
| LPARAM lparam);
|
|
|
| BOOL OnDialogMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
|
|
| // Creates the dialog window and registers the disconnect hot key.
|
| - bool BeginDialog(const std::string& username);
|
| + bool BeginDialog();
|
|
|
| // Closes the dialog, unregisters the hot key and invokes the disconnect
|
| // callback, if set.
|
| @@ -63,20 +64,23 @@ private:
|
| void SetDialogPosition();
|
|
|
| // Applies localization string and resizes the dialog.
|
| - bool SetStrings(const string16& username);
|
| + bool SetStrings();
|
|
|
| + // Invoked in the |caller_task_runner_| thread to disconnect the client
|
| + // session.
|
| base::Closure disconnect_callback_;
|
| +
|
| + // Specifies the remote user name.
|
| + std::string username_;
|
| +
|
| HWND hwnd_;
|
| bool has_hotkey_;
|
| base::win::ScopedGDIObject<HPEN> border_pen_;
|
|
|
| - // Points to the localized strings.
|
| - const UiStrings* ui_strings_;
|
| -
|
| DISALLOW_COPY_AND_ASSIGN(DisconnectWindowWin);
|
| };
|
|
|
| -static int GetControlTextWidth(HWND control) {
|
| +int GetControlTextWidth(HWND control) {
|
| RECT rect = {0, 0, 0, 0};
|
| WCHAR text[256];
|
| int result = GetWindowText(control, text, arraysize(text));
|
| @@ -89,41 +93,45 @@ static int GetControlTextWidth(HWND control) {
|
| return rect.right;
|
| }
|
|
|
| -DisconnectWindowWin::DisconnectWindowWin(const UiStrings* ui_strings)
|
| - : hwnd_(NULL),
|
| +DisconnectWindowWin::DisconnectWindowWin(
|
| + scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
|
| + scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
|
| + const base::Closure& disconnect_callback,
|
| + const std::string& username,
|
| + const UiStrings& ui_strings)
|
| + : HostWindow::Core(caller_task_runner,
|
| + ui_task_runner,
|
| + ui_strings),
|
| + disconnect_callback_(disconnect_callback),
|
| + username_(username),
|
| + hwnd_(NULL),
|
| has_hotkey_(false),
|
| border_pen_(CreatePen(PS_SOLID, 5,
|
| - RGB(0.13 * 255, 0.69 * 255, 0.11 * 255))),
|
| - ui_strings_(ui_strings) {
|
| + RGB(0.13 * 255, 0.69 * 255, 0.11 * 255))) {
|
| }
|
|
|
| DisconnectWindowWin::~DisconnectWindowWin() {
|
| - Hide();
|
| }
|
|
|
| -bool DisconnectWindowWin::Show(const base::Closure& disconnect_callback,
|
| - const std::string& username) {
|
| - DCHECK(disconnect_callback_.is_null());
|
| - DCHECK(!disconnect_callback.is_null());
|
| -
|
| - disconnect_callback_ = disconnect_callback;
|
| +void DisconnectWindowWin::StartOnUiThread() {
|
| + DCHECK(ui_task_runner()->BelongsToCurrentThread());
|
|
|
| - if (BeginDialog(username)) {
|
| - return true;
|
| - } else {
|
| - Hide();
|
| - return false;
|
| + if (!BeginDialog()) {
|
| + StopOnUiThread();
|
| + caller_task_runner()->PostTask(FROM_HERE, disconnect_callback_);
|
| }
|
| }
|
|
|
| -void DisconnectWindowWin::Hide() {
|
| - // Clear the |disconnect_callback_| so it won't be invoked by EndDialog().
|
| - disconnect_callback_.Reset();
|
| +void DisconnectWindowWin::StopOnUiThread() {
|
| + DCHECK(ui_task_runner()->BelongsToCurrentThread());
|
| +
|
| EndDialog();
|
| }
|
|
|
| -INT_PTR CALLBACK DisconnectWindowWin::DialogProc(HWND hwnd, UINT message,
|
| - WPARAM wparam, LPARAM lparam) {
|
| +INT_PTR CALLBACK DisconnectWindowWin::DialogProc(HWND hwnd,
|
| + UINT message,
|
| + WPARAM wparam,
|
| + LPARAM lparam) {
|
| LONG_PTR self = NULL;
|
| if (message == WM_INITDIALOG) {
|
| self = lparam;
|
| @@ -144,8 +152,12 @@ INT_PTR CALLBACK DisconnectWindowWin::DialogProc(HWND hwnd, UINT message,
|
| return FALSE;
|
| }
|
|
|
| -BOOL DisconnectWindowWin::OnDialogMessage(HWND hwnd, UINT message,
|
| - WPARAM wparam, LPARAM lparam) {
|
| +BOOL DisconnectWindowWin::OnDialogMessage(HWND hwnd,
|
| + UINT message,
|
| + WPARAM wparam,
|
| + LPARAM lparam) {
|
| + DCHECK(ui_task_runner()->BelongsToCurrentThread());
|
| +
|
| switch (message) {
|
| // Ignore close messages.
|
| case WM_CLOSE:
|
| @@ -210,7 +222,8 @@ BOOL DisconnectWindowWin::OnDialogMessage(HWND hwnd, UINT message,
|
| return FALSE;
|
| }
|
|
|
| -bool DisconnectWindowWin::BeginDialog(const std::string& username) {
|
| +bool DisconnectWindowWin::BeginDialog() {
|
| + DCHECK(ui_task_runner()->BelongsToCurrentThread());
|
| DCHECK(!hwnd_);
|
|
|
| // Load the dialog resource so that we can modify the RTL flags if necessary.
|
| @@ -233,7 +246,7 @@ bool DisconnectWindowWin::BeginDialog(const std::string& username) {
|
| // standard headers, so we treat it as a generic pointer and manipulate the
|
| // correct offsets explicitly.
|
| scoped_array<unsigned char> rtl_dialog_template;
|
| - if (ui_strings_->direction == UiStrings::RTL) {
|
| + if (ui_strings().direction == UiStrings::RTL) {
|
| unsigned long dialog_template_size =
|
| SizeofResource(module, dialog_resource);
|
| rtl_dialog_template.reset(new unsigned char[dialog_template_size]);
|
| @@ -254,7 +267,7 @@ bool DisconnectWindowWin::BeginDialog(const std::string& username) {
|
| has_hotkey_ = true;
|
| }
|
|
|
| - if (!SetStrings(UTF8ToUTF16(username)))
|
| + if (!SetStrings())
|
| return false;
|
|
|
| SetDialogPosition();
|
| @@ -263,6 +276,8 @@ bool DisconnectWindowWin::BeginDialog(const std::string& username) {
|
| }
|
|
|
| void DisconnectWindowWin::EndDialog() {
|
| + DCHECK(ui_task_runner()->BelongsToCurrentThread());
|
| +
|
| if (has_hotkey_) {
|
| UnregisterHotKey(hwnd_, DISCONNECT_HOTKEY_ID);
|
| has_hotkey_ = false;
|
| @@ -273,13 +288,12 @@ void DisconnectWindowWin::EndDialog() {
|
| hwnd_ = NULL;
|
| }
|
|
|
| - if (!disconnect_callback_.is_null()) {
|
| - disconnect_callback_.Run();
|
| - disconnect_callback_.Reset();
|
| - }
|
| + caller_task_runner()->PostTask(FROM_HERE, disconnect_callback_);
|
| }
|
|
|
| void DisconnectWindowWin::SetDialogPosition() {
|
| + DCHECK(ui_task_runner()->BelongsToCurrentThread());
|
| +
|
| // Try to center the window above the task-bar. If that fails, use the
|
| // primary monitor. If that fails (very unlikely), use the default position.
|
| HWND taskbar = FindWindow(kShellTrayWindowName, NULL);
|
| @@ -297,8 +311,10 @@ void DisconnectWindowWin::SetDialogPosition() {
|
| }
|
| }
|
|
|
| -bool DisconnectWindowWin::SetStrings(const string16& username) {
|
| - if (!SetWindowText(hwnd_, ui_strings_->product_name.c_str()))
|
| +bool DisconnectWindowWin::SetStrings() {
|
| + DCHECK(ui_task_runner()->BelongsToCurrentThread());
|
| +
|
| + if (!SetWindowText(hwnd_, ui_strings().product_name.c_str()))
|
| return false;
|
|
|
| // Localize the disconnect button text and measure length of the old and new
|
| @@ -308,7 +324,7 @@ bool DisconnectWindowWin::SetStrings(const string16& username) {
|
| return false;
|
| int button_old_required_width = GetControlTextWidth(disconnect_button);
|
| if (!SetWindowText(disconnect_button,
|
| - ui_strings_->disconnect_button_text.c_str())) {
|
| + ui_strings().disconnect_button_text.c_str())) {
|
| return false;
|
| }
|
| int button_new_required_width = GetControlTextWidth(disconnect_button);
|
| @@ -316,8 +332,8 @@ bool DisconnectWindowWin::SetStrings(const string16& username) {
|
| button_new_required_width - button_old_required_width;
|
|
|
| // Format and truncate "Your desktop is shared with ..." message.
|
| - string16 text = ReplaceStringPlaceholders(ui_strings_->disconnect_message,
|
| - username, NULL);
|
| + string16 text = ReplaceStringPlaceholders(ui_strings().disconnect_message,
|
| + UTF8ToUTF16(username_), NULL);
|
| if (text.length() > kMaxSharingWithTextLength)
|
| text.erase(kMaxSharingWithTextLength);
|
|
|
| @@ -385,9 +401,20 @@ bool DisconnectWindowWin::SetStrings(const string16& username) {
|
| return true;
|
| }
|
|
|
| -scoped_ptr<DisconnectWindow> DisconnectWindow::Create(
|
| - const UiStrings* ui_strings) {
|
| - return scoped_ptr<DisconnectWindow>(new DisconnectWindowWin(ui_strings));
|
| +} // namespace
|
| +
|
| +scoped_ptr<HostWindow> HostWindow::CreateDisconnectWindow(
|
| + scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
|
| + scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
|
| + const base::Closure& disconnect_callback,
|
| + const std::string& username,
|
| + const UiStrings& ui_strings) {
|
| + scoped_refptr<Core> core = new DisconnectWindowWin(caller_task_runner,
|
| + ui_task_runner,
|
| + disconnect_callback,
|
| + username,
|
| + ui_strings);
|
| + return scoped_ptr<HostWindow>(new HostWindow(core));
|
| }
|
|
|
| } // namespace remoting
|
|
|