1// Copyright (c) 2012 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/captive_portal_window_proxy.h"
6
7#include "chrome/browser/chromeos/login/captive_portal_view.h"
8#include "chrome/browser/chromeos/login/proxy_settings_dialog.h"
9#include "chrome/browser/chromeos/profiles/profile_helper.h"
10#include "components/web_modal/web_contents_modal_dialog_host.h"
11#include "components/web_modal/web_contents_modal_dialog_manager.h"
12#include "components/web_modal/web_contents_modal_dialog_manager_delegate.h"
13#include "ui/views/widget/widget.h"
14
15using web_modal::WebContentsModalDialogManager;
16using web_modal::WebContentsModalDialogManagerDelegate;
17
18namespace chromeos {
19
20CaptivePortalWindowProxy::CaptivePortalWindowProxy(
21    Delegate* delegate,
22    content::WebContents* web_contents)
23    : delegate_(delegate),
24      widget_(NULL),
25      web_contents_(web_contents) {
26  DCHECK(GetState() == STATE_IDLE);
27}
28
29CaptivePortalWindowProxy::~CaptivePortalWindowProxy() {
30  if (!widget_)
31    return;
32  DCHECK(GetState() == STATE_DISPLAYED);
33  widget_->RemoveObserver(this);
34  widget_->Close();
35}
36
37void CaptivePortalWindowProxy::ShowIfRedirected() {
38  if (GetState() != STATE_IDLE)
39    return;
40  InitCaptivePortalView();
41  DCHECK(GetState() == STATE_WAITING_FOR_REDIRECTION);
42}
43
44void CaptivePortalWindowProxy::Show() {
45  if (ProxySettingsDialog::IsShown()) {
46    // ProxySettingsDialog is being shown, don't cover it.
47    Close();
48    return;
49  }
50
51  if (GetState() == STATE_DISPLAYED)  // Dialog is already shown, do nothing.
52    return;
53
54  InitCaptivePortalView();
55
56  CaptivePortalView* captive_portal_view = captive_portal_view_.release();
57  WebContentsModalDialogManager* web_contents_modal_dialog_manager =
58      WebContentsModalDialogManager::FromWebContents(web_contents_);
59  DCHECK(web_contents_modal_dialog_manager);
60  WebContentsModalDialogManagerDelegate* delegate =
61      web_contents_modal_dialog_manager->delegate();
62  DCHECK(delegate);
63  widget_ = views::Widget::CreateWindowAsFramelessChild(
64      captive_portal_view,
65      delegate->GetWebContentsModalDialogHost()->GetHostView());
66  captive_portal_view->Init();
67
68  widget_->AddObserver(this);
69  web_contents_modal_dialog_manager->ShowDialog(widget_->GetNativeView());
70  DCHECK(GetState() == STATE_DISPLAYED);
71}
72
73void CaptivePortalWindowProxy::Close() {
74  if (GetState() == STATE_DISPLAYED)
75    widget_->Close();
76  captive_portal_view_.reset();
77}
78
79void CaptivePortalWindowProxy::OnRedirected() {
80  if (GetState() == STATE_WAITING_FOR_REDIRECTION)
81    Show();
82  delegate_->OnPortalDetected();
83}
84
85void CaptivePortalWindowProxy::OnOriginalURLLoaded() {
86  Close();
87}
88
89void CaptivePortalWindowProxy::OnWidgetClosing(views::Widget* widget) {
90  DCHECK(GetState() == STATE_DISPLAYED);
91  DCHECK(widget == widget_);
92
93  DetachFromWidget(widget);
94
95  DCHECK(GetState() == STATE_IDLE);
96}
97
98void CaptivePortalWindowProxy::OnWidgetDestroying(views::Widget* widget) {
99  DetachFromWidget(widget);
100}
101
102void CaptivePortalWindowProxy::OnWidgetDestroyed(views::Widget* widget) {
103  DetachFromWidget(widget);
104}
105
106void CaptivePortalWindowProxy::InitCaptivePortalView() {
107  DCHECK(GetState() == STATE_IDLE ||
108         GetState() == STATE_WAITING_FOR_REDIRECTION);
109  if (!captive_portal_view_.get()) {
110    captive_portal_view_.reset(
111        new CaptivePortalView(ProfileHelper::GetSigninProfile(), this));
112  }
113  captive_portal_view_->StartLoad();
114}
115
116CaptivePortalWindowProxy::State CaptivePortalWindowProxy::GetState() const {
117  if (widget_ == NULL) {
118    if (captive_portal_view_.get() == NULL)
119      return STATE_IDLE;
120    else
121      return STATE_WAITING_FOR_REDIRECTION;
122  } else {
123    if (captive_portal_view_.get() == NULL)
124      return STATE_DISPLAYED;
125    else
126      NOTREACHED();
127  }
128  return STATE_UNKNOWN;
129}
130
131void CaptivePortalWindowProxy::DetachFromWidget(views::Widget* widget) {
132  if (!widget_ || widget_ != widget)
133    return;
134  widget_->RemoveObserver(this);
135  widget_ = NULL;
136}
137
138}  // namespace chromeos
139