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

Side by Side Diff: content/ppapi_plugin/ppapi_thread.cc

Issue 13548005: Add UMA reporting on failure to load ppapi plugins. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: comment resolved Created 7 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 | Annotate | Revision Log
« no previous file with comments | « content/ppapi_plugin/ppapi_thread.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 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 "content/ppapi_plugin/ppapi_thread.h" 5 #include "content/ppapi_plugin/ppapi_thread.h"
6 6
7 #include <limits> 7 #include <limits>
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/debug/crash_logging.h" 10 #include "base/debug/crash_logging.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/metrics/histogram.h"
12 #include "base/process_util.h" 13 #include "base/process_util.h"
13 #include "base/rand_util.h" 14 #include "base/rand_util.h"
14 #include "base/stringprintf.h" 15 #include "base/stringprintf.h"
15 #include "base/threading/platform_thread.h" 16 #include "base/threading/platform_thread.h"
16 #include "base/time.h" 17 #include "base/time.h"
17 #include "base/utf_string_conversions.h" 18 #include "base/utf_string_conversions.h"
18 #include "content/common/child_process.h" 19 #include "content/common/child_process.h"
19 #include "content/common/child_process_messages.h" 20 #include "content/common/child_process_messages.h"
20 #include "content/common/sandbox_util.h" 21 #include "content/common/sandbox_util.h"
21 #include "content/ppapi_plugin/broker_process_dispatcher.h" 22 #include "content/ppapi_plugin/broker_process_dispatcher.h"
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
252 253
253 // If the plugin isn't internal then load it from |path|. 254 // If the plugin isn't internal then load it from |path|.
254 base::ScopedNativeLibrary library; 255 base::ScopedNativeLibrary library;
255 if (plugin_entry_points_.initialize_module == NULL) { 256 if (plugin_entry_points_.initialize_module == NULL) {
256 // Load the plugin from the specified library. 257 // Load the plugin from the specified library.
257 std::string error; 258 std::string error;
258 library.Reset(base::LoadNativeLibrary(path, &error)); 259 library.Reset(base::LoadNativeLibrary(path, &error));
259 if (!library.is_valid()) { 260 if (!library.is_valid()) {
260 LOG(ERROR) << "Failed to load Pepper module from " 261 LOG(ERROR) << "Failed to load Pepper module from "
261 << path.value() << " (error: " << error << ")"; 262 << path.value() << " (error: " << error << ")";
263 ReportLoadResult(path, LOAD_FAILED);
262 return; 264 return;
263 } 265 }
264 266
265 // Get the GetInterface function (required). 267 // Get the GetInterface function (required).
266 plugin_entry_points_.get_interface = 268 plugin_entry_points_.get_interface =
267 reinterpret_cast<PP_GetInterface_Func>( 269 reinterpret_cast<PP_GetInterface_Func>(
268 library.GetFunctionPointer("PPP_GetInterface")); 270 library.GetFunctionPointer("PPP_GetInterface"));
269 if (!plugin_entry_points_.get_interface) { 271 if (!plugin_entry_points_.get_interface) {
270 LOG(WARNING) << "No PPP_GetInterface in plugin library"; 272 LOG(WARNING) << "No PPP_GetInterface in plugin library";
273 ReportLoadResult(path, ENTRY_POINT_MISSING);
271 return; 274 return;
272 } 275 }
273 276
274 // The ShutdownModule/ShutdownBroker function is optional. 277 // The ShutdownModule/ShutdownBroker function is optional.
275 plugin_entry_points_.shutdown_module = 278 plugin_entry_points_.shutdown_module =
276 is_broker_ ? 279 is_broker_ ?
277 reinterpret_cast<PP_ShutdownModule_Func>( 280 reinterpret_cast<PP_ShutdownModule_Func>(
278 library.GetFunctionPointer("PPP_ShutdownBroker")) : 281 library.GetFunctionPointer("PPP_ShutdownBroker")) :
279 reinterpret_cast<PP_ShutdownModule_Func>( 282 reinterpret_cast<PP_ShutdownModule_Func>(
280 library.GetFunctionPointer("PPP_ShutdownModule")); 283 library.GetFunctionPointer("PPP_ShutdownModule"));
281 284
282 if (!is_broker_) { 285 if (!is_broker_) {
283 // Get the InitializeModule function (required for non-broker code). 286 // Get the InitializeModule function (required for non-broker code).
284 plugin_entry_points_.initialize_module = 287 plugin_entry_points_.initialize_module =
285 reinterpret_cast<PP_InitializeModule_Func>( 288 reinterpret_cast<PP_InitializeModule_Func>(
286 library.GetFunctionPointer("PPP_InitializeModule")); 289 library.GetFunctionPointer("PPP_InitializeModule"));
287 if (!plugin_entry_points_.initialize_module) { 290 if (!plugin_entry_points_.initialize_module) {
288 LOG(WARNING) << "No PPP_InitializeModule in plugin library"; 291 LOG(WARNING) << "No PPP_InitializeModule in plugin library";
292 ReportLoadResult(path, ENTRY_POINT_MISSING);
289 return; 293 return;
290 } 294 }
291 } 295 }
292 } 296 }
293 297
294 #if defined(OS_WIN) 298 #if defined(OS_WIN)
295 // If code subsequently tries to exit using abort(), force a crash (since 299 // If code subsequently tries to exit using abort(), force a crash (since
296 // otherwise these would be silent terminations and fly under the radar). 300 // otherwise these would be silent terminations and fly under the radar).
297 base::win::SetAbortBehaviorForCrashReporting(); 301 base::win::SetAbortBehaviorForCrashReporting();
298 if (permissions.HasPermission(ppapi::PERMISSION_FLASH)) { 302 if (permissions.HasPermission(ppapi::PERMISSION_FLASH)) {
(...skipping 17 matching lines...) Expand all
316 } 320 }
317 #endif 321 #endif
318 322
319 if (is_broker_) { 323 if (is_broker_) {
320 // Get the InitializeBroker function (required). 324 // Get the InitializeBroker function (required).
321 InitializeBrokerFunc init_broker = 325 InitializeBrokerFunc init_broker =
322 reinterpret_cast<InitializeBrokerFunc>( 326 reinterpret_cast<InitializeBrokerFunc>(
323 library.GetFunctionPointer("PPP_InitializeBroker")); 327 library.GetFunctionPointer("PPP_InitializeBroker"));
324 if (!init_broker) { 328 if (!init_broker) {
325 LOG(WARNING) << "No PPP_InitializeBroker in plugin library"; 329 LOG(WARNING) << "No PPP_InitializeBroker in plugin library";
330 ReportLoadResult(path, ENTRY_POINT_MISSING);
326 return; 331 return;
327 } 332 }
328 333
329 int32_t init_error = init_broker(&connect_instance_func_); 334 int32_t init_error = init_broker(&connect_instance_func_);
330 if (init_error != PP_OK) { 335 if (init_error != PP_OK) {
331 LOG(WARNING) << "InitBroker failed with error " << init_error; 336 LOG(WARNING) << "InitBroker failed with error " << init_error;
337 ReportLoadResult(path, INIT_FAILED);
332 return; 338 return;
333 } 339 }
334 if (!connect_instance_func_) { 340 if (!connect_instance_func_) {
335 LOG(WARNING) << "InitBroker did not provide PP_ConnectInstance_Func"; 341 LOG(WARNING) << "InitBroker did not provide PP_ConnectInstance_Func";
342 ReportLoadResult(path, INIT_FAILED);
336 return; 343 return;
337 } 344 }
338 } else { 345 } else {
339 #if defined(OS_MACOSX) 346 #if defined(OS_MACOSX)
340 // We need to do this after getting |PPP_GetInterface()| (or presumably 347 // We need to do this after getting |PPP_GetInterface()| (or presumably
341 // doing something nontrivial with the library), else the sandbox 348 // doing something nontrivial with the library), else the sandbox
342 // intercedes. 349 // intercedes.
343 CHECK(InitializeSandbox()); 350 CHECK(InitializeSandbox());
344 #endif 351 #endif
345 352
346 int32_t init_error = plugin_entry_points_.initialize_module( 353 int32_t init_error = plugin_entry_points_.initialize_module(
347 local_pp_module_, 354 local_pp_module_,
348 &ppapi::proxy::PluginDispatcher::GetBrowserInterface); 355 &ppapi::proxy::PluginDispatcher::GetBrowserInterface);
349 if (init_error != PP_OK) { 356 if (init_error != PP_OK) {
350 LOG(WARNING) << "InitModule failed with error " << init_error; 357 LOG(WARNING) << "InitModule failed with error " << init_error;
358 ReportLoadResult(path, INIT_FAILED);
351 return; 359 return;
352 } 360 }
353 } 361 }
354 362
363 ReportLoadResult(path, LOAD_SUCCESS);
ddorwin 2013/04/15 20:54:50 nit: I meant this should probably be the last line
xhwang 2013/04/15 20:56:46 Done.
364
355 // Initialization succeeded, so keep the plugin DLL loaded. 365 // Initialization succeeded, so keep the plugin DLL loaded.
356 library_.Reset(library.Release()); 366 library_.Reset(library.Release());
357 } 367 }
358 368
359 void PpapiThread::OnCreateChannel(base::ProcessId renderer_pid, 369 void PpapiThread::OnCreateChannel(base::ProcessId renderer_pid,
360 int renderer_child_id, 370 int renderer_child_id,
361 bool incognito) { 371 bool incognito) {
362 IPC::ChannelHandle channel_handle; 372 IPC::ChannelHandle channel_handle;
363 373
364 if (!plugin_entry_points_.get_interface || // Plugin couldn't be loaded. 374 if (!plugin_entry_points_.get_interface || // Plugin couldn't be loaded.
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
452 462
453 // From here, the dispatcher will manage its own lifetime according to the 463 // From here, the dispatcher will manage its own lifetime according to the
454 // lifetime of the attached channel. 464 // lifetime of the attached channel.
455 return true; 465 return true;
456 } 466 }
457 467
458 void PpapiThread::SavePluginName(const base::FilePath& path) { 468 void PpapiThread::SavePluginName(const base::FilePath& path) {
459 ppapi::proxy::PluginGlobals::Get()->set_plugin_name( 469 ppapi::proxy::PluginGlobals::Get()->set_plugin_name(
460 path.BaseName().AsUTF8Unsafe()); 470 path.BaseName().AsUTF8Unsafe());
461 471
462 // plugin() is NULL when in-process. Which is fine, because this is 472 // plugin() is NULL when in-process, which is fine, because this is
463 // just a hook for setting the process name. 473 // just a hook for setting the process name.
464 if (GetContentClient()->plugin()) { 474 if (GetContentClient()->plugin()) {
465 GetContentClient()->plugin()->PluginProcessStarted( 475 GetContentClient()->plugin()->PluginProcessStarted(
466 path.BaseName().RemoveExtension().LossyDisplayName()); 476 path.BaseName().RemoveExtension().LossyDisplayName());
467 } 477 }
468 } 478 }
469 479
480 void PpapiThread::ReportLoadResult(const base::FilePath& path,
481 LoadResult result) {
482 DCHECK_LT(result, LOAD_RESULT_MAX);
483
484 std::ostringstream histogram_name;
485 histogram_name << "Plugin.Ppapi" << (is_broker_ ? "Broker" : "Plugin")
486 << "LoadResult." << path.BaseName().MaybeAsASCII();
487
488 // Note: This leaks memory, which is expected behavior.
489 base::HistogramBase* histogram =
490 base::LinearHistogram::FactoryGet(
491 histogram_name.str(),
492 1,
493 LOAD_RESULT_MAX,
494 LOAD_RESULT_MAX + 1,
495 base::HistogramBase::kUmaTargetedHistogramFlag);
496
497 histogram->Add(result);
498 }
499
470 } // namespace content 500 } // namespace content
OLDNEW
« no previous file with comments | « content/ppapi_plugin/ppapi_thread.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698