ppapi_thread.cc revision 23730a6e56a168d1879203e4b3819bb36e3d8f1f
14b95526e5c4eb4fecde1cd642cf991a82c51b9f2johannkoenig@chromium.org// Copyright (c) 2012 The Chromium Authors. All rights reserved.
24b95526e5c4eb4fecde1cd642cf991a82c51b9f2johannkoenig@chromium.org// Use of this source code is governed by a BSD-style license that can be
36fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org// found in the LICENSE file.
46fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
56fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include "content/ppapi_plugin/ppapi_thread.h"
66fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
76fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include <limits>
86fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
96fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include "base/command_line.h"
106fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include "base/cpu.h"
116fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include "base/debug/crash_logging.h"
126fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include "base/logging.h"
136fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include "base/metrics/histogram.h"
14d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org#include "base/rand_util.h"
1510a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org#include "base/strings/stringprintf.h"
1687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#include "base/strings/utf_string_conversions.h"
17d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org#include "base/threading/platform_thread.h"
186fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include "base/time/time.h"
196fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include "content/child/browser_font_resource_trusted.h"
206fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include "content/child/child_process.h"
216fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include "content/common/child_process_messages.h"
224b95526e5c4eb4fecde1cd642cf991a82c51b9f2johannkoenig@chromium.org#include "content/common/sandbox_util.h"
2377496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org#include "content/ppapi_plugin/broker_process_dispatcher.h"
24d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#include "content/ppapi_plugin/plugin_process_dispatcher.h"
256fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include "content/ppapi_plugin/ppapi_webkitplatformsupport_impl.h"
266fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include "content/public/common/content_client.h"
276fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include "content/public/common/content_switches.h"
2887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#include "content/public/common/pepper_plugin_info.h"
2987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#include "content/public/common/sandbox_init.h"
3087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#include "content/public/plugin/content_plugin_client.h"
3187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#include "ipc/ipc_channel_handle.h"
3287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#include "ipc/ipc_platform_file.h"
3387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#include "ipc/ipc_sync_channel.h"
3487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#include "ipc/ipc_sync_message_filter.h"
356fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include "ppapi/c/dev/ppp_network_state_dev.h"
3662346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org#include "ppapi/c/pp_errors.h"
3762346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org#include "ppapi/c/ppp.h"
3862346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org#include "ppapi/proxy/interface_list.h"
3962346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org#include "ppapi/proxy/plugin_globals.h"
4047265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org#include "ppapi/proxy/plugin_message_filter.h"
4162346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org#include "ppapi/proxy/ppapi_messages.h"
4262346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org#include "ppapi/proxy/resource_reply_thread_registrar.h"
4362346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org#include "third_party/WebKit/public/web/WebKit.h"
4462346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org#include "ui/base/ui_base_switches.h"
4547265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org
4662346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org#if defined(OS_WIN)
4762346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org#include "base/win/win_util.h"
4862346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org#include "base/win/windows_version.h"
4962346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org#include "sandbox/win/src/sandbox.h"
5047265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org#elif defined(OS_MACOSX)
5162346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org#include "content/common/sandbox_init_mac.h"
5262346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org#endif
5362346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org
5462346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org#if defined(OS_WIN)
5547265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.orgextern sandbox::TargetServices* g_target_services;
5662346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org
5762346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org// Used by EnumSystemLocales for warming up.
5862346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.orgstatic BOOL CALLBACK EnumLocalesProc(LPTSTR lpLocaleString) {
5962346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org  return TRUE;
6047265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org}
6162346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org
6262346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.orgstatic BOOL CALLBACK EnumLocalesProcEx(
6362346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org    LPWSTR lpLocaleString,
6462346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org    DWORD dwFlags,
6547265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org    LPARAM lParam) {
6662346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org  return TRUE;
6762346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org}
6862346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org
6947265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org// Warm up language subsystems before the sandbox is turned on.
7062346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.orgstatic void WarmupWindowsLocales(const ppapi::PpapiPermissions& permissions) {
7162346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org  ::GetUserDefaultLangID();
7262346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org  ::GetUserDefaultLCID();
7347265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org
7462346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org  if (permissions.HasPermission(ppapi::PERMISSION_FLASH)) {
7562346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org    if (base::win::GetVersion() >= base::win::VERSION_VISTA) {
7647265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org      typedef BOOL (WINAPI *PfnEnumSystemLocalesEx)
7762346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org          (LOCALE_ENUMPROCEX, DWORD, LPARAM, LPVOID);
7862346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org
7947265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org      HMODULE handle_kern32 = GetModuleHandleW(L"Kernel32.dll");
8062346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org      PfnEnumSystemLocalesEx enum_sys_locales_ex =
8162346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org          reinterpret_cast<PfnEnumSystemLocalesEx>
8247265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org              (GetProcAddress(handle_kern32, "EnumSystemLocalesEx"));
8353a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org
8447265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org      enum_sys_locales_ex(EnumLocalesProcEx, LOCALE_WINDOWS, 0, 0);
8547265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org    } else {
8662346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org      EnumSystemLocalesW(EnumLocalesProc, LCID_INSTALLED);
8762346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org    }
8847265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  }
8962346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org}
9062346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org#else
9147265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.orgextern void* g_target_services;
9262346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org#endif
9362346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org
9447265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.orgnamespace content {
9562346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org
9662346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.orgtypedef int32_t (*InitializeBrokerFunc)
9747265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org    (PP_ConnectInstance_Func* connect_instance_func);
9862346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org
9962346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.orgPpapiThread::PpapiThread(const CommandLine& command_line, bool is_broker)
10062346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org    : is_broker_(is_broker),
10147265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org      connect_instance_func_(NULL),
10262346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org      local_pp_module_(
10362346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org          base::RandInt(0, std::numeric_limits<PP_Module>::max())),
10447265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org      next_plugin_dispatcher_id_(1) {
10562346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org  ppapi::proxy::PluginGlobals* globals = ppapi::proxy::PluginGlobals::Get();
10662346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org  globals->set_plugin_proxy_delegate(this);
10762346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org  globals->set_command_line(
10847265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org      command_line.GetSwitchValueASCII(switches::kPpapiFlashArgs));
10962346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org
11062346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org  webkit_platform_support_.reset(new PpapiWebKitPlatformSupportImpl);
11162346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org  blink::initialize(webkit_platform_support_.get());
11247265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org
11353a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org  if (!is_broker_) {
1140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    channel()->AddFilter(
1150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        new ppapi::proxy::PluginMessageFilter(
11647265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org            NULL, globals->resource_reply_thread_registrar()));
11762346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org  }
11862346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org}
11962346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org
12062346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.orgPpapiThread::~PpapiThread() {
12162346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org}
12262346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org
12362346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.orgvoid PpapiThread::Shutdown() {
12462346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org  ppapi::proxy::PluginGlobals::Get()->set_plugin_proxy_delegate(NULL);
12562346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org  if (plugin_entry_points_.shutdown_module)
12662346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org    plugin_entry_points_.shutdown_module();
12762346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org  webkit_platform_support_->Shutdown();
12862346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org  blink::shutdown();
12953a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org}
1309c920af5cd2f78ab30bb06f01f4a4d9d30d5c92bfgalligan@chromium.org
1319c920af5cd2f78ab30bb06f01f4a4d9d30d5c92bfgalligan@chromium.orgbool PpapiThread::Send(IPC::Message* msg) {
13247265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  // Allow access from multiple threads.
13362346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org  if (base::MessageLoop::current() == message_loop())
13462346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org    return ChildThread::Send(msg);
13562346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org
13662346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org  return sync_message_filter()->Send(msg);
13762346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org}
13862346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org
13962346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org// Note that this function is called only for messages from the channel to the
14062346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org// browser process. Messages from the renderer process are sent via a different
14162346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org// channel that ends up at Dispatcher::OnMessageReceived.
14262346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.orgbool PpapiThread::OnControlMessageReceived(const IPC::Message& msg) {
14362346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org  bool handled = true;
14462346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org  IPC_BEGIN_MESSAGE_MAP(PpapiThread, msg)
14553a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org    IPC_MESSAGE_HANDLER(PpapiMsg_LoadPlugin, OnLoadPlugin)
1460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    IPC_MESSAGE_HANDLER(PpapiMsg_CreateChannel, OnCreateChannel)
1470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    IPC_MESSAGE_HANDLER(PpapiMsg_SetNetworkState, OnSetNetworkState)
14847265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org    IPC_MESSAGE_HANDLER(PpapiMsg_Crash, OnCrash)
14962346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org    IPC_MESSAGE_HANDLER(PpapiMsg_Hang, OnHang)
15062346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org    IPC_MESSAGE_UNHANDLED(handled = false)
15162346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org  IPC_END_MESSAGE_MAP()
15247265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  return handled;
15362346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org}
15462346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org
15562346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.orgvoid PpapiThread::OnChannelConnected(int32 peer_pid) {
15647265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  ChildThread::OnChannelConnected(peer_pid);
15762346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org#if defined(OS_WIN)
15862346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org  if (is_broker_)
15962346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org    peer_handle_.Set(::OpenProcess(PROCESS_DUP_HANDLE, FALSE, peer_pid));
16047265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org#endif
16162346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org}
16262346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org
16347265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.orgbase::MessageLoopProxy* PpapiThread::GetIPCMessageLoop() {
16462346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org  return ChildProcess::current()->io_message_loop_proxy();
16562346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org}
16647265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org
16762346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.orgbase::WaitableEvent* PpapiThread::GetShutdownEvent() {
16862346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org  return ChildProcess::current()->GetShutDownEvent();
16962346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org}
17062346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org
17162346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.orgIPC::PlatformFileForTransit PpapiThread::ShareHandleWithRemote(
17262346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org    base::PlatformFile handle,
17362346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org    base::ProcessId peer_pid,
17462346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org    bool should_close_source) {
17562346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org#if defined(OS_WIN)
17662346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org  if (peer_handle_.IsValid()) {
17762346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org    DCHECK(is_broker_);
17862346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org    return IPC::GetFileHandleForProcess(handle, peer_handle_,
17962346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org                                        should_close_source);
18062346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org  }
18162346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org#endif
18262346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org
18362346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org  DCHECK(peer_pid != base::kNullProcessId);
18447265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  return BrokerGetFileHandleForProcess(handle, peer_pid, should_close_source);
18553a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org}
1869c920af5cd2f78ab30bb06f01f4a4d9d30d5c92bfgalligan@chromium.org
1879c920af5cd2f78ab30bb06f01f4a4d9d30d5c92bfgalligan@chromium.orgstd::set<PP_Instance>* PpapiThread::GetGloballySeenInstanceIDSet() {
18847265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  return &globally_seen_instance_ids_;
18962346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org}
19062346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org
19162346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.orgIPC::Sender* PpapiThread::GetBrowserSender() {
19262346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org  return this;
19362346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org}
19462346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org
19562346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.orgstd::string PpapiThread::GetUILanguage() {
19662346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org  CommandLine* command_line = CommandLine::ForCurrentProcess();
19762346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org  return command_line->GetSwitchValueASCII(switches::kLang);
19862346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org}
19962346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org
20062346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.orgvoid PpapiThread::PreCacheFont(const void* logfontw) {
20153a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org#if defined(OS_WIN)
20247265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  Send(new ChildProcessHostMsg_PreCacheFont(
20347265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org      *static_cast<const LOGFONTW*>(logfontw)));
20462346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org#endif
20562346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org}
20647265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org
20762346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.orgvoid PpapiThread::SetActiveURL(const std::string& url) {
20862346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org  GetContentClient()->SetActiveURL(GURL(url));
20947265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org}
21062346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org
21162346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.orgPP_Resource PpapiThread::CreateBrowserFont(
21247265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org    ppapi::proxy::Connection connection,
21377496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org    PP_Instance instance,
21495aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com    const PP_BrowserFont_Trusted_Description& desc,
21547265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org    const ppapi::Preferences& prefs) {
21687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  if (!BrowserFontResource_Trusted::IsPPFontDescriptionValid(desc))
21787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    return 0;
21887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  return (new BrowserFontResource_Trusted(
21947265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org        connection, instance, desc, prefs))->GetReference();
22087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org}
22187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org
22287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orguint32 PpapiThread::Register(ppapi::proxy::PluginDispatcher* plugin_dispatcher) {
22388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  if (!plugin_dispatcher ||
22487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      plugin_dispatchers_.size() >= std::numeric_limits<uint32>::max()) {
22587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    return 0;
22687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  }
22747265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org
22887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  uint32 id = 0;
22987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  do {
23087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    // Although it is unlikely, make sure that we won't cause any trouble when
23188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    // the counter overflows.
23287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    id = next_plugin_dispatcher_id_++;
23387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  } while (id == 0 ||
23487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org           plugin_dispatchers_.find(id) != plugin_dispatchers_.end());
23547265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  plugin_dispatchers_[id] = plugin_dispatcher;
23687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  return id;
23787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org}
23887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org
23947265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.orgvoid PpapiThread::Unregister(uint32 plugin_dispatcher_id) {
24087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  plugin_dispatchers_.erase(plugin_dispatcher_id);
24187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org}
24287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org
24388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgvoid PpapiThread::OnLoadPlugin(const base::FilePath& path,
24487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                               const ppapi::PpapiPermissions& permissions) {
24587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  // In case of crashes, the crash dump doesn't indicate which plugin
24687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  // it came from.
24747265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  base::debug::SetCrashKeyValue("ppapi_path", path.MaybeAsASCII());
24887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org
24987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  SavePluginName(path);
25087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org
25188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  // This must be set before calling into the plugin so it can get the
25287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  // interfaces it has permission for.
25387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  ppapi::proxy::InterfaceList::SetProcessGlobalPermissions(permissions);
25487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  permissions_ = permissions;
25547265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org
25687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  // Trusted Pepper plugins may be "internal", i.e. built-in to the browser
25787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  // binary.  If we're being asked to load such a plugin (e.g. the Chromoting
25887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  // client) then fetch the entry points from the embedder, rather than a DLL.
25947265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  std::vector<PepperPluginInfo> plugins;
26087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  GetContentClient()->AddPepperPlugins(&plugins);
26187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  for (size_t i = 0; i < plugins.size(); ++i) {
26287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    if (plugins[i].is_internal && plugins[i].path == path) {
26347265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org      // An internal plugin is being loaded, so fetch the entry points.
26477496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org      plugin_entry_points_ = plugins[i].internal_entry_points;
26562346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org    }
26647265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  }
267693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com
268693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  // If the plugin isn't internal then load it from |path|.
269693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  base::ScopedNativeLibrary library;
270693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  if (plugin_entry_points_.initialize_module == NULL) {
27147265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org    // Load the plugin from the specified library.
27287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    std::string error;
27387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    library.Reset(base::LoadNativeLibrary(path, &error));
27487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    if (!library.is_valid()) {
2756fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      LOG(ERROR) << "Failed to load Pepper module from "
27688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org        << path.value() << " (error: " << error << ")";
27788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org      ReportLoadResult(path, LOAD_FAILED);
27888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org      return;
27988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    }
28088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org
28188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    // Get the GetInterface function (required).
28288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    plugin_entry_points_.get_interface =
28388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org        reinterpret_cast<PP_GetInterface_Func>(
28462346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org            library.GetFunctionPointer("PPP_GetInterface"));
28562346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org    if (!plugin_entry_points_.get_interface) {
28662346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org      LOG(WARNING) << "No PPP_GetInterface in plugin library";
28762346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org      ReportLoadResult(path, ENTRY_POINT_MISSING);
28862346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org      return;
28962346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org    }
29062346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org
29162346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org    // The ShutdownModule/ShutdownBroker function is optional.
29262346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org    plugin_entry_points_.shutdown_module =
29362346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org        is_broker_ ?
29462346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org        reinterpret_cast<PP_ShutdownModule_Func>(
29562346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org            library.GetFunctionPointer("PPP_ShutdownBroker")) :
29662346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org        reinterpret_cast<PP_ShutdownModule_Func>(
29762346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org            library.GetFunctionPointer("PPP_ShutdownModule"));
29862346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org
29962346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org    if (!is_broker_) {
30062346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org      // Get the InitializeModule function (required for non-broker code).
30162346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org      plugin_entry_points_.initialize_module =
30262346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org          reinterpret_cast<PP_InitializeModule_Func>(
30362346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org              library.GetFunctionPointer("PPP_InitializeModule"));
30487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      if (!plugin_entry_points_.initialize_module) {
30587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org        LOG(WARNING) << "No PPP_InitializeModule in plugin library";
30687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org        ReportLoadResult(path, ENTRY_POINT_MISSING);
30787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org        return;
30862346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org      }
30987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    }
31087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  }
31187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org
31262346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org#if defined(OS_WIN)
31387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  // If code subsequently tries to exit using abort(), force a crash (since
31487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  // otherwise these would be silent terminations and fly under the radar).
31587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  base::win::SetAbortBehaviorForCrashReporting();
31687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org
31762346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org  // Once we lower the token the sandbox is locked down and no new modules
31887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  // can be loaded. TODO(cpu): consider changing to the loading style of
31987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  // regular plugins.
32087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  if (g_target_services) {
32162346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org    // Let Flash load DXVA before lockdown on Vista+.
32287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    if (permissions.HasPermission(ppapi::PERMISSION_FLASH)) {
32387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      if (base::win::OSInfo::GetInstance()->version() >=
32487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org          base::win::VERSION_VISTA) {
32562346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org        LoadLibraryA("dxva2.dll");
32687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      }
32787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org
32887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      if (base::win::OSInfo::GetInstance()->version() >=
32962346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org          base::win::VERSION_WIN7) {
33087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org        base::CPU cpu;
33187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org        if ((cpu.vendor_name() == "AuthenticAMD") && (cpu.family() > 0x14)) {
33287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org          // The AMD crypto acceleration is only AMD Bulldozer and above.
33362346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org#if defined(_WIN64)
33487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org          LoadLibraryA("amdhcp64.dll");
33587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#else
33687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org          LoadLibraryA("amdhcp32.dll");
33762346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org#endif
33887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org        }
33987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      }
34087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    }
34162346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org
34287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    // Cause advapi32 to load before the sandbox is turned on.
34387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    unsigned int dummy_rand;
34487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    rand_s(&dummy_rand);
34562346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org
34687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    WarmupWindowsLocales(permissions);
34787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org
34887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    g_target_services->LowerToken();
34962346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org  }
35087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#endif
35187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org
35287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  if (is_broker_) {
35362346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org    // Get the InitializeBroker function (required).
35487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    InitializeBrokerFunc init_broker =
35587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org        reinterpret_cast<InitializeBrokerFunc>(
35687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org            library.GetFunctionPointer("PPP_InitializeBroker"));
35762346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org    if (!init_broker) {
35887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      LOG(WARNING) << "No PPP_InitializeBroker in plugin library";
35987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      ReportLoadResult(path, ENTRY_POINT_MISSING);
36087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      return;
36162346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org    }
36287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org
36362346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org    int32_t init_error = init_broker(&connect_instance_func_);
36462346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org    if (init_error != PP_OK) {
36587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      LOG(WARNING) << "InitBroker failed with error " << init_error;
36662346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org      ReportLoadResult(path, INIT_FAILED);
36762346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org      return;
36862346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org    }
36962346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org    if (!connect_instance_func_) {
37062346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org      LOG(WARNING) << "InitBroker did not provide PP_ConnectInstance_Func";
37162346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org      ReportLoadResult(path, INIT_FAILED);
37262346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org      return;
37362346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org    }
37462346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org  } else {
37562346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org#if defined(OS_MACOSX)
37662346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org    // We need to do this after getting |PPP_GetInterface()| (or presumably
37762346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org    // doing something nontrivial with the library), else the sandbox
37862346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org    // intercedes.
37962346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org    CHECK(InitializeSandbox());
38062346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org#endif
38162346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org
38262346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org    int32_t init_error = plugin_entry_points_.initialize_module(
38362346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org        local_pp_module_,
38462346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org        &ppapi::proxy::PluginDispatcher::GetBrowserInterface);
38562346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org    if (init_error != PP_OK) {
38662346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org      LOG(WARNING) << "InitModule failed with error " << init_error;
38762346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org      ReportLoadResult(path, INIT_FAILED);
38862346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org      return;
38962346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org    }
39062346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org  }
391d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org
3928b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org  // Initialization succeeded, so keep the plugin DLL loaded.
3938b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org  library_.Reset(library.Release());
3948b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org
395d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  ReportLoadResult(path, LOAD_SUCCESS);
39662346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org}
39762346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org
39862346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.orgvoid PpapiThread::OnCreateChannel(base::ProcessId renderer_pid,
39962346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org                                  int renderer_child_id,
40062346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org                                  bool incognito) {
40162346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org  IPC::ChannelHandle channel_handle;
40262346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org
40362346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org  if (!plugin_entry_points_.get_interface ||  // Plugin couldn't be loaded.
4048b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org      !SetupRendererChannel(renderer_pid, renderer_child_id, incognito,
4058b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org                            &channel_handle)) {
4068b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org    Send(new PpapiHostMsg_ChannelCreated(IPC::ChannelHandle()));
407d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org    return;
4088b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org  }
4098b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org
4108b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org  Send(new PpapiHostMsg_ChannelCreated(channel_handle));
411d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org}
41262346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org
41362346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.orgvoid PpapiThread::OnSetNetworkState(bool online) {
41462346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org  // Note the browser-process side shouldn't send us these messages in the
415d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org  // first unless the plugin has dev permissions, so we don't need to check
41662346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org  // again here. We don't want random plugins depending on this dev interface.
417d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org  if (!plugin_entry_points_.get_interface)
418d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org    return;
419d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  const PPP_NetworkState_Dev* ns = static_cast<const PPP_NetworkState_Dev*>(
42062346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org      plugin_entry_points_.get_interface(PPP_NETWORK_STATE_DEV_INTERFACE));
421d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org  if (ns)
422d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org    ns->SetOnLine(PP_FromBool(online));
423d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org}
42462346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org
425d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.orgvoid PpapiThread::OnCrash() {
426d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org  // Intentionally crash upon the request of the browser.
42762346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org  volatile int* null_pointer = NULL;
42887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  *null_pointer = 0;
42962346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org}
43062346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org
43187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orgvoid PpapiThread::OnHang() {
43262346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org  // Intentionally hang upon the request of the browser.
43362346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org  for (;;)
43487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    base::PlatformThread::Sleep(base::TimeDelta::FromSeconds(1));
435e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org}
436e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org
43787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orgbool PpapiThread::SetupRendererChannel(base::ProcessId renderer_pid,
43895aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com                                       int renderer_child_id,
43995aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com                                       bool incognito,
440693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com                                       IPC::ChannelHandle* handle) {
44195aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com  DCHECK(is_broker_ == (connect_instance_func_ != NULL));
44262346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org  IPC::ChannelHandle plugin_handle;
44388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  plugin_handle.name = IPC::Channel::GenerateVerifiedChannelID(
44488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org      base::StringPrintf(
44588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org          "%d.r%d", base::GetCurrentProcId(), renderer_child_id));
44662346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org
44788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  ppapi::proxy::ProxyChannel* dispatcher = NULL;
44888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  bool init_result = false;
44988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  if (is_broker_) {
45062346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org    BrokerProcessDispatcher* broker_dispatcher =
45162346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org        new BrokerProcessDispatcher(plugin_entry_points_.get_interface,
45262346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org                                    connect_instance_func_);
45362346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org    init_result = broker_dispatcher->InitBrokerWithChannel(this,
45462346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org                                                           renderer_pid,
45562346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org                                                           plugin_handle,
45662346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org                                                           false);
45762346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org    dispatcher = broker_dispatcher;
45862346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org  } else {
45962346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org    PluginProcessDispatcher* plugin_dispatcher =
46062346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org        new PluginProcessDispatcher(plugin_entry_points_.get_interface,
46162346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org                                    permissions_,
46262346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org                                    incognito);
46388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    init_result = plugin_dispatcher->InitPluginWithChannel(this,
46488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org                                                           renderer_pid,
46588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org                                                           plugin_handle,
46662346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org                                                           false);
46788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    dispatcher = plugin_dispatcher;
46888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  }
46988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org
47062346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org  if (!init_result) {
47162346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org    delete dispatcher;
47262346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org    return false;
47362346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org  }
47462346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org
47588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  handle->name = plugin_handle.name;
47688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(OS_POSIX)
47788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  // On POSIX, transfer ownership of the renderer-side (client) FD.
47862346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org  // This ensures this process will be notified when it is closed even if a
47988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  // connection is not established.
48088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  handle->socket = base::FileDescriptor(dispatcher->TakeRendererFD(), true);
48188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  if (handle->socket.fd == -1)
48262346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org    return false;
48362346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org#endif
48462346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org
48562346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org  // From here, the dispatcher will manage its own lifetime according to the
48662346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org  // lifetime of the attached channel.
48762346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org  return true;
48862346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org}
48962346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org
49062346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.orgvoid PpapiThread::SavePluginName(const base::FilePath& path) {
49162346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org  ppapi::proxy::PluginGlobals::Get()->set_plugin_name(
49262346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org      path.BaseName().AsUTF8Unsafe());
49362346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org
49462346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org  // plugin() is NULL when in-process, which is fine, because this is
49588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  // just a hook for setting the process name.
49688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  if (GetContentClient()->plugin()) {
49788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    GetContentClient()->plugin()->PluginProcessStarted(
49862346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org        path.BaseName().RemoveExtension().LossyDisplayName());
49988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  }
50088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org}
50188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org
50262346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.orgvoid PpapiThread::ReportLoadResult(const base::FilePath& path,
50362346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org                                   LoadResult result) {
50462346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org  DCHECK_LT(result, LOAD_RESULT_MAX);
50562346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org
50662346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org  std::ostringstream histogram_name;
50788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  histogram_name << "Plugin.Ppapi" << (is_broker_ ? "Broker" : "Plugin")
50888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org                 << "LoadResult_" << path.BaseName().MaybeAsASCII();
50988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org
51062346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org  // Note: This leaks memory, which is expected behavior.
51188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  base::HistogramBase* histogram =
51288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org      base::LinearHistogram::FactoryGet(
51388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org          histogram_name.str(),
51462346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org          1,
51562346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org          LOAD_RESULT_MAX,
51662346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org          LOAD_RESULT_MAX + 1,
51762346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org          base::HistogramBase::kUmaTargetedHistogramFlag);
51862346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org
51962346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org  histogram->Add(result);
52062346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org}
52162346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org
52262346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org}  // namespace content
52362346fffe2566140c9f486b24be8377abf9e5b59fgalligan@chromium.org