Commit f4691128 authored by kelvinp's avatar kelvinp Committed by Commit bot

Remote assistance on Chrome OS Part V - It2MeHost Continue Window

This CL implements the ContinueWindow on ChromeOS, which will
be shown to the user for confirmation after 10 minutes into a Remote
Assistance session.

To implement the ContinueWindow, this CL introduces a new class
MessageBox, which is a re-usable component built on top of the
widget framework.

BUG=424908

Committed: https://crrev.com/6410d7ad4937a4a86e9ad28b9ecf99f961305b2d
Cr-Commit-Position: refs/heads/master@{#302657}

Review URL: https://codereview.chromium.org/690183002

Cr-Commit-Position: refs/heads/master@{#302706}
parent db77a378
// Copyright 2014 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/chromeos/message_box.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/views/controls/message_box_view.h"
#include "ui/views/widget/widget.h"
#include "ui/views/window/dialog_delegate.h"
namespace remoting {
// MessageBox::Core creates the dialog using the views::DialogWidget. The
// DialogWidget is created by the caller but its lifetime is managed by the
// NativeWidget. The DialogWidget communicates with the caller using the
//.DialogDelegateView interface, which must remain valid until DeleteDelegate()
// is called, at which the DialogDelegateView deletes itself.
//
// The Core class is introduced to abstract this awkward ownership model. The
// Core and the MessageBox hold a raw references to each other, which is
// invalidated when either side are destroyed.
class MessageBox::Core : public views::DialogDelegateView {
public:
Core(const base::string16& title_label,
const base::string16& message_label,
const base::string16& ok_label,
const base::string16& cancel_label,
ResultCallback result_callback,
MessageBox* message_box);
// Mirrors the public MessageBox interface.
void Show();
void Hide();
// views::DialogDelegateView interface.
bool Accept() override;
bool Cancel() override;
ui::ModalType GetModalType() const override;
base::string16 GetWindowTitle() const override;
base::string16 GetDialogButtonLabel(ui::DialogButton button) const override;
// views::WidgetDelegate interface.
views::View* GetContentsView() override;
views::Widget* GetWidget() override;
const views::Widget* GetWidget() const override;
void DeleteDelegate() override;
// Called by MessageBox::Core when it is destroyed.
void OnMessageBoxDestroyed();
private:
const base::string16 title_label_;
const base::string16 ok_label_;
const base::string16 cancel_label_;
ResultCallback result_callback_;
MessageBox* message_box_;
// Owned by the native widget hierarchy.
views::MessageBoxView* message_box_view_;
DISALLOW_COPY_AND_ASSIGN(Core);
};
MessageBox::Core::Core(const base::string16& title_label,
const base::string16& message_label,
const base::string16& ok_label,
const base::string16& cancel_label,
ResultCallback result_callback,
MessageBox* message_box)
: title_label_(title_label),
ok_label_(ok_label),
cancel_label_(cancel_label),
result_callback_(result_callback),
message_box_(message_box),
message_box_view_(new views::MessageBoxView(
views::MessageBoxView::InitParams(message_label))) {
DCHECK(message_box_);
}
void MessageBox::Core::Show() {
// The widget is owned by the NativeWidget. See comments in widget.h.
views::Widget* widget =
CreateDialogWidget(this, /* delegate */
nullptr /* parent window*/,
nullptr /* parent view */);
if (widget) {
widget->Show();
}
}
void MessageBox::Core::Hide() {
if (GetWidget()) {
GetWidget()->Close();
}
}
bool MessageBox::Core::Accept() {
if (!result_callback_.is_null()) {
base::ResetAndReturn(&result_callback_).Run(OK);
}
return true /* close the window*/;
}
bool MessageBox::Core::Cancel() {
if (!result_callback_.is_null()) {
base::ResetAndReturn(&result_callback_).Run(CANCEL);
}
return true /* close the window*/;
}
ui::ModalType MessageBox::Core::GetModalType() const {
return ui::MODAL_TYPE_SYSTEM;
}
base::string16 MessageBox::Core::GetWindowTitle() const {
return title_label_;
}
base::string16 MessageBox::Core::GetDialogButtonLabel(
ui::DialogButton button) const {
switch (button) {
case ui::DIALOG_BUTTON_OK:
return ok_label_;
case ui::DIALOG_BUTTON_CANCEL:
return cancel_label_;
default:
NOTREACHED();
return base::string16();
}
}
views::View* MessageBox::Core::GetContentsView() {
return message_box_view_;
}
views::Widget* MessageBox::Core::GetWidget() {
return message_box_view_->GetWidget();
}
const views::Widget* MessageBox::Core::GetWidget() const {
return message_box_view_->GetWidget();
}
void MessageBox::Core::DeleteDelegate() {
if (message_box_) {
message_box_->core_ = nullptr;
}
delete this;
}
void MessageBox::Core::OnMessageBoxDestroyed() {
DCHECK(message_box_);
message_box_ = nullptr;
// The callback should not be invoked after MessageBox is destroyed.
result_callback_.Reset();
}
MessageBox::MessageBox(const base::string16& title_label,
const base::string16& message_label,
const base::string16& ok_label,
const base::string16& cancel_label,
ResultCallback result_callback)
: core_(new Core(title_label,
message_label,
ok_label,
cancel_label,
result_callback,
this)) {
thread_checker_.DetachFromThread();
}
MessageBox::~MessageBox() {
if (core_) {
core_->OnMessageBoxDestroyed();
core_->Hide();
core_ = nullptr;
}
}
void MessageBox::Show() {
DCHECK(thread_checker_.CalledOnValidThread());
core_->Show();
}
void MessageBox::Hide() {
DCHECK(thread_checker_.CalledOnValidThread());
if (core_) {
core_->Hide();
}
}
} // namespace remoting
// Copyright 2014 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_CHROMEOS_MESSAGE_BOX_H_
#define REMOTING_HOST_CHROMEOS_MESSAGE_BOX_H_
#include "base/callback_helpers.h"
#include "base/strings/string16.h"
#include "base/threading/thread_checker.h"
namespace remoting {
// Overview:
// Shows a system modal message box with OK and cancel buttons. This class
// is not thread-safe, it must be called on the UI thread of the browser
// process.
class MessageBox {
public:
enum Result {
OK,
CANCEL
};
// ResultCallback will be invoked with Result::Cancel if the user closes the
// MessageBox without clicking on any buttons.
typedef base::Callback<void(Result)> ResultCallback;
MessageBox(const base::string16& title_label,
const base::string16& message_label,
const base::string16& ok_label,
const base::string16& cancel_label,
ResultCallback result_callback);
~MessageBox();
void Show();
void Hide();
private:
class Core;
Core* core_;
base::ThreadChecker thread_checker_;
DISALLOW_COPY_AND_ASSIGN(MessageBox);
};
} // namespace remoting
#endif // REMOTING_HOST_CHROMEOS_MESSAGE_BOX_H_
...@@ -4,41 +4,59 @@ ...@@ -4,41 +4,59 @@
#include "remoting/host/continue_window.h" #include "remoting/host/continue_window.h"
#include "remoting/base/string_resources.h"
#include "remoting/host/chromeos/message_box.h"
#include "ui/base/l10n/l10n_util.h"
namespace remoting { namespace remoting {
namespace { namespace {
// A place holder implementation for the ContinueWindow on
// ChromeOS. Remote assistance on Chrome OS is currently under a flag so it is
// secure to leave it unimplemented for now.
class ContinueWindowAura : public ContinueWindow { class ContinueWindowAura : public ContinueWindow {
public: public:
ContinueWindowAura(); ContinueWindowAura();
~ContinueWindowAura() override; ~ContinueWindowAura() override;
void OnMessageBoxResult(MessageBox::Result result);
protected: protected:
// ContinueWindow interface. // ContinueWindow interface.
void ShowUi() override; void ShowUi() override;
void HideUi() override; void HideUi() override;
private: private:
scoped_ptr<MessageBox> message_box_;
DISALLOW_COPY_AND_ASSIGN(ContinueWindowAura); DISALLOW_COPY_AND_ASSIGN(ContinueWindowAura);
}; };
ContinueWindowAura::ContinueWindowAura() { ContinueWindowAura::ContinueWindowAura() {
message_box_.reset(new MessageBox(
l10n_util::GetStringUTF16(IDS_MODE_IT2ME), // title
l10n_util::GetStringUTF16(IDS_CONTINUE_PROMPT), // dialog label
l10n_util::GetStringUTF16(IDS_CONTINUE_BUTTON), // ok label
l10n_util::GetStringUTF16(IDS_STOP_SHARING_BUTTON), // cancel label
base::Bind(&ContinueWindowAura::OnMessageBoxResult,
base::Unretained(this))));
} }
ContinueWindowAura::~ContinueWindowAura() { ContinueWindowAura::~ContinueWindowAura() {
message_box_->Hide();
}
void ContinueWindowAura::OnMessageBoxResult(MessageBox::Result result) {
if (result == MessageBox::OK) {
ContinueSession();
} else {
DisconnectSession();
}
} }
void ContinueWindowAura::ShowUi() { void ContinueWindowAura::ShowUi() {
// TODO(kelvinp): Implement this on Chrome OS (See crbug.com/424908). message_box_->Show();
NOTIMPLEMENTED();
} }
void ContinueWindowAura::HideUi() { void ContinueWindowAura::HideUi() {
// TODO(kelvinp): Implement this on Chrome OS (See crbug.com/424908). message_box_->Hide();
NOTIMPLEMENTED();
} }
} // namespace } // namespace
......
...@@ -74,6 +74,8 @@ ...@@ -74,6 +74,8 @@
'host/capture_scheduler.h', 'host/capture_scheduler.h',
'host/chromeos/aura_desktop_capturer.cc', 'host/chromeos/aura_desktop_capturer.cc',
'host/chromeos/aura_desktop_capturer.h', 'host/chromeos/aura_desktop_capturer.h',
'host/chromeos/message_box.cc',
'host/chromeos/message_box.h',
'host/chromium_port_allocator_factory.cc', 'host/chromium_port_allocator_factory.cc',
'host/chromium_port_allocator_factory.h', 'host/chromium_port_allocator_factory.h',
'host/chromoting_host.cc', 'host/chromoting_host.cc',
...@@ -328,6 +330,8 @@ ...@@ -328,6 +330,8 @@
'../skia/skia.gyp:skia', '../skia/skia.gyp:skia',
'../ui/aura/aura.gyp:aura', '../ui/aura/aura.gyp:aura',
'../ui/compositor/compositor.gyp:compositor', '../ui/compositor/compositor.gyp:compositor',
'../ui/events/events.gyp:events',
'../ui/views/views.gyp:views',
], ],
'include_dirs': [ 'include_dirs': [
'../third_party/skia/include/utils', '../third_party/skia/include/utils',
...@@ -343,6 +347,8 @@ ...@@ -343,6 +347,8 @@
'sources!' : [ 'sources!' : [
'host/chromeos/aura_desktop_capturer.cc', 'host/chromeos/aura_desktop_capturer.cc',
'host/chromeos/aura_desktop_capturer.h', 'host/chromeos/aura_desktop_capturer.h',
'host/chromeos/message_box.cc',
'host/chromeos/message_box.h',
'host/continue_window_chromeos.cc', 'host/continue_window_chromeos.cc',
'host/disconnect_window_chromeos.cc', 'host/disconnect_window_chromeos.cc',
'host/policy_hack/policy_watcher_chromeos.cc', 'host/policy_hack/policy_watcher_chromeos.cc',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment