1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/chromeos/login/ui/login_web_dialog.h"
6
7#include <deque>
8
9#include "base/lazy_instance.h"
10#include "base/strings/utf_string_conversions.h"
11#include "chrome/browser/chromeos/login/helper.h"
12#include "chrome/browser/ui/browser_dialogs.h"
13#include "content/public/browser/browser_context.h"
14#include "content/public/browser/notification_source.h"
15#include "content/public/browser/notification_types.h"
16#include "content/public/browser/web_contents.h"
17#include "ui/gfx/native_widget_types.h"
18#include "ui/gfx/rect.h"
19#include "ui/gfx/size.h"
20#include "ui/views/widget/widget.h"
21
22using content::WebContents;
23using content::WebUIMessageHandler;
24
25namespace chromeos {
26
27namespace {
28
29// Default width/height ratio of screen size.
30const double kDefaultWidthRatio = 0.6;
31const double kDefaultHeightRatio = 0.6;
32
33// Default width/height ratio of minimal dialog size.
34const double kMinimumWidthRatio = 0.25;
35const double kMinimumHeightRatio = 0.25;
36
37static base::LazyInstance<std::deque<content::WebContents*> >
38    g_web_contents_stack = LAZY_INSTANCE_INITIALIZER;
39
40}  // namespace
41
42///////////////////////////////////////////////////////////////////////////////
43// LoginWebDialog, public:
44
45void LoginWebDialog::Delegate::OnDialogClosed() {
46}
47
48LoginWebDialog::LoginWebDialog(content::BrowserContext* browser_context,
49                               Delegate* delegate,
50                               gfx::NativeWindow parent_window,
51                               const base::string16& title,
52                               const GURL& url,
53                               Style style)
54    : browser_context_(browser_context),
55      parent_window_(parent_window),
56      delegate_(delegate),
57      title_(title),
58      url_(url),
59      style_(style),
60      is_open_(false) {
61  gfx::Rect screen_bounds(chromeos::CalculateScreenBounds(gfx::Size()));
62  width_ = static_cast<int>(kDefaultWidthRatio * screen_bounds.width());
63  height_ = static_cast<int>(kDefaultHeightRatio * screen_bounds.height());
64}
65
66LoginWebDialog::~LoginWebDialog() {
67  delegate_ = NULL;
68}
69
70void LoginWebDialog::Show() {
71  chrome::ShowWebDialog(parent_window_, browser_context_, this);
72  is_open_ = true;
73}
74
75void LoginWebDialog::SetDialogSize(int width, int height) {
76  DCHECK(width >= 0 && height >= 0);
77  width_ = width;
78  height_ = height;
79}
80
81void LoginWebDialog::SetDialogTitle(const base::string16& title) {
82  title_ = title;
83}
84
85///////////////////////////////////////////////////////////////////////////////
86// LoginWebDialog, protected:
87
88ui::ModalType LoginWebDialog::GetDialogModalType() const {
89  return ui::MODAL_TYPE_SYSTEM;
90}
91
92base::string16 LoginWebDialog::GetDialogTitle() const {
93  return title_;
94}
95
96GURL LoginWebDialog::GetDialogContentURL() const {
97  return url_;
98}
99
100void LoginWebDialog::GetWebUIMessageHandlers(
101    std::vector<WebUIMessageHandler*>* handlers) const {
102}
103
104void LoginWebDialog::GetDialogSize(gfx::Size* size) const {
105  size->SetSize(width_, height_);
106}
107
108void LoginWebDialog::GetMinimumDialogSize(gfx::Size* size) const {
109  gfx::Rect screen_bounds(chromeos::CalculateScreenBounds(gfx::Size()));
110  size->SetSize(kMinimumWidthRatio * screen_bounds.width(),
111                kMinimumHeightRatio * screen_bounds.height());
112}
113
114std::string LoginWebDialog::GetDialogArgs() const {
115  return std::string();
116}
117
118// static.
119content::WebContents* LoginWebDialog::GetCurrentWebContents() {
120  if (!g_web_contents_stack.Pointer()->size())
121    return NULL;
122
123  return g_web_contents_stack.Pointer()->front();
124}
125
126void LoginWebDialog::OnDialogShown(content::WebUI* webui,
127                                   content::RenderViewHost* render_view_host) {
128  g_web_contents_stack.Pointer()->push_front(webui->GetWebContents());
129}
130
131void LoginWebDialog::OnDialogClosed(const std::string& json_retval) {
132  is_open_ = false;
133  notification_registrar_.RemoveAll();
134  if (delegate_)
135    delegate_->OnDialogClosed();
136  delete this;
137}
138
139void LoginWebDialog::OnCloseContents(WebContents* source,
140                                     bool* out_close_dialog) {
141  if (out_close_dialog)
142    *out_close_dialog = true;
143
144  if (g_web_contents_stack.Pointer()->size() &&
145      source == g_web_contents_stack.Pointer()->front()) {
146    g_web_contents_stack.Pointer()->pop_front();
147  } else {
148    NOTREACHED();
149  }
150}
151
152bool LoginWebDialog::ShouldShowDialogTitle() const {
153  return true;
154}
155
156bool LoginWebDialog::HandleContextMenu(
157    const content::ContextMenuParams& params) {
158  // Disable context menu.
159  return true;
160}
161
162void LoginWebDialog::Observe(int type,
163                             const content::NotificationSource& source,
164                             const content::NotificationDetails& details) {
165  DCHECK(type == content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME);
166  // TODO(saintlou): Do we need a throbber for Aura?
167  NOTIMPLEMENTED();
168}
169
170}  // namespace chromeos
171