blob: b93eb544e73ea603e73ebcde35e03a350661d581 [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/utility/utility_thread_impl.h"
#include <stddef.h>
#include "base/command_line.h"
#include "base/file_path.h"
#include "base/memory/scoped_vector.h"
#include "content/common/child_process.h"
#include "content/common/child_process_messages.h"
#include "content/common/indexed_db/indexed_db_key.h"
#include "content/common/utility_messages.h"
#include "content/common/webkitplatformsupport_impl.h"
#include "content/public/utility/content_utility_client.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebIDBKey.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebKit.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebSerializedScriptValue.h"
#include "webkit/glue/idb_bindings.h"
#include "webkit/plugins/npapi/plugin_list.h"
#if defined(TOOLKIT_GTK)
#include <gtk/gtk.h>
#include "ui/gfx/gtk_util.h"
#endif
namespace {
template<typename SRC, typename DEST>
void ConvertVector(const SRC& src, DEST* dest) {
dest->reserve(src.size());
for (typename SRC::const_iterator i = src.begin(); i != src.end(); ++i)
dest->push_back(typename DEST::value_type(*i));
}
} // namespace
UtilityThreadImpl::UtilityThreadImpl()
: batch_mode_(false) {
ChildProcess::current()->AddRefProcess();
webkit_platform_support_.reset(new content::WebKitPlatformSupportImpl);
WebKit::initialize(webkit_platform_support_.get());
content::GetContentClient()->utility()->UtilityThreadStarted();
}
UtilityThreadImpl::~UtilityThreadImpl() {
WebKit::shutdown();
}
bool UtilityThreadImpl::Send(IPC::Message* msg) {
return ChildThread::Send(msg);
}
void UtilityThreadImpl::ReleaseProcessIfNeeded() {
if (!batch_mode_)
ChildProcess::current()->ReleaseProcess();
}
#if defined(OS_WIN)
void UtilityThreadImpl::PreCacheFont(const LOGFONT& log_font) {
Send(new ChildProcessHostMsg_PreCacheFont(log_font));
}
void UtilityThreadImpl::ReleaseCachedFonts() {
Send(new ChildProcessHostMsg_ReleaseCachedFonts());
}
#endif // OS_WIN
bool UtilityThreadImpl::OnControlMessageReceived(const IPC::Message& msg) {
if (content::GetContentClient()->utility()->OnMessageReceived(msg))
return true;
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(UtilityThreadImpl, msg)
IPC_MESSAGE_HANDLER(UtilityMsg_IDBKeysFromValuesAndKeyPath,
OnIDBKeysFromValuesAndKeyPath)
IPC_MESSAGE_HANDLER(UtilityMsg_InjectIDBKey, OnInjectIDBKey)
IPC_MESSAGE_HANDLER(UtilityMsg_BatchMode_Started, OnBatchModeStarted)
IPC_MESSAGE_HANDLER(UtilityMsg_BatchMode_Finished, OnBatchModeFinished)
#if defined(OS_POSIX)
IPC_MESSAGE_HANDLER(UtilityMsg_LoadPlugins, OnLoadPlugins)
#endif // OS_POSIX
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
}
void UtilityThreadImpl::OnIDBKeysFromValuesAndKeyPath(
int id,
const std::vector<content::SerializedScriptValue>& serialized_script_values,
const string16& idb_key_path) {
std::vector<WebKit::WebSerializedScriptValue> web_values;
ConvertVector(serialized_script_values, &web_values);
std::vector<WebKit::WebIDBKey> web_keys;
bool error = webkit_glue::IDBKeysFromValuesAndKeyPath(
web_values, idb_key_path, &web_keys);
if (error) {
Send(new UtilityHostMsg_IDBKeysFromValuesAndKeyPath_Failed(id));
return;
}
std::vector<IndexedDBKey> keys;
ConvertVector(web_keys, &keys);
Send(new UtilityHostMsg_IDBKeysFromValuesAndKeyPath_Succeeded(id, keys));
ReleaseProcessIfNeeded();
}
void UtilityThreadImpl::OnInjectIDBKey(
const IndexedDBKey& key,
const content::SerializedScriptValue& value,
const string16& key_path) {
content::SerializedScriptValue new_value(
webkit_glue::InjectIDBKey(key, value, key_path));
Send(new UtilityHostMsg_InjectIDBKey_Finished(new_value));
ReleaseProcessIfNeeded();
}
void UtilityThreadImpl::OnBatchModeStarted() {
batch_mode_ = true;
}
void UtilityThreadImpl::OnBatchModeFinished() {
ChildProcess::current()->ReleaseProcess();
}
#if defined(OS_POSIX)
void UtilityThreadImpl::OnLoadPlugins(
const std::vector<FilePath>& plugin_paths) {
webkit::npapi::PluginList* plugin_list =
webkit::npapi::PluginList::Singleton();
// On Linux, some plugins expect the browser to have loaded glib/gtk. Do that
// before attempting to call into the plugin.
// g_thread_init API is deprecated since glib 2.31.0, please see release note:
// http://mail.gnome.org/archives/gnome-announce-list/2011-October/msg00041.html
#if defined(TOOLKIT_GTK)
#if !(GLIB_CHECK_VERSION(2, 31, 0))
if (!g_thread_get_initialized()) {
g_thread_init(NULL);
}
#endif
gfx::GtkInitFromCommandLine(*CommandLine::ForCurrentProcess());
#endif
ScopedVector<webkit::npapi::PluginGroup> plugin_groups;
// TODO(bauerb): If we restart loading plug-ins, we might mess up the logic in
// PluginList::ShouldLoadPlugin due to missing the previously loaded plug-ins
// in |plugin_groups|.
for (size_t i = 0; i < plugin_paths.size(); ++i) {
webkit::WebPluginInfo plugin;
if (!plugin_list->LoadPlugin(plugin_paths[i], &plugin_groups, &plugin))
Send(new UtilityHostMsg_LoadPluginFailed(i, plugin_paths[i]));
else
Send(new UtilityHostMsg_LoadedPlugin(i, plugin));
}
ReleaseProcessIfNeeded();
}
#endif