summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwjmaclean <wjmaclean@chromium.org>2015-10-16 12:57:24 -0700
committerCommit bot <commit-bot@chromium.org>2015-10-16 19:58:27 +0000
commit6f63918adf16bbd01bba2acb42ca87755fc8f439 (patch)
tree9e1be3185f5ca51dacd9d163913cb13cf1f957bb
parentee39de0c59d369c508e3a48317964ed0ab7b61ef (diff)
downloadchromium_src-6f63918adf16bbd01bba2acb42ca87755fc8f439.zip
chromium_src-6f63918adf16bbd01bba2acb42ca87755fc8f439.tar.gz
chromium_src-6f63918adf16bbd01bba2acb42ca87755fc8f439.tar.bz2
Update IPC browser_plugin_instance_id before sending queued messages
Currently, if BrowserPluginGuest receives messages for a BrowserPlugin prior to attachment, the message may be created with an invalid (0) value of |browser_plugin_instance_id|. After attachment, when queued messages are sent, these messages disappear into the ether. This CL modifies queued IPC messages in BrowserPluginGuest before those messages are sent, in order to give them a valid instance id. BUG=534839 Review URL: https://codereview.chromium.org/1410753003 Cr-Commit-Position: refs/heads/master@{#354572}
-rw-r--r--content/browser/browser_plugin/browser_plugin_guest.cc43
-rw-r--r--content/browser/browser_plugin/browser_plugin_guest.h6
2 files changed, 48 insertions, 1 deletions
diff --git a/content/browser/browser_plugin/browser_plugin_guest.cc b/content/browser/browser_plugin/browser_plugin_guest.cc
index eaec2fe..2c79731 100644
--- a/content/browser/browser_plugin/browser_plugin_guest.cc
+++ b/content/browser/browser_plugin/browser_plugin_guest.cc
@@ -565,6 +565,46 @@ void BrowserPluginGuest::EmbedderSystemDragEnded() {
EndSystemDragIfApplicable();
}
+// TODO(wjmaclean): Replace this approach with ones based on std::function
+// as in https://codereview.chromium.org/1404353004/ once all Chrome platforms
+// support this. https://crbug.com/544212
+IPC::Message* BrowserPluginGuest::UpdateInstanceIdIfNecessary(
+ IPC::Message* msg) const {
+ DCHECK(msg);
+
+ int msg_browser_plugin_instance_id = browser_plugin::kInstanceIDNone;
+ base::PickleIterator iter(*msg);
+ if (!iter.ReadInt(&msg_browser_plugin_instance_id) ||
+ msg_browser_plugin_instance_id != browser_plugin::kInstanceIDNone) {
+ return msg;
+ }
+
+ // This method may be called with no browser_plugin_instance_id in tests.
+ if (!browser_plugin_instance_id())
+ return msg;
+
+ scoped_ptr<IPC::Message> new_msg(
+ new IPC::Message(msg->routing_id(), msg->type(), msg->priority()));
+ new_msg->WriteInt(browser_plugin_instance_id());
+
+ // Copy remaining payload from original message.
+ // TODO(wjmaclean): it would be nice if IPC::PickleIterator had a method
+ // like 'RemainingBytes()' so that we don't have to include implementation-
+ // specific details like sizeof() in the next line.
+ DCHECK(msg->payload_size() > sizeof(int));
+ size_t remaining_bytes = msg->payload_size() - sizeof(int);
+ const char* data = nullptr;
+ bool read_success = iter.ReadBytes(&data, remaining_bytes);
+ CHECK(read_success)
+ << "Unexpected failure reading remaining IPC::Message payload.";
+ bool write_success = new_msg->WriteBytes(data, remaining_bytes);
+ CHECK(write_success)
+ << "Unexpected failure writing remaining IPC::Message payload.";
+
+ delete msg;
+ return new_msg.release();
+}
+
void BrowserPluginGuest::SendQueuedMessages() {
if (!attached())
return;
@@ -572,7 +612,8 @@ void BrowserPluginGuest::SendQueuedMessages() {
while (!pending_messages_.empty()) {
linked_ptr<IPC::Message> message_ptr = pending_messages_.front();
pending_messages_.pop_front();
- SendMessageToEmbedder(message_ptr.release());
+ SendMessageToEmbedder(
+ UpdateInstanceIdIfNecessary(message_ptr.release()));
}
}
diff --git a/content/browser/browser_plugin/browser_plugin_guest.h b/content/browser/browser_plugin/browser_plugin_guest.h
index f302c6d..d739434 100644
--- a/content/browser/browser_plugin/browser_plugin_guest.h
+++ b/content/browser/browser_plugin/browser_plugin_guest.h
@@ -386,6 +386,12 @@ class CONTENT_EXPORT BrowserPluginGuest : public GuestHost,
void OnWillAttachComplete(WebContentsImpl* embedder_web_contents,
const BrowserPluginHostMsg_Attach_Params& params);
+ // Returns identical message with current browser_plugin_instance_id() if
+ // the input was created with browser_plugin::kInstanceIdNone, else it returns
+ // the input message unmodified. If no current browser_plugin_instance_id()
+ // is set, or anything goes wrong, the input message is returned.
+ IPC::Message* UpdateInstanceIdIfNecessary(IPC::Message* msg) const;
+
// Forwards all messages from the |pending_messages_| queue to the embedder.
void SendQueuedMessages();