diff --git a/extensions/browser/extension_event_histogram_value.h b/extensions/browser/extension_event_histogram_value.h index 31a23a688787b..1424ceee4105e 100644 --- a/extensions/browser/extension_event_histogram_value.h +++ b/extensions/browser/extension_event_histogram_value.h @@ -424,6 +424,8 @@ enum HistogramValue { CLIPBOARD_ON_CLIPBOARD_DATA_CHANGED, VIRTUAL_KEYBOARD_PRIVATE_ON_KEYBOARD_CLOSED, FILE_MANAGER_PRIVATE_ON_APPS_UPDATED, + WEB_VIEW_INTERNAL_ON_TITLE_CHANGE, + WEB_VIEW_INTERNAL_ON_FAVICON_CHANGE, // Last entry: Add new entries above, then run: // python tools/metrics/histograms/update_extension_histograms.py ENUM_BOUNDARY diff --git a/extensions/browser/guest_view/guest_view_events.cc b/extensions/browser/guest_view/guest_view_events.cc index 8e8c739d9723c..fa90f3184c4b5 100644 --- a/extensions/browser/guest_view/guest_view_events.cc +++ b/extensions/browser/guest_view/guest_view_events.cc @@ -81,6 +81,8 @@ class EventMap { {webview::kEventErrorOccurred, events::WEB_VIEW_INTERNAL_ON_ERROR_OCCURRED}, {webview::kEventSendHeaders, events::WEB_VIEW_INTERNAL_ON_SEND_HEADERS}, + {webview::kEventFaviconChange, events::WEB_VIEW_INTERNAL_ON_FAVICON_CHANGE}, + {webview::kEventTitleChange, events::WEB_VIEW_INTERNAL_ON_TITLE_CHANGE}, }; for (const auto& name_and_value : names_and_values) { values_[name_and_value.name] = name_and_value.value; diff --git a/extensions/browser/guest_view/web_view/web_view_constants.cc b/extensions/browser/guest_view/web_view/web_view_constants.cc index 5511f881d17ab..47739131172a1 100644 --- a/extensions/browser/guest_view/web_view/web_view_constants.cc +++ b/extensions/browser/guest_view/web_view/web_view_constants.cc @@ -30,6 +30,7 @@ const char kEventDialog[] = "webViewInternal.onDialog"; const char kEventDropLink[] = "webViewInternal.onDropLink"; const char kEventExit[] = "webViewInternal.onExit"; const char kEventExitFullscreen[] = "webViewInternal.onExitFullscreen"; +const char kEventFaviconChange[] = "webViewInternal.onFaviconChange"; const char kEventFindReply[] = "webViewInternal.onFindReply"; const char kEventFrameNameChanged[] = "webViewInternal.onFrameNameChanged"; const char kEventHeadersReceived[] = "webViewInternal.onHeadersReceived"; @@ -45,6 +46,7 @@ const char kEventPermissionRequest[] = "webViewInternal.onPermissionRequest"; const char kEventResponseStarted[] = "webViewInternal.onResponseStarted"; const char kEventResponsive[] = "webViewInternal.onResponsive"; const char kEventSizeChanged[] = "webViewInternal.onSizeChanged"; +const char kEventTitleChange[] = "webViewInternal.onTitleChange"; const char kEventUnresponsive[] = "webViewInternal.onUnresponsive"; const char kEventZoomChange[] = "webViewInternal.onZoomChange"; @@ -63,6 +65,7 @@ const char kWebViewEventPrefix[] = "webViewInternal."; // Parameters/properties on events. const char kContextMenuItems[] = "items"; const char kDefaultPromptText[] = "defaultPromptText"; +const char kFaviconUrl[] = "faviconUrl"; const char kFindSearchText[] = "searchText"; const char kFindFinalUpdate[] = "finalUpdate"; const char kInitialHeight[] = "initialHeight"; @@ -98,6 +101,7 @@ const char kRequestId[] = "requestId"; const char kRequestInfo[] = "requestInfo"; const char kSourceId[] = "sourceId"; const char kTargetURL[] = "targetUrl"; +const char kTitle[] = "title"; const char kWindowID[] = "windowId"; const char kWindowOpenDisposition[] = "windowOpenDisposition"; const char kOldZoomFactor[] = "oldZoomFactor"; diff --git a/extensions/browser/guest_view/web_view/web_view_constants.h b/extensions/browser/guest_view/web_view/web_view_constants.h index 299042e33e71d..8e0747bf17eda 100644 --- a/extensions/browser/guest_view/web_view/web_view_constants.h +++ b/extensions/browser/guest_view/web_view/web_view_constants.h @@ -36,6 +36,7 @@ extern const char kEventDialog[]; extern const char kEventDropLink[]; extern const char kEventExit[]; extern const char kEventExitFullscreen[]; +extern const char kEventFaviconChange[]; extern const char kEventFindReply[]; extern const char kEventFrameNameChanged[]; extern const char kEventHeadersReceived[]; @@ -51,6 +52,7 @@ extern const char kEventPermissionRequest[]; extern const char kEventResponseStarted[]; extern const char kEventResponsive[]; extern const char kEventSizeChanged[]; +extern const char kEventTitleChange[]; extern const char kEventUnresponsive[]; extern const char kEventZoomChange[]; @@ -69,6 +71,7 @@ extern const char kWebViewEventPrefix[]; // Parameters/properties on events. extern const char kContextMenuItems[]; extern const char kDefaultPromptText[]; +extern const char kFaviconUrl[]; extern const char kFindSearchText[]; extern const char kFindFinalUpdate[]; extern const char kInitialHeight[]; @@ -104,6 +107,7 @@ extern const char kRequestId[]; extern const char kRequestInfo[]; extern const char kSourceId[]; extern const char kTargetURL[]; +extern const char kTitle[]; extern const char kWindowID[]; extern const char kWindowOpenDisposition[]; extern const char kOldZoomFactor[]; diff --git a/extensions/browser/guest_view/web_view/web_view_guest.cc b/extensions/browser/guest_view/web_view/web_view_guest.cc index 37f5a6ba43416..507728360cd16 100644 --- a/extensions/browser/guest_view/web_view/web_view_guest.cc +++ b/extensions/browser/guest_view/web_view/web_view_guest.cc @@ -26,6 +26,7 @@ #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/child_process_security_policy.h" +#include "content/public/browser/favicon_status.h" #include "content/public/browser/native_web_keyboard_event.h" #include "content/public/browser/navigation_entry.h" #include "content/public/browser/navigation_handle.h" @@ -44,6 +45,7 @@ #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_delegate.h" #include "content/public/common/browser_side_navigation_policy.h" +#include "content/public/common/favicon_url.h" #include "content/public/common/media_stream_request.h" #include "content/public/common/page_zoom.h" #include "content/public/common/result_codes.h" @@ -355,10 +357,10 @@ void WebViewGuest::CreateWebContents( persist_storage ? "persist" : "", url_encoded_partition.c_str())); - // If we already have a webview tag in the same app using the same storage - // partition, we should use the same SiteInstance so the existing tag and - // the new tag can script each other. - auto* guest_view_manager = GuestViewManager::FromBrowserContext( + // If we already have a webview tag in the same app using the same storage + // partition, we should use the same SiteInstance so the existing tag and + // the new tag can script each other. + auto* guest_view_manager = GuestViewManager::FromBrowserContext( owner_render_process_host->GetBrowserContext()); scoped_refptr guest_site_instance = guest_view_manager->GetGuestSiteInstance(guest_site); @@ -534,10 +536,10 @@ void WebViewGuest::WillDestroy() { } bool WebViewGuest::DidAddMessageToConsole(WebContents* source, - int32_t level, - const base::string16& message, - int32_t line_no, - const base::string16& source_id) { + int32_t level, + const base::string16& message, + int32_t line_no, + const base::string16& source_id) { std::unique_ptr args(new base::DictionaryValue()); // Log levels are from base/logging.h: LogSeverity. args->SetInteger(webview::kLevel, level); @@ -845,6 +847,12 @@ void WebViewGuest::DidFinishNavigation( SetZoom(pending_zoom_factor_); pending_zoom_factor_ = 0.0; } + + if ((int)navigation_handle->GetPageTransition() == (int)ui::PageTransition::PAGE_TRANSITION_AUTO_TOPLEVEL || + (int)navigation_handle->GetPageTransition() & (int)ui::PageTransition::PAGE_TRANSITION_FORWARD_BACK) { + FaviconEvent(web_contents()->GetController().GetEntryAtIndex(web_contents()->GetController().GetCurrentEntryIndex())->GetFavicon().url.spec()); + TitleWasSet(web_contents()->GetController().GetEntryAtIndex(web_contents()->GetController().GetCurrentEntryIndex()), true); + } } std::unique_ptr args(new base::DictionaryValue()); args->SetString(guest_view::kUrl, src_.spec()); @@ -990,8 +998,8 @@ void WebViewGuest::RemoveWebViewStateFromIOThread( content::BrowserThread::PostTask( content::BrowserThread::IO, FROM_HERE, base::Bind(&WebViewRendererState::RemoveGuest, - base::Unretained(WebViewRendererState::GetInstance()), - web_contents->GetRenderProcessHost()->GetID(), + base::Unretained(WebViewRendererState::GetInstance()), + web_contents->GetRenderProcessHost()->GetID(), web_contents->GetRenderViewHost()->GetRoutingID())); } @@ -1183,7 +1191,7 @@ void WebViewGuest::ApplyAttributes(const base::DictionaryValue& params) { if (!is_pending_new_window) { std::string src; if (params.GetString(webview::kAttributeSrc, &src)) - NavigateGuest(src, true /* force_navigation */); + NavigateGuest(src, true /* force_navigation */); } } @@ -1415,6 +1423,31 @@ void WebViewGuest::RequestToLockMouse(WebContents* web_contents, base::Unretained(web_contents))); } +void WebViewGuest::FaviconEvent(const std::string& faviconUrl) +{ + std::unique_ptr args(new base::DictionaryValue()); + args->SetString(webview::kFaviconUrl, faviconUrl); + DispatchEventToView(base::MakeUnique(webview::kEventFaviconChange, + std::move(args))); +} + +void WebViewGuest::DidUpdateFaviconURL(const std::vector& candidates) { + if (!candidates.empty()) + FaviconEvent(candidates[0].icon_url.spec()); + else + FaviconEvent(""); +} + +void WebViewGuest::TitleWasSet(content::NavigationEntry* entry, bool explicit_set) { + if (!entry) + return; + + std::unique_ptr args(new base::DictionaryValue()); + args->SetString(webview::kTitle, entry->GetTitleForDisplay()); + DispatchEventToView(base::MakeUnique(webview::kEventTitleChange, + std::move(args))); +} + void WebViewGuest::LoadURLWithParams( const GURL& url, const content::Referrer& referrer, diff --git a/extensions/browser/guest_view/web_view/web_view_guest.h b/extensions/browser/guest_view/web_view/web_view_guest.h index f7117a8eb36b5..f85552eb08911 100644 --- a/extensions/browser/guest_view/web_view/web_view_guest.h +++ b/extensions/browser/guest_view/web_view/web_view_guest.h @@ -26,6 +26,11 @@ namespace blink { struct WebFindOptions; } // namespace blink +namespace content { +class NavigationEntry; +struct FaviconURL; +} + namespace extensions { class WebViewInternalFindFunction; @@ -203,10 +208,10 @@ class WebViewGuest : public guest_view::GuestView, // WebContentsDelegate implementation. bool DidAddMessageToConsole(content::WebContents* source, - int32_t level, - const base::string16& message, - int32_t line_no, - const base::string16& source_id) final; + int32_t level, + const base::string16& message, + int32_t line_no, + const base::string16& source_id) final; void CloseContents(content::WebContents* source) final; bool HandleContextMenu(const content::ContextMenuParams& params) final; void HandleKeyboardEvent(content::WebContents* source, @@ -259,6 +264,10 @@ class WebViewGuest : public guest_view::GuestView, bool user_gesture, bool last_unlocked_by_target) override; + void FaviconEvent(const std::string& faviconUrl); + void DidUpdateFaviconURL(const std::vector& candidates) final; + void TitleWasSet(content::NavigationEntry* entry, bool explicit_set) final; + // WebContentsObserver implementation. void DidStartNavigation(content::NavigationHandle* navigation_handle) final; void DidFinishNavigation(content::NavigationHandle* navigation_handle) final; diff --git a/extensions/renderer/resources/guest_view/web_view/web_view_events.js b/extensions/renderer/resources/guest_view/web_view/web_view_events.js index 1077684de0038..d09d08fd03476 100644 --- a/extensions/renderer/resources/guest_view/web_view/web_view_events.js +++ b/extensions/renderer/resources/guest_view/web_view/web_view_events.js @@ -62,6 +62,10 @@ WebViewEvents.EVENTS = { handler: 'handleFullscreenExitEvent', internal: true }, + 'faviconchange': { + evt: CreateEvent('webViewInternal.onFaviconChange'), + fields: ['faviconUrl'] + }, 'findupdate': { evt: CreateEvent('webViewInternal.onFindReply'), fields: [ @@ -139,6 +143,10 @@ WebViewEvents.EVENTS = { fields: ['oldHeight', 'oldWidth', 'newHeight', 'newWidth'], handler: 'handleSizeChangedEvent' }, + 'titlechange': { + evt: CreateEvent('webViewInternal.onTitleChange'), + fields: ['title'] + }, 'unresponsive': { evt: CreateEvent('webViewInternal.onUnresponsive'), fields: ['processId']