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

Side by Side Diff: content/browser/plugin_loader_posix.cc

Issue 1862513003: Remove NPAPI from browser and utility (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 4 years, 8 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
« no previous file with comments | « content/browser/plugin_loader_posix.h ('k') | content/browser/plugin_loader_posix_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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 #include "content/browser/plugin_loader_posix.h"
6
7 #include "base/bind.h"
8 #include "base/location.h"
9 #include "base/metrics/histogram.h"
10 #include "base/single_thread_task_runner.h"
11 #include "base/thread_task_runner_handle.h"
12 #include "content/browser/utility_process_host_impl.h"
13 #include "content/common/child_process_host_impl.h"
14 #include "content/common/plugin_list.h"
15 #include "content/common/utility_messages.h"
16 #include "content/public/browser/browser_thread.h"
17 #include "content/public/browser/plugin_service.h"
18 #include "content/public/browser/user_metrics.h"
19
20 namespace content {
21
22 PluginLoaderPosix::PluginLoaderPosix()
23 : next_load_index_(0), loading_plugins_(false) {
24 }
25
26 void PluginLoaderPosix::GetPlugins(
27 const PluginService::GetPluginsCallback& callback) {
28 DCHECK_CURRENTLY_ON(BrowserThread::IO);
29
30 std::vector<WebPluginInfo> cached_plugins;
31 if (PluginList::Singleton()->GetPluginsNoRefresh(&cached_plugins)) {
32 // Can't assume the caller is reentrant.
33 base::ThreadTaskRunnerHandle::Get()->PostTask(
34 FROM_HERE, base::Bind(callback, cached_plugins));
35 return;
36 }
37
38 if (!loading_plugins_) {
39 loading_plugins_ = true;
40 callbacks_.push_back(callback);
41
42 // When |loading_plugins_| is set to false, this instance must call
43 // SetPlugins().
44 PluginList::Singleton()->PrepareForPluginLoading();
45
46 BrowserThread::PostTask(BrowserThread::FILE,
47 FROM_HERE,
48 base::Bind(&PluginLoaderPosix::GetPluginsToLoad,
49 make_scoped_refptr(this)));
50 } else {
51 // If we are currently loading plugins, the plugin list might have been
52 // invalidated in the mean time, or might get invalidated before we finish.
53 // We'll wait until we have finished the current run, then try to get them
54 // again from the plugin list. If it has indeed been invalidated, it will
55 // restart plugin loading, otherwise it will immediately run the callback.
56 callbacks_.push_back(base::Bind(&PluginLoaderPosix::GetPluginsWrapper,
57 make_scoped_refptr(this), callback));
58 }
59 }
60
61 bool PluginLoaderPosix::OnMessageReceived(const IPC::Message& message) {
62 bool handled = true;
63 IPC_BEGIN_MESSAGE_MAP(PluginLoaderPosix, message)
64 IPC_MESSAGE_HANDLER(UtilityHostMsg_LoadedPlugin, OnPluginLoaded)
65 IPC_MESSAGE_HANDLER(UtilityHostMsg_LoadPluginFailed, OnPluginLoadFailed)
66 IPC_MESSAGE_UNHANDLED(handled = false)
67 IPC_END_MESSAGE_MAP()
68 return handled;
69 }
70
71 void PluginLoaderPosix::OnProcessCrashed(int exit_code) {
72 RecordAction(
73 base::UserMetricsAction("PluginLoaderPosix.UtilityProcessCrashed"));
74
75 if (next_load_index_ == canonical_list_.size()) {
76 // How this case occurs is unknown. See crbug.com/111935.
77 canonical_list_.clear();
78 } else {
79 canonical_list_.erase(canonical_list_.begin(),
80 canonical_list_.begin() + next_load_index_ + 1);
81 }
82
83 next_load_index_ = 0;
84
85 LoadPluginsInternal();
86 }
87
88 void PluginLoaderPosix::OnProcessLaunchFailed() {
89 FinishedLoadingPlugins();
90 }
91
92 bool PluginLoaderPosix::Send(IPC::Message* message) {
93 if (process_host_.get())
94 return process_host_->Send(message);
95 return false;
96 }
97
98 PluginLoaderPosix::~PluginLoaderPosix() {
99 }
100
101 void PluginLoaderPosix::GetPluginsToLoad() {
102 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
103
104 base::TimeTicks start_time(base::TimeTicks::Now());
105
106 loaded_plugins_.clear();
107 next_load_index_ = 0;
108
109 canonical_list_.clear();
110 PluginList::Singleton()->GetPluginPathsToLoad(
111 &canonical_list_,
112 PluginService::GetInstance()->NPAPIPluginsSupported());
113
114 internal_plugins_.clear();
115 PluginList::Singleton()->GetInternalPlugins(&internal_plugins_);
116
117 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
118 base::Bind(&PluginLoaderPosix::LoadPluginsInternal,
119 make_scoped_refptr(this)));
120
121 LOCAL_HISTOGRAM_TIMES("PluginLoaderPosix.GetPluginList",
122 (base::TimeTicks::Now() - start_time) *
123 base::Time::kMicrosecondsPerMillisecond);
124 }
125
126 void PluginLoaderPosix::LoadPluginsInternal() {
127 DCHECK_CURRENTLY_ON(BrowserThread::IO);
128
129 // Check if the list is empty or all plugins have already been loaded before
130 // forking.
131 if (IsFinishedLoadingPlugins()) {
132 FinishedLoadingPlugins();
133 return;
134 }
135
136 RecordAction(
137 base::UserMetricsAction("PluginLoaderPosix.LaunchUtilityProcess"));
138
139 UtilityProcessHostImpl* host = new UtilityProcessHostImpl(
140 this,
141 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO).get());
142 process_host_ = host->AsWeakPtr();
143 process_host_->DisableSandbox();
144
145 bool launched = LaunchUtilityProcess();
146 if (!launched) {
147 // The utility process either failed to start or failed to receive the IPC.
148 // This process will never receive any callbacks for OnPluginLoaded() or
149 // OnPluginLoadFailed().
150 FinishedLoadingPlugins();
151 }
152 }
153
154 void PluginLoaderPosix::GetPluginsWrapper(
155 const PluginService::GetPluginsCallback& callback,
156 const std::vector<WebPluginInfo>& plugins_unused) {
157 // We are being called after plugin loading has finished, but we don't know
158 // whether the plugin list has been invalidated in the mean time
159 // (and therefore |plugins| might already be stale). So we simply ignore it
160 // and call regular GetPlugins() instead.
161 GetPlugins(callback);
162 }
163
164 void PluginLoaderPosix::OnPluginLoaded(uint32_t index,
165 const WebPluginInfo& plugin) {
166 if (index != next_load_index_) {
167 LOG(ERROR) << "Received unexpected plugin load message for "
168 << plugin.path.value() << "; index=" << index;
169 return;
170 }
171
172 auto it = FindInternalPlugin(plugin.path);
173 if (it != internal_plugins_.end()) {
174 loaded_plugins_.push_back(*it);
175 internal_plugins_.erase(it);
176 } else {
177 loaded_plugins_.push_back(plugin);
178 }
179
180 ++next_load_index_;
181
182 if (IsFinishedLoadingPlugins())
183 FinishedLoadingPlugins();
184 }
185
186 void PluginLoaderPosix::OnPluginLoadFailed(uint32_t index,
187 const base::FilePath& plugin_path) {
188 if (index != next_load_index_) {
189 LOG(ERROR) << "Received unexpected plugin load failure message for "
190 << plugin_path.value() << "; index=" << index;
191 return;
192 }
193
194 ++next_load_index_;
195
196 auto it = FindInternalPlugin(plugin_path);
197 if (it != internal_plugins_.end()) {
198 loaded_plugins_.push_back(*it);
199 internal_plugins_.erase(it);
200 }
201
202 if (IsFinishedLoadingPlugins())
203 FinishedLoadingPlugins();
204 }
205
206 std::vector<WebPluginInfo>::iterator PluginLoaderPosix::FindInternalPlugin(
207 const base::FilePath& plugin_path) {
208 return std::find_if(internal_plugins_.begin(), internal_plugins_.end(),
209 [&plugin_path](const WebPluginInfo& plugin) {
210 return plugin.path == plugin_path;
211 });
212 }
213
214 bool PluginLoaderPosix::IsFinishedLoadingPlugins() {
215 if (canonical_list_.empty())
216 return true;
217
218 DCHECK(next_load_index_ <= canonical_list_.size());
219 return next_load_index_ == canonical_list_.size();
220 }
221
222 void PluginLoaderPosix::FinishedLoadingPlugins() {
223 loading_plugins_ = false;
224 PluginList::Singleton()->SetPlugins(loaded_plugins_);
225
226 for (auto& callback : callbacks_) {
227 base::ThreadTaskRunnerHandle::Get()->PostTask(
228 FROM_HERE, base::Bind(callback, loaded_plugins_));
229 }
230 callbacks_.clear();
231 }
232
233 bool PluginLoaderPosix::LaunchUtilityProcess() {
234 return process_host_->Send(new UtilityMsg_LoadPlugins(canonical_list_));
235 }
236
237 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/plugin_loader_posix.h ('k') | content/browser/plugin_loader_posix_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698