Commit 67ef1b05 authored by fsamuel's avatar fsamuel Committed by Commit bot

GuestView: Show status bubbles in browser

For GuestView types in the browser, such as <webview> in WebUI and
<extensionoptions> in WebUI, we would live status messages to appear
in the browser. This CL plumbs that information out to the embedder.

ContentsMouseEvent, LoadingStateChanged, and UpdateTargetURL are calls out to the content embedder that are used by Browser to update status indicators such as the spinner, and status text.

This CL plumbs those calls out from the guest to the embedder. This is a bit racy because guest status and embedder status can interleave but that's OK because these status texts are transient and eventually they'll settle and disappear so there's no long lasting raciness of consequence.

BUG=453216
TBR=lazyboy@chromium.org

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

Cr-Commit-Position: refs/heads/master@{#314005}
parent 6f2b1673
......@@ -24,6 +24,7 @@
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "extensions/browser/guest_view/guest_view_manager.h"
#include "net/base/load_states.h"
#include "net/http/http_request_headers.h"
#include "ui/base/l10n/l10n_util.h"
......@@ -46,62 +47,9 @@ base::string16 CoreTabHelper::GetDefaultTitle() {
}
base::string16 CoreTabHelper::GetStatusText() const {
if (!web_contents()->IsLoading() ||
web_contents()->GetLoadState().state == net::LOAD_STATE_IDLE) {
return base::string16();
}
switch (web_contents()->GetLoadState().state) {
case net::LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL:
case net::LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET:
return l10n_util::GetStringUTF16(IDS_LOAD_STATE_WAITING_FOR_SOCKET_SLOT);
case net::LOAD_STATE_WAITING_FOR_DELEGATE:
if (!web_contents()->GetLoadState().param.empty()) {
return l10n_util::GetStringFUTF16(IDS_LOAD_STATE_WAITING_FOR_DELEGATE,
web_contents()->GetLoadState().param);
} else {
return l10n_util::GetStringUTF16(
IDS_LOAD_STATE_WAITING_FOR_DELEGATE_GENERIC);
}
case net::LOAD_STATE_WAITING_FOR_CACHE:
return l10n_util::GetStringUTF16(IDS_LOAD_STATE_WAITING_FOR_CACHE);
case net::LOAD_STATE_WAITING_FOR_APPCACHE:
return l10n_util::GetStringUTF16(IDS_LOAD_STATE_WAITING_FOR_APPCACHE);
case net::LOAD_STATE_ESTABLISHING_PROXY_TUNNEL:
return
l10n_util::GetStringUTF16(IDS_LOAD_STATE_ESTABLISHING_PROXY_TUNNEL);
case net::LOAD_STATE_DOWNLOADING_PROXY_SCRIPT:
return l10n_util::GetStringUTF16(IDS_LOAD_STATE_DOWNLOADING_PROXY_SCRIPT);
case net::LOAD_STATE_RESOLVING_PROXY_FOR_URL:
return l10n_util::GetStringUTF16(IDS_LOAD_STATE_RESOLVING_PROXY_FOR_URL);
case net::LOAD_STATE_RESOLVING_HOST_IN_PROXY_SCRIPT:
return l10n_util::GetStringUTF16(
IDS_LOAD_STATE_RESOLVING_HOST_IN_PROXY_SCRIPT);
case net::LOAD_STATE_RESOLVING_HOST:
return l10n_util::GetStringUTF16(IDS_LOAD_STATE_RESOLVING_HOST);
case net::LOAD_STATE_CONNECTING:
return l10n_util::GetStringUTF16(IDS_LOAD_STATE_CONNECTING);
case net::LOAD_STATE_SSL_HANDSHAKE:
return l10n_util::GetStringUTF16(IDS_LOAD_STATE_SSL_HANDSHAKE);
case net::LOAD_STATE_SENDING_REQUEST:
if (web_contents()->GetUploadSize()) {
return l10n_util::GetStringFUTF16Int(
IDS_LOAD_STATE_SENDING_REQUEST_WITH_PROGRESS,
static_cast<int>((100 * web_contents()->GetUploadPosition()) /
web_contents()->GetUploadSize()));
} else {
return l10n_util::GetStringUTF16(IDS_LOAD_STATE_SENDING_REQUEST);
}
case net::LOAD_STATE_WAITING_FOR_RESPONSE:
return l10n_util::GetStringFUTF16(IDS_LOAD_STATE_WAITING_FOR_RESPONSE,
web_contents()->GetLoadStateHost());
// Ignore net::LOAD_STATE_READING_RESPONSE and net::LOAD_STATE_IDLE
case net::LOAD_STATE_IDLE:
case net::LOAD_STATE_READING_RESPONSE:
break;
}
return base::string16();
base::string16 status_text;
GetStatusTextForWebContents(&status_text, web_contents());
return status_text;
}
void CoreTabHelper::OnCloseStarted() {
......@@ -135,6 +83,100 @@ void CoreTabHelper::UpdateContentRestrictions(int content_restrictions) {
#endif
}
// static
bool CoreTabHelper::GetStatusTextForWebContents(
base::string16* status_text, content::WebContents* source) {
auto guest_manager =
extensions::GuestViewManager::FromBrowserContextIfAvailable(
source->GetBrowserContext());
if (!source->IsLoading() ||
source->GetLoadState().state == net::LOAD_STATE_IDLE) {
if (!guest_manager)
return false;
return guest_manager->ForEachGuest(
source, base::Bind(&CoreTabHelper::GetStatusTextForWebContents,
status_text));
}
switch (source->GetLoadState().state) {
case net::LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL:
case net::LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET:
*status_text =
l10n_util::GetStringUTF16(IDS_LOAD_STATE_WAITING_FOR_SOCKET_SLOT);
return true;
case net::LOAD_STATE_WAITING_FOR_DELEGATE:
if (!source->GetLoadState().param.empty()) {
*status_text = l10n_util::GetStringFUTF16(
IDS_LOAD_STATE_WAITING_FOR_DELEGATE,
source->GetLoadState().param);
return true;
} else {
*status_text = l10n_util::GetStringUTF16(
IDS_LOAD_STATE_WAITING_FOR_DELEGATE_GENERIC);
return true;
}
case net::LOAD_STATE_WAITING_FOR_CACHE:
*status_text =
l10n_util::GetStringUTF16(IDS_LOAD_STATE_WAITING_FOR_CACHE);
return true;
case net::LOAD_STATE_WAITING_FOR_APPCACHE:
*status_text =
l10n_util::GetStringUTF16(IDS_LOAD_STATE_WAITING_FOR_APPCACHE);
return true;
case net::LOAD_STATE_ESTABLISHING_PROXY_TUNNEL:
*status_text =
l10n_util::GetStringUTF16(IDS_LOAD_STATE_ESTABLISHING_PROXY_TUNNEL);
return true;
case net::LOAD_STATE_DOWNLOADING_PROXY_SCRIPT:
*status_text =
l10n_util::GetStringUTF16(IDS_LOAD_STATE_DOWNLOADING_PROXY_SCRIPT);
return true;
case net::LOAD_STATE_RESOLVING_PROXY_FOR_URL:
*status_text =
l10n_util::GetStringUTF16(IDS_LOAD_STATE_RESOLVING_PROXY_FOR_URL);
return true;
case net::LOAD_STATE_RESOLVING_HOST_IN_PROXY_SCRIPT:
*status_text = l10n_util::GetStringUTF16(
IDS_LOAD_STATE_RESOLVING_HOST_IN_PROXY_SCRIPT);
return true;
case net::LOAD_STATE_RESOLVING_HOST:
*status_text = l10n_util::GetStringUTF16(IDS_LOAD_STATE_RESOLVING_HOST);
return true;
case net::LOAD_STATE_CONNECTING:
*status_text = l10n_util::GetStringUTF16(IDS_LOAD_STATE_CONNECTING);
return true;
case net::LOAD_STATE_SSL_HANDSHAKE:
*status_text = l10n_util::GetStringUTF16(IDS_LOAD_STATE_SSL_HANDSHAKE);
return true;
case net::LOAD_STATE_SENDING_REQUEST:
if (source->GetUploadSize()) {
*status_text = l10n_util::GetStringFUTF16Int(
IDS_LOAD_STATE_SENDING_REQUEST_WITH_PROGRESS,
static_cast<int>((100 * source->GetUploadPosition()) /
source->GetUploadSize()));
return true;
} else {
*status_text =
l10n_util::GetStringUTF16(IDS_LOAD_STATE_SENDING_REQUEST);
return true;
}
case net::LOAD_STATE_WAITING_FOR_RESPONSE:
*status_text =
l10n_util::GetStringFUTF16(IDS_LOAD_STATE_WAITING_FOR_RESPONSE,
source->GetLoadStateHost());
return true;
// Ignore net::LOAD_STATE_READING_RESPONSE and net::LOAD_STATE_IDLE
case net::LOAD_STATE_IDLE:
case net::LOAD_STATE_READING_RESPONSE:
break;
}
if (!guest_manager)
return false;
return guest_manager->ForEachGuest(
source, base::Bind(&CoreTabHelper::GetStatusTextForWebContents,
status_text));
}
////////////////////////////////////////////////////////////////////////////////
// WebContentsObserver overrides
......
......@@ -55,6 +55,9 @@ class CoreTabHelper : public content::WebContentsObserver,
explicit CoreTabHelper(content::WebContents* web_contents);
friend class content::WebContentsUserData<CoreTabHelper>;
static bool GetStatusTextForWebContents(base::string16* status_text,
content::WebContents* source);
// content::WebContentsObserver overrides:
void DidStartLoading(content::RenderViewHost* render_view_host) override;
void WasShown() override;
......
......@@ -557,6 +557,16 @@ void GuestViewBase::DeactivateContents(WebContents* web_contents) {
embedder_web_contents());
}
void GuestViewBase::ContentsMouseEvent(content::WebContents* source,
const gfx::Point& location,
bool motion) {
if (!attached() || !embedder_web_contents()->GetDelegate())
return;
embedder_web_contents()->GetDelegate()->ContentsMouseEvent(
embedder_web_contents(), location, motion);
}
void GuestViewBase::ContentsZoomChange(bool zoom_in) {
ui_zoom::PageZoom::Zoom(
embedder_web_contents(),
......@@ -574,6 +584,15 @@ void GuestViewBase::HandleKeyboardEvent(
HandleKeyboardEvent(embedder_web_contents(), event);
}
void GuestViewBase::LoadingStateChanged(content::WebContents* source,
bool to_different_document) {
if (!attached() || !embedder_web_contents()->GetDelegate())
return;
embedder_web_contents()->GetDelegate()->LoadingStateChanged(
embedder_web_contents(), to_different_document);
}
void GuestViewBase::RunFileChooser(WebContents* web_contents,
const content::FileChooserParams& params) {
if (!attached() || !embedder_web_contents()->GetDelegate())
......@@ -606,6 +625,15 @@ void GuestViewBase::UpdatePreferredSize(
}
}
void GuestViewBase::UpdateTargetURL(content::WebContents* source,
const GURL& url) {
if (!attached() || !embedder_web_contents()->GetDelegate())
return;
embedder_web_contents()->GetDelegate()->UpdateTargetURL(
embedder_web_contents(), url);
}
GuestViewBase::~GuestViewBase() {
}
......
......@@ -301,10 +301,15 @@ class GuestViewBase : public content::BrowserPluginGuestDelegate,
// WebContentsDelegate implementation.
void ActivateContents(content::WebContents* contents) final;
void DeactivateContents(content::WebContents* contents) final;
void ContentsMouseEvent(content::WebContents* source,
const gfx::Point& location,
bool motion) override;
void ContentsZoomChange(bool zoom_in) override;
void HandleKeyboardEvent(
content::WebContents* source,
const content::NativeWebKeyboardEvent& event) override;
void LoadingStateChanged(content::WebContents* source,
bool to_different_document) final;
void RunFileChooser(content::WebContents* web_contents,
const content::FileChooserParams& params) override;
bool ShouldFocusPageAfterCrash() final;
......@@ -312,6 +317,7 @@ class GuestViewBase : public content::BrowserPluginGuestDelegate,
const blink::WebGestureEvent& event) final;
void UpdatePreferredSize(content::WebContents* web_contents,
const gfx::Size& pref_size) final;
void UpdateTargetURL(content::WebContents* source, const GURL& url) override;
private:
class OwnerLifetimeObserver;
......
......@@ -36,7 +36,7 @@ GuestViewManager::GuestViewManager(content::BrowserContext* context)
GuestViewManager::~GuestViewManager() {}
// static.
// static
GuestViewManager* GuestViewManager::FromBrowserContext(
BrowserContext* context) {
GuestViewManager* guest_manager =
......@@ -53,6 +53,13 @@ GuestViewManager* GuestViewManager::FromBrowserContext(
return guest_manager;
}
// static
GuestViewManager* GuestViewManager::FromBrowserContextIfAvailable(
BrowserContext* context) {
return static_cast<GuestViewManager*>(context->GetUserData(
guestview::kGuestViewManagerKeyName));
}
content::WebContents* GuestViewManager::GetGuestByInstanceIDSafely(
int guest_instance_id,
int embedder_render_process_id) {
......
......@@ -31,8 +31,15 @@ class GuestViewManager : public content::BrowserPluginGuestManager,
explicit GuestViewManager(content::BrowserContext* context);
~GuestViewManager() override;
// Returns the GuestViewManager associated with |context|. If one isn't
// available, then it is created and returned.
static GuestViewManager* FromBrowserContext(content::BrowserContext* context);
// Returns the GuestViewManager associated with |context|. If one isn't
// available, then nullptr is returned.
static GuestViewManager* FromBrowserContextIfAvailable(
content::BrowserContext* context);
// Overrides factory for testing. Default (NULL) value indicates regular
// (non-test) environment.
static void set_factory_for_testing(GuestViewManagerFactory* factory) {
......
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