Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(40)

Side by Side Diff: content/browser/renderer_host/java/java_bridge_dispatcher_host.cc

Issue 336313018: [Android] Move content/browser/{renderer_host => android}/java/* (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Updated paths for unit tests, rebased Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "content/browser/renderer_host/java/java_bridge_dispatcher_host.h"
6
7 #include "base/android/java_handler_thread.h"
8 #include "base/bind.h"
9 #include "base/lazy_instance.h"
10 #include "content/browser/renderer_host/java/java_bridge_channel_host.h"
11 #include "content/child/child_process.h"
12 #include "content/child/npapi/npobject_stub.h"
13 #include "content/child/npapi/npobject_util.h" // For CreateNPVariantParam()
14 #include "content/common/java_bridge_messages.h"
15 #include "content/public/browser/browser_thread.h"
16 #include "content/public/browser/render_frame_host.h"
17 #include "content/public/browser/render_process_host.h"
18 #include "third_party/WebKit/public/web/WebBindings.h"
19
20 #if !defined(OS_ANDROID)
21 #error "JavaBridge only supports OS_ANDROID"
22 #endif
23
24 namespace content {
25
26 namespace {
27 // The JavaBridge needs to use a Java thread so the callback
28 // will happen on a thread with a prepared Looper.
29 class JavaBridgeThread : public base::android::JavaHandlerThread {
30 public:
31 JavaBridgeThread() : base::android::JavaHandlerThread("JavaBridge") {
32 Start();
33 }
34 virtual ~JavaBridgeThread() {
35 Stop();
36 }
37 };
38
39 void CleanUpStubs(const std::vector<base::WeakPtr<NPObjectStub> > & stubs) {
40 for (size_t i = 0; i < stubs.size(); ++i) {
41 if (stubs[i]) {
42 stubs[i]->DeleteSoon();
43 }
44 }
45 }
46
47 base::LazyInstance<JavaBridgeThread> g_background_thread =
48 LAZY_INSTANCE_INITIALIZER;
49 } // namespace
50
51 JavaBridgeDispatcherHost::JavaBridgeDispatcherHost(
52 RenderFrameHost* render_frame_host)
53 : render_frame_host_(render_frame_host) {
54 }
55
56 JavaBridgeDispatcherHost::~JavaBridgeDispatcherHost() {
57 g_background_thread.Get().message_loop()->PostTask(
58 FROM_HERE,
59 base::Bind(&CleanUpStubs, stubs_));
60 }
61
62 void JavaBridgeDispatcherHost::AddNamedObject(const base::string16& name,
63 NPObject* object) {
64 NPVariant_Param variant_param;
65 CreateNPVariantParam(object, &variant_param);
66
67 Send(new JavaBridgeMsg_AddNamedObject(
68 render_frame_host_->GetRoutingID(), name, variant_param));
69 }
70
71 void JavaBridgeDispatcherHost::RemoveNamedObject(const base::string16& name) {
72 // On receipt of this message, the JavaBridgeDispatcher will drop its
73 // reference to the corresponding proxy object. When the last reference is
74 // removed, the proxy object will delete its NPObjectProxy, which will cause
75 // the NPObjectStub to be deleted, which will drop its reference to the
76 // original NPObject.
77 Send(new JavaBridgeMsg_RemoveNamedObject(
78 render_frame_host_->GetRoutingID(), name));
79 }
80
81 void JavaBridgeDispatcherHost::RenderFrameDeleted() {
82 render_frame_host_ = NULL;
83 }
84
85 void JavaBridgeDispatcherHost::OnGetChannelHandle(IPC::Message* reply_msg) {
86 g_background_thread.Get().message_loop()->PostTask(
87 FROM_HERE,
88 base::Bind(&JavaBridgeDispatcherHost::GetChannelHandle, this, reply_msg));
89 }
90
91 void JavaBridgeDispatcherHost::Send(IPC::Message* msg) {
92 if (render_frame_host_) {
93 render_frame_host_->Send(msg);
94 return;
95 }
96
97 delete msg;
98 }
99
100 void JavaBridgeDispatcherHost::GetChannelHandle(IPC::Message* reply_msg) {
101 // The channel creates the channel handle based on the renderer ID we passed
102 // to GetJavaBridgeChannelHost() and, on POSIX, the file descriptor used by
103 // the underlying channel.
104 JavaBridgeHostMsg_GetChannelHandle::WriteReplyParams(
105 reply_msg,
106 channel_->channel_handle());
107
108 BrowserThread::PostTask(
109 BrowserThread::UI,
110 FROM_HERE,
111 base::Bind(&JavaBridgeDispatcherHost::Send, this, reply_msg));
112 }
113
114 void JavaBridgeDispatcherHost::CreateNPVariantParam(NPObject* object,
115 NPVariant_Param* param) {
116 // The JavaBridgeChannelHost needs to be created on the background thread, as
117 // that is where Java objects will live, and CreateNPVariantParam() needs the
118 // channel to create the NPObjectStub. To avoid blocking here until the
119 // channel is ready, create the NPVariant_Param by hand, then post a message
120 // to the background thread to set up the channel and create the corresponding
121 // NPObjectStub. Post that message before doing any IPC, to make sure that
122 // the channel and object proxies are ready before responses are received
123 // from the renderer.
124
125 // Create an NPVariantParam suitable for serialization over IPC from our
126 // NPVariant. See CreateNPVariantParam() in npobject_utils.
127 param->type = NPVARIANT_PARAM_SENDER_OBJECT_ROUTING_ID;
128 int route_id = JavaBridgeChannelHost::ThreadsafeGenerateRouteID();
129 param->npobject_routing_id = route_id;
130
131 blink::WebBindings::retainObject(object);
132 g_background_thread.Get().message_loop()->PostTask(
133 FROM_HERE,
134 base::Bind(&JavaBridgeDispatcherHost::CreateObjectStub, this, object,
135 render_frame_host_->GetProcess()->GetID(), route_id));
136 }
137
138 void JavaBridgeDispatcherHost::CreateObjectStub(NPObject* object,
139 int render_process_id,
140 int route_id) {
141 DCHECK_EQ(g_background_thread.Get().message_loop(),
142 base::MessageLoop::current());
143 if (!channel_.get()) {
144 channel_ = JavaBridgeChannelHost::GetJavaBridgeChannelHost(
145 render_process_id,
146 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO));
147 }
148
149 // In a typical scenario, the lifetime of each NPObjectStub is governed by
150 // that of the NPObjectProxy in the renderer, via the channel. However,
151 // we cannot guaranteed that the renderer always terminates cleanly
152 // (crashes / sometimes just unavoidable). We keep a weak reference to
153 // it now and schedule a delete on it when this host is getting deleted.
154
155 // Pass 0 for the containing window, as it's only used by plugins to pump the
156 // window message queue when a method on a renderer-side object causes a
157 // dialog to be displayed, and the Java Bridge does not need this
158 // functionality. The page URL is also not required.
159 stubs_.push_back((new NPObjectStub(
160 object, channel_.get(), route_id, 0, GURL()))->AsWeakPtr());
161
162 // The NPObjectStub takes a reference to the NPObject. Release the ref added
163 // in CreateNPVariantParam().
164 blink::WebBindings::releaseObject(object);
165 }
166
167 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698