Chromium Code Reviews| 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 LOG_IF(ERROR, !weak_ptr) << "Client has gone away"; | |
|
ddorwin
2012/08/12 22:51:16
Seems more like a warning.
Bernhard Bauer
2012/08/13 09:02:12
Oops, that was for debugging. Removed.
| |
| 192 LOG_IF(ERROR, !i->second.authorized) << "Client is waiting for permission"; | |
|
ddorwin
2012/08/12 22:51:16
Is this really an error that should always be logg
| |
| 193 if (!i->second.authorized) { | |
|
ddorwin
2012/08/12 22:51:16
Is the renderer process responsible for enforcing
Bernhard Bauer
2012/08/13 09:02:12
Yeah, I talked about this with Justin. AFAIU, a co
| |
| 194 ++i; | |
| 195 continue; | |
| 205 } | 196 } |
| 206 } else { | 197 |
| 207 // Report failure to all clients. | 198 if (weak_ptr) |
| 208 for (ClientMap::iterator i = pending_connects_.begin(); | 199 ConnectPluginToBroker(weak_ptr); |
| 209 i != pending_connects_.end(); ++i) { | 200 |
| 210 base::WeakPtr<webkit::ppapi::PPB_Broker_Impl>& weak_ptr = i->second; | 201 pending_connects_.erase(i++); |
| 211 if (weak_ptr) { | 202 } |
| 212 weak_ptr->BrokerConnected( | 203 } |
| 213 ppapi::PlatformFileToInt(base::kInvalidPlatformFileValue), | 204 |
| 214 PP_ERROR_FAILED); | 205 void PepperBrokerImpl::OnBrokerPermissionResult( |
| 215 } | 206 webkit::ppapi::PPB_Broker_Impl* client, |
| 207 bool result) { | |
| 208 ClientMap::iterator entry = pending_connects_.find(client); | |
| 209 if (entry == pending_connects_.end()) | |
| 210 return; | |
| 211 | |
| 212 if (!entry->second.client) { | |
| 213 // Client has gone away. | |
| 214 pending_connects_.erase(entry); | |
| 215 return; | |
| 216 } | |
| 217 | |
| 218 if (!result) { | |
| 219 // Report failure. | |
| 220 client->BrokerConnected( | |
| 221 ppapi::PlatformFileToInt(base::kInvalidPlatformFileValue), | |
| 222 PP_ERROR_NOACCESS); | |
| 223 pending_connects_.erase(entry); | |
| 224 return; | |
| 225 } | |
| 226 | |
| 227 if (dispatcher_.get()) { | |
| 228 ConnectPluginToBroker(client); | |
| 229 pending_connects_.erase(entry); | |
| 230 return; | |
| 231 } | |
| 232 | |
| 233 // Mark the request as authorized, continue waiting for the broker | |
| 234 // connection. | |
| 235 DCHECK(!entry->second.authorized); | |
| 236 entry->second.authorized = true; | |
| 237 } | |
| 238 | |
| 239 PepperBrokerImpl::PendingConnection::PendingConnection() : authorized(false) { | |
| 240 } | |
| 241 | |
| 242 PepperBrokerImpl::PendingConnection::~PendingConnection() { | |
| 243 } | |
| 244 | |
| 245 void PepperBrokerImpl::ReportFailureToClients() { | |
| 246 for (ClientMap::iterator i = pending_connects_.begin(); | |
| 247 i != pending_connects_.end(); ++i) { | |
| 248 base::WeakPtr<webkit::ppapi::PPB_Broker_Impl>& weak_ptr = | |
| 249 i->second.client; | |
| 250 if (weak_ptr) { | |
| 251 weak_ptr->BrokerConnected( | |
| 252 ppapi::PlatformFileToInt(base::kInvalidPlatformFileValue), | |
| 253 PP_ERROR_ABORTED); | |
| 216 } | 254 } |
| 217 } | 255 } |
| 218 pending_connects_.clear(); | 256 pending_connects_.clear(); |
| 219 } | 257 } |
| 220 | 258 |
| 221 void PepperBrokerImpl::ConnectPluginToBroker( | 259 void PepperBrokerImpl::ConnectPluginToBroker( |
| 222 webkit::ppapi::PPB_Broker_Impl* client) { | 260 webkit::ppapi::PPB_Broker_Impl* client) { |
| 223 base::SyncSocket::Handle plugin_handle = base::kInvalidPlatformFileValue; | 261 base::SyncSocket::Handle plugin_handle = base::kInvalidPlatformFileValue; |
| 224 int32_t result = PP_OK; | 262 int32_t result = PP_OK; |
| 225 | 263 |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 241 | 279 |
| 242 // TOOD(ddorwin): Change the IPC to asynchronous: Queue an object containing | 280 // TOOD(ddorwin): Change the IPC to asynchronous: Queue an object containing |
| 243 // client and plugin_socket.release(), then return. | 281 // client and plugin_socket.release(), then return. |
| 244 // That message handler will then call client->BrokerConnected() with the | 282 // That message handler will then call client->BrokerConnected() with the |
| 245 // saved pipe handle. | 283 // saved pipe handle. |
| 246 // Temporarily, just call back. | 284 // Temporarily, just call back. |
| 247 client->BrokerConnected(ppapi::PlatformFileToInt(plugin_handle), result); | 285 client->BrokerConnected(ppapi::PlatformFileToInt(plugin_handle), result); |
| 248 } | 286 } |
| 249 | 287 |
| 250 } // namespace content | 288 } // namespace content |
| OLD | NEW |