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 CHROME_RENDERER_PLUGINS_PLUGIN_PLACEHOLDER_H_
6#define CHROME_RENDERER_PLUGINS_PLUGIN_PLACEHOLDER_H_
7
8#include "chrome/renderer/plugins/webview_plugin.h"
9#include "content/public/common/webplugininfo.h"
10#include "content/public/renderer/context_menu_client.h"
11#include "content/public/renderer/render_process_observer.h"
12#include "content/public/renderer/render_view_observer.h"
13#include "third_party/WebKit/public/web/WebPluginParams.h"
14#include "webkit/renderer/cpp_bound_class.h"
15
16struct ChromeViewHostMsg_GetPluginInfo_Status;
17
18namespace content {
19struct WebPluginInfo;
20}
21
22// Placeholders can be used if a plug-in is missing or not available
23// (blocked or disabled).
24class PluginPlaceholder : public content::RenderViewObserver,
25                          public content::RenderProcessObserver,
26                          public webkit_glue::CppBoundClass,
27                          public WebViewPlugin::Delegate,
28                          public content::ContextMenuClient {
29 public:
30  // Creates a new WebViewPlugin with a MissingPlugin as a delegate.
31  static PluginPlaceholder* CreateMissingPlugin(
32      content::RenderView* render_view,
33      WebKit::WebFrame* frame,
34      const WebKit::WebPluginParams& params);
35
36  static PluginPlaceholder* CreateErrorPlugin(
37      content::RenderView* render_view,
38      const base::FilePath& plugin_path);
39
40  static PluginPlaceholder* CreateBlockedPlugin(
41      content::RenderView* render_view,
42      WebKit::WebFrame* frame,
43      const WebKit::WebPluginParams& params,
44      const content::WebPluginInfo& info,
45      const std::string& identifier,
46      const string16& name,
47      int resource_id,
48      const string16& message);
49
50#if defined(ENABLE_MOBILE_YOUTUBE_PLUGIN)
51  // Placeholder for old style embedded youtube video on mobile device. For old
52  // style embedded youtube video, it has a url in the form of
53  // http://www.youtube.com/v/VIDEO_ID. This placeholder replaces the url with a
54  // simple html page and clicking the play image redirects the user to the
55  // mobile youtube app.
56  static PluginPlaceholder* CreateMobileYoutubePlugin(
57       content::RenderView* render_view,
58       WebKit::WebFrame* frame,
59       const WebKit::WebPluginParams& params);
60#endif
61
62  WebViewPlugin* plugin() { return plugin_; }
63
64  void set_blocked_for_prerendering(bool blocked_for_prerendering) {
65    is_blocked_for_prerendering_ = blocked_for_prerendering;
66  }
67
68  void set_allow_loading(bool allow_loading) { allow_loading_ = allow_loading; }
69
70  void SetStatus(const ChromeViewHostMsg_GetPluginInfo_Status& status);
71
72#if defined(ENABLE_PLUGIN_INSTALLATION)
73  int32 CreateRoutingId();
74#endif
75
76#if defined(ENABLE_MOBILE_YOUTUBE_PLUGIN)
77  // Whether this is a youtube url.
78  static bool IsYouTubeURL(const GURL& url, const std::string& mime_type);
79#endif
80
81 private:
82  // |render_view| and |frame| are weak pointers. If either one is going away,
83  // our |plugin_| will be destroyed as well and will notify us.
84  PluginPlaceholder(content::RenderView* render_view,
85                    WebKit::WebFrame* frame,
86                    const WebKit::WebPluginParams& params,
87                    const std::string& html_data,
88                    const string16& title);
89
90  virtual ~PluginPlaceholder();
91
92  // WebViewPlugin::Delegate methods:
93  virtual void BindWebFrame(WebKit::WebFrame* frame) OVERRIDE;
94  virtual void WillDestroyPlugin() OVERRIDE;
95  virtual void ShowContextMenu(const WebKit::WebMouseEvent&) OVERRIDE;
96
97  // content::RenderViewObserver methods:
98  virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
99
100  // content::RenderProcessObserver methods:
101  virtual void PluginListChanged() OVERRIDE;
102
103  // content::ContextMenuClient methods:
104  virtual void OnMenuAction(int request_id, unsigned action) OVERRIDE;
105  virtual void OnMenuClosed(int request_id) OVERRIDE;
106
107  // Replace this placeholder with a different plugin (which could be
108  // a placeholder again).
109  void ReplacePlugin(WebKit::WebPlugin* new_plugin);
110
111  // Hide this placeholder.
112  void HidePlugin();
113
114  // Load the blocked plugin.
115  void LoadPlugin();
116
117  // Javascript callbacks:
118  // Load the blocked plugin by calling LoadPlugin().
119  // Takes no arguments, and returns nothing.
120  void LoadCallback(const webkit_glue::CppArgumentList& args,
121                    webkit_glue::CppVariant* result);
122
123  // Hide the blocked plugin by calling HidePlugin().
124  // Takes no arguments, and returns nothing.
125  void HideCallback(const webkit_glue::CppArgumentList& args,
126                    webkit_glue::CppVariant* result);
127
128  // Opens chrome://plugins in a new tab.
129  // Takes no arguments, and returns nothing.
130  void OpenAboutPluginsCallback(const webkit_glue::CppArgumentList& args,
131                                webkit_glue::CppVariant* result);
132
133  void DidFinishLoadingCallback(const webkit_glue::CppArgumentList& args,
134                                webkit_glue::CppVariant* result);
135
136  void OnLoadBlockedPlugins(const std::string& identifier);
137  void OnSetIsPrerendering(bool is_prerendering);
138#if defined(ENABLE_PLUGIN_INSTALLATION)
139  void OnDidNotFindMissingPlugin();
140  void OnFoundMissingPlugin(const string16& plugin_name);
141  void OnStartedDownloadingPlugin();
142  void OnFinishedDownloadingPlugin();
143  void OnErrorDownloadingPlugin(const std::string& error);
144  void OnCancelledDownloadingPlugin();
145#endif
146
147#if defined(ENABLE_MOBILE_YOUTUBE_PLUGIN)
148 // Check whether the url is valid.
149  static bool IsValidYouTubeVideo(const std::string& path);
150
151  // Opens a youtube app in the current tab.
152  void OpenYoutubeUrlCallback(const webkit_glue::CppArgumentList& args,
153                              webkit_glue::CppVariant* result);
154#endif
155
156  void SetMessage(const string16& message);
157  void UpdateMessage();
158
159  WebKit::WebFrame* frame_;
160  WebKit::WebPluginParams plugin_params_;
161  WebViewPlugin* plugin_;
162
163  content::WebPluginInfo plugin_info_;
164
165  string16 title_;
166  string16 message_;
167
168  // We use a scoped_ptr so we can forward-declare the struct; it's defined in
169  // an IPC message file which can't be easily included in other header files.
170  scoped_ptr<ChromeViewHostMsg_GetPluginInfo_Status> status_;
171
172  // True iff the plugin was blocked because the page was being prerendered.
173  // Plugin will automatically be loaded when the page is displayed.
174  bool is_blocked_for_prerendering_;
175  bool allow_loading_;
176
177#if defined(ENABLE_PLUGIN_INSTALLATION)
178  // |routing_id()| is the routing ID of our associated RenderView, but we have
179  // a separate routing ID for messages specific to this placeholder.
180  int32 placeholder_routing_id_;
181#endif
182
183  bool hidden_;
184  bool has_host_;
185  bool finished_loading_;
186  string16 plugin_name_;
187  std::string identifier_;
188  int context_menu_request_id_;  // Nonzero when request pending.
189
190  DISALLOW_COPY_AND_ASSIGN(PluginPlaceholder);
191};
192
193#endif  // CHROME_RENDERER_PLUGINS_PLUGIN_PLACEHOLDER_H_
194