Implements frame sniffer to watch iframe loading state.

Also sniffer listener was implemented on the WebUI side, which signals when
GAIA page loading error appears.

BUG=chromium-os:18744
TEST=Behind captive portal, try to click 'Add new user'. Corresponding message page should be shown.

Review URL: http://codereview.chromium.org/7779010

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@99777 0039d316-1c4b-4281-b951-d872f2087c98
parent 21c7ff9a
...@@ -13317,6 +13317,9 @@ Keep your key file in a safe place. You will need it to create new versions of y ...@@ -13317,6 +13317,9 @@ Keep your key file in a safe place. You will need it to create new versions of y
<message name="IDS_LOGIN_FIX_CAPTIVE_PORTAL" desc="An link text to fix Internet connection (captive portal) in guest mode."> <message name="IDS_LOGIN_FIX_CAPTIVE_PORTAL" desc="An link text to fix Internet connection (captive portal) in guest mode.">
Start a Guest session Start a Guest session
</message> </message>
<message name="IDS_LOGIN_MAYBE_CAPTIVE_PORTAL" desc="An offline message shown when we suggest that user may be behind the captive portal.">
Connected to a network, but still can't sign in? You might be on a network that requires a web-based authentication. Start a guest browsing session (if available) and see if a network log-in page appears. Once you're logged in to the network and are able to visit different web pages, exit the guest session and try signing in again.
</message>
<message name="IDS_LOGIN_ERROR_CAPTIVE_PORTAL_NO_GUEST_MODE" desc="An error message shown when we suggest that user may be behind the captive portal but Guest mode is disabled."> <message name="IDS_LOGIN_ERROR_CAPTIVE_PORTAL_NO_GUEST_MODE" desc="An error message shown when we suggest that user may be behind the captive portal but Guest mode is disabled.">
Your password cannot be verified on this current network. Please select another network. Your password cannot be verified on this current network. Please select another network.
</message> </message>
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
#include "chrome/browser/chromeos/login/webui_login_view.h" #include "chrome/browser/chromeos/login/webui_login_view.h"
#include "base/i18n/rtl.h" #include "base/i18n/rtl.h"
#include "base/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/browser/chromeos/accessibility_util.h" #include "chrome/browser/chromeos/accessibility_util.h"
#include "chrome/browser/chromeos/login/proxy_settings_dialog.h" #include "chrome/browser/chromeos/login/proxy_settings_dialog.h"
#include "chrome/browser/chromeos/login/webui_login_display.h" #include "chrome/browser/chromeos/login/webui_login_display.h"
...@@ -15,6 +17,8 @@ ...@@ -15,6 +17,8 @@
#include "chrome/browser/chromeos/wm_ipc.h" #include "chrome/browser/chromeos/wm_ipc.h"
#include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/ui/views/dom_view.h" #include "chrome/browser/ui/views/dom_view.h"
#include "chrome/common/render_messages.h"
#include "content/browser/renderer_host/render_view_host_observer.h"
#include "content/browser/tab_contents/tab_contents.h" #include "content/browser/tab_contents/tab_contents.h"
#include "ui/gfx/rect.h" #include "ui/gfx/rect.h"
#include "ui/gfx/size.h" #include "ui/gfx/size.h"
...@@ -33,6 +37,39 @@ const char kViewClassName[] = "browser/chromeos/login/WebUILoginView"; ...@@ -33,6 +37,39 @@ const char kViewClassName[] = "browser/chromeos/login/WebUILoginView";
const char kAccelNameAccessibility[] = "accessibility"; const char kAccelNameAccessibility[] = "accessibility";
const char kAccelNameEnrollment[] = "enrollment"; const char kAccelNameEnrollment[] = "enrollment";
// Observes IPC messages from the FrameSniffer and notifies JS if error
// appears.
class SnifferObserver : public RenderViewHostObserver {
public:
SnifferObserver(RenderViewHost* host, WebUI* webui)
: RenderViewHostObserver(host), webui_(webui) {
DCHECK(webui_);
Send(new ChromeViewMsg_StartFrameSniffer(routing_id(),
UTF8ToUTF16("gaia-frame")));
}
virtual ~SnifferObserver() {}
// IPC::Channel::Listener implementation.
virtual bool OnMessageReceived(const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(SnifferObserver, message)
IPC_MESSAGE_HANDLER(ChromeViewHostMsg_FrameLoadingError, OnError)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
}
private:
void OnError(int error) {
base::FundamentalValue error_value(error);
webui_->CallJavascriptFunction("login.OfflineMessageScreen.onFrameError",
error_value);
}
WebUI* webui_;
};
// A View class which places its first child at the right most position. // A View class which places its first child at the right most position.
class RightAlignedView : public views::View { class RightAlignedView : public views::View {
public: public:
...@@ -53,7 +90,6 @@ void RightAlignedView::ChildPreferredSizeChanged(View* child) { ...@@ -53,7 +90,6 @@ void RightAlignedView::ChildPreferredSizeChanged(View* child) {
Layout(); Layout();
} }
} // namespace } // namespace
namespace chromeos { namespace chromeos {
...@@ -226,6 +262,10 @@ void WebUILoginView::OnLocaleChanged() { ...@@ -226,6 +262,10 @@ void WebUILoginView::OnLocaleChanged() {
SchedulePaint(); SchedulePaint();
} }
void WebUILoginView::OnRenderHostCreated(RenderViewHost* host) {
new SnifferObserver(host, GetWebUI());
}
void WebUILoginView::OnTabMainFrameLoaded() { void WebUILoginView::OnTabMainFrameLoaded() {
} }
......
...@@ -91,6 +91,7 @@ class WebUILoginView : public views::View, ...@@ -91,6 +91,7 @@ class WebUILoginView : public views::View,
virtual void OnLocaleChanged() OVERRIDE; virtual void OnLocaleChanged() OVERRIDE;
// TabFirstRenderWatcher::Delegate implementation. // TabFirstRenderWatcher::Delegate implementation.
virtual void OnRenderHostCreated(RenderViewHost* host) OVERRIDE;
virtual void OnTabMainFrameLoaded() OVERRIDE; virtual void OnTabMainFrameLoaded() OVERRIDE;
virtual void OnTabMainFrameFirstRender() OVERRIDE; virtual void OnTabMainFrameFirstRender() OVERRIDE;
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "chrome/browser/chromeos/tab_first_render_watcher.h" #include "chrome/browser/chromeos/tab_first_render_watcher.h"
#include "content/browser/renderer_host/render_widget_host.h" #include "content/browser/renderer_host/render_widget_host.h"
#include "content/browser/renderer_host/render_view_host.h"
#include "content/common/content_notification_types.h" #include "content/common/content_notification_types.h"
#include "content/common/notification_details.h" #include "content/common/notification_details.h"
#include "content/common/notification_source.h" #include "content/common/notification_source.h"
...@@ -32,6 +33,7 @@ void TabFirstRenderWatcher::Observe(int type, ...@@ -32,6 +33,7 @@ void TabFirstRenderWatcher::Observe(int type,
registrar_.Add(this, registrar_.Add(this,
content::NOTIFICATION_RENDER_WIDGET_HOST_DID_PAINT, content::NOTIFICATION_RENDER_WIDGET_HOST_DID_PAINT,
Source<RenderWidgetHost>(rwh)); Source<RenderWidgetHost>(rwh));
delegate_->OnRenderHostCreated(Details<RenderViewHost>(details).ptr());
break; break;
} }
case content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME: case content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME:
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "content/common/notification_observer.h" #include "content/common/notification_observer.h"
#include "content/common/notification_registrar.h" #include "content/common/notification_registrar.h"
class RenderViewHost;
class TabContents; class TabContents;
namespace chromeos { namespace chromeos {
...@@ -20,6 +21,7 @@ class TabFirstRenderWatcher : public NotificationObserver { ...@@ -20,6 +21,7 @@ class TabFirstRenderWatcher : public NotificationObserver {
public: public:
class Delegate { class Delegate {
public: public:
virtual void OnRenderHostCreated(RenderViewHost* host) = 0;
virtual void OnTabMainFrameLoaded() = 0; virtual void OnTabMainFrameLoaded() = 0;
virtual void OnTabMainFrameFirstRender() = 0; virtual void OnTabMainFrameFirstRender() = 0;
}; };
......
...@@ -225,7 +225,6 @@ cr.define('cr.ui', function() { ...@@ -225,7 +225,6 @@ cr.define('cr.ui', function() {
prepareForLoginDisplay_ : function() { prepareForLoginDisplay_ : function() {
for (var i = 0, screenId; screenId = this.screens_[i]; ++i) { for (var i = 0, screenId; screenId = this.screens_[i]; ++i) {
var screen = $(screenId); var screen = $(screenId);
screen.classList.add('faded'); screen.classList.add('faded');
screen.classList.remove('right'); screen.classList.remove('right');
screen.classList.remove('left'); screen.classList.remove('left');
......
...@@ -144,6 +144,7 @@ cr.define('login', function() { ...@@ -144,6 +144,7 @@ cr.define('login', function() {
chrome.send('completeLogin', [msg.email, msg.password] ); chrome.send('completeLogin', [msg.email, msg.password] );
this.loading = true; this.loading = true;
} else if (msg.method == 'loginUILoaded' && this.isAuthExtMessage_(e)) { } else if (msg.method == 'loginUILoaded' && this.isAuthExtMessage_(e)) {
$('offline-message').update();
this.loading = false; this.loading = false;
chrome.send('loginWebuiReady'); chrome.send('loginWebuiReady');
} }
......
<div id="offline-message" class="step faded hidden"> <div id="offline-message" class="step faded hidden">
<span id="offline-message-title" i18n-content="offlineMessageTitle"></span> <span id="offline-message-title" i18n-content="offlineMessageTitle"></span>
<span id="offline-message-body" i18n-content="offlineMessageBody"></span> <div id="offline-message-body">
<span id="offline-message-text" i18n-content="offlineMessageBody"></span>
<span id="captive-portal-message-text" hidden
i18n-content="captivePortalMessage"></span>
</div>
</div> </div>
...@@ -49,15 +49,20 @@ cr.define('login', function() { ...@@ -49,15 +49,20 @@ cr.define('login', function() {
var shouldOverlay = MANAGED_SCREENS.indexOf(currentScreen.id) != -1; var shouldOverlay = MANAGED_SCREENS.indexOf(currentScreen.id) != -1;
if (isOffline && shouldOverlay) { if (isOffline && shouldOverlay) {
$('offline-message-text').hidden = false;
$('captive-portal-message-text').hidden = true;
offlineMessage.classList.remove('hidden'); offlineMessage.classList.remove('hidden');
offlineMessage.classList.remove('faded'); offlineMessage.classList.remove('faded');
currentScreen.classList.add('faded'); if (!currentScreen.classList.contains('faded')) {
currentScreen.addEventListener('webkitTransitionEnd', currentScreen.classList.add('faded');
function f(e) { currentScreen.addEventListener('webkitTransitionEnd',
currentScreen.removeEventListener('webkitTransitionEnd', f); function f(e) {
currentScreen.classList.add('hidden'); currentScreen.removeEventListener('webkitTransitionEnd', f);
}); currentScreen.classList.add('hidden');
});
}
} else { } else {
if (!offlineMessage.classList.contains('faded')) { if (!offlineMessage.classList.contains('faded')) {
offlineMessage.classList.add('faded'); offlineMessage.classList.add('faded');
...@@ -85,6 +90,38 @@ cr.define('login', function() { ...@@ -85,6 +90,38 @@ cr.define('login', function() {
} }
}; };
/**
* Handler for iframe's error notification coming from the outside.
* For more info see C++ class 'SnifferObserver' which calls this method.
* @param {number} error Error code.
*/
OfflineMessageScreen.onFrameError = function(error) {
var currentScreen = Oobe.getInstance().currentScreen;
var offlineMessage = $('offline-message');
var isOffline = !window.navigator.onLine;
var shouldOverlay = MANAGED_SCREENS.indexOf(currentScreen.id) != -1;
if (!shouldOverlay)
return;
if (!isOffline) {
$('offline-message-text').hidden = true;
$('captive-portal-message-text').hidden = false;
}
if (!currentScreen.classList.contains('faded')) {
offlineMessage.classList.remove('hidden');
offlineMessage.classList.remove('faded');
currentScreen.classList.add('faded');
currentScreen.addEventListener('webkitTransitionEnd',
function f(e) {
currentScreen.removeEventListener('webkitTransitionEnd', f);
currentScreen.classList.add('hidden');
});
}
};
return { return {
OfflineMessageScreen: OfflineMessageScreen OfflineMessageScreen: OfflineMessageScreen
}; };
......
...@@ -160,6 +160,8 @@ void SigninScreenHandler::GetLocalizedStrings( ...@@ -160,6 +160,8 @@ void SigninScreenHandler::GetLocalizedStrings(
l10n_util::GetStringUTF16(IDS_LOGIN_OFFLINE_TITLE)); l10n_util::GetStringUTF16(IDS_LOGIN_OFFLINE_TITLE));
localized_strings->SetString("offlineMessageBody", localized_strings->SetString("offlineMessageBody",
l10n_util::GetStringUTF16(IDS_LOGIN_OFFLINE_MESSAGE)); l10n_util::GetStringUTF16(IDS_LOGIN_OFFLINE_MESSAGE));
localized_strings->SetString("captivePortalMessage",
l10n_util::GetStringUTF16(IDS_LOGIN_MAYBE_CAPTIVE_PORTAL));
localized_strings->SetString("createAccount", localized_strings->SetString("createAccount",
l10n_util::GetStringUTF16(IDS_CREATE_ACCOUNT_HTML)); l10n_util::GetStringUTF16(IDS_CREATE_ACCOUNT_HTML));
localized_strings->SetString("guestSignin", localized_strings->SetString("guestSignin",
......
...@@ -82,6 +82,8 @@ ...@@ -82,6 +82,8 @@
'renderer/extensions/user_script_idle_scheduler.h', 'renderer/extensions/user_script_idle_scheduler.h',
'renderer/extensions/user_script_slave.cc', 'renderer/extensions/user_script_slave.cc',
'renderer/extensions/user_script_slave.h', 'renderer/extensions/user_script_slave.h',
'renderer/frame_sniffer.cc',
'renderer/frame_sniffer.h',
'renderer/loadtimes_extension_bindings.h', 'renderer/loadtimes_extension_bindings.h',
'renderer/loadtimes_extension_bindings.cc', 'renderer/loadtimes_extension_bindings.cc',
'renderer/net/predictor_queue.cc', 'renderer/net/predictor_queue.cc',
......
...@@ -289,6 +289,10 @@ IPC_MESSAGE_ROUTED1(ChromeViewMsg_SetAllowRunningInsecureContent, ...@@ -289,6 +289,10 @@ IPC_MESSAGE_ROUTED1(ChromeViewMsg_SetAllowRunningInsecureContent,
IPC_MESSAGE_ROUTED1(ChromeViewMsg_SetClientSidePhishingDetection, IPC_MESSAGE_ROUTED1(ChromeViewMsg_SetClientSidePhishingDetection,
bool /* enable_phishing_detection */) bool /* enable_phishing_detection */)
// This message asks frame sniffer start.
IPC_MESSAGE_ROUTED1(ChromeViewMsg_StartFrameSniffer,
string16 /* frame-name */)
// JavaScript related messages ----------------------------------------------- // JavaScript related messages -----------------------------------------------
// Notify the JavaScript engine in the render to change its parameters // Notify the JavaScript engine in the render to change its parameters
...@@ -532,6 +536,10 @@ IPC_MESSAGE_ROUTED2(ChromeViewHostMsg_InstantSupportDetermined, ...@@ -532,6 +536,10 @@ IPC_MESSAGE_ROUTED2(ChromeViewHostMsg_InstantSupportDetermined,
// The currently displayed PDF has an unsupported feature. // The currently displayed PDF has an unsupported feature.
IPC_MESSAGE_ROUTED0(ChromeViewHostMsg_PDFHasUnsupportedFeature) IPC_MESSAGE_ROUTED0(ChromeViewHostMsg_PDFHasUnsupportedFeature)
// This message indicates the error appeared in the frame.
IPC_MESSAGE_ROUTED1(ChromeViewHostMsg_FrameLoadingError,
int /* error */)
// The following messages are used to set and get cookies for ChromeFrame // The following messages are used to set and get cookies for ChromeFrame
// processes. // processes.
// Used to set a cookie. The cookie is set asynchronously, but will be // Used to set a cookie. The cookie is set asynchronously, but will be
...@@ -547,4 +555,3 @@ IPC_SYNC_MESSAGE_ROUTED2_1(ChromeViewHostMsg_GetCookies, ...@@ -547,4 +555,3 @@ IPC_SYNC_MESSAGE_ROUTED2_1(ChromeViewHostMsg_GetCookies,
GURL /* url */, GURL /* url */,
GURL /* first_party_for_cookies */, GURL /* first_party_for_cookies */,
std::string /* cookies */) std::string /* cookies */)
...@@ -15,10 +15,11 @@ ...@@ -15,10 +15,11 @@
#include "chrome/common/thumbnail_score.h" #include "chrome/common/thumbnail_score.h"
#include "chrome/common/url_constants.h" #include "chrome/common/url_constants.h"
#include "chrome/renderer/about_handler.h" #include "chrome/renderer/about_handler.h"
#include "chrome/renderer/content_settings_observer.h"
#include "chrome/renderer/automation/dom_automation_controller.h" #include "chrome/renderer/automation/dom_automation_controller.h"
#include "chrome/renderer/content_settings_observer.h"
#include "chrome/renderer/extensions/extension_renderer_context.h" #include "chrome/renderer/extensions/extension_renderer_context.h"
#include "chrome/renderer/external_host_bindings.h" #include "chrome/renderer/external_host_bindings.h"
#include "chrome/renderer/frame_sniffer.h"
#include "chrome/renderer/prerender/prerender_helper.h" #include "chrome/renderer/prerender/prerender_helper.h"
#include "chrome/renderer/safe_browsing/phishing_classifier_delegate.h" #include "chrome/renderer/safe_browsing/phishing_classifier_delegate.h"
#include "chrome/renderer/translate_helper.h" #include "chrome/renderer/translate_helper.h"
...@@ -238,6 +239,9 @@ bool ChromeRenderViewObserver::OnMessageReceived(const IPC::Message& message) { ...@@ -238,6 +239,9 @@ bool ChromeRenderViewObserver::OnMessageReceived(const IPC::Message& message) {
OnSetAllowRunningInsecureContent) OnSetAllowRunningInsecureContent)
IPC_MESSAGE_HANDLER(ChromeViewMsg_SetClientSidePhishingDetection, IPC_MESSAGE_HANDLER(ChromeViewMsg_SetClientSidePhishingDetection,
OnSetClientSidePhishingDetection) OnSetClientSidePhishingDetection)
#if defined(OS_CHROMEOS)
IPC_MESSAGE_HANDLER(ChromeViewMsg_StartFrameSniffer, OnStartFrameSniffer)
#endif
IPC_MESSAGE_UNHANDLED(handled = false) IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP() IPC_END_MESSAGE_MAP()
...@@ -341,6 +345,10 @@ void ChromeRenderViewObserver::OnSetClientSidePhishingDetection( ...@@ -341,6 +345,10 @@ void ChromeRenderViewObserver::OnSetClientSidePhishingDetection(
#endif #endif
} }
void ChromeRenderViewObserver::OnStartFrameSniffer(const string16& frame_name) {
new FrameSniffer(render_view(), frame_name);
}
bool ChromeRenderViewObserver::allowDatabase( bool ChromeRenderViewObserver::allowDatabase(
WebFrame* frame, WebFrame* frame,
const WebString& name, const WebString& name,
......
...@@ -118,6 +118,7 @@ class ChromeRenderViewObserver : public RenderViewObserver, ...@@ -118,6 +118,7 @@ class ChromeRenderViewObserver : public RenderViewObserver,
void OnSetAllowDisplayingInsecureContent(bool allow); void OnSetAllowDisplayingInsecureContent(bool allow);
void OnSetAllowRunningInsecureContent(bool allow); void OnSetAllowRunningInsecureContent(bool allow);
void OnSetClientSidePhishingDetection(bool enable_phishing_detection); void OnSetClientSidePhishingDetection(bool enable_phishing_detection);
void OnStartFrameSniffer(const string16& frame_name);
// Captures the thumbnail and text contents for indexing for the given load // Captures the thumbnail and text contents for indexing for the given load
// ID. If the view's load ID is different than the parameter, this call is // ID. If the view's load ID is different than the parameter, this call is
......
// Copyright (c) 2011 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 "chrome/renderer/frame_sniffer.h"
#include "base/logging.h"
#include "chrome/common/render_messages.h"
#include "content/common/view_messages.h"
#include "content/renderer/navigation_state.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebURLError.h"
FrameSniffer::FrameSniffer(RenderView* render_view, const string16 &frame_name)
: RenderViewObserver(render_view), frame_name_(frame_name) {
}
FrameSniffer::~FrameSniffer() {
}
void FrameSniffer::DidFailProvisionalLoad(WebKit::WebFrame* frame,
const WebKit::WebURLError& error) {
if (!ShouldSniffFrame(frame))
return;
Send(new ChromeViewHostMsg_FrameLoadingError(routing_id(), -error.reason));
}
bool FrameSniffer::ShouldSniffFrame(WebKit::WebFrame* frame) {
return frame->name() == frame_name_;
}
// Copyright (c) 2011 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 CHROME_RENDERER_FRAME_SNIFFER_H_
#define CHROME_RENDERER_FRAME_SNIFFER_H_
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "content/renderer/render_view_observer.h"
// Class which observes events from the frame with specific name and sends IPC
// messages to be handled by RenderViewHostObserver.
class FrameSniffer : public RenderViewObserver {
public:
FrameSniffer(RenderView* render_view, const string16 &frame_name);
virtual ~FrameSniffer();
// Implements RenderViewObserver.
virtual void DidFailProvisionalLoad(
WebKit::WebFrame* frame, const WebKit::WebURLError& error) OVERRIDE;
private:
bool ShouldSniffFrame(WebKit::WebFrame* frame);
// Name of the frame to be monitored.
string16 frame_name_;
DISALLOW_COPY_AND_ASSIGN(FrameSniffer);
};
#endif // CHROME_RENDERER_FRAME_SNIFFER_H_
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