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