15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/utility/utility_thread_impl.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stddef.h>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_vector.h"
11effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "content/child/blink_platform_impl.h"
12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/child/child_process.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/child_process_messages.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/utility_messages.h"
157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "content/public/common/content_switches.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/utility/content_utility_client.h"
177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "ipc/ipc_sync_channel.h"
187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebKit.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if defined(OS_POSIX) && defined(ENABLE_PLUGINS)
211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_path.h"
221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/common/plugin_list.h"
231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif
241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename SRC, typename DEST>
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ConvertVector(const SRC& src, DEST* dest) {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dest->reserve(src.size());
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (typename SRC::const_iterator i = src.begin(); i != src.end(); ++i)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dest->push_back(typename DEST::value_type(*i));
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
387dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochUtilityThreadImpl::UtilityThreadImpl() : single_process_(false) {
397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  Init();
407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
427dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochUtilityThreadImpl::UtilityThreadImpl(const std::string& channel_name)
435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    : ChildThread(Options(channel_name, false)),
447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      single_process_(true) {
457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  Init();
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)UtilityThreadImpl::~UtilityThreadImpl() {
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void UtilityThreadImpl::Shutdown() {
52a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  ChildThread::Shutdown();
53a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!single_process_)
55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    blink::shutdown();
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool UtilityThreadImpl::Send(IPC::Message* msg) {
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ChildThread::Send(msg);
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UtilityThreadImpl::ReleaseProcessIfNeeded() {
637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (batch_mode_)
647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (single_process_) {
677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // Close the channel to cause UtilityProcessHostImpl to be deleted. We need
687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // to take a different code path than the multi-process case because that
697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // depends on the child process going away to close the channel, but that
707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // can't happen when we're in single process mode.
717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    channel()->Close();
727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  } else {
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ChildProcess::current()->ReleaseProcess();
747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UtilityThreadImpl::PreCacheFont(const LOGFONT& log_font) {
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Send(new ChildProcessHostMsg_PreCacheFont(log_font));
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UtilityThreadImpl::ReleaseCachedFonts() {
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Send(new ChildProcessHostMsg_ReleaseCachedFonts());
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // OS_WIN
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid UtilityThreadImpl::Init() {
907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  batch_mode_ = false;
917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  ChildProcess::current()->AddRefProcess();
927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!single_process_) {
937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // We can only initialize WebKit on one thread, and in single process mode
947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // we run the utility thread on separate thread. This means that if any code
957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // needs WebKit initialized in the utility process, they need to have
967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // another path to support single process mode.
97effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    webkit_platform_support_.reset(new BlinkPlatformImpl);
98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    blink::initialize(webkit_platform_support_.get());
997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
1007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  GetContentClient()->utility()->UtilityThreadStarted();
1017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool UtilityThreadImpl::OnControlMessageReceived(const IPC::Message& msg) {
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (GetContentClient()->utility()->OnMessageReceived(msg))
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool handled = true;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC_BEGIN_MESSAGE_MAP(UtilityThreadImpl, msg)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(UtilityMsg_BatchMode_Started, OnBatchModeStarted)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(UtilityMsg_BatchMode_Finished, OnBatchModeFinished)
1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if defined(OS_POSIX) && defined(ENABLE_PLUGINS)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(UtilityMsg_LoadPlugins, OnLoadPlugins)
1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_UNHANDLED(handled = false)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC_END_MESSAGE_MAP()
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return handled;
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UtilityThreadImpl::OnBatchModeStarted() {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  batch_mode_ = true;
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UtilityThreadImpl::OnBatchModeFinished() {
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  batch_mode_ = false;
1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ReleaseProcessIfNeeded();
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if defined(OS_POSIX) && defined(ENABLE_PLUGINS)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UtilityThreadImpl::OnLoadPlugins(
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::vector<base::FilePath>& plugin_paths) {
131ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  PluginList* plugin_list = PluginList::Singleton();
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
133ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  std::vector<WebPluginInfo> plugins;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(bauerb): If we restart loading plug-ins, we might mess up the logic in
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // PluginList::ShouldLoadPlugin due to missing the previously loaded plug-ins
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in |plugin_groups|.
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < plugin_paths.size(); ++i) {
138ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    WebPluginInfo plugin;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!plugin_list->LoadPluginIntoPluginList(
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        plugin_paths[i], &plugins, &plugin))
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Send(new UtilityHostMsg_LoadPluginFailed(i, plugin_paths[i]));
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Send(new UtilityHostMsg_LoadedPlugin(i, plugin));
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ReleaseProcessIfNeeded();
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
151