| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Implements the Chrome Extensions WebNavigation API. | 5 // Implements the Chrome Extensions WebNavigation API. |
| 6 | 6 |
| 7 #include "chrome/browser/extensions/api/web_navigation/web_navigation_api.h" | 7 #include "chrome/browser/extensions/api/web_navigation/web_navigation_api.h" |
| 8 | 8 |
| 9 #include "base/lazy_instance.h" | 9 #include "base/lazy_instance.h" |
| 10 #include "chrome/browser/chrome_notification_types.h" | 10 #include "chrome/browser/chrome_notification_types.h" |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 43 namespace keys = web_navigation_api_constants; | 43 namespace keys = web_navigation_api_constants; |
| 44 namespace web_navigation = api::web_navigation; | 44 namespace web_navigation = api::web_navigation; |
| 45 | 45 |
| 46 namespace { | 46 namespace { |
| 47 | 47 |
| 48 typedef std::map<content::WebContents*, WebNavigationTabObserver*> | 48 typedef std::map<content::WebContents*, WebNavigationTabObserver*> |
| 49 TabObserverMap; | 49 TabObserverMap; |
| 50 static base::LazyInstance<TabObserverMap> g_tab_observer = | 50 static base::LazyInstance<TabObserverMap> g_tab_observer = |
| 51 LAZY_INSTANCE_INITIALIZER; | 51 LAZY_INSTANCE_INITIALIZER; |
| 52 | 52 |
| 53 typedef std::map<content::WebContents*, |
| 54 WebNavigationEventRouter::PendingWebContents> |
| 55 PendingWebContentsMap; |
| 56 static base::LazyInstance<PendingWebContentsMap> g_pending_web_contents = |
| 57 LAZY_INSTANCE_INITIALIZER; |
| 58 |
| 53 } // namespace | 59 } // namespace |
| 54 | 60 |
| 55 // WebNavigtionEventRouter ------------------------------------------- | 61 // WebNavigtionEventRouter ------------------------------------------- |
| 56 | 62 |
| 57 WebNavigationEventRouter::PendingWebContents::PendingWebContents() | 63 WebNavigationEventRouter::PendingWebContents::PendingWebContents() |
| 58 : source_web_contents(NULL), | 64 : source_web_contents(NULL), |
| 59 source_frame_host(NULL), | 65 source_frame_host(NULL), |
| 60 target_web_contents(NULL), | 66 target_web_contents(NULL), |
| 61 target_url() { | 67 target_url() { |
| 62 } | 68 } |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 | 123 |
| 118 helpers::DispatchOnTabReplaced(old_contents, profile_, new_contents); | 124 helpers::DispatchOnTabReplaced(old_contents, profile_, new_contents); |
| 119 } | 125 } |
| 120 | 126 |
| 121 void WebNavigationEventRouter::Observe( | 127 void WebNavigationEventRouter::Observe( |
| 122 int type, | 128 int type, |
| 123 const content::NotificationSource& source, | 129 const content::NotificationSource& source, |
| 124 const content::NotificationDetails& details) { | 130 const content::NotificationDetails& details) { |
| 125 switch (type) { | 131 switch (type) { |
| 126 case chrome::NOTIFICATION_RETARGETING: { | 132 case chrome::NOTIFICATION_RETARGETING: { |
| 133 LOG(ERROR) << "WNTO::Observe: retargeting"; |
| 127 Profile* profile = content::Source<Profile>(source).ptr(); | 134 Profile* profile = content::Source<Profile>(source).ptr(); |
| 128 if (profile->GetOriginalProfile() == profile_) { | 135 if (profile->GetOriginalProfile() == profile_) { |
| 129 Retargeting( | 136 Retargeting( |
| 130 content::Details<const RetargetingDetails>(details).ptr()); | 137 content::Details<const RetargetingDetails>(details).ptr()); |
| 131 } | 138 } |
| 132 break; | 139 break; |
| 133 } | 140 } |
| 134 | 141 |
| 135 case chrome::NOTIFICATION_TAB_ADDED: | 142 case chrome::NOTIFICATION_TAB_ADDED: |
| 143 LOG(ERROR) << "WNTO::Observe: tab added"; |
| 136 TabAdded(content::Details<content::WebContents>(details).ptr()); | 144 TabAdded(content::Details<content::WebContents>(details).ptr()); |
| 137 break; | 145 break; |
| 138 | 146 |
| 139 case content::NOTIFICATION_WEB_CONTENTS_DESTROYED: | 147 case content::NOTIFICATION_WEB_CONTENTS_DESTROYED: |
| 148 LOG(ERROR) << "WNTO::Observe: web contents destroyed"; |
| 140 TabDestroyed(content::Source<content::WebContents>(source).ptr()); | 149 TabDestroyed(content::Source<content::WebContents>(source).ptr()); |
| 141 break; | 150 break; |
| 142 | 151 |
| 143 default: | 152 default: |
| 144 NOTREACHED(); | 153 NOTREACHED(); |
| 145 } | 154 } |
| 146 } | 155 } |
| 147 | 156 |
| 148 void WebNavigationEventRouter::Retargeting(const RetargetingDetails* details) { | 157 void WebNavigationEventRouter::Retargeting(const RetargetingDetails* details) { |
| 158 LOG(ERROR) << "WNER::Retargeting: " |
| 159 << " url:" << details->target_url |
| 160 << " source wc:" << details->source_web_contents |
| 161 << " target wc:" << details->target_web_contents |
| 162 << " not yet in ts:" << details->not_yet_in_tabstrip; |
| 149 if (details->source_render_frame_id == 0) | 163 if (details->source_render_frame_id == 0) |
| 150 return; | 164 return; |
| 151 WebNavigationTabObserver* tab_observer = | 165 WebNavigationTabObserver* tab_observer = |
| 152 WebNavigationTabObserver::Get(details->source_web_contents); | 166 WebNavigationTabObserver::Get(details->source_web_contents); |
| 153 if (!tab_observer) { | 167 if (!tab_observer) { |
| 154 // If you hit this DCHECK(), please add reproduction steps to | 168 // If you hit this DCHECK(), please add reproduction steps to |
| 155 // http://crbug.com/109464. | 169 // http://crbug.com/109464. |
| 156 DCHECK(GetViewType(details->source_web_contents) != VIEW_TYPE_TAB_CONTENTS); | 170 DCHECK(GetViewType(details->source_web_contents) != VIEW_TYPE_TAB_CONTENTS); |
| 157 return; | 171 return; |
| 158 } | 172 } |
| 159 const FrameNavigationState& frame_navigation_state = | 173 const FrameNavigationState& frame_navigation_state = |
| 160 tab_observer->frame_navigation_state(); | 174 tab_observer->frame_navigation_state(); |
| 161 | 175 |
| 162 content::RenderFrameHost* frame_host = content::RenderFrameHost::FromID( | 176 content::RenderFrameHost* frame_host = content::RenderFrameHost::FromID( |
| 163 details->source_render_process_id, details->source_render_frame_id); | 177 details->source_render_process_id, details->source_render_frame_id); |
| 164 if (!frame_navigation_state.CanSendEvents(frame_host)) | 178 if (!frame_navigation_state.CanSendEvents(frame_host)) |
| 165 return; | 179 return; |
| 166 | 180 |
| 167 // If the WebContents isn't yet inserted into a tab strip, we need to delay | 181 // If the WebContents isn't yet inserted into a tab strip, we need to delay |
| 168 // the extension event until the WebContents is fully initialized. | 182 // the extension event until the WebContents is fully initialized. |
| 169 if (details->not_yet_in_tabstrip) { | 183 if (details->not_yet_in_tabstrip) { |
| 170 pending_web_contents_[details->target_web_contents] = | 184 g_pending_web_contents.Get()[details->target_web_contents] = |
| 171 PendingWebContents(details->source_web_contents, | 185 PendingWebContents(details->source_web_contents, frame_host, |
| 172 frame_host, | 186 details->target_web_contents, details->target_url); |
| 173 details->target_web_contents, | |
| 174 details->target_url); | |
| 175 } else { | 187 } else { |
| 176 helpers::DispatchOnCreatedNavigationTarget( | 188 helpers::DispatchOnCreatedNavigationTarget( |
| 177 details->source_web_contents, | 189 details->source_web_contents, |
| 178 details->target_web_contents->GetBrowserContext(), | 190 details->target_web_contents->GetBrowserContext(), |
| 179 frame_host, | 191 frame_host, |
| 180 details->target_web_contents, | 192 details->target_web_contents, |
| 181 details->target_url); | 193 details->target_url); |
| 182 } | 194 } |
| 183 } | 195 } |
| 184 | 196 |
| 185 void WebNavigationEventRouter::TabAdded(content::WebContents* tab) { | 197 void WebNavigationEventRouter::TabAdded(content::WebContents* tab) { |
| 186 std::map<content::WebContents*, PendingWebContents>::iterator iter = | 198 std::map<content::WebContents*, PendingWebContents>::iterator iter = |
| 187 pending_web_contents_.find(tab); | 199 g_pending_web_contents.Get().find(tab); |
| 188 if (iter == pending_web_contents_.end()) | 200 if (iter == g_pending_web_contents.Get().end()) |
| 189 return; | 201 return; |
| 190 | 202 |
| 191 WebNavigationTabObserver* tab_observer = | 203 WebNavigationTabObserver* tab_observer = |
| 192 WebNavigationTabObserver::Get(iter->second.source_web_contents); | 204 WebNavigationTabObserver::Get(iter->second.source_web_contents); |
| 193 if (!tab_observer) { | 205 if (!tab_observer) { |
| 194 NOTREACHED(); | 206 NOTREACHED(); |
| 195 return; | 207 return; |
| 196 } | 208 } |
| 197 const FrameNavigationState& frame_navigation_state = | 209 const FrameNavigationState& frame_navigation_state = |
| 198 tab_observer->frame_navigation_state(); | 210 tab_observer->frame_navigation_state(); |
| 199 | 211 |
| 200 if (frame_navigation_state.CanSendEvents(iter->second.source_frame_host)) { | 212 if (frame_navigation_state.CanSendEvents(iter->second.source_frame_host)) { |
| 201 helpers::DispatchOnCreatedNavigationTarget( | 213 helpers::DispatchOnCreatedNavigationTarget( |
| 202 iter->second.source_web_contents, | 214 iter->second.source_web_contents, |
| 203 iter->second.target_web_contents->GetBrowserContext(), | 215 iter->second.target_web_contents->GetBrowserContext(), |
| 204 iter->second.source_frame_host, | 216 iter->second.source_frame_host, |
| 205 iter->second.target_web_contents, | 217 iter->second.target_web_contents, |
| 206 iter->second.target_url); | 218 iter->second.target_url); |
| 207 } | 219 } |
| 208 pending_web_contents_.erase(iter); | 220 g_pending_web_contents.Get().erase(iter); |
| 209 } | 221 } |
| 210 | 222 |
| 211 void WebNavigationEventRouter::TabDestroyed(content::WebContents* tab) { | 223 void WebNavigationEventRouter::TabDestroyed(content::WebContents* tab) { |
| 212 pending_web_contents_.erase(tab); | 224 g_pending_web_contents.Get().erase(tab); |
| 213 for (std::map<content::WebContents*, PendingWebContents>::iterator i = | 225 for (std::map<content::WebContents*, PendingWebContents>::iterator i = |
| 214 pending_web_contents_.begin(); i != pending_web_contents_.end(); ) { | 226 g_pending_web_contents.Get().begin(); |
| 227 i != g_pending_web_contents.Get().end();) { |
| 215 if (i->second.source_web_contents == tab) | 228 if (i->second.source_web_contents == tab) |
| 216 pending_web_contents_.erase(i++); | 229 g_pending_web_contents.Get().erase(i++); |
| 217 else | 230 else |
| 218 ++i; | 231 ++i; |
| 219 } | 232 } |
| 220 } | 233 } |
| 221 | 234 |
| 222 // WebNavigationTabObserver ------------------------------------------ | 235 // WebNavigationTabObserver ------------------------------------------ |
| 223 | 236 |
| 224 WebNavigationTabObserver::WebNavigationTabObserver( | 237 WebNavigationTabObserver::WebNavigationTabObserver( |
| 225 content::WebContents* web_contents) | 238 content::WebContents* web_contents) |
| 226 : WebContentsObserver(web_contents) { | 239 : WebContentsObserver(web_contents) { |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 261 if (old_host) { | 274 if (old_host) { |
| 262 RenderFrameDeleted(old_host); | 275 RenderFrameDeleted(old_host); |
| 263 navigation_state_.FrameHostDeleted(old_host); | 276 navigation_state_.FrameHostDeleted(old_host); |
| 264 } | 277 } |
| 265 | 278 |
| 266 navigation_state_.FrameHostCreated(new_host); | 279 navigation_state_.FrameHostCreated(new_host); |
| 267 } | 280 } |
| 268 | 281 |
| 269 void WebNavigationTabObserver::DidStartNavigation( | 282 void WebNavigationTabObserver::DidStartNavigation( |
| 270 content::NavigationHandle* navigation_handle) { | 283 content::NavigationHandle* navigation_handle) { |
| 284 LOG(ERROR) << "WNTP::DidStartNavigation: handle:" << navigation_handle; |
| 271 if (navigation_handle->IsSynchronousNavigation() || | 285 if (navigation_handle->IsSynchronousNavigation() || |
| 272 !FrameNavigationState::IsValidUrl(navigation_handle->GetURL())) { | 286 !FrameNavigationState::IsValidUrl(navigation_handle->GetURL())) { |
| 273 return; | 287 return; |
| 274 } | 288 } |
| 275 | 289 |
| 276 helpers::DispatchOnBeforeNavigate(navigation_handle); | 290 helpers::DispatchOnBeforeNavigate(navigation_handle); |
| 277 } | 291 } |
| 278 | 292 |
| 279 void WebNavigationTabObserver::DidFinishNavigation( | 293 void WebNavigationTabObserver::DidFinishNavigation( |
| 280 content::NavigationHandle* navigation_handle) { | 294 content::NavigationHandle* navigation_handle) { |
| 295 LOG(ERROR) << "WNTP::DidFinishNavigation: handle:" << navigation_handle; |
| 281 if (navigation_handle->HasCommitted() && !navigation_handle->IsErrorPage()) { | 296 if (navigation_handle->HasCommitted() && !navigation_handle->IsErrorPage()) { |
| 282 HandleCommit(navigation_handle); | 297 HandleCommit(navigation_handle); |
| 283 return; | 298 return; |
| 284 } | 299 } |
| 285 | 300 |
| 286 HandleError(navigation_handle); | 301 HandleError(navigation_handle); |
| 287 } | 302 } |
| 288 | 303 |
| 289 void WebNavigationTabObserver::DocumentLoadedInFrame( | 304 void WebNavigationTabObserver::DocumentLoadedInFrame( |
| 290 content::RenderFrameHost* render_frame_host) { | 305 content::RenderFrameHost* render_frame_host) { |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 361 navigation_state_.SetErrorOccurredInFrame(render_frame_host); | 376 navigation_state_.SetErrorOccurredInFrame(render_frame_host); |
| 362 } | 377 } |
| 363 | 378 |
| 364 void WebNavigationTabObserver::DidOpenRequestedURL( | 379 void WebNavigationTabObserver::DidOpenRequestedURL( |
| 365 content::WebContents* new_contents, | 380 content::WebContents* new_contents, |
| 366 content::RenderFrameHost* source_render_frame_host, | 381 content::RenderFrameHost* source_render_frame_host, |
| 367 const GURL& url, | 382 const GURL& url, |
| 368 const content::Referrer& referrer, | 383 const content::Referrer& referrer, |
| 369 WindowOpenDisposition disposition, | 384 WindowOpenDisposition disposition, |
| 370 ui::PageTransition transition) { | 385 ui::PageTransition transition) { |
| 386 LOG(ERROR) << "WNTO::DidOpenRequestedURL: " |
| 387 << " new_contents:" << new_contents << " url:" << url |
| 388 << " disposition:" << (int)disposition |
| 389 << " source rfh:" << source_render_frame_host; |
| 390 |
| 371 if (!navigation_state_.CanSendEvents(source_render_frame_host)) | 391 if (!navigation_state_.CanSendEvents(source_render_frame_host)) |
| 372 return; | 392 return; |
| 373 | 393 |
| 374 // We only send the onCreatedNavigationTarget if we end up creating a new | 394 // We only send the onCreatedNavigationTarget if we end up creating a new |
| 375 // window. | 395 // window. |
| 376 if (disposition != WindowOpenDisposition::SINGLETON_TAB && | 396 if (disposition != WindowOpenDisposition::SINGLETON_TAB && |
| 377 disposition != WindowOpenDisposition::NEW_FOREGROUND_TAB && | 397 disposition != WindowOpenDisposition::NEW_FOREGROUND_TAB && |
| 378 disposition != WindowOpenDisposition::NEW_BACKGROUND_TAB && | 398 disposition != WindowOpenDisposition::NEW_BACKGROUND_TAB && |
| 379 disposition != WindowOpenDisposition::NEW_POPUP && | 399 disposition != WindowOpenDisposition::NEW_POPUP && |
| 380 disposition != WindowOpenDisposition::NEW_WINDOW && | 400 disposition != WindowOpenDisposition::NEW_WINDOW && |
| 381 disposition != WindowOpenDisposition::OFF_THE_RECORD) | 401 disposition != WindowOpenDisposition::OFF_THE_RECORD) |
| 382 return; | 402 return; |
| 383 | 403 |
| 404 if (!ExtensionTabUtil::GetTabById( |
| 405 ExtensionTabUtil::GetTabId(new_contents), |
| 406 Profile::FromBrowserContext(new_contents->GetBrowserContext()), false, |
| 407 NULL, NULL, NULL, NULL)) { |
| 408 DCHECK_EQ(web_contents(), content::WebContents::FromRenderFrameHost( |
| 409 source_render_frame_host)); |
| 410 |
| 411 g_pending_web_contents.Get()[new_contents] = |
| 412 WebNavigationEventRouter::PendingWebContents( |
| 413 web_contents(), source_render_frame_host, new_contents, url); |
| 414 return; |
| 415 } |
| 416 |
| 384 helpers::DispatchOnCreatedNavigationTarget(web_contents(), | 417 helpers::DispatchOnCreatedNavigationTarget(web_contents(), |
| 385 new_contents->GetBrowserContext(), | 418 new_contents->GetBrowserContext(), |
| 386 source_render_frame_host, | 419 source_render_frame_host, |
| 387 new_contents, | 420 new_contents, |
| 388 url); | 421 url); |
| 389 } | 422 } |
| 390 | 423 |
| 391 void WebNavigationTabObserver::WebContentsDestroyed() { | 424 void WebNavigationTabObserver::WebContentsDestroyed() { |
| 392 g_tab_observer.Get().erase(web_contents()); | 425 g_tab_observer.Get().erase(web_contents()); |
| 393 registrar_.RemoveAll(); | 426 registrar_.RemoveAll(); |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 562 return g_factory.Pointer(); | 595 return g_factory.Pointer(); |
| 563 } | 596 } |
| 564 | 597 |
| 565 void WebNavigationAPI::OnListenerAdded(const EventListenerInfo& details) { | 598 void WebNavigationAPI::OnListenerAdded(const EventListenerInfo& details) { |
| 566 web_navigation_event_router_.reset(new WebNavigationEventRouter( | 599 web_navigation_event_router_.reset(new WebNavigationEventRouter( |
| 567 Profile::FromBrowserContext(browser_context_))); | 600 Profile::FromBrowserContext(browser_context_))); |
| 568 EventRouter::Get(browser_context_)->UnregisterObserver(this); | 601 EventRouter::Get(browser_context_)->UnregisterObserver(this); |
| 569 } | 602 } |
| 570 | 603 |
| 571 } // namespace extensions | 604 } // namespace extensions |
| OLD | NEW |