Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(394)

Side by Side Diff: chrome/browser/plugin_service.cc

Issue 24017: More refactoring of PluginProcessHost (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/plugin_service.h" 5 #include "chrome/browser/plugin_service.h"
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/singleton.h"
9 #include "base/thread.h" 8 #include "base/thread.h"
10 #include "chrome/browser/browser_process.h" 9 #include "chrome/browser/browser_process.h"
11 #include "chrome/browser/chrome_plugin_host.h" 10 #include "chrome/browser/chrome_plugin_host.h"
12 #include "chrome/browser/chrome_thread.h" 11 #include "chrome/browser/chrome_thread.h"
13 #include "chrome/browser/plugin_process_host.h" 12 #include "chrome/browser/plugin_process_host.h"
14 #include "chrome/browser/renderer_host/render_process_host.h" 13 #include "chrome/browser/renderer_host/render_process_host.h"
15 #include "chrome/browser/renderer_host/resource_message_filter.h" 14 #include "chrome/browser/renderer_host/resource_message_filter.h"
16 #include "chrome/common/chrome_plugin_lib.h" 15 #include "chrome/common/chrome_plugin_lib.h"
17 #include "chrome/common/chrome_switches.h" 16 #include "chrome/common/chrome_switches.h"
18 #include "chrome/common/logging_chrome.h" 17 #include "chrome/common/logging_chrome.h"
19 #include "webkit/glue/plugins/plugin_list.h" 18 #include "webkit/glue/plugins/plugin_list.h"
20 19
21 // static 20 // static
22 PluginService* PluginService::GetInstance() { 21 PluginService* PluginService::GetInstance() {
23 return Singleton<PluginService>::get(); 22 return Singleton<PluginService>::get();
24 } 23 }
25 24
26 PluginService::PluginService() 25 PluginService::PluginService()
27 : main_message_loop_(MessageLoop::current()), 26 : main_message_loop_(MessageLoop::current()),
28 resource_dispatcher_host_(NULL), 27 resource_dispatcher_host_(NULL),
29 ui_locale_(g_browser_process->GetApplicationLocale()), 28 ui_locale_(g_browser_process->GetApplicationLocale()),
30 plugin_shutdown_handler_(new ShutdownHandler) { 29 plugin_shutdown_handler_(new ShutdownHandler) {
31 // Have the NPAPI plugin list search for Chrome plugins as well. 30 // Have the NPAPI plugin list search for Chrome plugins as well.
32 ChromePluginLib::RegisterPluginsWithNPAPI(); 31 ChromePluginLib::RegisterPluginsWithNPAPI();
33
34 // Load the one specified on the command line as well. 32 // Load the one specified on the command line as well.
35 const CommandLine* command_line = CommandLine::ForCurrentProcess(); 33 const CommandLine* command_line = CommandLine::ForCurrentProcess();
36 std::wstring path = command_line->GetSwitchValue(switches::kLoadPlugin); 34 std::wstring path = command_line->GetSwitchValue(switches::kLoadPlugin);
37 if (!path.empty()) 35 if (!path.empty())
38 NPAPI::PluginList::AddExtraPluginPath(FilePath::FromWStringHack(path)); 36 NPAPI::PluginList::AddExtraPluginPath(FilePath::FromWStringHack(path));
39 } 37 }
40 38
41 PluginService::~PluginService() { 39 PluginService::~PluginService() {
42 } 40 }
43 41
(...skipping 26 matching lines...) Expand all
70 PluginProcessHost* PluginService::FindPluginProcess( 68 PluginProcessHost* PluginService::FindPluginProcess(
71 const FilePath& plugin_path) { 69 const FilePath& plugin_path) {
72 DCHECK(MessageLoop::current() == 70 DCHECK(MessageLoop::current() ==
73 ChromeThread::GetMessageLoop(ChromeThread::IO)); 71 ChromeThread::GetMessageLoop(ChromeThread::IO));
74 72
75 if (plugin_path.value().empty()) { 73 if (plugin_path.value().empty()) {
76 NOTREACHED() << "should only be called if we have a plugin to load"; 74 NOTREACHED() << "should only be called if we have a plugin to load";
77 return NULL; 75 return NULL;
78 } 76 }
79 77
80 PluginMap::iterator found = plugin_hosts_.find(plugin_path); 78 for (ChildProcessInfo::Iterator iter(ChildProcessInfo::PLUGIN_PROCESS);
81 if (found != plugin_hosts_.end()) 79 !iter.Done(); ++iter) {
82 return found->second; 80 PluginProcessHost* plugin = static_cast<PluginProcessHost*>(*iter);
81 if (plugin->info().path == plugin_path)
82 return plugin;
83 }
84
83 return NULL; 85 return NULL;
84 } 86 }
85 87
86 PluginProcessHost* PluginService::FindOrStartPluginProcess( 88 PluginProcessHost* PluginService::FindOrStartPluginProcess(
87 const FilePath& plugin_path, 89 const FilePath& plugin_path,
88 const std::string& clsid) { 90 const std::string& clsid) {
89 DCHECK(MessageLoop::current() == 91 DCHECK(MessageLoop::current() ==
90 ChromeThread::GetMessageLoop(ChromeThread::IO)); 92 ChromeThread::GetMessageLoop(ChromeThread::IO));
91 93
92 PluginProcessHost *plugin_host = FindPluginProcess(plugin_path); 94 PluginProcessHost *plugin_host = FindPluginProcess(plugin_path);
93 if (plugin_host) 95 if (plugin_host)
94 return plugin_host; 96 return plugin_host;
95 97
96 WebPluginInfo info; 98 WebPluginInfo info;
97 if (!GetPluginInfoByPath(plugin_path, &info)) { 99 if (!GetPluginInfoByPath(plugin_path, &info)) {
98 DCHECK(false); 100 DCHECK(false);
99 return NULL; 101 return NULL;
100 } 102 }
101 103
102 // This plugin isn't loaded by any plugin process, so create a new process. 104 // This plugin isn't loaded by any plugin process, so create a new process.
103 plugin_host = new PluginProcessHost(this); 105 plugin_host = new PluginProcessHost();
104 if (!plugin_host->Init(info, clsid, ui_locale_)) { 106 if (!plugin_host->Init(info, clsid, ui_locale_)) {
105 DCHECK(false); // Init is not expected to fail 107 DCHECK(false); // Init is not expected to fail
106 delete plugin_host; 108 delete plugin_host;
107 return NULL; 109 return NULL;
108 } 110 }
109 plugin_hosts_[plugin_path] = plugin_host; 111
110 return plugin_host; 112 return plugin_host;
111 113
112 // TODO(jabdelmalek): adding a new channel means we can have one less 114 // TODO(jabdelmalek): adding a new channel means we can have one less
113 // renderer process (since each child process uses one handle in the 115 // renderer process (since each child process uses one handle in the
114 // IPC thread and main thread's WaitForMultipleObjects call). Limit the 116 // IPC thread and main thread's WaitForMultipleObjects call). Limit the
115 // number of plugin processes. 117 // number of plugin processes.
116 } 118 }
117 119
118 void PluginService::OpenChannelToPlugin( 120 void PluginService::OpenChannelToPlugin(
119 ResourceMessageFilter* renderer_msg_filter, const GURL& url, 121 ResourceMessageFilter* renderer_msg_filter, const GURL& url,
120 const std::string& mime_type, const std::string& clsid, 122 const std::string& mime_type, const std::string& clsid,
121 const std::wstring& locale, IPC::Message* reply_msg) { 123 const std::wstring& locale, IPC::Message* reply_msg) {
122 DCHECK(MessageLoop::current() == 124 DCHECK(MessageLoop::current() ==
123 ChromeThread::GetMessageLoop(ChromeThread::IO)); 125 ChromeThread::GetMessageLoop(ChromeThread::IO));
124 FilePath plugin_path = GetPluginPath(url, mime_type, clsid, NULL); 126 FilePath plugin_path = GetPluginPath(url, mime_type, clsid, NULL);
125 PluginProcessHost* plugin_host = FindOrStartPluginProcess(plugin_path, clsid); 127 PluginProcessHost* plugin_host = FindOrStartPluginProcess(plugin_path, clsid);
126 if (plugin_host) { 128 if (plugin_host) {
127 plugin_host->OpenChannelToPlugin(renderer_msg_filter, mime_type, reply_msg); 129 plugin_host->OpenChannelToPlugin(renderer_msg_filter, mime_type, reply_msg);
128 } else { 130 } else {
129 PluginProcessHost::ReplyToRenderer(renderer_msg_filter, 131 PluginProcessHost::ReplyToRenderer(renderer_msg_filter,
130 std::wstring(), 132 std::wstring(),
131 FilePath(), 133 FilePath(),
132 reply_msg); 134 reply_msg);
133 } 135 }
134 } 136 }
135 137
136 void PluginService::OnPluginProcessIsShuttingDown(PluginProcessHost* host) {
137 RemoveHost(host);
138 }
139
140 void PluginService::OnPluginProcessExited(PluginProcessHost* host) {
141 RemoveHost(host); // in case shutdown was not graceful
142 delete host;
143 }
144
145 void PluginService::RemoveHost(PluginProcessHost* host) {
146 DCHECK(MessageLoop::current() ==
147 ChromeThread::GetMessageLoop(ChromeThread::IO));
148 // Search for the instance rather than lookup by plugin path,
149 // there is a small window where two instances for the same
150 // plugin path can co-exists.
151 PluginMap::iterator i = plugin_hosts_.begin();
152 while (i != plugin_hosts_.end()) {
153 if (i->second == host) {
154 plugin_hosts_.erase(i);
155 return;
156 }
157 i++;
158 }
159 }
160
161 FilePath PluginService::GetPluginPath(const GURL& url, 138 FilePath PluginService::GetPluginPath(const GURL& url,
162 const std::string& mime_type, 139 const std::string& mime_type,
163 const std::string& clsid, 140 const std::string& clsid,
164 std::string* actual_mime_type) { 141 std::string* actual_mime_type) {
165 AutoLock lock(lock_); 142 AutoLock lock(lock_);
166 bool allow_wildcard = true; 143 bool allow_wildcard = true;
167 WebPluginInfo info; 144 WebPluginInfo info;
168 NPAPI::PluginList::Singleton()->GetPluginInfo(url, mime_type, clsid, 145 NPAPI::PluginList::Singleton()->GetPluginInfo(url, mime_type, clsid,
169 allow_wildcard, &info, 146 allow_wildcard, &info,
170 actual_mime_type); 147 actual_mime_type);
(...skipping 15 matching lines...) Expand all
186 return NPAPI::PluginList::Singleton()->GetPluginInfo(url, mime_type, "", 163 return NPAPI::PluginList::Singleton()->GetPluginInfo(url, mime_type, "",
187 allow_wildcard, &info, 164 allow_wildcard, &info,
188 NULL); 165 NULL);
189 } 166 }
190 167
191 void PluginService::Shutdown() { 168 void PluginService::Shutdown() {
192 plugin_shutdown_handler_->InitiateShutdown(); 169 plugin_shutdown_handler_->InitiateShutdown();
193 } 170 }
194 171
195 void PluginService::OnShutdown() { 172 void PluginService::OnShutdown() {
196 PluginMap::iterator host_index; 173 for (ChildProcessInfo::Iterator iter(ChildProcessInfo::PLUGIN_PROCESS);
197 for (host_index = plugin_hosts_.begin(); host_index != plugin_hosts_.end(); 174 !iter.Done(); ++iter) {
198 ++host_index) { 175 static_cast<PluginProcessHost*>(*iter)->Shutdown();
199 host_index->second->Shutdown();
200 } 176 }
201 } 177 }
202 178
203 PluginProcessHostIterator::PluginProcessHostIterator()
204 : iterator_(PluginService::GetInstance()->plugin_hosts_.begin()),
205 end_(PluginService::GetInstance()->plugin_hosts_.end()) {
206 DCHECK(MessageLoop::current() ==
207 ChromeThread::GetMessageLoop(ChromeThread::IO)) <<
208 "PluginProcessHostIterator must be used on the IO thread.";
209 }
210
211 PluginProcessHostIterator::PluginProcessHostIterator(
212 const PluginProcessHostIterator& instance)
213 : iterator_(instance.iterator_) {
214 DCHECK(MessageLoop::current() ==
215 ChromeThread::GetMessageLoop(ChromeThread::IO)) <<
216 "PluginProcessHostIterator must be used on the IO thread.";
217 }
218
219 void PluginService::ShutdownHandler::InitiateShutdown() { 179 void PluginService::ShutdownHandler::InitiateShutdown() {
220 g_browser_process->io_thread()->message_loop()->PostTask( 180 g_browser_process->io_thread()->message_loop()->PostTask(
221 FROM_HERE, 181 FROM_HERE,
222 NewRunnableMethod(this, &ShutdownHandler::OnShutdown)); 182 NewRunnableMethod(this, &ShutdownHandler::OnShutdown));
223 } 183 }
224 184
225 void PluginService::ShutdownHandler::OnShutdown() { 185 void PluginService::ShutdownHandler::OnShutdown() {
226 PluginService* plugin_service = PluginService::GetInstance(); 186 PluginService* plugin_service = PluginService::GetInstance();
227 if (plugin_service) { 187 if (plugin_service) {
228 plugin_service->OnShutdown(); 188 plugin_service->OnShutdown();
229 } 189 }
230 } 190 }
231 191
OLDNEW
« no previous file with comments | « chrome/browser/plugin_service.h ('k') | chrome/browser/renderer_host/browser_render_process_host.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698