Convert PrefSyncStatus into PrefRegistrationFlags
[chromium-blink-merge.git] / ppapi / proxy / plugin_globals.cc
blob060aa71d4827536eba314941bc1c2ea6511ccfab
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.
5 #include "ppapi/proxy/plugin_globals.h"
7 #include "base/task_runner.h"
8 #include "base/threading/thread.h"
9 #include "ipc/ipc_message.h"
10 #include "ipc/ipc_sender.h"
11 #include "ppapi/proxy/plugin_dispatcher.h"
12 #include "ppapi/proxy/plugin_message_filter.h"
13 #include "ppapi/proxy/plugin_proxy_delegate.h"
14 #include "ppapi/proxy/ppapi_messages.h"
15 #include "ppapi/proxy/ppb_message_loop_proxy.h"
16 #include "ppapi/proxy/resource_reply_thread_registrar.h"
17 #include "ppapi/proxy/udp_socket_filter.h"
18 #include "ppapi/shared_impl/ppapi_constants.h"
19 #include "ppapi/shared_impl/proxy_lock.h"
20 #include "ppapi/thunk/enter.h"
22 namespace ppapi {
23 namespace proxy {
25 // It performs necessary locking/unlocking of the proxy lock, and forwards all
26 // messages to the underlying sender.
27 class PluginGlobals::BrowserSender : public IPC::Sender {
28 public:
29 // |underlying_sender| must outlive this object.
30 explicit BrowserSender(IPC::Sender* underlying_sender)
31 : underlying_sender_(underlying_sender) {
34 ~BrowserSender() override {}
36 // IPC::Sender implementation.
37 bool Send(IPC::Message* msg) override {
38 if (msg->is_sync()) {
39 // Synchronous messages might be re-entrant, so we need to drop the lock.
40 ProxyAutoUnlock unlock;
41 return underlying_sender_->Send(msg);
44 return underlying_sender_->Send(msg);
47 private:
48 // Non-owning pointer.
49 IPC::Sender* underlying_sender_;
51 DISALLOW_COPY_AND_ASSIGN(BrowserSender);
54 PluginGlobals* PluginGlobals::plugin_globals_ = NULL;
56 PluginGlobals::PluginGlobals(
57 const scoped_refptr<base::TaskRunner>& ipc_task_runner)
58 : ppapi::PpapiGlobals(),
59 plugin_proxy_delegate_(NULL),
60 callback_tracker_(new CallbackTracker),
61 ipc_task_runner_(ipc_task_runner),
62 resource_reply_thread_registrar_(
63 new ResourceReplyThreadRegistrar(GetMainThreadMessageLoop())),
64 udp_socket_filter_(new UDPSocketFilter()),
65 plugin_recently_active_(false),
66 keepalive_throttle_interval_milliseconds_(
67 ppapi::kKeepaliveThrottleIntervalDefaultMilliseconds),
68 weak_factory_(this) {
69 DCHECK(!plugin_globals_);
70 plugin_globals_ = this;
72 // ResourceTracker asserts that we have the lock when we add new resources,
73 // so we lock when creating the MessageLoopResource even though there is no
74 // chance of race conditions.
75 ProxyAutoLock lock;
76 loop_for_main_thread_ =
77 new MessageLoopResource(MessageLoopResource::ForMainThread());
80 PluginGlobals::PluginGlobals(
81 PerThreadForTest per_thread_for_test,
82 const scoped_refptr<base::TaskRunner>& ipc_task_runner)
83 : ppapi::PpapiGlobals(per_thread_for_test),
84 plugin_proxy_delegate_(NULL),
85 callback_tracker_(new CallbackTracker),
86 ipc_task_runner_(ipc_task_runner),
87 resource_reply_thread_registrar_(
88 new ResourceReplyThreadRegistrar(GetMainThreadMessageLoop())),
89 plugin_recently_active_(false),
90 keepalive_throttle_interval_milliseconds_(
91 kKeepaliveThrottleIntervalDefaultMilliseconds),
92 weak_factory_(this) {
93 DCHECK(!plugin_globals_);
96 PluginGlobals::~PluginGlobals() {
97 DCHECK(plugin_globals_ == this || !plugin_globals_);
99 ProxyAutoLock lock;
100 // Release the main-thread message loop. We should have the last reference
101 // count, so this will delete the MessageLoop resource. We do this before
102 // we clear plugin_globals_, because the Resource destructor tries to access
103 // this PluginGlobals.
104 DCHECK(!loop_for_main_thread_.get() || loop_for_main_thread_->HasOneRef());
105 loop_for_main_thread_ = NULL;
107 plugin_globals_ = NULL;
110 ResourceTracker* PluginGlobals::GetResourceTracker() {
111 return &plugin_resource_tracker_;
114 VarTracker* PluginGlobals::GetVarTracker() {
115 return &plugin_var_tracker_;
118 CallbackTracker* PluginGlobals::GetCallbackTrackerForInstance(
119 PP_Instance instance) {
120 // In the plugin process, the callback tracker is always the same, regardless
121 // of the instance.
122 return callback_tracker_.get();
125 thunk::PPB_Instance_API* PluginGlobals::GetInstanceAPI(PP_Instance instance) {
126 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance);
127 if (dispatcher)
128 return dispatcher->GetInstanceAPI();
129 return NULL;
132 thunk::ResourceCreationAPI* PluginGlobals::GetResourceCreationAPI(
133 PP_Instance instance) {
134 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance);
135 if (dispatcher)
136 return dispatcher->GetResourceCreationAPI();
137 return NULL;
140 PP_Module PluginGlobals::GetModuleForInstance(PP_Instance instance) {
141 // Currently proxied plugins don't use the PP_Module for anything useful.
142 return 0;
145 std::string PluginGlobals::GetCmdLine() {
146 return command_line_;
149 void PluginGlobals::PreCacheFontForFlash(const void* logfontw) {
150 ProxyAutoUnlock unlock;
151 plugin_proxy_delegate_->PreCacheFont(logfontw);
154 void PluginGlobals::LogWithSource(PP_Instance instance,
155 PP_LogLevel level,
156 const std::string& source,
157 const std::string& value) {
158 const std::string& fixed_up_source = source.empty() ? plugin_name_ : source;
159 PluginDispatcher::LogWithSource(instance, level, fixed_up_source, value);
162 void PluginGlobals::BroadcastLogWithSource(PP_Module /* module */,
163 PP_LogLevel level,
164 const std::string& source,
165 const std::string& value) {
166 // Since we have only one module in a plugin process, broadcast is always
167 // the same as "send to everybody" which is what the dispatcher implements
168 // for the "instance = 0" case.
169 LogWithSource(0, level, source, value);
172 MessageLoopShared* PluginGlobals::GetCurrentMessageLoop() {
173 return MessageLoopResource::GetCurrent();
176 base::TaskRunner* PluginGlobals::GetFileTaskRunner() {
177 if (!file_thread_.get()) {
178 file_thread_.reset(new base::Thread("Plugin::File"));
179 base::Thread::Options options;
180 options.message_loop_type = base::MessageLoop::TYPE_IO;
181 file_thread_->StartWithOptions(options);
183 return file_thread_->message_loop_proxy().get();
186 void PluginGlobals::MarkPluginIsActive() {
187 if (!plugin_recently_active_) {
188 plugin_recently_active_ = true;
189 if (!GetBrowserSender() || !base::MessageLoop::current())
190 return;
191 GetBrowserSender()->Send(new PpapiHostMsg_Keepalive());
192 DCHECK(keepalive_throttle_interval_milliseconds_);
193 GetMainThreadMessageLoop()->PostDelayedTask(
194 FROM_HERE,
195 RunWhileLocked(base::Bind(&PluginGlobals::OnReleaseKeepaliveThrottle,
196 weak_factory_.GetWeakPtr())),
197 base::TimeDelta::FromMilliseconds(
198 keepalive_throttle_interval_milliseconds_));
202 IPC::Sender* PluginGlobals::GetBrowserSender() {
203 // CAUTION: This function is called without the ProxyLock. See also
204 // InterfaceList::GetInterfaceForPPB.
206 // See also SetPluginProxyDelegate. That initializes browser_sender_ before
207 // the plugin can start threads, and it may be cleared after the
208 // plugin has torn down threads. So this pointer is expected to remain valid
209 // during the lifetime of the plugin.
210 return browser_sender_.get();
213 std::string PluginGlobals::GetUILanguage() {
214 return plugin_proxy_delegate_->GetUILanguage();
217 void PluginGlobals::SetActiveURL(const std::string& url) {
218 plugin_proxy_delegate_->SetActiveURL(url);
221 PP_Resource PluginGlobals::CreateBrowserFont(
222 Connection connection,
223 PP_Instance instance,
224 const PP_BrowserFont_Trusted_Description& desc,
225 const ppapi::Preferences& prefs) {
226 return plugin_proxy_delegate_->CreateBrowserFont(
227 connection, instance, desc, prefs);
230 void PluginGlobals::SetPluginProxyDelegate(PluginProxyDelegate* delegate) {
231 DCHECK(delegate && !plugin_proxy_delegate_);
232 plugin_proxy_delegate_ = delegate;
233 browser_sender_.reset(
234 new BrowserSender(plugin_proxy_delegate_->GetBrowserSender()));
237 void PluginGlobals::ResetPluginProxyDelegate() {
238 DCHECK(plugin_proxy_delegate_);
239 plugin_proxy_delegate_ = NULL;
240 browser_sender_.reset();
243 MessageLoopResource* PluginGlobals::loop_for_main_thread() {
244 return loop_for_main_thread_.get();
247 void PluginGlobals::RegisterResourceMessageFilters(
248 ppapi::proxy::PluginMessageFilter* plugin_filter) {
249 plugin_filter->AddResourceMessageFilter(udp_socket_filter_.get());
252 void PluginGlobals::set_keepalive_throttle_interval_milliseconds(unsigned i) {
253 keepalive_throttle_interval_milliseconds_ = i;
256 bool PluginGlobals::IsPluginGlobals() const {
257 return true;
260 void PluginGlobals::OnReleaseKeepaliveThrottle() {
261 ppapi::ProxyLock::AssertAcquiredDebugOnly();
262 plugin_recently_active_ = false;
265 } // namespace proxy
266 } // namespace ppapi