| 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 | 
|---|