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 |