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#ifndef PPAPI_PROXY_PLUGIN_GLOBALS_H_
6#define PPAPI_PROXY_PLUGIN_GLOBALS_H_
7
8#include <string>
9
10#include "base/compiler_specific.h"
11#include "base/memory/scoped_ptr.h"
12#include "base/threading/thread_local_storage.h"
13#include "ppapi/proxy/connection.h"
14#include "ppapi/proxy/plugin_resource_tracker.h"
15#include "ppapi/proxy/plugin_var_tracker.h"
16#include "ppapi/proxy/ppapi_proxy_export.h"
17#include "ppapi/shared_impl/callback_tracker.h"
18#include "ppapi/shared_impl/ppapi_globals.h"
19
20namespace base {
21class Thread;
22}
23namespace IPC {
24class Sender;
25}
26
27struct PP_BrowserFont_Trusted_Description;
28
29namespace ppapi {
30
31struct Preferences;
32
33namespace proxy {
34
35class MessageLoopResource;
36class PluginProxyDelegate;
37class ResourceReplyThreadRegistrar;
38
39class PPAPI_PROXY_EXPORT PluginGlobals : public PpapiGlobals {
40 public:
41  PluginGlobals();
42  explicit PluginGlobals(PpapiGlobals::PerThreadForTest);
43  virtual ~PluginGlobals();
44
45  // Getter for the global singleton. Generally, you should use
46  // PpapiGlobals::Get() when possible. Use this only when you need some
47  // plugin-specific functionality.
48  inline static PluginGlobals* Get() {
49    // Explicitly crash if this is the wrong process type, we want to get
50    // crash reports.
51    CHECK(PpapiGlobals::Get()->IsPluginGlobals());
52    return static_cast<PluginGlobals*>(PpapiGlobals::Get());
53  }
54
55  // PpapiGlobals implementation.
56  virtual ResourceTracker* GetResourceTracker() OVERRIDE;
57  virtual VarTracker* GetVarTracker() OVERRIDE;
58  virtual CallbackTracker* GetCallbackTrackerForInstance(
59      PP_Instance instance) OVERRIDE;
60  virtual thunk::PPB_Instance_API* GetInstanceAPI(
61      PP_Instance instance) OVERRIDE;
62  virtual thunk::ResourceCreationAPI* GetResourceCreationAPI(
63      PP_Instance instance) OVERRIDE;
64  virtual PP_Module GetModuleForInstance(PP_Instance instance) OVERRIDE;
65  virtual std::string GetCmdLine() OVERRIDE;
66  virtual void PreCacheFontForFlash(const void* logfontw) OVERRIDE;
67  virtual void LogWithSource(PP_Instance instance,
68                             PP_LogLevel level,
69                             const std::string& source,
70                             const std::string& value) OVERRIDE;
71  virtual void BroadcastLogWithSource(PP_Module module,
72                                      PP_LogLevel level,
73                                      const std::string& source,
74                                      const std::string& value) OVERRIDE;
75  virtual MessageLoopShared* GetCurrentMessageLoop() OVERRIDE;
76  base::TaskRunner* GetFileTaskRunner() OVERRIDE;
77  virtual void MarkPluginIsActive() OVERRIDE;
78
79  // Returns the channel for sending to the browser.
80  IPC::Sender* GetBrowserSender();
81
82  // Returns the language code of the current UI language.
83  std::string GetUILanguage();
84
85  // Sets the active url which is reported by breakpad.
86  void SetActiveURL(const std::string& url);
87
88  PP_Resource CreateBrowserFont(
89      Connection connection,
90      PP_Instance instance,
91      const PP_BrowserFont_Trusted_Description& desc,
92      const Preferences& prefs);
93
94  // Getters for the plugin-specific versions.
95  PluginResourceTracker* plugin_resource_tracker() {
96    return &plugin_resource_tracker_;
97  }
98  PluginVarTracker* plugin_var_tracker() {
99    return &plugin_var_tracker_;
100  }
101
102  // The embedder should call SetPluginProxyDelegate during startup.
103  void SetPluginProxyDelegate(PluginProxyDelegate* d);
104  // The embedder may choose to call ResetPluginProxyDelegate during shutdown.
105  // After that point, it's unsafe to call most members of PluginGlobals,
106  // and GetBrowserSender will return NULL.
107  void ResetPluginProxyDelegate();
108
109  // Returns the TLS slot that holds the message loop TLS.
110  //
111  // If we end up needing more TLS storage for more stuff, we should probably
112  // have a struct in here for the different items.
113  base::ThreadLocalStorage::Slot* msg_loop_slot() {
114    return msg_loop_slot_.get();
115  }
116
117  // Sets the message loop slot, takes ownership of the given heap-alloated
118  // pointer.
119  void set_msg_loop_slot(base::ThreadLocalStorage::Slot* slot) {
120    msg_loop_slot_.reset(slot);
121  }
122
123  // Return the special Resource that represents the MessageLoop for the main
124  // thread. This Resource is not associated with any instance, and lives as
125  // long as the plugin.
126  MessageLoopResource* loop_for_main_thread();
127
128  // The embedder should call this function when the name of the plugin module
129  // is known. This will be used for error logging.
130  void set_plugin_name(const std::string& name) { plugin_name_ = name; }
131
132  // The embedder should call this function when the command line is known.
133  void set_command_line(const std::string& c) { command_line_ = c; }
134
135  ResourceReplyThreadRegistrar* resource_reply_thread_registrar() {
136    return resource_reply_thread_registrar_.get();
137  }
138
139  // Interval to limit how many IPC messages are sent indicating that the plugin
140  // is active and should be kept alive. The value must be smaller than any
141  // threshold used to kill inactive plugins by the embedder host.
142  void set_keepalive_throttle_interval_milliseconds(unsigned i);
143
144 private:
145  class BrowserSender;
146
147  // PpapiGlobals overrides.
148  virtual bool IsPluginGlobals() const OVERRIDE;
149
150  // Locks the proxy lock and releases the throttle on keepalive IPC messages.
151  void OnReleaseKeepaliveThrottle();
152
153  static PluginGlobals* plugin_globals_;
154
155  PluginProxyDelegate* plugin_proxy_delegate_;
156  PluginResourceTracker plugin_resource_tracker_;
157  PluginVarTracker plugin_var_tracker_;
158  scoped_refptr<CallbackTracker> callback_tracker_;
159
160  scoped_ptr<base::ThreadLocalStorage::Slot> msg_loop_slot_;
161  // Note that loop_for_main_thread's constructor sets msg_loop_slot_, so it
162  // must be initialized after msg_loop_slot_ (hence the order here).
163  scoped_refptr<MessageLoopResource> loop_for_main_thread_;
164
165  // Name of the plugin used for error logging. This will be empty until
166  // set_plugin_name is called.
167  std::string plugin_name_;
168
169  // Command line for the plugin. This will be empty until set_command_line is
170  // called.
171  std::string command_line_;
172
173  scoped_ptr<BrowserSender> browser_sender_;
174
175  // Thread for performing potentially blocking file operations. It's created
176  // lazily, since it might not be needed.
177  scoped_ptr<base::Thread> file_thread_;
178
179  scoped_refptr<ResourceReplyThreadRegistrar> resource_reply_thread_registrar_;
180
181  // Indicates activity by the plugin. Used to monitor when a plugin can be
182  // shutdown due to idleness. Current needs do not require differentiating
183  // between idle state between multiple instances, if any are active they are
184  // all considered active.
185  bool plugin_recently_active_;
186
187  unsigned keepalive_throttle_interval_milliseconds_;
188
189  // Member variables should appear before the WeakPtrFactory, see weak_ptr.h.
190  base::WeakPtrFactory<PluginGlobals> weak_factory_;
191
192  DISALLOW_COPY_AND_ASSIGN(PluginGlobals);
193};
194
195}  // namespace proxy
196}  // namespace ppapi
197
198#endif   // PPAPI_PROXY_PLUGIN_GLOBALS_H_
199