Chromium Code Reviews| 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 #include "chrome/browser/extensions/api/messaging/extension_message_port.h" | 5 #include "chrome/browser/extensions/api/messaging/extension_message_port.h" |
| 6 | 6 |
| 7 #include "base/scoped_observer.h" | 7 #include "base/scoped_observer.h" |
| 8 #include "chrome/browser/profiles/profile.h" | 8 #include "chrome/browser/profiles/profile.h" |
| 9 #include "content/public/browser/interstitial_page.h" | |
| 9 #include "content/public/browser/navigation_details.h" | 10 #include "content/public/browser/navigation_details.h" |
| 10 #include "content/public/browser/render_frame_host.h" | 11 #include "content/public/browser/render_frame_host.h" |
| 11 #include "content/public/browser/render_process_host.h" | 12 #include "content/public/browser/render_process_host.h" |
| 12 #include "content/public/browser/web_contents.h" | 13 #include "content/public/browser/web_contents.h" |
| 13 #include "content/public/browser/web_contents_observer.h" | 14 #include "content/public/browser/web_contents_observer.h" |
| 14 #include "extensions/browser/extension_host.h" | 15 #include "extensions/browser/extension_host.h" |
| 15 #include "extensions/browser/process_manager.h" | 16 #include "extensions/browser/process_manager.h" |
| 16 #include "extensions/browser/process_manager_observer.h" | 17 #include "extensions/browser/process_manager_observer.h" |
| 17 #include "extensions/common/extension_messages.h" | 18 #include "extensions/common/extension_messages.h" |
| 18 #include "extensions/common/manifest_handlers/background_info.h" | 19 #include "extensions/common/manifest_handlers/background_info.h" |
| 19 | 20 |
| 20 namespace extensions { | 21 namespace extensions { |
| 21 | 22 |
| 22 const char kReceivingEndDoesntExistError[] = | 23 const char kReceivingEndDoesntExistError[] = |
| 23 "Could not establish connection. Receiving end does not exist."; | 24 "Could not establish connection. Receiving end does not exist."; |
| 24 | 25 |
| 25 // Helper class to detect when frames are destroyed. | 26 // Helper class to detect when frames are destroyed. |
| 26 class ExtensionMessagePort::FrameTracker : public content::WebContentsObserver, | 27 class ExtensionMessagePort::FrameTracker : public content::WebContentsObserver, |
| 27 public ProcessManagerObserver { | 28 public ProcessManagerObserver { |
| 28 public: | 29 public: |
| 29 explicit FrameTracker(ExtensionMessagePort* port) | 30 explicit FrameTracker(ExtensionMessagePort* port) |
| 30 : pm_observer_(this), port_(port) {} | 31 : pm_observer_(this), port_(port), interstitial_frame_(nullptr) {} |
| 31 ~FrameTracker() override {} | 32 ~FrameTracker() override {} |
| 32 | 33 |
| 33 void TrackExtensionProcessFrames() { | 34 void TrackExtensionProcessFrames() { |
| 34 pm_observer_.Add(ProcessManager::Get(port_->browser_context_)); | 35 pm_observer_.Add(ProcessManager::Get(port_->browser_context_)); |
| 35 } | 36 } |
| 36 | 37 |
| 37 void TrackTabFrames(content::WebContents* tab) { | 38 void TrackTabFrames(content::WebContents* tab) { |
| 38 Observe(tab); | 39 Observe(tab); |
| 39 } | 40 } |
| 40 | 41 |
| 42 void TrackInterstitialFrame(content::WebContents* tab, | |
| 43 content::RenderFrameHost* interstitial_frame) { | |
| 44 interstitial_frame_ = interstitial_frame; | |
| 45 Observe(tab); | |
| 46 } | |
| 47 | |
| 41 private: | 48 private: |
| 42 // content::WebContentsObserver overrides: | 49 // content::WebContentsObserver overrides: |
| 43 void RenderFrameDeleted(content::RenderFrameHost* render_frame_host) | 50 void RenderFrameDeleted(content::RenderFrameHost* render_frame_host) |
| 44 override { | 51 override { |
| 45 port_->UnregisterFrame(render_frame_host); | 52 port_->UnregisterFrame(render_frame_host); |
| 46 } | 53 } |
| 47 | 54 |
| 48 // TODO(robwu): This should be superfluous with RenderFrameDeleted above, but | |
| 49 // we are not entirely sure. | |
| 50 void FrameDeleted(content::RenderFrameHost* render_frame_host) override { | |
| 51 port_->UnregisterFrame(render_frame_host); | |
| 52 } | |
| 53 | |
| 54 void DidNavigateAnyFrame(content::RenderFrameHost* render_frame_host, | 55 void DidNavigateAnyFrame(content::RenderFrameHost* render_frame_host, |
| 55 const content::LoadCommittedDetails& details, | 56 const content::LoadCommittedDetails& details, |
| 56 const content::FrameNavigateParams&) override { | 57 const content::FrameNavigateParams&) override { |
| 57 if (!details.is_in_page) | 58 if (!details.is_in_page) |
| 58 port_->UnregisterFrame(render_frame_host); | 59 port_->UnregisterFrame(render_frame_host); |
| 59 } | 60 } |
| 60 | 61 |
| 62 void DidDetachInterstitialPage() override { | |
|
Charlie Reis
2016/01/25 21:47:38
Hmm. I suppose this will work, since the intersti
robwu
2016/01/25 22:54:41
Acknowledged.
| |
| 63 if (interstitial_frame_) { | |
|
Charlie Reis
2016/01/25 21:47:38
nit: No braces for a one-line body.
robwu
2016/01/25 22:54:41
Done.
| |
| 64 port_->UnregisterFrame(interstitial_frame_); | |
| 65 } | |
| 66 } | |
| 67 | |
| 61 // extensions::ProcessManagerObserver overrides: | 68 // extensions::ProcessManagerObserver overrides: |
| 62 void OnExtensionFrameUnregistered( | 69 void OnExtensionFrameUnregistered( |
| 63 const std::string& extension_id, | 70 const std::string& extension_id, |
| 64 content::RenderFrameHost* render_frame_host) override { | 71 content::RenderFrameHost* render_frame_host) override { |
| 65 if (extension_id == port_->extension_id_) | 72 if (extension_id == port_->extension_id_) |
| 66 port_->UnregisterFrame(render_frame_host); | 73 port_->UnregisterFrame(render_frame_host); |
| 67 } | 74 } |
| 68 | 75 |
| 69 ScopedObserver<ProcessManager, ProcessManagerObserver> pm_observer_; | 76 ScopedObserver<ProcessManager, ProcessManagerObserver> pm_observer_; |
| 70 ExtensionMessagePort* port_; // Owns this FrameTracker. | 77 ExtensionMessagePort* port_; // Owns this FrameTracker. |
| 78 content::RenderFrameHost* interstitial_frame_; | |
|
Charlie Reis
2016/01/25 21:47:38
This needs a comment saying that it's only present
robwu
2016/01/25 22:54:41
Done.
| |
| 71 | 79 |
| 72 DISALLOW_COPY_AND_ASSIGN(FrameTracker); | 80 DISALLOW_COPY_AND_ASSIGN(FrameTracker); |
| 73 }; | 81 }; |
| 74 | 82 |
| 75 ExtensionMessagePort::ExtensionMessagePort( | 83 ExtensionMessagePort::ExtensionMessagePort( |
| 76 base::WeakPtr<MessageService> message_service, | 84 base::WeakPtr<MessageService> message_service, |
| 77 int port_id, | 85 int port_id, |
| 78 const std::string& extension_id, | 86 const std::string& extension_id, |
| 79 content::RenderProcessHost* extension_process) | 87 content::RenderProcessHost* extension_process) |
| 80 : weak_message_service_(message_service), | 88 : weak_message_service_(message_service), |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 101 bool include_child_frames) | 109 bool include_child_frames) |
| 102 : weak_message_service_(message_service), | 110 : weak_message_service_(message_service), |
| 103 port_id_(port_id), | 111 port_id_(port_id), |
| 104 extension_id_(extension_id), | 112 extension_id_(extension_id), |
| 105 browser_context_(rfh->GetProcess()->GetBrowserContext()), | 113 browser_context_(rfh->GetProcess()->GetBrowserContext()), |
| 106 extension_process_(nullptr), | 114 extension_process_(nullptr), |
| 107 did_create_port_(false), | 115 did_create_port_(false), |
| 108 background_host_ptr_(nullptr), | 116 background_host_ptr_(nullptr), |
| 109 frame_tracker_(new FrameTracker(this)) { | 117 frame_tracker_(new FrameTracker(this)) { |
| 110 content::WebContents* tab = content::WebContents::FromRenderFrameHost(rfh); | 118 content::WebContents* tab = content::WebContents::FromRenderFrameHost(rfh); |
| 111 CHECK(tab); | 119 content::InterstitialPage* interstitial = nullptr; |
| 120 if (!tab) { | |
| 121 interstitial = content::InterstitialPage::FromRenderFrameHost(rfh); | |
| 122 // A RenderFrameHost must be hosted in a WebContents or InterstitialPage. | |
| 123 CHECK(interstitial); | |
| 124 tab = interstitial->web_contents(); | |
|
Charlie Reis
2016/01/25 21:47:38
This isn't obviously safe to me. It depends on wh
robwu
2016/01/25 22:54:41
Done.
Charlie Reis
2016/01/26 01:14:30
I don't see any justification for this, but I thin
robwu
2016/01/26 11:29:32
Done.
| |
| 125 // This is not expected to happen. When it happens, investigate why it | |
|
Charlie Reis
2016/01/25 21:47:38
Let's elaborate on what "This" means here. Are yo
robwu
2016/01/25 22:54:41
Done.
| |
| 126 // happens anyway and fix it or return early. This is a CHECK, not a DCHECK | |
| 127 // because we really need an observer subject to detect frame removal. | |
| 128 CHECK(tab); | |
| 129 if (!rfh->GetParent()) { | |
| 130 // Only the main frame of an interstitial is supported. | |
|
Charlie Reis
2016/01/25 21:47:38
Let's give a reason why subframes aren't supported
robwu
2016/01/25 22:54:41
Done.
| |
| 131 frame_tracker_->TrackInterstitialFrame(tab, rfh); | |
| 132 RegisterFrame(rfh); | |
| 133 } | |
| 134 return; | |
| 135 } | |
| 136 | |
| 112 frame_tracker_->TrackTabFrames(tab); | 137 frame_tracker_->TrackTabFrames(tab); |
| 113 if (include_child_frames) { | 138 if (include_child_frames) { |
| 114 tab->ForEachFrame(base::Bind(&ExtensionMessagePort::RegisterFrame, | 139 tab->ForEachFrame(base::Bind(&ExtensionMessagePort::RegisterFrame, |
| 115 base::Unretained(this))); | 140 base::Unretained(this))); |
| 116 } else { | 141 } else { |
| 117 RegisterFrame(rfh); | 142 RegisterFrame(rfh); |
| 118 } | 143 } |
| 119 } | 144 } |
| 120 | 145 |
| 121 ExtensionMessagePort::~ExtensionMessagePort() {} | 146 ExtensionMessagePort::~ExtensionMessagePort() {} |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 251 return; | 276 return; |
| 252 } | 277 } |
| 253 for (content::RenderFrameHost* rfh : frames_) { | 278 for (content::RenderFrameHost* rfh : frames_) { |
| 254 IPC::Message* msg_copy = new IPC::Message(*msg.get()); | 279 IPC::Message* msg_copy = new IPC::Message(*msg.get()); |
| 255 msg_copy->set_routing_id(rfh->GetRoutingID()); | 280 msg_copy->set_routing_id(rfh->GetRoutingID()); |
| 256 rfh->Send(msg_copy); | 281 rfh->Send(msg_copy); |
| 257 } | 282 } |
| 258 } | 283 } |
| 259 | 284 |
| 260 } // namespace extensions | 285 } // namespace extensions |
| OLD | NEW |