OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2011 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 "webkit/plugins/ppapi/ppapi_plugin_list.h" |
| 6 |
| 7 #include "base/command_line.h" |
| 8 #include "base/file_util.h" |
| 9 #include "base/native_library.h" |
| 10 #include "base/string_split.h" |
| 11 #include "base/utf_string_conversions.h" |
| 12 #include "webkit/plugins/plugin_switches.h" |
| 13 |
| 14 namespace webkit { |
| 15 namespace ppapi { |
| 16 |
| 17 void PluginList::LoadModules() { |
| 18 // Note that in each case, AddLiveModule must be called before completing |
| 19 // initialization. If we bail out (in the continue clauses) before saving |
| 20 // the initialized module, it will still try to unregister itself in its |
| 21 // destructor. |
| 22 for (size_t i = 0; i < plugin_list_.size(); i++) { |
| 23 const PluginInfo& current = plugin_list_[i]; |
| 24 if (current.is_out_of_process) |
| 25 continue; // Out of process plugins need no special pre-initialization. |
| 26 |
| 27 scoped_refptr<PluginModule> module = NULL; |
| 28 //new PluginModule(current.name, current.path, this); |
| 29 AddLiveModule(current.path, module); |
| 30 if (current.is_internal) { |
| 31 if (!module->InitAsInternalPlugin(current.internal_entry_points)) { |
| 32 DLOG(ERROR) << "Failed to load pepper module: " << current.path.value(); |
| 33 continue; |
| 34 } |
| 35 } else { |
| 36 // Preload all external plugins we're not running out of process. |
| 37 if (!module->InitAsLibrary(current.path)) { |
| 38 DLOG(ERROR) << "Failed to load pepper module: " << current.path.value(); |
| 39 continue; |
| 40 } |
| 41 } |
| 42 preloaded_modules_[current.path] = module; |
| 43 } |
| 44 } |
| 45 |
| 46 void PluginList::PreloadModules() { |
| 47 for (size_t i = 0; i < plugin_list_.size(); ++i) { |
| 48 if (!plugin_list_[i].is_internal) { |
| 49 std::string error; |
| 50 base::NativeLibrary library = base::LoadNativeLibrary( |
| 51 plugin_list_[i].path, &error); |
| 52 LOG_IF(WARNING, !library) << "Unable to load plugin " |
| 53 << plugin_list_[i].path.value() << " " |
| 54 << error; |
| 55 } |
| 56 } |
| 57 } |
| 58 |
| 59 const PluginInfo* PluginList::GetInfoForPlugin(const FilePath& plugin_path) { |
| 60 for (size_t i = 0; i < plugin_list_.size(); ++i) { |
| 61 if (plugin_path == plugin_list_[i].path) |
| 62 return &plugin_list_[i]; |
| 63 } |
| 64 // We did not find the plugin in our list. But wait! the plugin can also |
| 65 // be a latecomer, as it happens with pepper flash. This information |
| 66 // is actually in |info| and we can use it to construct it and add it to |
| 67 // the list. This same deal needs to be done in the browser side in |
| 68 // PluginService. |
| 69 /*PluginInfo plugin; |
| 70 if (!WebToPepperPluginInfo(info, &plugin)) |
| 71 return NULL; |
| 72 |
| 73 plugin_list_.push_back(plugin); |
| 74 return &plugin_list_[plugin_list_.size() - 1];*/ |
| 75 return NULL; |
| 76 } |
| 77 |
| 78 PluginModule* PluginList::GetLiveModule(const FilePath& path) { |
| 79 NonOwningModuleMap::iterator it = live_modules_.find(path); |
| 80 if (it == live_modules_.end()) |
| 81 return NULL; |
| 82 return it->second; |
| 83 } |
| 84 |
| 85 void PluginList::AddLiveModule(const FilePath& path, PluginModule* module) { |
| 86 DCHECK(live_modules_.find(path) == live_modules_.end()); |
| 87 live_modules_[path] = module; |
| 88 } |
| 89 |
| 90 void PluginList::PluginModuleDead(PluginModule* dead_module) { |
| 91 // DANGER: Don't dereference the dead_module pointer! It may be in the |
| 92 // process of being deleted. |
| 93 |
| 94 // Modules aren't destroyed very often and there are normally at most a |
| 95 // couple of them. So for now we just do a brute-force search. |
| 96 for (NonOwningModuleMap::iterator i = live_modules_.begin(); |
| 97 i != live_modules_.end(); ++i) { |
| 98 if (i->second == dead_module) { |
| 99 live_modules_.erase(i); |
| 100 return; |
| 101 } |
| 102 } |
| 103 NOTREACHED(); // Should have always found the module above. |
| 104 } |
| 105 |
| 106 PluginList::PluginList() { |
| 107 AddFromCommandLine(); |
| 108 } |
| 109 |
| 110 PluginList::~PluginList() { |
| 111 // Explicitly clear all preloaded modules first. This will cause callbacks |
| 112 // to erase these modules from the live_modules_ list, and we don't want |
| 113 // that to happen implicitly out-of-order. |
| 114 preloaded_modules_.clear(); |
| 115 |
| 116 DCHECK(live_modules_.empty()); |
| 117 } |
| 118 |
| 119 void PluginList::AddFromCommandLine() { |
| 120 bool out_of_process = |
| 121 CommandLine::ForCurrentProcess()->HasSwitch(switches::kPpapiOutOfProcess); |
| 122 const std::string value = |
| 123 CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
| 124 switches::kRegisterPepperPlugins); |
| 125 if (value.empty()) |
| 126 return; |
| 127 |
| 128 // FORMAT: |
| 129 // command-line = <plugin-entry> + *( LWS + "," + LWS + <plugin-entry> ) |
| 130 // plugin-entry = |
| 131 // <file-path> + |
| 132 // ["#" + <name> + ["#" + <description> + ["#" + <version>]]] + |
| 133 // *1( LWS + ";" + LWS + <mime-type> ) |
| 134 std::vector<std::string> modules; |
| 135 base::SplitString(value, ',', &modules); |
| 136 for (size_t i = 0; i < modules.size(); ++i) { |
| 137 std::vector<std::string> parts; |
| 138 base::SplitString(modules[i], ';', &parts); |
| 139 if (parts.size() < 2) { |
| 140 DLOG(ERROR) << "Required mime-type not found"; |
| 141 continue; |
| 142 } |
| 143 |
| 144 std::vector<std::string> name_parts; |
| 145 base::SplitString(parts[0], '#', &name_parts); |
| 146 |
| 147 PluginInfo plugin; |
| 148 plugin.is_out_of_process = out_of_process; |
| 149 #if defined(OS_WIN) |
| 150 // This means we can't provide plugins from non-ASCII paths, but |
| 151 // since this switch is only for development I don't think that's |
| 152 // too awful. |
| 153 plugin.path = FilePath(ASCIIToUTF16(name_parts[0])); |
| 154 #else |
| 155 plugin.path = FilePath(name_parts[0]); |
| 156 #endif |
| 157 if (name_parts.size() > 1) |
| 158 plugin.name = name_parts[1]; |
| 159 if (name_parts.size() > 2) |
| 160 plugin.description = name_parts[2]; |
| 161 if (name_parts.size() > 3) |
| 162 plugin.version = name_parts[3]; |
| 163 for (size_t j = 1; j < parts.size(); ++j) { |
| 164 webkit::WebPluginMimeType mime_type(parts[j], |
| 165 std::string(), |
| 166 plugin.description); |
| 167 plugin.mime_types.push_back(mime_type); |
| 168 } |
| 169 |
| 170 plugin_list_.push_back(plugin); |
| 171 } |
| 172 } |
| 173 |
| 174 } // namespace ppapi |
| 175 } // namespace webkit |
OLD | NEW |