• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/plugin_globals.h"
6 
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_proxy_delegate.h"
13 #include "ppapi/proxy/ppb_message_loop_proxy.h"
14 #include "ppapi/proxy/resource_reply_thread_registrar.h"
15 #include "ppapi/shared_impl/proxy_lock.h"
16 #include "ppapi/thunk/enter.h"
17 
18 namespace ppapi {
19 namespace proxy {
20 
21 // It performs necessary locking/unlocking of the proxy lock, and forwards all
22 // messages to the underlying sender.
23 class PluginGlobals::BrowserSender : public IPC::Sender {
24  public:
25   // |underlying_sender| must outlive this object.
BrowserSender(IPC::Sender * underlying_sender)26   explicit BrowserSender(IPC::Sender* underlying_sender)
27       : underlying_sender_(underlying_sender) {
28   }
29 
~BrowserSender()30   virtual ~BrowserSender() {}
31 
32   // IPC::Sender implementation.
Send(IPC::Message * msg)33   virtual bool Send(IPC::Message* msg) OVERRIDE {
34     if (msg->is_sync()) {
35       // Synchronous messages might be re-entrant, so we need to drop the lock.
36       ProxyAutoUnlock unlock;
37       return underlying_sender_->Send(msg);
38     }
39 
40     return underlying_sender_->Send(msg);
41   }
42 
43  private:
44   // Non-owning pointer.
45   IPC::Sender* underlying_sender_;
46 
47   DISALLOW_COPY_AND_ASSIGN(BrowserSender);
48 };
49 
50 PluginGlobals* PluginGlobals::plugin_globals_ = NULL;
51 
PluginGlobals()52 PluginGlobals::PluginGlobals()
53     : ppapi::PpapiGlobals(),
54       plugin_proxy_delegate_(NULL),
55       callback_tracker_(new CallbackTracker),
56       resource_reply_thread_registrar_(
57           new ResourceReplyThreadRegistrar(GetMainThreadMessageLoop())) {
58   DCHECK(!plugin_globals_);
59   plugin_globals_ = this;
60 
61   // ResourceTracker asserts that we have the lock when we add new resources,
62   // so we lock when creating the MessageLoopResource even though there is no
63   // chance of race conditions.
64   ProxyAutoLock lock;
65   loop_for_main_thread_ =
66       new MessageLoopResource(MessageLoopResource::ForMainThread());
67 }
68 
PluginGlobals(PerThreadForTest per_thread_for_test)69 PluginGlobals::PluginGlobals(PerThreadForTest per_thread_for_test)
70     : ppapi::PpapiGlobals(per_thread_for_test),
71       plugin_proxy_delegate_(NULL),
72       callback_tracker_(new CallbackTracker),
73       resource_reply_thread_registrar_(
74           new ResourceReplyThreadRegistrar(GetMainThreadMessageLoop())) {
75   DCHECK(!plugin_globals_);
76 }
77 
~PluginGlobals()78 PluginGlobals::~PluginGlobals() {
79   DCHECK(plugin_globals_ == this || !plugin_globals_);
80   {
81     ProxyAutoLock lock;
82     // Release the main-thread message loop. We should have the last reference
83     // count, so this will delete the MessageLoop resource. We do this before
84     // we clear plugin_globals_, because the Resource destructor tries to access
85     // this PluginGlobals.
86     DCHECK(!loop_for_main_thread_.get() || loop_for_main_thread_->HasOneRef());
87     loop_for_main_thread_ = NULL;
88   }
89   plugin_globals_ = NULL;
90 }
91 
GetResourceTracker()92 ResourceTracker* PluginGlobals::GetResourceTracker() {
93   return &plugin_resource_tracker_;
94 }
95 
GetVarTracker()96 VarTracker* PluginGlobals::GetVarTracker() {
97   return &plugin_var_tracker_;
98 }
99 
GetCallbackTrackerForInstance(PP_Instance instance)100 CallbackTracker* PluginGlobals::GetCallbackTrackerForInstance(
101     PP_Instance instance) {
102   // In the plugin process, the callback tracker is always the same, regardless
103   // of the instance.
104   return callback_tracker_.get();
105 }
106 
GetInstanceAPI(PP_Instance instance)107 thunk::PPB_Instance_API* PluginGlobals::GetInstanceAPI(PP_Instance instance) {
108   PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance);
109   if (dispatcher)
110     return dispatcher->GetInstanceAPI();
111   return NULL;
112 }
113 
GetResourceCreationAPI(PP_Instance instance)114 thunk::ResourceCreationAPI* PluginGlobals::GetResourceCreationAPI(
115     PP_Instance instance) {
116   PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance);
117   if (dispatcher)
118     return dispatcher->GetResourceCreationAPI();
119   return NULL;
120 }
121 
GetModuleForInstance(PP_Instance instance)122 PP_Module PluginGlobals::GetModuleForInstance(PP_Instance instance) {
123   // Currently proxied plugins don't use the PP_Module for anything useful.
124   return 0;
125 }
126 
GetCmdLine()127 std::string PluginGlobals::GetCmdLine() {
128   return command_line_;
129 }
130 
PreCacheFontForFlash(const void * logfontw)131 void PluginGlobals::PreCacheFontForFlash(const void* logfontw) {
132   ProxyAutoUnlock unlock;
133   plugin_proxy_delegate_->PreCacheFont(logfontw);
134 }
135 
LogWithSource(PP_Instance instance,PP_LogLevel level,const std::string & source,const std::string & value)136 void PluginGlobals::LogWithSource(PP_Instance instance,
137                                   PP_LogLevel level,
138                                   const std::string& source,
139                                   const std::string& value) {
140   const std::string& fixed_up_source = source.empty() ? plugin_name_ : source;
141   PluginDispatcher::LogWithSource(instance, level, fixed_up_source, value);
142 }
143 
BroadcastLogWithSource(PP_Module,PP_LogLevel level,const std::string & source,const std::string & value)144 void PluginGlobals::BroadcastLogWithSource(PP_Module /* module */,
145                                            PP_LogLevel level,
146                                            const std::string& source,
147                                            const std::string& value) {
148   // Since we have only one module in a plugin process, broadcast is always
149   // the same as "send to everybody" which is what the dispatcher implements
150   // for the "instance = 0" case.
151   LogWithSource(0, level, source, value);
152 }
153 
GetCurrentMessageLoop()154 MessageLoopShared* PluginGlobals::GetCurrentMessageLoop() {
155   return MessageLoopResource::GetCurrent();
156 }
157 
GetFileTaskRunner()158 base::TaskRunner* PluginGlobals::GetFileTaskRunner() {
159   if (!file_thread_.get()) {
160     file_thread_.reset(new base::Thread("Plugin::File"));
161     base::Thread::Options options;
162     options.message_loop_type = base::MessageLoop::TYPE_IO;
163     file_thread_->StartWithOptions(options);
164   }
165   return file_thread_->message_loop_proxy();
166 }
167 
GetBrowserSender()168 IPC::Sender* PluginGlobals::GetBrowserSender() {
169   if (!browser_sender_.get()) {
170     browser_sender_.reset(
171         new BrowserSender(plugin_proxy_delegate_->GetBrowserSender()));
172   }
173 
174   return browser_sender_.get();
175 }
176 
GetUILanguage()177 std::string PluginGlobals::GetUILanguage() {
178   return plugin_proxy_delegate_->GetUILanguage();
179 }
180 
SetActiveURL(const std::string & url)181 void PluginGlobals::SetActiveURL(const std::string& url) {
182   plugin_proxy_delegate_->SetActiveURL(url);
183 }
184 
CreateBrowserFont(Connection connection,PP_Instance instance,const PP_BrowserFont_Trusted_Description & desc,const ppapi::Preferences & prefs)185 PP_Resource PluginGlobals::CreateBrowserFont(
186     Connection connection,
187     PP_Instance instance,
188     const PP_BrowserFont_Trusted_Description& desc,
189     const ppapi::Preferences& prefs) {
190   return plugin_proxy_delegate_->CreateBrowserFont(
191       connection, instance, desc, prefs);
192 }
193 
loop_for_main_thread()194 MessageLoopResource* PluginGlobals::loop_for_main_thread() {
195   return loop_for_main_thread_.get();
196 }
197 
IsPluginGlobals() const198 bool PluginGlobals::IsPluginGlobals() const {
199   return true;
200 }
201 
202 }  // namespace proxy
203 }  // namespace ppapi
204