Skip to content

Commit 05945c3

Browse files
committed
API impl refactor: Id allocation and global object register in browser
This is mainly for dealing with Window in new renderer process, where multiple dispatcher hosts should share the same object registry. And the Id allocation on the renderer side is moved to the browser side to keep the id global across multiple renderers.
1 parent 794f5d5 commit 05945c3

12 files changed

+106
-11
lines changed

src/api/api_messages.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,3 +101,5 @@ IPC_MESSAGE_CONTROL0(ShellViewMsg_ClearCache)
101101
// grant the policy permissions
102102
IPC_SYNC_MESSAGE_ROUTED0_1(ShellViewHostMsg_GrantUniversalPermissions, int)
103103

104+
IPC_SYNC_MESSAGE_ROUTED0_1(ShellViewHostMsg_AllocateId, int)
105+

src/api/bindings_common.cc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,16 @@ base::StringPiece GetStringResource(int resource_id) {
6868

6969
namespace remote {
7070

71+
v8::Handle<v8::Value> AllocateId(int routing_id) {
72+
v8::HandleScope handle_scope;
73+
74+
int result = 0;
75+
RenderThread::Get()->Send(new ShellViewHostMsg_AllocateId(
76+
routing_id,
77+
&result));
78+
return v8::Integer::New(result);
79+
}
80+
7181
v8::Handle<v8::Value> AllocateObject(int routing_id,
7282
int object_id,
7383
const std::string& type,

src/api/bindings_common.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ base::StringPiece GetStringResource(int resource_id);
3737

3838
namespace remote {
3939

40+
v8::Handle<v8::Value> AllocateId(int routing_id);
41+
4042
// Tell browser to allocate a new object.
4143
// function AllocateObject(id, name, options);
4244
v8::Handle<v8::Value> AllocateObject(int routing_id,

src/api/dispatcher_bindings.cc

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,8 @@ DispatcherBindings::GetNativeFunction(v8::Handle<v8::String> name) {
134134
return v8::FunctionTemplate::New(CrashRenderer);
135135
else if (name->Equals(v8::String::New("SetCrashDumpDir")))
136136
return v8::FunctionTemplate::New(SetCrashDumpDir);
137+
else if (name->Equals(v8::String::New("AllocateId")))
138+
return v8::FunctionTemplate::New(AllocateId);
137139

138140
NOTREACHED() << "Trying to get an non-exist function in DispatcherBindings:"
139141
<< *v8::String::Utf8Value(name);
@@ -255,6 +257,18 @@ DispatcherBindings::CreateShell(const v8::FunctionCallbackInfo<v8::Value>& args)
255257
}
256258

257259
// static
260+
void
261+
DispatcherBindings::AllocateId(const v8::FunctionCallbackInfo<v8::Value>& args) {
262+
RenderView* render_view = GetCurrentRenderView();
263+
if (!render_view) {
264+
args.GetReturnValue().Set(v8::ThrowException(v8::Exception::Error(v8::String::New(
265+
"Unable to get render view in AllocateId"))));
266+
return;
267+
}
268+
269+
args.GetReturnValue().Set(remote::AllocateId(render_view->GetRoutingID()));
270+
}
271+
258272
void
259273
DispatcherBindings::AllocateObject(const v8::FunctionCallbackInfo<v8::Value>& args) {
260274
if (args.Length() < 3) {
@@ -308,6 +322,8 @@ DispatcherBindings::CallObjectMethod(const v8::FunctionCallbackInfo<v8::Value>&
308322
std::string method = *v8::String::Utf8Value(args[2]);
309323

310324
RenderView* render_view = GetCurrentRenderView();
325+
if (!render_view)
326+
render_view = GetEnteredRenderView();
311327
if (!render_view) {
312328
args.GetReturnValue().Set(v8::ThrowException(v8::Exception::Error(v8::String::New(
313329
"Unable to get render view in CallObjectMethod"))));

src/api/dispatcher_bindings.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ class DispatcherBindings : public v8::Extension {
5353
static void CreateShell(const v8::FunctionCallbackInfo<v8::Value>& args);
5454

5555
// Remote objects.
56+
static void AllocateId(const v8::FunctionCallbackInfo<v8::Value>& args);
5657
static void AllocateObject(const v8::FunctionCallbackInfo<v8::Value>& args);
5758
static void DeallocateObject(const v8::FunctionCallbackInfo<v8::Value>& args);
5859
static void CallObjectMethod(const v8::FunctionCallbackInfo<v8::Value>& args);

src/api/dispatcher_bindings.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ var nwDispatcher = nwDispatcher || {};
2828
native function GetRoutingIDForCurrentContext();
2929
native function CreateShell();
3030

31+
native function AllocateId();
3132
native function AllocateObject();
3233
native function DeallocateObject();
3334
native function CallObjectMethod();
@@ -43,7 +44,7 @@ var nwDispatcher = nwDispatcher || {};
4344
nwDispatcher.allocateObject = function(object, option) {
4445
var v8_util = process.binding('v8_util');
4546

46-
var id = global.__nwObjectsRegistry.allocateId();
47+
var id = AllocateId();
4748
AllocateObject(id, v8_util.getConstructorName(object), option);
4849

4950
// Store object id and make it readonly
@@ -95,4 +96,5 @@ var nwDispatcher = nwDispatcher || {};
9596

9697
nwDispatcher.crashRenderer = CrashRenderer;
9798
nwDispatcher.setCrashDumpDir = SetCrashDumpDir;
99+
nwDispatcher.allocateId = AllocateId;
98100
})();

src/api/dispatcher_host.cc

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,20 +41,40 @@
4141

4242
using content::WebContents;
4343
using content::ShellBrowserContext;
44+
using content::Shell;
4445

4546
namespace api {
4647

48+
IDMap<Base, IDMapOwnPointer> api::DispatcherHost::objects_registry_;
49+
int api::DispatcherHost::next_object_id_ = 1;
50+
static std::map<content::RenderViewHost*, DispatcherHost*> g_dispatcher_host_map;
51+
4752
DispatcherHost::DispatcherHost(content::RenderViewHost* render_view_host)
4853
: content::RenderViewHostObserver(render_view_host) {
54+
g_dispatcher_host_map[render_view_host] = this;
4955
}
5056

5157
DispatcherHost::~DispatcherHost() {
58+
g_dispatcher_host_map.erase(render_view_host());
59+
}
60+
61+
DispatcherHost*
62+
FindDispatcherHost(content::RenderViewHost* render_view_host) {
63+
std::map<content::RenderViewHost*, DispatcherHost*>::iterator it
64+
= g_dispatcher_host_map.find(render_view_host);
65+
if (it == g_dispatcher_host_map.end())
66+
return NULL;
67+
return it->second;
5268
}
5369

5470
Base* DispatcherHost::GetApiObject(int id) {
5571
return objects_registry_.Lookup(id);
5672
}
5773

74+
int DispatcherHost::AllocateId() {
75+
return next_object_id_++;
76+
}
77+
5878
void DispatcherHost::SendEvent(Base* object,
5979
const std::string& event,
6080
const base::ListValue& arguments) {
@@ -84,6 +104,7 @@ bool DispatcherHost::OnMessageReceived(const IPC::Message& message) {
84104
IPC_MESSAGE_HANDLER(ShellViewHostMsg_GetShellId, OnGetShellId);
85105
IPC_MESSAGE_HANDLER(ShellViewHostMsg_CreateShell, OnCreateShell);
86106
IPC_MESSAGE_HANDLER(ShellViewHostMsg_GrantUniversalPermissions, OnGrantUniversalPermissions);
107+
IPC_MESSAGE_HANDLER(ShellViewHostMsg_AllocateId, OnAllocateId);
87108
IPC_MESSAGE_UNHANDLED(handled = false)
88109
IPC_END_MESSAGE_MAP()
89110

@@ -239,6 +260,12 @@ void DispatcherHost::OnCreateShell(const std::string& url,
239260
browser_context->set_pinning_renderer(true);
240261

241262
*routing_id = web_contents->GetRoutingID();
263+
264+
int object_id = 0;
265+
if (new_manifest->GetInteger("object_id", &object_id)) {
266+
DispatcherHost* dhost = FindDispatcherHost(web_contents->GetRenderViewHost());
267+
dhost->OnAllocateObject(object_id, "Window", *new_manifest.get());
268+
}
242269
}
243270

244271
void DispatcherHost::OnGrantUniversalPermissions(int *ret) {
@@ -251,4 +278,8 @@ void DispatcherHost::OnGrantUniversalPermissions(int *ret) {
251278
*ret = 0;
252279
}
253280

281+
void DispatcherHost::OnAllocateId(int * ret) {
282+
*ret = AllocateId();
283+
}
284+
254285
} // namespace api

src/api/dispatcher_host.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ class DispatcherHost : public content::RenderViewHostObserver {
4848
// Get C++ object from its id.
4949
Base* GetApiObject(int id);
5050

51+
static int AllocateId();
5152
// Helper function to convert type.
5253
template<class T>
5354
T* GetApiObject(int id) {
@@ -65,7 +66,8 @@ class DispatcherHost : public content::RenderViewHostObserver {
6566
}
6667

6768
private:
68-
IDMap<Base, IDMapOwnPointer> objects_registry_;
69+
static IDMap<Base, IDMapOwnPointer> objects_registry_;
70+
static int next_object_id_;
6971

7072
// RenderViewHostObserver implementation.
7173
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
@@ -96,6 +98,7 @@ class DispatcherHost : public content::RenderViewHostObserver {
9698
const base::DictionaryValue& manifest,
9799
int* routing_id);
98100
void OnGrantUniversalPermissions(int* ret);
101+
void OnAllocateId(int* ret);
99102
DISALLOW_COPY_AND_ASSIGN(DispatcherHost);
100103
};
101104

src/api/window/window.js

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,17 @@ exports.Window = {
3232
id = nw.getShellIdForCurrentContext();
3333

3434
// Return API's window object from id.
35+
var ret;
3536
if (id > 0) {
3637
window.__nwWindowId = id;
37-
return global.__nwWindowsStore[window.__nwWindowId];
38+
ret = global.__nwWindowsStore[window.__nwWindowId];
39+
if (!ret) {
40+
ret = new global.Window(nw.getRoutingIDForCurrentContext(), true, id);
41+
}
42+
return ret;
3843
}
3944

40-
// Otherwise create it.
41-
var win = new global.Window(nw.getRoutingIDForCurrentContext());
42-
window.__nwWindowId = win.id;
43-
return win;
45+
return new global.Window(nw.getRoutingIDForCurrentContext());
4446
},
4547
open: function(url, options) {
4648
// Conver relative url to full url.
@@ -58,8 +60,10 @@ exports.Window = {
5860
options.focus = false;
5961
}
6062
// Create new shell and get it's routing id.
63+
var id = nw.allocateId();
64+
options.object_id = id;
6165
var routing_id = nw.createShell(url, options);
6266

63-
return new global.Window(routing_id, options['new-instance']);
67+
return new global.Window(routing_id, options['new-instance'], id);
6468
}
6569
};

src/api/window_bindings.cc

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ WindowBindings::GetNativeFunction(v8::Handle<v8::String> name) {
6060
return v8::FunctionTemplate::New(CallObjectMethodSync);
6161
else if (name->Equals(v8::String::New("GetWindowObject")))
6262
return v8::FunctionTemplate::New(GetWindowObject);
63+
else if (name->Equals(v8::String::New("AllocateId")))
64+
return v8::FunctionTemplate::New(AllocateId);
6365

6466
return v8::FunctionTemplate::New();
6567
}
@@ -75,6 +77,14 @@ WindowBindings::BindToShell(const v8::FunctionCallbackInfo<v8::Value>& args) {
7577
args.GetReturnValue().Set(v8::Undefined());
7678
}
7779

80+
void
81+
WindowBindings::AllocateId(const v8::FunctionCallbackInfo<v8::Value>& args) {
82+
content::RenderViewImpl* render_view = static_cast<content::RenderViewImpl*>(GetEnteredRenderView());
83+
int routing_id = render_view->GetRoutingID();
84+
85+
args.GetReturnValue().Set(remote::AllocateId(routing_id));
86+
}
87+
7888
// static
7989
void
8090
WindowBindings::CallObjectMethod(const v8::FunctionCallbackInfo<v8::Value>& args) {
@@ -84,6 +94,9 @@ WindowBindings::CallObjectMethod(const v8::FunctionCallbackInfo<v8::Value>& args
8494
std::string method = *v8::String::Utf8Value(args[1]);
8595
content::RenderViewImpl* render_view = static_cast<content::RenderViewImpl*>(
8696
content::RenderViewImpl::FromRoutingID(routing_id));
97+
if (!render_view)
98+
render_view = static_cast<content::RenderViewImpl*>(GetEnteredRenderView());
99+
87100
if (!render_view) {
88101
std::string msg = "Unable to get render view in " + method;
89102
args.GetReturnValue().Set(v8::ThrowException(v8::Exception::Error(v8::String::New(msg.c_str()))));
@@ -103,7 +116,9 @@ WindowBindings::CallObjectMethod(const v8::FunctionCallbackInfo<v8::Value>& args
103116
return;
104117
}
105118

106-
args.GetReturnValue().Set(remote::CallObjectMethod(routing_id, object_id, "Window", method, args[2]));
119+
args.GetReturnValue().Set(remote::CallObjectMethod(render_view->GetRoutingID(),
120+
object_id,
121+
"Window", method, args[2]));
107122
}
108123

109124
// static

src/api/window_bindings.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ class WindowBindings : public v8::Extension {
3636
virtual v8::Handle<v8::FunctionTemplate>
3737
GetNativeFunction(v8::Handle<v8::String> name) OVERRIDE;
3838
private:
39+
static void AllocateId(const v8::FunctionCallbackInfo<v8::Value>& args);
40+
3941
// Tell browser to bind a js object to Shell.
4042
static void BindToShell(const v8::FunctionCallbackInfo<v8::Value>& args);
4143

src/api/window_bindings.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
1-
function Window(routing_id, nobind) {
1+
function Window(routing_id, nobind, predefined_id) {
22
// Get and set id.
33
native function CallObjectMethod();
44
native function CallObjectMethodSync();
5-
var id = global.__nwObjectsRegistry.allocateId();
5+
native function AllocateId();
6+
7+
var id;
8+
if (predefined_id)
9+
id = predefined_id;
10+
else
11+
id = AllocateId();
12+
613
Object.defineProperty(this, 'id', {
714
value: id,
815
writable: false

0 commit comments

Comments
 (0)