OLD | NEW |
(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 "ppapi/proxy/ppb_network_monitor_private_proxy.h" |
| 6 |
| 7 #include "ppapi/proxy/enter_proxy.h" |
| 8 #include "ppapi/proxy/ppapi_messages.h" |
| 9 #include "ppapi/shared_impl/proxy_lock.h" |
| 10 #include "ppapi/thunk/ppb_network_monitor_api.h" |
| 11 |
| 12 namespace ppapi { |
| 13 namespace proxy { |
| 14 |
| 15 class PPB_NetworkMonitor_Private_Proxy::NetworkMonitor |
| 16 : public Resource, |
| 17 public thunk::PPB_NetworkMonitor_API, |
| 18 public base::SupportsWeakPtr< |
| 19 PPB_NetworkMonitor_Private_Proxy::NetworkMonitor> { |
| 20 public: |
| 21 NetworkMonitor(PP_Instance instance, |
| 22 PPB_NetworkMonitor_Private_Proxy* proxy) |
| 23 : Resource(OBJECT_IS_PROXY, instance), |
| 24 proxy_(proxy), |
| 25 initial_list_sent_(false), |
| 26 network_list_(NULL) { |
| 27 } |
| 28 |
| 29 virtual ~NetworkMonitor() { |
| 30 if (TrackedCallback::IsPending(update_callback_)) |
| 31 update_callback_->PostAbort(); |
| 32 proxy_->OnNetworkMonitorDeleted(this, pp_instance()); |
| 33 } |
| 34 |
| 35 // thunk::PPB_NetworkMonitor_API interface. |
| 36 virtual int32_t UpdateNetworkList( |
| 37 PP_Resource* network_list, |
| 38 scoped_refptr<TrackedCallback> callback) OVERRIDE { |
| 39 if (!network_list) |
| 40 return PP_ERROR_BADARGUMENT; |
| 41 if (TrackedCallback::IsPending(update_callback_)) |
| 42 return PP_ERROR_INPROGRESS; |
| 43 |
| 44 if (current_list_ && !initial_list_sent_) { |
| 45 initial_list_sent_ = true; |
| 46 thunk::EnterResourceCreationNoLock enter(pp_instance()); |
| 47 *network_list = PPB_NetworkList_Private_Shared::Create( |
| 48 OBJECT_IS_PROXY, pp_instance(), current_list_); |
| 49 return PP_OK; |
| 50 } |
| 51 |
| 52 network_list_ = network_list; |
| 53 update_callback_ = callback; |
| 54 return PP_OK_COMPLETIONPENDING; |
| 55 } |
| 56 |
| 57 // Resource overrides. |
| 58 virtual ppapi::thunk::PPB_NetworkMonitor_API* |
| 59 AsPPB_NetworkMonitor_API() OVERRIDE { |
| 60 return this; |
| 61 } |
| 62 |
| 63 // This is invoked when a network list is received for this monitor (either |
| 64 // initially or on a change). |
| 65 void OnNetworkListReceived(const scoped_refptr<NetworkListStorage>& list) { |
| 66 current_list_ = list; |
| 67 |
| 68 if (TrackedCallback::IsPending(update_callback_)) { |
| 69 initial_list_sent_ = true; |
| 70 { |
| 71 thunk::EnterResourceCreationNoLock enter(pp_instance()); |
| 72 *network_list_ = PPB_NetworkList_Private_Shared::Create( |
| 73 OBJECT_IS_PROXY, pp_instance(), list); |
| 74 network_list_ = NULL; |
| 75 } |
| 76 update_callback_->Run(PP_OK); |
| 77 } |
| 78 } |
| 79 |
| 80 private: |
| 81 PPB_NetworkMonitor_Private_Proxy* proxy_; |
| 82 scoped_refptr<NetworkListStorage> current_list_; |
| 83 bool initial_list_sent_; |
| 84 |
| 85 // Parameters passed to UpdateNetworkList(); |
| 86 PP_Resource* network_list_; |
| 87 scoped_refptr<TrackedCallback> update_callback_; |
| 88 |
| 89 DISALLOW_COPY_AND_ASSIGN(NetworkMonitor); |
| 90 }; |
| 91 |
| 92 PPB_NetworkMonitor_Private_Proxy::PPB_NetworkMonitor_Private_Proxy( |
| 93 Dispatcher* dispatcher) |
| 94 : InterfaceProxy(dispatcher), |
| 95 monitors_(ObserverList<NetworkMonitor>::NOTIFY_EXISTING_ONLY) { |
| 96 } |
| 97 |
| 98 PPB_NetworkMonitor_Private_Proxy::~PPB_NetworkMonitor_Private_Proxy() { |
| 99 DCHECK(!monitors_.might_have_observers()); |
| 100 } |
| 101 |
| 102 // static |
| 103 PP_Resource PPB_NetworkMonitor_Private_Proxy::CreateProxyResource( |
| 104 PP_Instance instance) { |
| 105 // TODO(dmichael): Check that this thread has a valid message loop associated |
| 106 // with it. |
| 107 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance); |
| 108 if (!dispatcher) |
| 109 return 0; |
| 110 PPB_NetworkMonitor_Private_Proxy* proxy = |
| 111 static_cast<PPB_NetworkMonitor_Private_Proxy*>( |
| 112 dispatcher->GetInterfaceProxy(kApiID)); |
| 113 if (!proxy) |
| 114 return 0; |
| 115 |
| 116 scoped_refptr<NetworkMonitor> result(new NetworkMonitor(instance, proxy)); |
| 117 |
| 118 bool first_network_monitor = !proxy->monitors_.might_have_observers(); |
| 119 proxy->monitors_.AddObserver(result.get()); |
| 120 if (first_network_monitor) { |
| 121 // If that is the first network monitor then send Start message. |
| 122 PluginGlobals::Get()->GetBrowserSender()->Send( |
| 123 new PpapiHostMsg_PPBNetworkMonitor_Start( |
| 124 dispatcher->plugin_dispatcher_id())); |
| 125 |
| 126 // We could have received network list message after sending the |
| 127 // previous Stop message. This list is stale now, so reset it |
| 128 // here. |
| 129 proxy->current_list_ = NULL; |
| 130 } else if (proxy->current_list_.get()) { |
| 131 result->OnNetworkListReceived(proxy->current_list_); |
| 132 } |
| 133 |
| 134 return result->GetReference(); |
| 135 } |
| 136 |
| 137 bool PPB_NetworkMonitor_Private_Proxy::OnMessageReceived( |
| 138 const IPC::Message& msg) { |
| 139 bool handled = true; |
| 140 IPC_BEGIN_MESSAGE_MAP(PPB_NetworkMonitor_Private_Proxy, msg) |
| 141 IPC_MESSAGE_HANDLER(PpapiMsg_PPBNetworkMonitor_NetworkList, |
| 142 OnPluginMsgNetworkList) |
| 143 IPC_MESSAGE_UNHANDLED(handled = false) |
| 144 IPC_END_MESSAGE_MAP() |
| 145 return handled; |
| 146 } |
| 147 |
| 148 void PPB_NetworkMonitor_Private_Proxy::OnPluginMsgNetworkList( |
| 149 uint32 plugin_dispatcher_id, |
| 150 const ppapi::NetworkList& list) { |
| 151 scoped_refptr<NetworkListStorage> list_storage(new NetworkListStorage(list)); |
| 152 current_list_ = list_storage; |
| 153 FOR_EACH_OBSERVER(NetworkMonitor, monitors_, |
| 154 OnNetworkListReceived(list_storage)); |
| 155 } |
| 156 |
| 157 void PPB_NetworkMonitor_Private_Proxy::OnNetworkMonitorDeleted( |
| 158 NetworkMonitor* monitor, |
| 159 PP_Instance instance) { |
| 160 monitors_.RemoveObserver(monitor); |
| 161 if (!monitors_.might_have_observers()) { |
| 162 // Send Stop message if that was the last NetworkMonitor. |
| 163 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance); |
| 164 if (dispatcher) { |
| 165 PluginGlobals::Get()->GetBrowserSender()->Send( |
| 166 new PpapiHostMsg_PPBNetworkMonitor_Stop( |
| 167 dispatcher->plugin_dispatcher_id())); |
| 168 } |
| 169 current_list_ = NULL; |
| 170 } |
| 171 } |
| 172 |
| 173 } // namespace proxy |
| 174 } // namespace ppapi |
OLD | NEW |