| 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 |