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 "content/renderer/pepper/pepper_broker_impl.h" | 5 #include "content/renderer/pepper/pepper_broker_impl.h" |
6 | 6 |
7 #include "build/build_config.h" | 7 #include "build/build_config.h" |
8 #include "content/public/renderer/renderer_restrict_dispatch_group.h" | 8 #include "content/public/renderer/renderer_restrict_dispatch_group.h" |
9 #include "content/renderer/pepper/pepper_plugin_delegate_impl.h" | 9 #include "content/renderer/pepper/pepper_plugin_delegate_impl.h" |
10 #include "content/renderer/pepper/pepper_proxy_channel_delegate_impl.h" | 10 #include "content/renderer/pepper/pepper_proxy_channel_delegate_impl.h" |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
109 PepperPluginDelegateImpl* delegate) | 109 PepperPluginDelegateImpl* delegate) |
110 : plugin_module_(plugin_module), | 110 : plugin_module_(plugin_module), |
111 delegate_(delegate->AsWeakPtr()) { | 111 delegate_(delegate->AsWeakPtr()) { |
112 DCHECK(plugin_module_); | 112 DCHECK(plugin_module_); |
113 DCHECK(delegate_); | 113 DCHECK(delegate_); |
114 | 114 |
115 plugin_module_->SetBroker(this); | 115 plugin_module_->SetBroker(this); |
116 } | 116 } |
117 | 117 |
118 PepperBrokerImpl::~PepperBrokerImpl() { | 118 PepperBrokerImpl::~PepperBrokerImpl() { |
119 // Report failure to all clients that had pending operations. | 119 ReportFailureToClients(); |
120 for (ClientMap::iterator i = pending_connects_.begin(); | |
121 i != pending_connects_.end(); ++i) { | |
122 base::WeakPtr<webkit::ppapi::PPB_Broker_Impl>& weak_ptr = i->second; | |
123 if (weak_ptr) { | |
124 weak_ptr->BrokerConnected( | |
125 ppapi::PlatformFileToInt(base::kInvalidPlatformFileValue), | |
126 PP_ERROR_ABORTED); | |
127 } | |
128 } | |
129 pending_connects_.clear(); | |
130 | |
131 plugin_module_->SetBroker(NULL); | 120 plugin_module_->SetBroker(NULL); |
132 plugin_module_ = NULL; | 121 plugin_module_ = NULL; |
133 } | 122 } |
134 | 123 |
135 // If the channel is not ready, queue the connection. | 124 // If the channel is not ready, queue the connection. |
136 void PepperBrokerImpl::Connect(webkit::ppapi::PPB_Broker_Impl* client) { | 125 void PepperBrokerImpl::Connect(webkit::ppapi::PPB_Broker_Impl* client) { |
137 DCHECK(pending_connects_.find(client) == pending_connects_.end()) | 126 DCHECK(pending_connects_.find(client) == pending_connects_.end()) |
138 << "Connect was already called for this client"; | 127 << "Connect was already called for this client"; |
139 | 128 |
140 // Ensure this object and the associated broker exist as long as the | 129 // Ensure this object and the associated broker exist as long as the |
141 // client exists. There is a corresponding Release() call in Disconnect(), | 130 // client exists. There is a corresponding Release() call in Disconnect(), |
142 // which is called when the PPB_Broker_Impl is destroyed. The only other | 131 // which is called when the PPB_Broker_Impl is destroyed. The only other |
143 // possible reference is in pending_connect_broker_, which only holds a | 132 // possible reference is in pending_connect_broker_, which only holds a |
144 // transient reference. This ensures the broker is available as long as the | 133 // transient reference. This ensures the broker is available as long as the |
145 // plugin needs it and allows the plugin to release the broker when it is no | 134 // plugin needs it and allows the plugin to release the broker when it is no |
146 // longer using it. | 135 // longer using it. |
147 AddRef(); | 136 AddRef(); |
148 | 137 |
149 if (!dispatcher_.get()) { | 138 pending_connects_[client].client = client->AsWeakPtr(); |
150 pending_connects_[client] = client->AsWeakPtr(); | |
151 return; | |
152 } | |
153 DCHECK(pending_connects_.empty()); | |
154 | |
155 ConnectPluginToBroker(client); | |
156 } | 139 } |
157 | 140 |
158 void PepperBrokerImpl::Disconnect(webkit::ppapi::PPB_Broker_Impl* client) { | 141 void PepperBrokerImpl::Disconnect(webkit::ppapi::PPB_Broker_Impl* client) { |
159 // Remove the pending connect if one exists. This class will not call client's | 142 // Remove the pending connect if one exists. This class will not call client's |
160 // callback. | 143 // callback. |
161 pending_connects_.erase(client); | 144 pending_connects_.erase(client); |
162 | 145 |
163 // TODO(ddorwin): Send message disconnect message using dispatcher_. | 146 // TODO(ddorwin): Send message disconnect message using dispatcher_. |
164 | 147 |
165 if (pending_connects_.empty()) { | 148 if (pending_connects_.empty()) { |
166 // There are no more clients of this broker. Ensure it will be deleted even | 149 // There are no more clients of this broker. Ensure it will be deleted even |
167 // if the IPC response never comes and OnPepperBrokerChannelCreated is not | 150 // if the IPC response never comes and OnPepperBrokerChannelCreated is not |
168 // called to remove this object from pending_connect_broker_. | 151 // called to remove this object from pending_connect_broker_. |
169 // Before the broker is connected, clients must either be in | 152 // Before the broker is connected, clients must either be in |
170 // pending_connects_ or not yet associated with this object. Thus, if this | 153 // pending_connects_ or not yet associated with this object. Thus, if this |
171 // object is in pending_connect_broker_, there can be no associated clients | 154 // object is in pending_connect_broker_, there can be no associated clients |
172 // once pending_connects_ is empty and it is thus safe to remove this from | 155 // once pending_connects_ is empty and it is thus safe to remove this from |
173 // pending_connect_broker_. Doing so will cause this object to be deleted, | 156 // pending_connect_broker_. Doing so will cause this object to be deleted, |
174 // removing it from the PluginModule. Any new clients will create a new | 157 // removing it from the PluginModule. Any new clients will create a new |
175 // instance of this object. | 158 // instance of this object. |
176 // This doesn't solve all potential problems, but it helps with the ones | 159 // This doesn't solve all potential problems, but it helps with the ones |
177 // we can influence. | 160 // we can influence. |
178 if (delegate_) { | 161 if (delegate_) { |
179 bool stopped = delegate_->StopWaitingForBrokerConnection(this); | 162 bool stopped = delegate_->StopWaitingForBrokerConnection(this); |
180 | 163 |
181 // Verify the assumption that there are no references other than the one | 164 // Verify the assumption that there are no references other than the one |
182 // client holds, which will be released below. | 165 // |client| holds, which will be released below. |
183 DCHECK(!stopped || HasOneRef()); | 166 DCHECK(!stopped || HasOneRef()); |
184 } | 167 } |
185 } | 168 } |
186 | 169 |
187 // Release the reference added in Connect(). | 170 // Release the reference added in Connect(). |
188 // This must be the last statement because it may delete this object. | 171 // This must be the last statement because it may delete this object. |
189 Release(); | 172 Release(); |
190 } | 173 } |
191 | 174 |
192 void PepperBrokerImpl::OnBrokerChannelConnected( | 175 void PepperBrokerImpl::OnBrokerChannelConnected( |
193 const IPC::ChannelHandle& channel_handle) { | 176 const IPC::ChannelHandle& channel_handle) { |
194 scoped_ptr<PepperBrokerDispatcherWrapper> dispatcher( | 177 scoped_ptr<PepperBrokerDispatcherWrapper> dispatcher( |
195 new PepperBrokerDispatcherWrapper); | 178 new PepperBrokerDispatcherWrapper); |
196 if (dispatcher->Init(channel_handle)) { | 179 if (!dispatcher->Init(channel_handle)) { |
197 dispatcher_.reset(dispatcher.release()); | 180 ReportFailureToClients(); |
181 return; | |
182 } | |
198 | 183 |
199 // Process all pending channel requests from the plugins. | 184 dispatcher_.reset(dispatcher.release()); |
200 for (ClientMap::iterator i = pending_connects_.begin(); | 185 |
201 i != pending_connects_.end(); ++i) { | 186 // Process all pending channel requests from the plugins. |
202 base::WeakPtr<webkit::ppapi::PPB_Broker_Impl>& weak_ptr = i->second; | 187 for (ClientMap::iterator i = pending_connects_.begin(); |
203 if (weak_ptr) | 188 i != pending_connects_.end();) { |
204 ConnectPluginToBroker(weak_ptr); | 189 base::WeakPtr<webkit::ppapi::PPB_Broker_Impl>& weak_ptr = |
190 i->second.client; | |
191 if (!i->second.is_authorized) { | |
192 ++i; | |
193 continue; | |
205 } | 194 } |
206 } else { | 195 |
207 // Report failure to all clients. | 196 if (weak_ptr) |
208 for (ClientMap::iterator i = pending_connects_.begin(); | 197 ConnectPluginToBroker(weak_ptr); |
209 i != pending_connects_.end(); ++i) { | 198 |
210 base::WeakPtr<webkit::ppapi::PPB_Broker_Impl>& weak_ptr = i->second; | 199 pending_connects_.erase(i++); |
211 if (weak_ptr) { | 200 } |
212 weak_ptr->BrokerConnected( | 201 } |
213 ppapi::PlatformFileToInt(base::kInvalidPlatformFileValue), | 202 |
214 PP_ERROR_FAILED); | 203 void PepperBrokerImpl::OnBrokerPermissionResult( |
215 } | 204 webkit::ppapi::PPB_Broker_Impl* client, |
205 bool result) { | |
206 ClientMap::iterator entry = pending_connects_.find(client); | |
207 if (entry == pending_connects_.end()) | |
208 return; | |
209 | |
210 if (!entry->second.client) { | |
211 // Client has gone away. | |
212 pending_connects_.erase(entry); | |
213 return; | |
214 } | |
215 | |
216 if (!result) { | |
217 // Report failure. | |
218 client->BrokerConnected( | |
219 ppapi::PlatformFileToInt(base::kInvalidPlatformFileValue), | |
220 PP_ERROR_NOACCESS); | |
221 pending_connects_.erase(entry); | |
222 return; | |
223 } | |
224 | |
225 if (dispatcher_.get()) { | |
226 ConnectPluginToBroker(client); | |
227 pending_connects_.erase(entry); | |
228 return; | |
229 } | |
230 | |
231 // Mark the request as authorized, continue waiting for the broker | |
232 // connection. | |
233 DCHECK(!entry->second.is_authorized); | |
234 entry->second.is_authorized = true; | |
235 } | |
236 | |
237 PepperBrokerImpl::PendingConnection::PendingConnection() | |
238 : is_authorized(false) { | |
239 } | |
240 | |
241 PepperBrokerImpl::PendingConnection::~PendingConnection() { | |
242 } | |
243 | |
244 void PepperBrokerImpl::ReportFailureToClients() { | |
245 for (ClientMap::iterator i = pending_connects_.begin(); | |
246 i != pending_connects_.end(); ++i) { | |
247 base::WeakPtr<webkit::ppapi::PPB_Broker_Impl>& weak_ptr = | |
248 i->second.client; | |
249 if (weak_ptr) { | |
250 weak_ptr->BrokerConnected( | |
251 ppapi::PlatformFileToInt(base::kInvalidPlatformFileValue), | |
252 PP_ERROR_ABORTED); | |
ddorwin
2012/08/13 22:27:04
The code this function replaces had two different
Bernhard Bauer
2012/08/13 22:42:14
Done.
| |
216 } | 253 } |
217 } | 254 } |
218 pending_connects_.clear(); | 255 pending_connects_.clear(); |
219 } | 256 } |
220 | 257 |
221 void PepperBrokerImpl::ConnectPluginToBroker( | 258 void PepperBrokerImpl::ConnectPluginToBroker( |
222 webkit::ppapi::PPB_Broker_Impl* client) { | 259 webkit::ppapi::PPB_Broker_Impl* client) { |
223 base::SyncSocket::Handle plugin_handle = base::kInvalidPlatformFileValue; | 260 base::SyncSocket::Handle plugin_handle = base::kInvalidPlatformFileValue; |
224 int32_t result = PP_OK; | 261 int32_t result = PP_OK; |
225 | 262 |
(...skipping 15 matching lines...) Expand all Loading... | |
241 | 278 |
242 // TOOD(ddorwin): Change the IPC to asynchronous: Queue an object containing | 279 // TOOD(ddorwin): Change the IPC to asynchronous: Queue an object containing |
243 // client and plugin_socket.release(), then return. | 280 // client and plugin_socket.release(), then return. |
244 // That message handler will then call client->BrokerConnected() with the | 281 // That message handler will then call client->BrokerConnected() with the |
245 // saved pipe handle. | 282 // saved pipe handle. |
246 // Temporarily, just call back. | 283 // Temporarily, just call back. |
247 client->BrokerConnected(ppapi::PlatformFileToInt(plugin_handle), result); | 284 client->BrokerConnected(ppapi::PlatformFileToInt(plugin_handle), result); |
248 } | 285 } |
249 | 286 |
250 } // namespace content | 287 } // namespace content |
OLD | NEW |