Chromium Code Reviews| Index: ppapi/proxy/ppb_network_monitor_private_proxy.cc |
| diff --git a/ppapi/proxy/ppb_network_monitor_private_proxy.cc b/ppapi/proxy/ppb_network_monitor_private_proxy.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..56633ca9f4b4af6f9d8f8d4347d723515d7f0896 |
| --- /dev/null |
| +++ b/ppapi/proxy/ppb_network_monitor_private_proxy.cc |
| @@ -0,0 +1,140 @@ |
| +// Copyright (c) 2012 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. |
| + |
| +#include "ppapi/proxy/ppb_network_monitor_private_proxy.h" |
| + |
| +#include "ppapi/proxy/enter_proxy.h" |
| +#include "ppapi/proxy/plugin_proxy_delegate.h" |
| +#include "ppapi/proxy/ppapi_messages.h" |
| +#include "ppapi/thunk/ppb_network_monitor_private_api.h" |
| + |
| +namespace ppapi { |
| +namespace proxy { |
| + |
| +class PPB_NetworkMonitor_Private_Proxy::NetworkMonitor |
| + : public Resource, |
| + public thunk::PPB_NetworkMonitor_Private_API, |
| + public base::SupportsWeakPtr< |
| + PPB_NetworkMonitor_Private_Proxy::NetworkMonitor> { |
| + public: |
| + NetworkMonitor(PP_Instance instance, |
| + PPB_NetworkMonitor_Private_Proxy* proxy, |
| + PPB_NetworkMonitor_Callback callback, |
| + void* user_data) |
| + : Resource(OBJECT_IS_PROXY, instance), |
| + proxy_(proxy), |
| + callback_(callback), |
| + user_data_(user_data) { |
| + } |
| + |
| + virtual ~NetworkMonitor() { |
| + proxy_->OnNetworkMonitorDeleted(this, pp_instance()); |
| + } |
| + |
| + // Resource overrides. |
| + virtual ppapi::thunk::PPB_NetworkMonitor_Private_API* |
| + AsPPB_NetworkMonitor_Private_API() OVERRIDE { |
| + return this; |
|
dmichael (off chromium)
2012/03/16 19:55:22
ditto here
Sergey Ulanov
2012/03/16 23:37:28
Done.
|
| + } |
| + |
| + void OnNetworkListReceived(const scoped_refptr<NetworkListStorage>& list) { |
| + PP_Resource list_resource = |
| + PPB_NetworkList_Private_Shared::Create( |
| + OBJECT_IS_PROXY, pp_instance(), list); |
| + CallWhileUnlocked(callback_, user_data_, list_resource); |
| + } |
| + |
| + private: |
| + PPB_NetworkMonitor_Private_Proxy* proxy_; |
| + PPB_NetworkMonitor_Callback callback_; |
| + void* user_data_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(NetworkMonitor); |
| +}; |
| + |
| +PPB_NetworkMonitor_Private_Proxy::PPB_NetworkMonitor_Private_Proxy( |
| + Dispatcher* dispatcher) |
| + : InterfaceProxy(dispatcher), |
| + monitors_(new ObserverListThreadSafe<NetworkMonitor>()), |
| + monitors_count_(0) { |
| +} |
| + |
| +PPB_NetworkMonitor_Private_Proxy::~PPB_NetworkMonitor_Private_Proxy() { |
| + monitors_->AssertEmpty(); |
| +} |
| + |
| +// static |
| +PP_Resource PPB_NetworkMonitor_Private_Proxy::CreateProxyResource( |
| + PP_Instance instance, |
| + PPB_NetworkMonitor_Callback callback, |
| + void* user_data) { |
| + if (!callback) |
| + return 0; |
| + |
| + PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance); |
| + if (!dispatcher) |
| + return 0; |
| + PPB_NetworkMonitor_Private_Proxy* proxy = |
| + static_cast<PPB_NetworkMonitor_Private_Proxy*>( |
| + dispatcher->GetInterfaceProxy(kApiID)); |
| + if (!proxy) |
| + return 0; |
| + |
| + scoped_ptr<NetworkMonitor> result( |
| + new NetworkMonitor(instance, proxy, callback, user_data)); |
| + proxy->monitors_->AddObserver(result.get()); |
| + |
| + proxy->monitors_count_++; |
| + if (proxy->monitors_count_ == 1) { |
| + // If that is the first network monitor then send Start message. |
| + PluginGlobals::Get()->plugin_proxy_delegate()->SendToBrowser( |
| + new PpapiHostMsg_PPBNetworkMonitor_Start( |
| + dispatcher->plugin_dispatcher_id())); |
| + } else if (proxy->current_list_.get()) { |
| + MessageLoop::current()->PostTask(FROM_HERE, base::Bind( |
| + &NetworkMonitor::OnNetworkListReceived, |
| + result->AsWeakPtr(), proxy->current_list_)); |
| + } |
| + |
| + return result.release()->GetReference(); |
| +} |
| + |
| +bool PPB_NetworkMonitor_Private_Proxy::OnMessageReceived( |
| + const IPC::Message& msg) { |
| + bool handled = true; |
| + IPC_BEGIN_MESSAGE_MAP(PPB_NetworkMonitor_Private_Proxy, msg) |
| + IPC_MESSAGE_HANDLER(PpapiMsg_PPBNetworkMonitor_NetworkList, |
| + OnPluginMsgNetworkList) |
| + IPC_MESSAGE_UNHANDLED(handled = false) |
| + IPC_END_MESSAGE_MAP() |
| + return handled; |
| +} |
| + |
| +void PPB_NetworkMonitor_Private_Proxy::OnPluginMsgNetworkList( |
| + uint32 plugin_dispatcher_id, |
| + const ppapi::NetworkList& list) { |
| + scoped_refptr<NetworkListStorage> list_storage(new NetworkListStorage(list)); |
| + current_list_ = list_storage; |
| + monitors_->Notify(&NetworkMonitor::OnNetworkListReceived, list_storage); |
|
dmichael (off chromium)
2012/03/16 19:55:22
Have you thought about corner cases due to the asy
Sergey Ulanov
2012/03/16 23:37:28
Heh, that scenario is the reason I initially had t
|
| +} |
| + |
| +void PPB_NetworkMonitor_Private_Proxy::OnNetworkMonitorDeleted( |
| + NetworkMonitor* monitor, |
| + PP_Instance instance) { |
| + monitors_->RemoveObserver(monitor); |
| + monitors_count_--; |
| + if (monitors_count_ == 0) { |
| + // Send Stop message if that was the last NetworkMonitor. |
| + PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance); |
| + if (dispatcher) { |
| + current_list_ = NULL; |
| + PluginGlobals::Get()->plugin_proxy_delegate()->SendToBrowser( |
| + new PpapiHostMsg_PPBNetworkMonitor_Stop( |
| + dispatcher->plugin_dispatcher_id())); |
| + } |
| + } |
| +} |
| + |
| +} // namespace proxy |
| +} // namespace ppapi |