1bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
3bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch// found in the LICENSE file.
4bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
5bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "content/common/pepper_plugin_list.h"
6bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
71e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/basictypes.h"
8bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "base/command_line.h"
91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h"
10bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "base/strings/string_split.h"
11bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "base/strings/string_util.h"
12bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "base/strings/utf_string_conversions.h"
13bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "content/public/common/content_client.h"
14bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "content/public/common/content_switches.h"
15bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "content/public/common/pepper_plugin_info.h"
16bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "ppapi/shared_impl/ppapi_permissions.h"
17bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
18bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochnamespace content {
19bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochnamespace {
20bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// The maximum number of plugins allowed to be registered from command line.
221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)const size_t kMaxPluginsToRegisterFromCommandLine = 64;
231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
24bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch// Appends any plugins from the command line to the given vector.
25bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochvoid ComputePluginsFromCommandLine(std::vector<PepperPluginInfo>* plugins) {
261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // On Linux, once we're sandboxed, we can't know if a plugin is available or
271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // not. But (on Linux) this function is always called once before we're
281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // sandboxed. So when this function is called for the first time we set a
291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // flag if the plugin file is available. Then we can skip the check on file
301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // existence in subsequent calls if the flag is set.
311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // NOTE: In theory we could have unlimited number of plugins registered in
321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // command line. But in practice, 64 plugins should be more than enough.
331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  static uint64 skip_file_check_flags = 0;
341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  COMPILE_ASSERT(
351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      kMaxPluginsToRegisterFromCommandLine <= sizeof(skip_file_check_flags) * 8,
361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      max_plugins_to_register_from_command_line_exceeds_limit);
371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
38bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  bool out_of_process = true;
396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          switches::kPpapiInProcess))
41bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    out_of_process = false;
42bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
43bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  const std::string value =
446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
45bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch          switches::kRegisterPepperPlugins);
46bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  if (value.empty())
47bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    return;
48bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
49bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  // FORMAT:
50bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  // command-line = <plugin-entry> + *( LWS + "," + LWS + <plugin-entry> )
51bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  // plugin-entry =
52bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  //    <file-path> +
53bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  //    ["#" + <name> + ["#" + <description> + ["#" + <version>]]] +
54bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  //    *1( LWS + ";" + LWS + <mime-type> )
55bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  std::vector<std::string> modules;
56bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  base::SplitString(value, ',', &modules);
571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  size_t plugins_to_register = modules.size();
591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (plugins_to_register > kMaxPluginsToRegisterFromCommandLine) {
60a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    VLOG(1) << plugins_to_register << " pepper plugins registered from"
611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        << " command line which exceeds the limit (maximum "
621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        << kMaxPluginsToRegisterFromCommandLine << " plugins allowed)";
631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    plugins_to_register = kMaxPluginsToRegisterFromCommandLine;
641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  for (size_t i = 0; i < plugins_to_register; ++i) {
67bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    std::vector<std::string> parts;
68bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    base::SplitString(modules[i], ';', &parts);
69bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    if (parts.size() < 2) {
70a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      VLOG(1) << "Required mime-type not found";
71bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch      continue;
72bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    }
73bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
74bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    std::vector<std::string> name_parts;
75bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    base::SplitString(parts[0], '#', &name_parts);
76bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
77bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    PepperPluginInfo plugin;
78bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    plugin.is_out_of_process = out_of_process;
79bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#if defined(OS_WIN)
80bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    // This means we can't provide plugins from non-ASCII paths, but
81bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    // since this switch is only for development I don't think that's
82bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    // too awful.
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    plugin.path = base::FilePath(base::ASCIIToUTF16(name_parts[0]));
84bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#else
85bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    plugin.path = base::FilePath(name_parts[0]);
86bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#endif
871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    uint64 index_mask = 1ULL << i;
891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (!(skip_file_check_flags & index_mask)) {
901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      if (base::PathExists(plugin.path)) {
911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        skip_file_check_flags |= index_mask;
921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      } else {
93a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        VLOG(1) << "Plugin doesn't exist: " << plugin.path.MaybeAsASCII();
941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        continue;
951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      }
961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    }
971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
98bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    if (name_parts.size() > 1)
99bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch      plugin.name = name_parts[1];
100bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    if (name_parts.size() > 2)
101bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch      plugin.description = name_parts[2];
102bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    if (name_parts.size() > 3)
103bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch      plugin.version = name_parts[3];
104bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    for (size_t j = 1; j < parts.size(); ++j) {
105bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch      WebPluginMimeType mime_type(parts[j],
106bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch                                  std::string(),
107bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch                                  plugin.description);
108bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch      plugin.mime_types.push_back(mime_type);
109bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    }
110bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
111bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    // If the plugin name is empty, use the filename.
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (plugin.name.empty()) {
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      plugin.name =
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          base::UTF16ToUTF8(plugin.path.BaseName().LossyDisplayName());
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
116bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
117bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    // Command-line plugins get full permissions.
118bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    plugin.permissions = ppapi::PERMISSION_ALL_BITS;
119bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
120bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    plugins->push_back(plugin);
121bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  }
122bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch}
123bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
124bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch}  // namespace
125bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
126bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochbool MakePepperPluginInfo(const WebPluginInfo& webplugin_info,
127bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch                          PepperPluginInfo* pepper_info) {
128bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  if (!webplugin_info.is_pepper_plugin())
129bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    return false;
130bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
131bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  pepper_info->is_out_of_process =
132bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch      webplugin_info.type == WebPluginInfo::PLUGIN_TYPE_PEPPER_OUT_OF_PROCESS ||
133bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch      webplugin_info.type == WebPluginInfo::PLUGIN_TYPE_PEPPER_UNSANDBOXED;
134bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  pepper_info->is_sandboxed = webplugin_info.type !=
135bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch      WebPluginInfo::PLUGIN_TYPE_PEPPER_UNSANDBOXED;
136bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
137bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  pepper_info->path = base::FilePath(webplugin_info.path);
138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  pepper_info->name = base::UTF16ToASCII(webplugin_info.name);
139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  pepper_info->description = base::UTF16ToASCII(webplugin_info.desc);
140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  pepper_info->version = base::UTF16ToASCII(webplugin_info.version);
141bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  pepper_info->mime_types = webplugin_info.mime_types;
142bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  pepper_info->permissions = webplugin_info.pepper_permissions;
143bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
144bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  return true;
145bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch}
146bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
147bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochvoid ComputePepperPluginList(std::vector<PepperPluginInfo>* plugins) {
148bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  GetContentClient()->AddPepperPlugins(plugins);
149bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  ComputePluginsFromCommandLine(plugins);
150bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch}
151bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
152bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch}  // namespace content
153