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