Commit db06dca9 authored by Evan Stade's avatar Evan Stade Committed by Commit Bot

Remove NotificationService notifications from WebNavigationApi.

Bug: 268984
Change-Id: Idd1b13ad08f66f029706a1b04ad811aa148e29a1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1719275
Commit-Queue: Evan Stade <estade@chromium.org>
Reviewed-by: default avatarIstiaque Ahmed <lazyboy@chromium.org>
Reviewed-by: default avatarNasko Oskov <nasko@chromium.org>
Cr-Commit-Position: refs/heads/master@{#686246}
parent 89b95b5d
...@@ -9,7 +9,6 @@ ...@@ -9,7 +9,6 @@
#include <memory> #include <memory>
#include "base/no_destructor.h" #include "base/no_destructor.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/extensions/api/web_navigation/web_navigation_api_constants.h" #include "chrome/browser/extensions/api/web_navigation/web_navigation_api_constants.h"
#include "chrome/browser/extensions/api/web_navigation/web_navigation_api_helpers.h" #include "chrome/browser/extensions/api/web_navigation/web_navigation_api_helpers.h"
#include "chrome/browser/extensions/extension_tab_util.h" #include "chrome/browser/extensions/extension_tab_util.h"
...@@ -19,8 +18,6 @@ ...@@ -19,8 +18,6 @@
#include "chrome/common/extensions/api/web_navigation.h" #include "chrome/common/extensions/api/web_navigation.h"
#include "content/public/browser/navigation_details.h" #include "content/public/browser/navigation_details.h"
#include "content/public/browser/navigation_handle.h" #include "content/public/browser/navigation_handle.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h" #include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents.h"
...@@ -51,41 +48,36 @@ TabObserverMap& GetTabObserverMap() { ...@@ -51,41 +48,36 @@ TabObserverMap& GetTabObserverMap() {
// WebNavigtionEventRouter ------------------------------------------- // WebNavigtionEventRouter -------------------------------------------
WebNavigationEventRouter::PendingWebContents::PendingWebContents() WebNavigationEventRouter::PendingWebContents::PendingWebContents() = default;
: source_web_contents(NULL), WebNavigationEventRouter::PendingWebContents::~PendingWebContents() {}
source_frame_host(NULL),
target_web_contents(NULL),
target_url() {
}
WebNavigationEventRouter::PendingWebContents::PendingWebContents( void WebNavigationEventRouter::PendingWebContents::Set(
content::WebContents* source_web_contents, int source_tab_id,
content::RenderFrameHost* source_frame_host, int source_render_process_id,
int source_extension_frame_id,
content::WebContents* target_web_contents, content::WebContents* target_web_contents,
const GURL& target_url) const GURL& target_url,
: source_web_contents(source_web_contents), base::OnceCallback<void(content::WebContents*)> on_destroy) {
source_frame_host(source_frame_host), Observe(target_web_contents);
target_web_contents(target_web_contents), source_tab_id_ = source_tab_id;
target_url(target_url) { source_render_process_id_ = source_render_process_id;
source_extension_frame_id_ = source_extension_frame_id;
target_web_contents_ = target_web_contents;
target_url_ = target_url;
on_destroy_ = std::move(on_destroy);
} }
WebNavigationEventRouter::PendingWebContents::~PendingWebContents() {} void WebNavigationEventRouter::PendingWebContents::WebContentsDestroyed() {
std::move(on_destroy_).Run(target_web_contents_);
// |this| is deleted!
}
WebNavigationEventRouter::WebNavigationEventRouter(Profile* profile) WebNavigationEventRouter::WebNavigationEventRouter(Profile* profile)
: profile_(profile), browser_tab_strip_tracker_(this, this, nullptr) { : profile_(profile), browser_tab_strip_tracker_(this, this, nullptr) {
CHECK(registrar_.IsEmpty());
registrar_.Add(this,
chrome::NOTIFICATION_TAB_ADDED,
content::NotificationService::AllSources());
registrar_.Add(this,
content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
content::NotificationService::AllSources());
browser_tab_strip_tracker_.Init(); browser_tab_strip_tracker_.Init();
} }
WebNavigationEventRouter::~WebNavigationEventRouter() { WebNavigationEventRouter::~WebNavigationEventRouter() = default;
}
bool WebNavigationEventRouter::ShouldTrackBrowser(Browser* browser) { bool WebNavigationEventRouter::ShouldTrackBrowser(Browser* browser) {
return profile_->IsSameProfile(browser->profile()); return profile_->IsSameProfile(browser->profile());
...@@ -95,42 +87,26 @@ void WebNavigationEventRouter::OnTabStripModelChanged( ...@@ -95,42 +87,26 @@ void WebNavigationEventRouter::OnTabStripModelChanged(
TabStripModel* tab_strip_model, TabStripModel* tab_strip_model,
const TabStripModelChange& change, const TabStripModelChange& change,
const TabStripSelectionChange& selection) { const TabStripSelectionChange& selection) {
if (change.type() != TabStripModelChange::kReplaced) if (change.type() == TabStripModelChange::kReplaced) {
return; auto* replace = change.GetReplace();
WebNavigationTabObserver* tab_observer =
auto* replace = change.GetReplace(); WebNavigationTabObserver::Get(replace->old_contents);
WebNavigationTabObserver* tab_observer =
WebNavigationTabObserver::Get(replace->old_contents); if (!tab_observer) {
// If you hit this DCHECK(), please add reproduction steps to
if (!tab_observer) { // http://crbug.com/109464.
// If you hit this DCHECK(), please add reproduction steps to DCHECK(GetViewType(replace->old_contents) != VIEW_TYPE_TAB_CONTENTS);
// http://crbug.com/109464. return;
DCHECK(GetViewType(replace->old_contents) != VIEW_TYPE_TAB_CONTENTS); }
return; if (!FrameNavigationState::IsValidUrl(replace->old_contents->GetURL()) ||
} !FrameNavigationState::IsValidUrl(replace->new_contents->GetURL()))
if (!FrameNavigationState::IsValidUrl(replace->old_contents->GetURL()) || return;
!FrameNavigationState::IsValidUrl(replace->new_contents->GetURL()))
return; web_navigation_api_helpers::DispatchOnTabReplaced(
replace->old_contents, profile_, replace->new_contents);
web_navigation_api_helpers::DispatchOnTabReplaced( } else if (change.type() == TabStripModelChange::kInserted) {
replace->old_contents, profile_, replace->new_contents); for (auto& tab : change.GetInsert()->contents)
} TabAdded(tab.contents);
void WebNavigationEventRouter::Observe(
int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) {
switch (type) {
case chrome::NOTIFICATION_TAB_ADDED:
TabAdded(content::Details<content::WebContents>(details).ptr());
break;
case content::NOTIFICATION_WEB_CONTENTS_DESTROYED:
TabDestroyed(content::Source<content::WebContents>(source).ptr());
break;
default:
NOTREACHED();
} }
} }
...@@ -159,15 +135,23 @@ void WebNavigationEventRouter::RecordNewWebContents( ...@@ -159,15 +135,23 @@ void WebNavigationEventRouter::RecordNewWebContents(
if (!frame_navigation_state.CanSendEvents(frame_host)) if (!frame_navigation_state.CanSendEvents(frame_host))
return; return;
int source_extension_frame_id =
ExtensionApiFrameIdMap::GetFrameId(frame_host);
int source_tab_id = ExtensionTabUtil::GetTabId(source_web_contents);
// If the WebContents isn't yet inserted into a tab strip, we need to delay // If the WebContents isn't yet inserted into a tab strip, we need to delay
// the extension event until the WebContents is fully initialized. // the extension event until the WebContents is fully initialized.
if (not_yet_in_tabstrip) { if (not_yet_in_tabstrip) {
pending_web_contents_[target_web_contents] = PendingWebContents( pending_web_contents_[target_web_contents].Set(
source_web_contents, frame_host, target_web_contents, target_url); source_tab_id, source_render_process_id, source_extension_frame_id,
target_web_contents, target_url,
base::BindOnce(&WebNavigationEventRouter::PendingWebContentsDestroyed,
base::Unretained(this)));
} else { } else {
web_navigation_api_helpers::DispatchOnCreatedNavigationTarget( web_navigation_api_helpers::DispatchOnCreatedNavigationTarget(
source_web_contents, target_web_contents->GetBrowserContext(), source_tab_id, source_render_process_id, source_extension_frame_id,
frame_host, target_web_contents, target_url); target_web_contents->GetBrowserContext(), target_web_contents,
target_url);
} }
} }
...@@ -176,34 +160,18 @@ void WebNavigationEventRouter::TabAdded(content::WebContents* tab) { ...@@ -176,34 +160,18 @@ void WebNavigationEventRouter::TabAdded(content::WebContents* tab) {
if (iter == pending_web_contents_.end()) if (iter == pending_web_contents_.end())
return; return;
WebNavigationTabObserver* tab_observer = const PendingWebContents& pending_tab = iter->second;
WebNavigationTabObserver::Get(iter->second.source_web_contents); web_navigation_api_helpers::DispatchOnCreatedNavigationTarget(
if (!tab_observer) { pending_tab.source_tab_id(), pending_tab.source_render_process_id(),
NOTREACHED(); pending_tab.source_extension_frame_id(),
return; pending_tab.target_web_contents()->GetBrowserContext(),
} pending_tab.target_web_contents(), pending_tab.target_url());
const FrameNavigationState& frame_navigation_state =
tab_observer->frame_navigation_state();
if (frame_navigation_state.CanSendEvents(iter->second.source_frame_host)) {
web_navigation_api_helpers::DispatchOnCreatedNavigationTarget(
iter->second.source_web_contents,
iter->second.target_web_contents->GetBrowserContext(),
iter->second.source_frame_host, iter->second.target_web_contents,
iter->second.target_url);
}
pending_web_contents_.erase(iter); pending_web_contents_.erase(iter);
} }
void WebNavigationEventRouter::TabDestroyed(content::WebContents* tab) { void WebNavigationEventRouter::PendingWebContentsDestroyed(
content::WebContents* tab) {
pending_web_contents_.erase(tab); pending_web_contents_.erase(tab);
for (auto i = pending_web_contents_.begin();
i != pending_web_contents_.end();) {
if (i->second.source_web_contents == tab)
pending_web_contents_.erase(i++);
else
++i;
}
} }
// WebNavigationTabObserver ------------------------------------------ // WebNavigationTabObserver ------------------------------------------
...@@ -264,11 +232,11 @@ void WebNavigationTabObserver::DidStartNavigation( ...@@ -264,11 +232,11 @@ void WebNavigationTabObserver::DidStartNavigation(
// and sent after the addition, to preserve the ordering of events. // and sent after the addition, to preserve the ordering of events.
// //
// TODO(nasko|devlin): This check is necessary because chrome::Navigate() // TODO(nasko|devlin): This check is necessary because chrome::Navigate()
// begins the navigation before the sending the TAB_ADDED notification, and it // begins the navigation before adding the tab to the TabStripModel, and it
// is used an indication of that. It would be best if instead it was known // is used an indication of that. It would be best if instead it was known
// when the tab was created and immediately sent the created event instead of // when the tab was created and immediately sent the created event instead of
// waiting for the later TAB_ADDED notification, but this appears to work for // waiting for the later TabStripModel kInserted change, but this appears to
// now. // work for now.
if (ExtensionTabUtil::GetTabById(ExtensionTabUtil::GetTabId(web_contents()), if (ExtensionTabUtil::GetTabById(ExtensionTabUtil::GetTabId(web_contents()),
web_contents()->GetBrowserContext(), false, web_contents()->GetBrowserContext(), false,
nullptr)) { nullptr)) {
...@@ -400,7 +368,6 @@ void WebNavigationTabObserver::DidOpenRequestedURL( ...@@ -400,7 +368,6 @@ void WebNavigationTabObserver::DidOpenRequestedURL(
void WebNavigationTabObserver::WebContentsDestroyed() { void WebNavigationTabObserver::WebContentsDestroyed() {
GetTabObserverMap().erase(web_contents()); GetTabObserverMap().erase(web_contents());
registrar_.RemoveAll();
} }
void WebNavigationTabObserver::DispatchCachedOnBeforeNavigate() { void WebNavigationTabObserver::DispatchCachedOnBeforeNavigate() {
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include <map> #include <map>
#include <set> #include <set>
#include "base/callback.h"
#include "base/compiler_specific.h" #include "base/compiler_specific.h"
#include "base/macros.h" #include "base/macros.h"
#include "chrome/browser/extensions/api/web_navigation/frame_navigation_state.h" #include "chrome/browser/extensions/api/web_navigation/frame_navigation_state.h"
...@@ -19,8 +20,6 @@ ...@@ -19,8 +20,6 @@
#include "chrome/browser/ui/browser_tab_strip_tracker.h" #include "chrome/browser/ui/browser_tab_strip_tracker.h"
#include "chrome/browser/ui/browser_tab_strip_tracker_delegate.h" #include "chrome/browser/ui/browser_tab_strip_tracker_delegate.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_contents_observer.h"
#include "content/public/browser/web_contents_user_data.h" #include "content/public/browser/web_contents_user_data.h"
#include "extensions/browser/browser_context_keyed_api_factory.h" #include "extensions/browser/browser_context_keyed_api_factory.h"
...@@ -97,19 +96,14 @@ class WebNavigationTabObserver ...@@ -97,19 +96,14 @@ class WebNavigationTabObserver
// the tab strip and is ready to dispatch events. // the tab strip and is ready to dispatch events.
std::unique_ptr<Event> pending_on_before_navigate_event_; std::unique_ptr<Event> pending_on_before_navigate_event_;
// Used for tracking registrations to redirect notifications.
content::NotificationRegistrar registrar_;
WEB_CONTENTS_USER_DATA_KEY_DECL(); WEB_CONTENTS_USER_DATA_KEY_DECL();
DISALLOW_COPY_AND_ASSIGN(WebNavigationTabObserver); DISALLOW_COPY_AND_ASSIGN(WebNavigationTabObserver);
}; };
// Observes navigation notifications and routes them as events to the extension // Tracks new tab navigations and routes them as events to the extension system.
// system.
class WebNavigationEventRouter : public TabStripModelObserver, class WebNavigationEventRouter : public TabStripModelObserver,
public BrowserTabStripTrackerDelegate, public BrowserTabStripTrackerDelegate {
public content::NotificationObserver {
public: public:
explicit WebNavigationEventRouter(Profile* profile); explicit WebNavigationEventRouter(Profile* profile);
~WebNavigationEventRouter() override; ~WebNavigationEventRouter() override;
...@@ -117,7 +111,7 @@ class WebNavigationEventRouter : public TabStripModelObserver, ...@@ -117,7 +111,7 @@ class WebNavigationEventRouter : public TabStripModelObserver,
// Router level handler for the creation of WebContents. Stores information // Router level handler for the creation of WebContents. Stores information
// about the newly created WebContents. This information is later used when // about the newly created WebContents. This information is later used when
// the WebContents for the tab is added to the tabstrip and we receive the // the WebContents for the tab is added to the tabstrip and we receive the
// TAB_ADDED notification. // TabStripModelChanged insertion.
void RecordNewWebContents(content::WebContents* source_web_contents, void RecordNewWebContents(content::WebContents* source_web_contents,
int source_render_process_id, int source_render_process_id,
int source_render_frame_id, int source_render_frame_id,
...@@ -127,18 +121,42 @@ class WebNavigationEventRouter : public TabStripModelObserver, ...@@ -127,18 +121,42 @@ class WebNavigationEventRouter : public TabStripModelObserver,
private: private:
// Used to cache the information about newly created WebContents objects. // Used to cache the information about newly created WebContents objects.
struct PendingWebContents{ // Will run |on_destroy_| if/when the target WebContents is destroyed.
class PendingWebContents : public content::WebContentsObserver {
public:
PendingWebContents(); PendingWebContents();
PendingWebContents(content::WebContents* source_web_contents, ~PendingWebContents() override;
content::RenderFrameHost* source_frame_host,
content::WebContents* target_web_contents, void Set(int source_tab_id,
const GURL& target_url); int source_render_process_id,
~PendingWebContents(); int source_extension_frame_id,
content::WebContents* target_web_contents,
content::WebContents* source_web_contents; const GURL& target_url,
content::RenderFrameHost* source_frame_host; base::OnceCallback<void(content::WebContents*)> on_destroy);
content::WebContents* target_web_contents;
GURL target_url; // content::WebContentsObserver:
void WebContentsDestroyed() override;
int source_tab_id() const { return source_tab_id_; }
int source_render_process_id() const { return source_render_process_id_; }
int source_extension_frame_id() const { return source_extension_frame_id_; }
content::WebContents* target_web_contents() const {
return target_web_contents_;
}
GURL target_url() const { return target_url_; }
private:
// The Extensions API ID for the source tab.
int source_tab_id_ = -1;
// The source frame's RenderProcessHost ID.
int source_render_process_id_ = -1;
// The Extensions API ID for the source frame.
int source_extension_frame_id_ = -1;
content::WebContents* target_web_contents_ = nullptr;
GURL target_url_;
base::OnceCallback<void(content::WebContents*)> on_destroy_;
DISALLOW_COPY_AND_ASSIGN(PendingWebContents);
}; };
// BrowserTabStripTrackerDelegate implementation. // BrowserTabStripTrackerDelegate implementation.
...@@ -150,26 +168,17 @@ class WebNavigationEventRouter : public TabStripModelObserver, ...@@ -150,26 +168,17 @@ class WebNavigationEventRouter : public TabStripModelObserver,
const TabStripModelChange& change, const TabStripModelChange& change,
const TabStripSelectionChange& selection) override; const TabStripSelectionChange& selection) override;
// content::NotificationObserver implementation. // The method takes the details of such an event and creates a JSON formatted
void Observe(int type, // extension event from it.
const content::NotificationSource& source,
const content::NotificationDetails& details) override;
// Handler for the NOTIFICATION_TAB_ADDED event. The method takes the details
// of such an event and creates a JSON formated extension event from it.
void TabAdded(content::WebContents* tab); void TabAdded(content::WebContents* tab);
// Handler for NOTIFICATION_WEB_CONTENTS_DESTROYED. If |tab| is in // Removes |tab| from |pending_web_contents_| if it is there.
// |pending_web_contents_|, it is removed. void PendingWebContentsDestroyed(content::WebContents* tab);
void TabDestroyed(content::WebContents* tab);
// Mapping pointers to WebContents objects to information about how they got // Mapping pointers to WebContents objects to information about how they got
// created. // created.
std::map<content::WebContents*, PendingWebContents> pending_web_contents_; std::map<content::WebContents*, PendingWebContents> pending_web_contents_;
// Used for tracking registrations to navigation notifications.
content::NotificationRegistrar registrar_;
// The profile that owns us via ExtensionService. // The profile that owns us via ExtensionService.
Profile* profile_; Profile* profile_;
......
...@@ -192,9 +192,10 @@ void DispatchOnCompleted(content::WebContents* web_contents, ...@@ -192,9 +192,10 @@ void DispatchOnCompleted(content::WebContents* web_contents,
// Constructs and dispatches an onCreatedNavigationTarget event. // Constructs and dispatches an onCreatedNavigationTarget event.
void DispatchOnCreatedNavigationTarget( void DispatchOnCreatedNavigationTarget(
content::WebContents* web_contents, int source_tab_id,
int source_render_process_id,
int source_extension_frame_id,
content::BrowserContext* browser_context, content::BrowserContext* browser_context,
content::RenderFrameHost* source_frame_host,
content::WebContents* target_web_contents, content::WebContents* target_web_contents,
const GURL& target_url) { const GURL& target_url) {
// Check that the tab is already inserted into a tab strip model. This code // Check that the tab is already inserted into a tab strip model. This code
...@@ -205,10 +206,9 @@ void DispatchOnCreatedNavigationTarget( ...@@ -205,10 +206,9 @@ void DispatchOnCreatedNavigationTarget(
false, nullptr)); false, nullptr));
web_navigation::OnCreatedNavigationTarget::Details details; web_navigation::OnCreatedNavigationTarget::Details details;
details.source_tab_id = ExtensionTabUtil::GetTabId(web_contents); details.source_tab_id = source_tab_id;
details.source_process_id = source_frame_host->GetProcess()->GetID(); details.source_process_id = source_render_process_id;
details.source_frame_id = details.source_frame_id = source_extension_frame_id;
ExtensionApiFrameIdMap::GetFrameId(source_frame_host);
details.url = target_url.possibly_invalid_spec(); details.url = target_url.possibly_invalid_spec();
details.tab_id = ExtensionTabUtil::GetTabId(target_web_contents); details.tab_id = ExtensionTabUtil::GetTabId(target_web_contents);
details.time_stamp = MilliSecondsFromTime(base::Time::Now()); details.time_stamp = MilliSecondsFromTime(base::Time::Now());
......
...@@ -48,9 +48,10 @@ void DispatchOnCompleted(content::WebContents* web_contents, ...@@ -48,9 +48,10 @@ void DispatchOnCompleted(content::WebContents* web_contents,
const GURL& url); const GURL& url);
void DispatchOnCreatedNavigationTarget( void DispatchOnCreatedNavigationTarget(
content::WebContents* web_contents, int source_tab_id,
int source_render_process_id,
int source_extension_frame_id,
content::BrowserContext* browser_context, content::BrowserContext* browser_context,
content::RenderFrameHost* source_frame_host,
content::WebContents* target_web_contents, content::WebContents* target_web_contents,
const GURL& target_url); const GURL& target_url);
......
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