summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/extensions/extension_browsertests_misc.cc46
-rw-r--r--chrome/browser/extensions/extension_host.cc25
-rw-r--r--chrome/browser/extensions/extension_host.h8
-rw-r--r--chrome/browser/extensions/extension_process_manager.cc6
-rw-r--r--chrome/browser/renderer_host/render_view_host.cc8
-rw-r--r--chrome/browser/renderer_host/render_view_host.h3
-rw-r--r--chrome/browser/renderer_host/render_view_host_delegate.h8
-rw-r--r--chrome/browser/tab_contents/interstitial_page.cc4
-rw-r--r--chrome/browser/tab_contents/interstitial_page.h5
-rw-r--r--chrome/browser/tab_contents/tab_contents.cc9
-rw-r--r--chrome/browser/tab_contents/tab_contents.h2
-rw-r--r--chrome/browser/views/tabs/tab_strip.cc5
-rw-r--r--chrome/chrome.gyp1
-rw-r--r--chrome/common/common_resources.grd2
-rwxr-xr-xchrome/common/extensions/api/extension_api.json67
-rw-r--r--chrome/common/render_messages.h7
-rw-r--r--chrome/common/render_messages_internal.h9
-rwxr-xr-xchrome/common/view_types.h29
-rw-r--r--chrome/renderer/extensions/bindings_utils.cc4
-rw-r--r--chrome/renderer/extensions/extension_process_bindings.cc74
-rw-r--r--chrome/renderer/render_view.cc17
-rw-r--r--chrome/renderer/render_view.h21
-rw-r--r--chrome/renderer/renderer_resources.grd2
-rw-r--r--chrome/renderer/resources/extension_process_bindings.js163
-rwxr-xr-xchrome/test/data/extensions/good/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/backgroundpage.html5
-rw-r--r--chrome/test/data/extensions/good/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/manifest.json1
-rwxr-xr-xchrome/test/data/extensions/good/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/test_gettabs.html5
-rw-r--r--chrome/test/data/extensions/good/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/toolstrip1.html29
-rw-r--r--chrome/test/data/extensions/good/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/toolstrip2.html3
-rw-r--r--ipc/ipc_message_utils.h18
30 files changed, 455 insertions, 131 deletions
diff --git a/chrome/browser/extensions/extension_browsertests_misc.cc b/chrome/browser/extensions/extension_browsertests_misc.cc
index c3770b0..1384998 100644
--- a/chrome/browser/extensions/extension_browsertests_misc.cc
+++ b/chrome/browser/extensions/extension_browsertests_misc.cc
@@ -48,11 +48,12 @@ IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, Toolstrip) {
AppendASCII("1.0.0.0");
ASSERT_TRUE(LoadExtension(extension_test_data_dir));
- // At this point, there should be two ExtensionHosts loaded because this
- // extension has two toolstrips. Find the one that is hosting toolstrip1.html.
+ // At this point, there should be three ExtensionHosts loaded because this
+ // extension has two toolstrips and one background page. Find the one that is
+ // hosting toolstrip1.html.
ExtensionProcessManager* manager =
browser()->profile()->GetExtensionProcessManager();
- ExtensionHost* host = FindHostWithPath(manager, "/toolstrip1.html", 2);
+ ExtensionHost* host = FindHostWithPath(manager, "/toolstrip1.html", 3);
// Tell it to run some JavaScript that tests that basic extension code works.
bool result = false;
@@ -77,6 +78,45 @@ IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, Toolstrip) {
#endif
}
+IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, ExtensionViews) {
+ FilePath extension_test_data_dir = test_data_dir_.AppendASCII("good").
+ AppendASCII("Extensions").AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj").
+ AppendASCII("1.0.0.0");
+ ASSERT_TRUE(LoadExtension(extension_test_data_dir));
+
+ // At this point, there should be three ExtensionHosts loaded because this
+ // extension has two toolstrips and one background page. Find the one that is
+ // hosting toolstrip1.html.
+ ExtensionProcessManager* manager =
+ browser()->profile()->GetExtensionProcessManager();
+ ExtensionHost* host = FindHostWithPath(manager, "/toolstrip1.html", 3);
+
+ FilePath gettabs_url = extension_test_data_dir.AppendASCII(
+ "test_gettabs.html");
+ ui_test_utils::NavigateToURL(
+ browser(),
+ GURL(gettabs_url.ToWStringHack()));
+
+ bool result = false;
+ ui_test_utils::ExecuteJavaScriptAndExtractBool(
+ host->render_view_host(), L"", L"testgetToolstripsAPI()", &result);
+ EXPECT_TRUE(result);
+
+ result = false;
+ ui_test_utils::ExecuteJavaScriptAndExtractBool(
+ host->render_view_host(), L"", L"testgetBackgroundPageAPI()", &result);
+ EXPECT_TRUE(result);
+
+ ui_test_utils::NavigateToURL(
+ browser(),
+ GURL("chrome-extension://behllobkkfkfnphdnhnkndlbkcpglgmj/"
+ "test_gettabs.html"));
+ result = false;
+ ui_test_utils::ExecuteJavaScriptAndExtractBool(
+ host->render_view_host(), L"", L"testgetTabContentsesAPI()", &result);
+ EXPECT_TRUE(result);
+}
+
// Tests that the ExtensionShelf initializes properly, notices that
// an extension loaded and has a view available, and then sets that up
// properly.
diff --git a/chrome/browser/extensions/extension_host.cc b/chrome/browser/extensions/extension_host.cc
index 898aeaa..e43df14 100644
--- a/chrome/browser/extensions/extension_host.cc
+++ b/chrome/browser/extensions/extension_host.cc
@@ -11,6 +11,7 @@
#include "chrome/browser/browser_list.h"
#include "chrome/browser/debugger/devtools_manager.h"
#include "chrome/browser/extensions/extension_message_service.h"
+#include "chrome/browser/extensions/extension_tabs_module.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/renderer_host/render_process_host.h"
@@ -25,6 +26,7 @@
#include "chrome/common/notification_service.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/pref_service.h"
+#include "chrome/common/view_types.h"
#include "chrome/common/render_messages.h"
#include "chrome/common/url_constants.h"
@@ -84,12 +86,13 @@ class CrashedExtensionInfobarDelegate : public ConfirmInfoBarDelegate {
bool ExtensionHost::enable_dom_automation_ = false;
ExtensionHost::ExtensionHost(Extension* extension, SiteInstance* site_instance,
- const GURL& url)
+ const GURL& url, ViewType::Type host_type)
: extension_(extension),
profile_(site_instance->browsing_instance()->profile()),
did_stop_loading_(false),
document_element_available_(false),
- url_(url) {
+ url_(url),
+ extension_host_type_(host_type) {
render_view_host_ = new RenderViewHost(
site_instance, this, MSG_ROUTING_NONE, NULL);
render_view_host_->AllowBindings(BindingsPolicy::EXTENSION);
@@ -385,6 +388,10 @@ Browser* ExtensionHost::GetBrowser() {
return browser;
}
+ViewType::Type ExtensionHost::GetRenderViewType() const {
+ return extension_host_type_;
+}
+
void ExtensionHost::RenderViewCreated(RenderViewHost* render_view_host) {
// TODO(mpcomplete): This is duplicated in DidNavigate, which means that
// we'll create 2 EFDs for the first navigation. We should try to find a
@@ -393,3 +400,17 @@ void ExtensionHost::RenderViewCreated(RenderViewHost* render_view_host) {
extension_function_dispatcher_.reset(
new ExtensionFunctionDispatcher(render_view_host, this, url_));
}
+
+int ExtensionHost::GetBrowserWindowID() const {
+ int window_id = -1;
+ if (extension_host_type_ == ViewType::EXTENSION_TOOLSTRIP) {
+ window_id = ExtensionTabUtil::GetWindowId(
+ const_cast<ExtensionHost* >(this)->GetBrowser());
+ } else if (extension_host_type_ == ViewType::EXTENSION_BACKGROUND_PAGE) {
+ // Background page is not attached to any browser window, so pass -1.
+ window_id = -1;
+ } else {
+ NOTREACHED();
+ }
+ return window_id;
+}
diff --git a/chrome/browser/extensions/extension_host.h b/chrome/browser/extensions/extension_host.h
index 1a9ffed..1d42ead 100644
--- a/chrome/browser/extensions/extension_host.h
+++ b/chrome/browser/extensions/extension_host.h
@@ -40,7 +40,7 @@ class ExtensionHost : public RenderViewHostDelegate,
static void EnableDOMAutomation() { enable_dom_automation_ = true; }
ExtensionHost(Extension* extension, SiteInstance* site_instance,
- const GURL& url);
+ const GURL& url, ViewType::Type host_type);
~ExtensionHost();
#if defined(TOOLKIT_VIEWS)
@@ -84,6 +84,8 @@ class ExtensionHost : public RenderViewHostDelegate,
virtual RenderViewHostDelegate::View* GetViewDelegate();
virtual const GURL& GetURL() const { return url_; }
virtual void RenderViewCreated(RenderViewHost* render_view_host);
+ virtual ViewType::Type GetRenderViewType() const;
+ virtual int GetBrowserWindowID() const;
virtual void RenderViewGone(RenderViewHost* render_view_host);
virtual void DidNavigate(RenderViewHost* render_view_host,
const ViewHostMsg_FrameNavigate_Params& params);
@@ -177,6 +179,10 @@ class ExtensionHost : public RenderViewHostDelegate,
scoped_ptr<ExtensionFunctionDispatcher> extension_function_dispatcher_;
+ // Only EXTENSION_TOOLSTRIP and EXTENSION_BACKGROUND_PAGE are used here,
+ // others are not hostd by ExtensionHost.
+ ViewType::Type extension_host_type_;
+
DISALLOW_COPY_AND_ASSIGN(ExtensionHost);
};
diff --git a/chrome/browser/extensions/extension_process_manager.cc b/chrome/browser/extensions/extension_process_manager.cc
index 0a362a4..acf43af 100644
--- a/chrome/browser/extensions/extension_process_manager.cc
+++ b/chrome/browser/extensions/extension_process_manager.cc
@@ -56,7 +56,8 @@ ExtensionHost* ExtensionProcessManager::CreateView(Extension* extension,
DCHECK(extension);
DCHECK(browser);
ExtensionHost* host =
- new ExtensionHost(extension, GetSiteInstanceForURL(url), url);
+ new ExtensionHost(extension, GetSiteInstanceForURL(url), url,
+ ViewType::EXTENSION_TOOLSTRIP);
host->CreateView(browser);
OnExtensionHostCreated(host, false);
return host;
@@ -78,7 +79,8 @@ ExtensionHost* ExtensionProcessManager::CreateView(const GURL& url,
ExtensionHost* ExtensionProcessManager::CreateBackgroundHost(
Extension* extension, const GURL& url) {
ExtensionHost* host =
- new ExtensionHost(extension, GetSiteInstanceForURL(url), url);
+ new ExtensionHost(extension, GetSiteInstanceForURL(url), url,
+ ViewType::EXTENSION_BACKGROUND_PAGE);
host->CreateRenderView(NULL); // create a RenderViewHost with no view
OnExtensionHostCreated(host, true);
return host;
diff --git a/chrome/browser/renderer_host/render_view_host.cc b/chrome/browser/renderer_host/render_view_host.cc
index b94d72b..49c4821 100644
--- a/chrome/browser/renderer_host/render_view_host.cc
+++ b/chrome/browser/renderer_host/render_view_host.cc
@@ -223,7 +223,9 @@ bool RenderViewHost::CreateRenderView() {
// If it's enabled, tell the renderer to set up the Javascript bindings for
// sending messages back to the browser.
Send(new ViewMsg_AllowBindings(routing_id(), enabled_bindings_));
-
+ UpdateBrowserWindowId(delegate_->GetBrowserWindowID());
+ Send(new ViewMsg_NotifyRenderViewType(routing_id(),
+ delegate_->GetRenderViewType()));
// Let our delegate know that we created a RenderView.
delegate_->RenderViewCreated(this);
process()->ViewCreated();
@@ -1641,3 +1643,7 @@ void RenderViewHost::ResetModalDialogEvent() {
if (--modal_dialog_count_ == 0)
modal_dialog_event_->Reset();
}
+
+void RenderViewHost::UpdateBrowserWindowId(int window_id) {
+ Send(new ViewMsg_UpdateBrowserWindowId(routing_id(), window_id));
+}
diff --git a/chrome/browser/renderer_host/render_view_host.h b/chrome/browser/renderer_host/render_view_host.h
index 959b99b..71a15fe 100644
--- a/chrome/browser/renderer_host/render_view_host.h
+++ b/chrome/browser/renderer_host/render_view_host.h
@@ -426,6 +426,9 @@ class RenderViewHost : public RenderWidgetHost,
void SignalModalDialogEvent();
void ResetModalDialogEvent();
+ // Tell renderer which browser window it is being attached to.
+ void UpdateBrowserWindowId(int window_id);
+
void set_in_inspect_element_mode(bool enabled) {
in_inspect_element_mode_ = enabled;
}
diff --git a/chrome/browser/renderer_host/render_view_host_delegate.h b/chrome/browser/renderer_host/render_view_host_delegate.h
index 564a6e80..d9a7d9c 100644
--- a/chrome/browser/renderer_host/render_view_host_delegate.h
+++ b/chrome/browser/renderer_host/render_view_host_delegate.h
@@ -10,6 +10,7 @@
#include "base/basictypes.h"
#include "base/string16.h"
+#include "chrome/common/view_types.h"
#include "net/base/load_states.h"
#include "webkit/glue/window_open_disposition.h"
@@ -373,6 +374,13 @@ class RenderViewHostDelegate {
// not a TabContents, returns NULL.
virtual TabContents* GetAsTabContents();
+ // Return id number of browser window which this object is attached to. If no
+ // browser window is attached to, just return -1.
+ virtual int GetBrowserWindowID() const = 0;
+
+ // Return type of RenderView which is attached with this object.
+ virtual ViewType::Type GetRenderViewType() const = 0;
+
// The RenderView is being constructed (message sent to the renderer process
// to construct a RenderView). Now is a good time to send other setup events
// to the RenderView. This precedes any other commands to the RenderView.
diff --git a/chrome/browser/tab_contents/interstitial_page.cc b/chrome/browser/tab_contents/interstitial_page.cc
index 5cc0288..b7e739e 100644
--- a/chrome/browser/tab_contents/interstitial_page.cc
+++ b/chrome/browser/tab_contents/interstitial_page.cc
@@ -591,3 +591,7 @@ void InterstitialPage::InterstitialPageRVHViewDelegate::OnFindReply(
int request_id, int number_of_matches, const gfx::Rect& selection_rect,
int active_match_ordinal, bool final_update) {
}
+
+int InterstitialPage::GetBrowserWindowID() const {
+ return tab_->GetBrowserWindowID();
+}
diff --git a/chrome/browser/tab_contents/interstitial_page.h b/chrome/browser/tab_contents/interstitial_page.h
index c2d7db9..dce25e4 100644
--- a/chrome/browser/tab_contents/interstitial_page.h
+++ b/chrome/browser/tab_contents/interstitial_page.h
@@ -86,6 +86,11 @@ class InterstitialPage : public NotificationObserver,
// Called when tab traversing.
void FocusThroughTabTraversal(bool reverse);
+ virtual ViewType::Type GetRenderViewType() const {
+ return ViewType::INTERSTITIAL_PAGE;
+ }
+ virtual int GetBrowserWindowID() const;
+
protected:
// NotificationObserver method:
virtual void Observe(NotificationType type,
diff --git a/chrome/browser/tab_contents/tab_contents.cc b/chrome/browser/tab_contents/tab_contents.cc
index 72cca16..062f9dc 100644
--- a/chrome/browser/tab_contents/tab_contents.cc
+++ b/chrome/browser/tab_contents/tab_contents.cc
@@ -1776,12 +1776,19 @@ TabContents* TabContents::GetAsTabContents() {
return this;
}
+ViewType::Type TabContents::GetRenderViewType() const {
+ return ViewType::TAB_CONTENTS;
+}
+
+int TabContents::GetBrowserWindowID() const {
+ return controller().window_id().id();
+}
+
void TabContents::RenderViewCreated(RenderViewHost* render_view_host) {
NotificationService::current()->Notify(
NotificationType::RENDER_VIEW_HOST_CREATED_FOR_TAB,
Source<TabContents>(this),
Details<RenderViewHost>(render_view_host));
-
NavigationEntry* entry = controller_.GetActiveEntry();
if (!entry)
return;
diff --git a/chrome/browser/tab_contents/tab_contents.h b/chrome/browser/tab_contents/tab_contents.h
index 3feaaf3..22a51c5 100644
--- a/chrome/browser/tab_contents/tab_contents.h
+++ b/chrome/browser/tab_contents/tab_contents.h
@@ -806,6 +806,8 @@ class TabContents : public PageNavigator,
virtual RenderViewHostDelegate::FavIcon* GetFavIconDelegate();
virtual RenderViewHostDelegate::Autofill* GetAutofillDelegate();
virtual TabContents* GetAsTabContents();
+ virtual ViewType::Type GetRenderViewType() const;
+ virtual int GetBrowserWindowID() const;
virtual void RenderViewCreated(RenderViewHost* render_view_host);
virtual void RenderViewReady(RenderViewHost* render_view_host);
virtual void RenderViewGone(RenderViewHost* render_view_host);
diff --git a/chrome/browser/views/tabs/tab_strip.cc b/chrome/browser/views/tabs/tab_strip.cc
index 52f61a9..89097e3 100644
--- a/chrome/browser/views/tabs/tab_strip.cc
+++ b/chrome/browser/views/tabs/tab_strip.cc
@@ -739,7 +739,10 @@ void TabStrip::TabInsertedAt(TabContents* contents,
bool foreground) {
DCHECK(contents);
DCHECK(index == TabStripModel::kNoTab || model_->ContainsIndex(index));
-
+ // This tab may be attached to another browser window, we should notify
+ // renderer.
+ contents->render_view_host()->UpdateBrowserWindowId(
+ contents->controller().window_id().id());
if (active_animation_.get())
active_animation_->Stop();
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index 8bad388..74839ad 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -513,6 +513,7 @@
'common/transport_dib_win.cc',
'common/url_constants.cc',
'common/url_constants.h',
+ 'common/view_types.h',
'common/visitedlink_common.cc',
'common/visitedlink_common.h',
'common/webkit_param_traits.h',
diff --git a/chrome/common/common_resources.grd b/chrome/common/common_resources.grd
index 5fc44f4..e8510c5 100644
--- a/chrome/common/common_resources.grd
+++ b/chrome/common/common_resources.grd
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- This comment is only here because changes to resources are not picked up
-without changes to the corresponding grd file. rw -->
+without changes to the corresponding grd file. aa1 -->
<grit latest_public_release="0" current_release="1">
<outputs>
<output filename="grit/common_resources.h" type="rc_header">
diff --git a/chrome/common/extensions/api/extension_api.json b/chrome/common/extensions/api/extension_api.json
index 11627d7..2225236 100755
--- a/chrome/common/extensions/api/extension_api.json
+++ b/chrome/common/extensions/api/extension_api.json
@@ -31,6 +31,52 @@
"$ref": "Port",
"description": "Port through which messages can be sent and received with the extension."
}
+ },
+ {
+ "name": "getViews",
+ "type": "function",
+ "description": "Returns an array of the global JavaScript objects for each of the views running inside the current extension. This includes toolstrips, background pages, and tabs.",
+ "parameters": [],
+ "returns": {
+ "type": "array",
+ "description": "Array of global objects",
+ "items": { "type": "object" }
+ }
+ },
+ {
+ "name": "getBackgroundPage",
+ "type": "function",
+ "description": "Returns the global JavaScript object for the background page running inside the current extension. Returns null if the extension has no backround page.",
+ "parameters": [],
+ "returns": {
+ "type": "object"
+ }
+ },
+ {
+ "name": "getToolstrips",
+ "type": "function",
+ "description": "Returns an array of the global JavaScript objects for each of the toolstrip views running inside the current extension. If windowId is specified, returns only the toolstrips attached to the specified window.",
+ "parameters": [
+ {"type": "integer", "name": "windowId", "optional": true}
+ ],
+ "returns": {
+ "type": "array",
+ "description": "Array of global objects",
+ "items": { "type": "object" }
+ }
+ },
+ {
+ "name": "getTabContentses",
+ "type": "function",
+ "description": "Returns an array of the global JavaScript objects for each of the tab contents views running inside the current extension. If windowId is specified, returns only the tab contentses attached to the specified window.",
+ "parameters": [
+ {"type": "integer", "name": "windowId", "optional": true}
+ ],
+ "returns": {
+ "type": "array",
+ "description": "Array of global objects",
+ "items": { "type": "object" }
+ }
}
],
"events": [
@@ -45,25 +91,6 @@
]
},
{
- "namespace": "self",
- "types": [
- ],
- "functions": [
- {
- "name": "getViews",
- "type": "function",
- "description": "Returns an array of the global JavaScript objects for each of the views running inside the current extension. This includes toolstrips, background pages, and tabs.",
- "parameters": [],
- "returns": {
- "type": "array",
- "description": "Array of HTMLWindow objects",
- "items": { "type": "object" }
- }
- }
- ],
- "events": []
- },
- {
"namespace": "windows",
"types": [
{
@@ -101,7 +128,7 @@
{
"name": "getCurrent",
"type": "function",
- "description": "Get the window that is the container for the caller. i.e. the window containing the ToolStrip that makes the call.",
+ "description": "Get the window that is the container for the caller. i.e. the window containing the toolstrip that makes the call.",
"parameters": [
{
"type": "function",
diff --git a/chrome/common/render_messages.h b/chrome/common/render_messages.h
index f16957c7..5dce342 100644
--- a/chrome/common/render_messages.h
+++ b/chrome/common/render_messages.h
@@ -21,6 +21,7 @@
#include "chrome/common/page_transition_types.h"
#include "chrome/common/renderer_preferences.h"
#include "chrome/common/transport_dib.h"
+#include "chrome/common/view_types.h"
#include "chrome/common/webkit_param_traits.h"
#include "googleurl/src/gurl.h"
#include "ipc/ipc_message_utils.h"
@@ -1159,8 +1160,6 @@ struct ParamTraits<ViewMsg_UploadFile_Params> {
}
};
-
-
// Traits for webkit_glue::PasswordFormDomManager::FillData.
template <>
struct ParamTraits<webkit_glue::PasswordFormDomManager::FillData> {
@@ -2000,6 +1999,10 @@ struct ParamTraits<ViewHostMsg_ScriptedPrint_Params> {
}
};
+template <>
+struct SimilarTypeTraits<ViewType::Type> {
+ typedef int Type;
+};
} // namespace IPC
diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h
index 51fe0e9..80e5510 100644
--- a/chrome/common/render_messages_internal.h
+++ b/chrome/common/render_messages_internal.h
@@ -20,6 +20,7 @@
#include "base/values.h"
#include "chrome/common/css_colors.h"
#include "chrome/common/transport_dib.h"
+#include "chrome/common/view_types.h"
#include "ipc/ipc_channel_handle.h"
#include "ipc/ipc_message_macros.h"
#include "third_party/skia/include/core/SkBitmap.h"
@@ -646,6 +647,14 @@ IPC_BEGIN_MESSAGES(View)
IPC_MESSAGE_CONTROL1(UtilityMsg_UnpackWebResource,
std::string /* JSON data */)
+ // Tell the renderer which browser window it's being attached to.
+ IPC_MESSAGE_ROUTED1(ViewMsg_UpdateBrowserWindowId,
+ int /* id of browser window */)
+
+ // Tell the renderer which type this view is.
+ IPC_MESSAGE_ROUTED1(ViewMsg_NotifyRenderViewType,
+ ViewType::Type /* view_type */)
+
// Returns a file handle
IPC_MESSAGE_CONTROL2(ViewMsg_DatabaseOpenFileResponse,
int32 /* the ID of the message we're replying to */,
diff --git a/chrome/common/view_types.h b/chrome/common/view_types.h
new file mode 100755
index 0000000..4151fdd
--- /dev/null
+++ b/chrome/common/view_types.h
@@ -0,0 +1,29 @@
+// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_COMMON_VIEW_TYPES_H_
+#define CHROME_COMMON_VIEW_TYPES_H_
+
+#include "base/basictypes.h"
+
+// Indicates different types of views
+class ViewType {
+ public:
+ enum Type {
+ INVALID,
+ TAB_CONTENTS,
+ EXTENSION_TOOLSTRIP,
+ EXTENSION_BACKGROUND_PAGE,
+ DEV_TOOLS_UI,
+ INTERSTITIAL_PAGE,
+ };
+
+ private:
+ // This class is for scoping only, so you shouldn't create an instance of it.
+ ViewType() {}
+
+ DISALLOW_COPY_AND_ASSIGN(ViewType);
+};
+
+#endif // CHROME_COMMON_VIEW_TYPES_H_
diff --git a/chrome/renderer/extensions/bindings_utils.cc b/chrome/renderer/extensions/bindings_utils.cc
index 3d29f4b..13deb2a 100644
--- a/chrome/renderer/extensions/bindings_utils.cc
+++ b/chrome/renderer/extensions/bindings_utils.cc
@@ -68,8 +68,8 @@ ContextList::iterator FindContext(v8::Handle<v8::Context> context) {
ContextList::iterator it = all_contexts.begin();
for (; it != all_contexts.end(); ++it) {
- if ((*it)->context == context)
- break;
+ if ((*it)->context == context)
+ break;
}
return it;
diff --git a/chrome/renderer/extensions/extension_process_bindings.cc b/chrome/renderer/extensions/extension_process_bindings.cc
index cf0f344..cb22bce 100644
--- a/chrome/renderer/extensions/extension_process_bindings.cc
+++ b/chrome/renderer/extensions/extension_process_bindings.cc
@@ -92,8 +92,8 @@ class ExtensionImpl : public ExtensionBase {
v8::Handle<v8::String> name) {
if (name->Equals(v8::String::New("GetExtensionAPIDefinition"))) {
return v8::FunctionTemplate::New(GetExtensionAPIDefinition);
- } else if (name->Equals(v8::String::New("GetViews"))) {
- return v8::FunctionTemplate::New(GetViews);
+ } else if (name->Equals(v8::String::New("GetExtensionViews"))) {
+ return v8::FunctionTemplate::New(GetExtensionViews);
} else if (name->Equals(v8::String::New("GetNextRequestId"))) {
return v8::FunctionTemplate::New(GetNextRequestId);
} else if (name->Equals(v8::String::New("OpenChannelToTab"))) {
@@ -113,22 +113,66 @@ class ExtensionImpl : public ExtensionBase {
return v8::String::New(GetStringResource<IDR_EXTENSION_API_JSON>());
}
- static v8::Handle<v8::Value> GetViews(const v8::Arguments& args) {
- std::string extension_id = ExtensionIdForCurrentContext();
+ static v8::Handle<v8::Value> GetExtensionViews(const v8::Arguments& args) {
+ if (args.Length() != 2)
+ return v8::Undefined();
+
+ if (!args[0]->IsInt32() || !args[1]->IsString())
+ return v8::Undefined();
- ContextList contexts =
- bindings_utils::GetContextsForExtension(extension_id);
- DCHECK(contexts.size() > 0);
+ // |browser_window_id| == -1 means getting views attached to any browser
+ // window.
+ int browser_window_id = args[0]->Int32Value();
+
+ std::string view_type_string = *v8::String::Utf8Value(args[1]->ToString());
+ // |view_type| == ViewType::INVALID means getting any type of views.
+ ViewType::Type view_type = ViewType::INVALID;
+ if (view_type_string == "TOOLSTRIP") {
+ view_type = ViewType::EXTENSION_TOOLSTRIP;
+ } else if (view_type_string == "BACKGROUND") {
+ view_type = ViewType::EXTENSION_BACKGROUND_PAGE;
+ } else if (view_type_string == "TAB") {
+ view_type = ViewType::TAB_CONTENTS;
+ } else if (view_type_string != "ALL") {
+ return v8::Undefined();
+ }
- v8::Local<v8::Array> views = v8::Array::New(contexts.size());
+ v8::Local<v8::Array> views = v8::Array::New();
int index = 0;
- ContextList::const_iterator it = contexts.begin();
- for (; it != contexts.end(); ++it) {
- v8::Local<v8::Value> window = (*it)->context->Global()->Get(
- v8::String::New("window"));
- DCHECK(!window.IsEmpty());
- views->Set(v8::Integer::New(index), window);
- index++;
+ RenderView::RenderViewSet* render_view_set_pointer =
+ Singleton<RenderView::RenderViewSet>::get();
+ DCHECK(render_view_set_pointer->render_view_set_.size() > 0);
+
+ v8::Local<v8::Value> window;
+ std::string current_extension_id = ExtensionIdForCurrentContext();
+ std::set<RenderView* >::iterator it =
+ render_view_set_pointer->render_view_set_.begin();
+ for (; it != render_view_set_pointer->render_view_set_.end(); ++it) {
+ if (view_type != ViewType::INVALID && (*it)->view_type() != view_type)
+ continue;
+
+ GURL url = (*it)->webview()->GetMainFrame()->url();
+ if (!url.SchemeIs(chrome::kExtensionScheme))
+ continue;
+ std::string extension_id = url.host();
+ if (extension_id != current_extension_id)
+ continue;
+
+ if (browser_window_id != -1 &&
+ (*it)->browser_window_id() != browser_window_id) {
+ continue;
+ }
+
+ v8::Local<v8::Context> context =
+ (*it)->webview()->GetMainFrame()->mainWorldScriptContext();
+ if (!context.IsEmpty()) {
+ v8::Local<v8::Value> window = context->Global();
+ DCHECK(!window.IsEmpty());
+ views->Set(v8::Integer::New(index), window);
+ index++;
+ if (view_type == ViewType::EXTENSION_BACKGROUND_PAGE)
+ break;
+ }
}
return views;
}
diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc
index 1ddf4cc..9fd1f1d 100644
--- a/chrome/renderer/render_view.cc
+++ b/chrome/renderer/render_view.cc
@@ -19,6 +19,7 @@
#include "base/gfx/png_encoder.h"
#include "base/gfx/native_widget_types.h"
#include "base/process_util.h"
+#include "base/singleton.h"
#include "base/string_piece.h"
#include "base/string_util.h"
#include "build/build_config.h"
@@ -201,10 +202,14 @@ RenderView::RenderView(RenderThreadBase* render_thread)
preferred_width_(0),
send_preferred_width_changes_(false),
determine_page_text_after_loading_stops_(false),
+ view_type_(ViewType::INVALID),
+ browser_window_id_(-1),
last_top_level_navigation_page_id_(-1) {
+ Singleton<RenderViewSet>()->render_view_set_.insert(this);
}
RenderView::~RenderView() {
+ Singleton<RenderViewSet>()->render_view_set_.erase(this);
if (decrement_shared_popup_at_destruction_)
shared_popup_counter_->data--;
@@ -427,6 +432,10 @@ void RenderView::OnMessageReceived(const IPC::Message& message) {
IPC_MESSAGE_HANDLER(ViewMsg_EnableIntrinsicWidthChangedMode,
OnEnableIntrinsicWidthChangedMode)
IPC_MESSAGE_HANDLER(ViewMsg_SetRendererPrefs, OnSetRendererPrefs)
+ IPC_MESSAGE_HANDLER(ViewMsg_UpdateBrowserWindowId,
+ OnUpdateBrowserWindowId)
+ IPC_MESSAGE_HANDLER(ViewMsg_NotifyRenderViewType,
+ OnNotifyRendererViewType)
IPC_MESSAGE_HANDLER(ViewMsg_MediaPlayerActionAt, OnMediaPlayerActionAt)
IPC_MESSAGE_HANDLER(ViewMsg_SetActive, OnSetActive)
@@ -2777,6 +2786,14 @@ void RenderView::OnMediaPlayerActionAt(int x,
webview()->MediaPlayerActionAt(x, y, action);
}
+void RenderView::OnNotifyRendererViewType(ViewType::Type type) {
+ view_type_ = type;
+}
+
+void RenderView::OnUpdateBrowserWindowId(int window_id) {
+ browser_window_id_ = window_id;
+}
+
void RenderView::OnUpdateBackForwardListCount(int back_list_count,
int forward_list_count) {
history_back_list_count_ = back_list_count;
diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h
index ef29a81..d7781e2 100644
--- a/chrome/renderer/render_view.h
+++ b/chrome/renderer/render_view.h
@@ -19,6 +19,7 @@
#include "build/build_config.h"
#include "chrome/common/id_map.h"
#include "chrome/common/renderer_preferences.h"
+#include "chrome/common/view_types.h"
#include "chrome/renderer/automation/dom_automation_controller.h"
#include "chrome/renderer/dom_ui_bindings.h"
#include "chrome/renderer/extensions/extension_process_bindings.h"
@@ -98,6 +99,9 @@ class RenderView : public RenderWidget,
public WebViewDelegate,
public webkit_glue::DomSerializerDelegate {
public:
+ struct RenderViewSet {
+ std::set<RenderView* > render_view_set_;
+ };
// Creates a new RenderView. The parent_hwnd specifies a HWND to use as the
// parent of the WebView HWND that will be created. The modal_dialog_event
// is set by the RenderView whenever a modal dialog alert is shown, so that
@@ -132,6 +136,14 @@ class RenderView : public RenderWidget,
return modal_dialog_event_.get();
}
+ int browser_window_id() {
+ return browser_window_id_;
+ }
+
+ ViewType::Type view_type() {
+ return view_type_;
+ }
+
// IPC::Channel::Listener
virtual void OnMessageReceived(const IPC::Message& msg);
@@ -543,6 +555,8 @@ class RenderView : public RenderWidget,
void OnMediaPlayerActionAt(int x,
int y,
const MediaPlayerAction& action);
+ void OnNotifyRendererViewType(ViewType::Type view_type);
+ void OnUpdateBrowserWindowId(int window_id);
void OnUpdateBackForwardListCount(int back_list_count,
int forward_list_count);
void OnGetAccessibilityInfo(
@@ -837,6 +851,13 @@ class RenderView : public RenderWidget,
RendererPreferences renderer_preferences_;
+ // Type of view attached with RenderView, it could be INVALID, TAB_CONTENTS,
+ // EXTENSION_TOOLSTRIP, EXTENSION_BACKGROUND_PAGE, DEV_TOOLS_UI.
+ ViewType::Type view_type_;
+
+ // Id number of browser window which RenderView is attached to.
+ int browser_window_id_;
+
// page id for the last navigation sent to the browser.
int32 last_top_level_navigation_page_id_;
diff --git a/chrome/renderer/renderer_resources.grd b/chrome/renderer/renderer_resources.grd
index e5c7fcf..eb128c7 100644
--- a/chrome/renderer/renderer_resources.grd
+++ b/chrome/renderer/renderer_resources.grd
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- This comment is only here because changes to resources are not picked up
-without changes to the corresponding grd file. rw2 -->
+without changes to the corresponding grd file. aa1 -->
<grit latest_public_release="0" current_release="1">
<outputs>
<output filename="grit/renderer_resources.h" type="rc_header">
diff --git a/chrome/renderer/resources/extension_process_bindings.js b/chrome/renderer/resources/extension_process_bindings.js
index e828bd5..f132e55 100644
--- a/chrome/renderer/resources/extension_process_bindings.js
+++ b/chrome/renderer/resources/extension_process_bindings.js
@@ -15,7 +15,7 @@ var chrome = chrome || {};
native function GetExtensionAPIDefinition();
native function StartRequest();
native function GetCurrentPageActions(extensionId);
- native function GetViews();
+ native function GetExtensionViews();
native function GetChromeHidden();
native function GetNextRequestId();
native function OpenChannelToTab();
@@ -122,19 +122,6 @@ var chrome = chrome || {};
return StartRequest(functionName, sargs, requestId, hasCallback);
}
- // Read api definitions and setup api functions in the chrome namespace.
- // TODO(rafaelw): Consider defining a json schema for an api definition
- // and validating either here, in a unit_test or both.
- // TODO(rafaelw): Handle synchronous functions.
- // TOOD(rafaelw): Consider providing some convenient override points
- // for api functions that wish to insert themselves into the call.
- var apiDefinitions = JSON.parse(GetExtensionAPIDefinition());
-
- // |apiFunctions| is a hash of name -> object that stores the
- // name & definition of the apiFunction. Custom handling of api functions
- // is implemented by adding a "handleRequest" function to the object.
- var apiFunctions = {};
-
// Using forEach for convenience, and to bind |module|s & |apiDefs|s via
// closures.
function forEach(a, f) {
@@ -149,49 +136,6 @@ var chrome = chrome || {};
};
}
- forEach(apiDefinitions, function(apiDef) {
- chrome[apiDef.namespace] = chrome[apiDef.namespace] || {};
- var module = chrome[apiDef.namespace];
-
- // Setup Functions.
- if (apiDef.functions) {
- forEach(apiDef.functions, function(functionDef) {
- // Module functions may have been defined earlier by hand. Don't clobber
- // them.
- if (module[functionDef.name])
- return;
-
- var apiFunction = {};
- apiFunction.definition = functionDef;
- apiFunction.name = apiDef.namespace + "." + functionDef.name;;
- apiFunctions[apiFunction.name] = apiFunction;
-
- module[functionDef.name] = bind(apiFunction, function() {
- validate(arguments, this.definition.parameters);
-
- if (this.handleRequest)
- return this.handleRequest.apply(this, arguments);
- else
- return sendRequest(this.name, arguments,
- this.definition.parameters);
- });
- });
- }
-
- // Setup Events
- if (apiDef.events) {
- forEach(apiDef.events, function(eventDef) {
- // Module events may have been defined earlier by hand. Don't clobber
- // them.
- if (module[eventDef.name])
- return;
-
- var eventName = apiDef.namespace + "." + eventDef.name;
- module[eventDef.name] = new chrome.Event(eventName);
- });
- }
- });
-
// --- Setup additional api's not currently handled in common/extensions/api
// Page action events send (pageActionId, {tabId, tabUrl}).
@@ -205,26 +149,97 @@ var chrome = chrome || {};
}
}
- // Tabs connect()
- apiFunctions["tabs.connect"].handleRequest = function(tabId, opt_name) {
- var portId = OpenChannelToTab(tabId, chrome.extension.id_, opt_name || "");
- return chromeHidden.Port.createPort(portId, opt_name);
- }
-
- // chrome.self / chrome.extension.
- chrome.self = chrome.self || {};
-
chromeHidden.onLoad.addListener(function (extensionId) {
chrome.extension = new chrome.Extension(extensionId);
- // TODO(mpcomplete): self.onConnect is deprecated. Remove it at 1.0.
+
+ // TODO(mpcomplete): chrome.self is deprecated. Remove it at 1.0.
// http://code.google.com/p/chromium/issues/detail?id=16356
- chrome.self.onConnect = chrome.extension.onConnect;
+ chrome.self = chrome.extension;
+
+ // |apiFunctions| is a hash of name -> object that stores the
+ // name & definition of the apiFunction. Custom handling of api functions
+ // is implemented by adding a "handleRequest" function to the object.
+ var apiFunctions = {};
+
+ // Read api definitions and setup api functions in the chrome namespace.
+ // TODO(rafaelw): Consider defining a json schema for an api definition
+ // and validating either here, in a unit_test or both.
+ // TODO(rafaelw): Handle synchronous functions.
+ // TOOD(rafaelw): Consider providing some convenient override points
+ // for api functions that wish to insert themselves into the call.
+ var apiDefinitions = JSON.parse(GetExtensionAPIDefinition());
+
+ forEach(apiDefinitions, function(apiDef) {
+ chrome[apiDef.namespace] = chrome[apiDef.namespace] || {};
+ var module = chrome[apiDef.namespace];
+
+ // Setup Functions.
+ if (apiDef.functions) {
+ forEach(apiDef.functions, function(functionDef) {
+ // Module functions may have been defined earlier by hand. Don't
+ // clobber them.
+ if (module[functionDef.name])
+ return;
+
+ var apiFunction = {};
+ apiFunction.definition = functionDef;
+ apiFunction.name = apiDef.namespace + "." + functionDef.name;;
+ apiFunctions[apiFunction.name] = apiFunction;
+
+ module[functionDef.name] = bind(apiFunction, function() {
+ validate(arguments, this.definition.parameters);
+
+ if (this.handleRequest)
+ return this.handleRequest.apply(this, arguments);
+ else
+ return sendRequest(this.name, arguments,
+ this.definition.parameters);
+ });
+ });
+ }
+
+ // Setup Events
+ if (apiDef.events) {
+ forEach(apiDef.events, function(eventDef) {
+ // Module events may have been defined earlier by hand. Don't clobber
+ // them.
+ if (module[eventDef.name])
+ return;
+
+ var eventName = apiDef.namespace + "." + eventDef.name;
+ module[eventDef.name] = new chrome.Event(eventName);
+ });
+ }
+ });
+
+ apiFunctions["tabs.connect"].handleRequest = function(tabId, opt_name) {
+ var portId = OpenChannelToTab(
+ tabId, chrome.extension.id_, opt_name || "");
+ return chromeHidden.Port.createPort(portId, opt_name);
+ }
+
+ apiFunctions["extension.getViews"].handleRequest = function() {
+ return GetExtensionViews(-1, "ALL");
+ }
+
+ apiFunctions["extension.getBackgroundPage"].handleRequest = function() {
+ return GetExtensionViews(-1, "BACKGROUND")[0] || null;
+ }
+
+ apiFunctions["extension.getToolstrips"].handleRequest =
+ function(windowId) {
+ if (typeof(windowId) == "undefined")
+ windowId = -1;
+ return GetExtensionViews(windowId, "TOOLSTRIP");
+ }
+
+ apiFunctions["extension.getTabContentses"].handleRequest =
+ function(windowId) {
+ if (typeof(windowId) == "undefined")
+ windowId = -1;
+ return GetExtensionViews(windowId, "TAB");
+ }
setupPageActionEvents(extensionId);
});
-
- // Self getViews();
- apiFunctions["self.getViews"].handleRequest = function() {
- return GetViews();
- }
-})();
+ })();
diff --git a/chrome/test/data/extensions/good/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/backgroundpage.html b/chrome/test/data/extensions/good/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/backgroundpage.html
new file mode 100755
index 0000000..1bc7aee
--- /dev/null
+++ b/chrome/test/data/extensions/good/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/backgroundpage.html
@@ -0,0 +1,5 @@
+<html>
+ <script>
+ var isBackgroundPage = 1;
+ </script>
+</html> \ No newline at end of file
diff --git a/chrome/test/data/extensions/good/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/manifest.json b/chrome/test/data/extensions/good/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/manifest.json
index 65283a3..40c4860 100644
--- a/chrome/test/data/extensions/good/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/manifest.json
+++ b/chrome/test/data/extensions/good/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/manifest.json
@@ -14,6 +14,7 @@
},
"toolstrip2.html"
],
+ "background_page": "backgroundpage.html",
"permissions": ["tabs", "http://*.google.com/*", "https://*.google.com/*"],
"content_scripts": [
{
diff --git a/chrome/test/data/extensions/good/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/test_gettabs.html b/chrome/test/data/extensions/good/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/test_gettabs.html
new file mode 100755
index 0000000..47df48b
--- /dev/null
+++ b/chrome/test/data/extensions/good/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/test_gettabs.html
@@ -0,0 +1,5 @@
+<html>
+ <script>
+ var isTabContents = 1;
+ </script>
+</html> \ No newline at end of file
diff --git a/chrome/test/data/extensions/good/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/toolstrip1.html b/chrome/test/data/extensions/good/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/toolstrip1.html
index 5d8d673..8fb82aa 100644
--- a/chrome/test/data/extensions/good/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/toolstrip1.html
+++ b/chrome/test/data/extensions/good/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/toolstrip1.html
@@ -1,4 +1,5 @@
<script>
+var isToolstrip = 1;
// This function is called from the C++ browser test. It does a basic sanity
// test that we can call extension APIs.
function testTabsAPI() {
@@ -18,6 +19,34 @@ function testTabsLanguageAPI() {
});
}
+// This function is called from the C++ browser test. It tests the getToolstrips
+// function to make sure it can be used as an extension API. This will pass if
+// getToolstrips returns all toolstrip views.
+function testgetToolstripsAPI() {
+ var views = chrome.extension.getToolstrips();
+ window.domAutomationController.send(views.length == 2 &&
+ views[0].isToolstrip == 1 &&
+ views[1].isToolstrip == 1);
+}
+
+// This function is called from the C++ browser test. It tests the
+// getBackgroundPage function to make sure it can be used as an extension API.
+// This will pass if getBackgroundPage returns background page view.
+function testgetBackgroundPageAPI() {
+ var view = chrome.extension.getBackgroundPage();
+ window.domAutomationController.send(view != null &&
+ view.isBackgroundPage == 1);
+}
+
+// This function is called from the C++ browser test. It tests the
+// getTabContentses function to make sure it can be used as an extension API.
+// This will pass if getTabContentses returns tabcontent view.
+function testgetTabContentsesAPI() {
+ var views = chrome.extension.getTabContentses();
+ window.domAutomationController.send(views.length == 1 &&
+ views[0].isTabContents == 1);
+}
+
</script>
<select>
<option>one</option>
diff --git a/chrome/test/data/extensions/good/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/toolstrip2.html b/chrome/test/data/extensions/good/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/toolstrip2.html
index 568a6da..2f0bc54 100644
--- a/chrome/test/data/extensions/good/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/toolstrip2.html
+++ b/chrome/test/data/extensions/good/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/toolstrip2.html
@@ -1 +1,4 @@
+<script>
+ var isToolstrip = 1;
+</script>
<button onclick="window.open('http://www.google.com', 'mywindow', 'width=640, height=480');">HTML button</button>
diff --git a/ipc/ipc_message_utils.h b/ipc/ipc_message_utils.h
index f337814..5ec80a7 100644
--- a/ipc/ipc_message_utils.h
+++ b/ipc/ipc_message_utils.h
@@ -100,22 +100,31 @@ class MessageIterator {
//-----------------------------------------------------------------------------
// ParamTraits specializations, etc.
-template <class P> struct ParamTraits {};
+template <class P> struct ParamTraits {
+};
+
+template <class P>
+struct SimilarTypeTraits {
+ typedef P Type;
+};
template <class P>
static inline void WriteParam(Message* m, const P& p) {
- ParamTraits<P>::Write(m, p);
+ typedef typename SimilarTypeTraits<P>::Type Type;
+ ParamTraits<Type>::Write(m, static_cast<const Type& >(p));
}
template <class P>
static inline bool WARN_UNUSED_RESULT ReadParam(const Message* m, void** iter,
P* p) {
- return ParamTraits<P>::Read(m, iter, p);
+ typedef typename SimilarTypeTraits<P>::Type Type;
+ return ParamTraits<Type>::Read(m, iter, reinterpret_cast<Type* >(p));
}
template <class P>
static inline void LogParam(const P& p, std::wstring* l) {
- ParamTraits<P>::Log(p, l);
+ typedef typename SimilarTypeTraits<P>::Type Type;
+ ParamTraits<Type>::Log(static_cast<const Type& >(p), l);
}
template <>
@@ -788,7 +797,6 @@ struct ParamTraits<LogData> {
}
};
-
template <>
struct ParamTraits<Message> {
static void Write(Message* m, const Message& p) {