Add the ability to (issue #236):

1. Disable pack file loading via CefSettings.pack_loading_disabled.
2. Customize pack file load paths via CefSettings.pack_file_path and CefSettings.locales_dir_path.
3. Provide custom resource bundle handling via CefResourceBundleHandler.

git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@501 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
Marshall Greenblatt
2012-02-16 17:11:49 +00:00
parent def9fdb540
commit 1a092a0c1a
34 changed files with 795 additions and 236 deletions

View File

@@ -13,6 +13,7 @@
#include "include/cef_stream.h"
#include "include/cef_url.h"
#include "libcef/browser_webkit_glue.h"
#include "libcef/cef_context.h"
#include "base/file_util.h"
#include "base/string_util.h"
@@ -105,7 +106,7 @@ class DevToolsSchemeHandlerFactory : public CefSchemeHandlerFactory {
for (size_t i = 0; i < kDevtoolsResourcesSize; ++i) {
if (base::strcasecmp(kDevtoolsResources[i].name, path) == 0) {
base::StringPiece piece =
webkit_glue::GetDataResource(kDevtoolsResources[i].value);
_Context->GetDataResource(kDevtoolsResources[i].value);
if (!piece.empty()) {
size = piece.size();
return CefStreamReader::CreateForData(const_cast<char*>(piece.data()),

View File

@@ -16,18 +16,11 @@ MSVC_PUSH_WARNING_LEVEL(0);
MSVC_POP_WARNING();
#undef LOG
#include "libcef/cef_context.h"
#include "base/file_util.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/path_service.h"
#include "base/string_util.h"
#include "base/string16.h"
#include "net/base/mime_util.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h"
#include "ui/base/resource/resource_bundle.h"
#include "webkit/glue/user_agent.h"
#include "webkit/glue/webkit_glue.h"
#include "webkit/plugins/npapi/plugin_list.h"
@@ -39,33 +32,6 @@ using WebKit::WebFrameImpl;
namespace webkit_glue {
void InitializeResourceBundle(const std::string& locale) {
// Load chrome.pak (on Mac) and the appropiate locale pack.
const std::string loaded_locale =
ResourceBundle::InitSharedInstance(locale);
CHECK(!loaded_locale.empty()) << "Locale could not be found for " << locale;
#if defined(OS_WIN)
// Explicitly load chrome.pak on Windows. Use the module (libcef.dll)
// directory to match the location of the locale folder.
FilePath chrome_pack_path;
PathService::Get(base::DIR_MODULE, &chrome_pack_path);
chrome_pack_path = chrome_pack_path.AppendASCII("chrome.pak");
if (file_util::PathExists(chrome_pack_path))
ResourceBundle::AddDataPackToSharedInstance(chrome_pack_path);
else
NOTREACHED() << "Could not load chrome.pak";
#endif
}
void CleanupResourceBundle() {
ResourceBundle::CleanupSharedInstance();
}
string16 GetLocalizedString(int message_id) {
return ResourceBundle::GetSharedInstance().GetLocalizedString(message_id);
}
bool IsMediaPlayerAvailable() {
return true;
}

View File

@@ -9,7 +9,6 @@
#include <string>
#include "base/compiler_specific.h"
#include "base/string_piece.h"
#include "v8/include/v8.h"
#if defined(OS_WIN)
@@ -24,10 +23,6 @@ namespace webkit {
struct WebPluginInfo;
}
#if defined(OS_MACOSX)
class FilePath;
#endif
namespace webkit_glue {
#if defined(OS_WIN)
@@ -39,16 +34,6 @@ void CaptureWebViewBitmap(HWND mainWnd, WebKit::WebView* webview,
BOOL SaveBitmapToFile(HBITMAP hBmp, HDC hDC, LPCTSTR file, LPBYTE lpBits);
#endif
void InitializeResourceBundle(const std::string& locale);
void CleanupResourceBundle();
#if defined(OS_MACOSX)
FilePath GetResourcesFilePath();
#endif
string16 GetLocalizedString(int message_id);
base::StringPiece GetDataResource(int resource_id);
// Text encoding objects must be initialized on the main thread.
void InitializeTextEncoding();

View File

@@ -1,23 +0,0 @@
// Copyright (c) 2008-2009 The Chromium Embedded Framework Authors.
// Portions copyright (c) 2006-2008 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 "libcef/browser_webkit_glue.h"
#include "libcef/cef_context.h"
#include "ui/base/resource/resource_bundle.h"
namespace webkit_glue {
base::StringPiece GetDataResource(int resource_id) {
base::StringPiece piece;
// Try to load the resource from the resource pack.
if (piece.empty())
piece = ResourceBundle::GetSharedInstance().GetRawDataResource(resource_id);
DCHECK(!piece.empty()) << "Resource " << resource_id <<
" could not be loaded";
return piece;
}
} // namespace webkit_glue

View File

@@ -1,90 +0,0 @@
// Copyright (c) 2010 The Chromium Embedded Framework Authors.
// Portions copyright (c) 2006-2008 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 "libcef/browser_webkit_glue.h"
#include "base/compiler_specific.h"
#include "third_party/WebKit/Source/WebCore/config.h"
#undef LOG
#include "base/file_util.h"
#include "base/logging.h"
#include "base/mac/mac_util.h"
#include "base/path_service.h"
#include "base/utf_string_conversions.h"
#include "grit/webkit_resources.h"
#include "ui/base/resource/resource_bundle.h"
#include "webkit/glue/webkit_glue.h"
namespace webkit_glue {
// Helper method for getting the path to the CEF resources directory.
FilePath GetResourcesFilePath() {
FilePath path;
// We need to know if we're bundled or not to know which path to use.
if (base::mac::AmIBundled()) {
PathService::Get(base::DIR_EXE, &path);
path = path.Append(FilePath::kParentDirectory);
return path.AppendASCII("Resources");
} else {
// TODO(port): Allow the embedder to customize the resource path.
PathService::Get(base::DIR_SOURCE_ROOT, &path);
path = path.AppendASCII("src");
path = path.AppendASCII("cef");
path = path.AppendASCII("tests");
path = path.AppendASCII("cefclient");
return path.AppendASCII("res");
}
}
base::StringPiece GetDataResource(int resource_id) {
switch (resource_id) {
case IDR_BROKENIMAGE: {
// Use webkit's broken image icon (16x16)
static std::string broken_image_data;
if (broken_image_data.empty()) {
FilePath path = GetResourcesFilePath();
// In order to match WebKit's colors for the missing image, we have to
// use a PNG. The GIF doesn't have the color range needed to correctly
// match the TIFF they use in Safari.
path = path.AppendASCII("missingImage.png");
bool success = file_util::ReadFileToString(path, &broken_image_data);
if (!success) {
LOG(FATAL) << "Failed reading: " << path.value();
}
}
return broken_image_data;
}
case IDR_TEXTAREA_RESIZER: {
// Use webkit's text area resizer image.
static std::string resize_corner_data;
if (resize_corner_data.empty()) {
FilePath path = GetResourcesFilePath();
path = path.AppendASCII("textAreaResizeCorner.png");
bool success = file_util::ReadFileToString(path, &resize_corner_data);
if (!success) {
LOG(FATAL) << "Failed reading: " << path.value();
}
}
return resize_corner_data;
}
default:
break;
}
base::StringPiece piece =
ResourceBundle::GetSharedInstance().GetRawDataResource(resource_id);
DCHECK(!piece.empty());
return piece;
}
void DidLoadPlugin(const std::string& filename) {
}
void DidUnloadPlugin(const std::string& filename) {
}
} // namespace webkit_glue

View File

@@ -16,13 +16,10 @@ MSVC_POP_WARNING();
#undef LOG
#include "base/logging.h"
#include "base/path_service.h"
#include "base/win/resource_util.h"
#include "skia/ext/platform_canvas.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebRect.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebSize.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/gdi_util.h"
#include "webkit/glue/webkit_glue.h"
@@ -32,37 +29,6 @@ using WebKit::WebView;
namespace webkit_glue {
base::StringPiece GetRawDataResource(HMODULE module, int resource_id) {
void* data_ptr;
size_t data_size;
return base::win::GetDataResourceFromModule(module, resource_id, &data_ptr,
&data_size)
? base::StringPiece(static_cast<char*>(data_ptr), data_size)
: base::StringPiece();
}
base::StringPiece GetDataResource(int resource_id) {
base::StringPiece piece;
FilePath file_path;
HMODULE hModule = NULL;
// Try to load the resource from the DLL.
if (PathService::Get(base::FILE_MODULE, &file_path))
hModule = ::GetModuleHandle(file_path.value().c_str());
if (!hModule)
hModule = ::GetModuleHandle(NULL);
piece = GetRawDataResource(hModule, resource_id);
// Try to load the resource from the resource pack.
if (piece.empty())
piece = ResourceBundle::GetSharedInstance().GetRawDataResource(resource_id);
DCHECK(!piece.empty()) << "Resource " << resource_id <<
" could not be loaded";
return piece;
}
bool EnsureFontLoaded(HFONT font) {
return true;
}

View File

@@ -274,11 +274,11 @@ void BrowserWebKitInit::GetPlugins(
}
string16 BrowserWebKitInit::GetLocalizedString(int message_id) {
return webkit_glue::GetLocalizedString(message_id);
return _Context->GetLocalizedString(message_id);
}
base::StringPiece BrowserWebKitInit::GetDataResource(int resource_id) {
return webkit_glue::GetDataResource(resource_id);
return _Context->GetDataResource(resource_id);
}
webkit_glue::ResourceLoaderBridge* BrowserWebKitInit::CreateResourceLoader(

View File

@@ -96,7 +96,7 @@ void SelectionClipboardGetContents(GtkClipboard* clipboard,
} // namespace
// WebViewClient ----------------------------------s----------------------------
// WebViewClient ---------------------------------------------------------------
WebKit::WebExternalPopupMenu* BrowserWebViewDelegate::createExternalPopupMenu(
const WebKit::WebPopupMenuInfo& info,

View File

@@ -9,12 +9,24 @@
#include "base/bind.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/synchronization/waitable_event.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/ui_base_paths.h"
#if defined(OS_MACOSX) || defined(OS_WIN)
#include "crypto/nss_util.h"
#endif
#if defined(OS_MACOSX)
#include "base/mac/mac_util.h"
#include "grit/webkit_resources.h"
#endif
#if defined(OS_WIN)
#include "base/win/resource_util.h"
#endif
// Both the CefContext constuctor and the CefContext::RemoveBrowser method need
// to initialize or reset to the same value.
const int kNextBrowserIdReset = 1;
@@ -38,6 +50,20 @@ class DestructionObserver : public MessageLoop::DestructionObserver {
base::WaitableEvent *event_;
};
#if defined(OS_WIN)
// Helper method for retrieving a resource from a module.
base::StringPiece GetRawDataResource(HMODULE module, int resource_id) {
void* data_ptr;
size_t data_size;
return base::win::GetDataResourceFromModule(module, resource_id, &data_ptr,
&data_size)
? base::StringPiece(static_cast<char*>(data_ptr), data_size)
: base::StringPiece();
}
#endif // defined(OS_MACOSX)
} // namespace
bool CefInitialize(const CefSettings& settings, CefRefPtr<CefApp> application) {
@@ -266,6 +292,166 @@ CefRefPtr<CefBrowserImpl> CefContext::GetBrowserByID(int id) {
return NULL;
}
void CefContext::InitializeResourceBundle() {
if (settings_.pack_loading_disabled)
return;
FilePath pak_file, locales_dir;
if (settings_.pack_file_path.length > 0)
pak_file = FilePath(CefString(&settings_.pack_file_path));
if (pak_file.empty()) {
FilePath pak_dir;
PathService::Get(base::DIR_MODULE, &pak_dir);
pak_file = pak_dir.Append(FILE_PATH_LITERAL("chrome.pak"));
}
if (!pak_file.empty())
PathService::Override(ui::FILE_RESOURCES_PAK, pak_file);
if (settings_.locales_dir_path.length > 0)
locales_dir = FilePath(CefString(&settings_.locales_dir_path));
if (!locales_dir.empty())
PathService::Override(ui::DIR_LOCALES, locales_dir);
std::string locale_str = locale();
const std::string loaded_locale =
ui::ResourceBundle::InitSharedInstance(locale_str);
CHECK(!loaded_locale.empty()) << "Locale could not be found for " <<
locale_str;
#if defined(OS_WIN)
// Explicitly load chrome.pak on Windows.
if (file_util::PathExists(pak_file))
ResourceBundle::AddDataPackToSharedInstance(pak_file);
else
NOTREACHED() << "Could not load chrome.pak";
#endif
}
void CefContext::CleanupResourceBundle() {
if (!settings_.pack_loading_disabled)
ResourceBundle::CleanupSharedInstance();
}
string16 CefContext::GetLocalizedString(int message_id) const {
string16 value;
if (application_.get()) {
CefRefPtr<CefResourceBundleHandler> handler =
application_->GetResourceBundleHandler();
if (handler.get()) {
CefString cef_str;
if (handler->GetLocalizedString(message_id, cef_str))
value = cef_str;
}
}
if (value.empty() && !settings_.pack_loading_disabled)
value = ResourceBundle::GetSharedInstance().GetLocalizedString(message_id);
if (value.empty())
LOG(ERROR) << "No localized string available for id " << message_id;
return value;
}
base::StringPiece CefContext::GetDataResource(int resource_id) const {
base::StringPiece value;
if (application_.get()) {
CefRefPtr<CefResourceBundleHandler> handler =
application_->GetResourceBundleHandler();
if (handler.get()) {
void* data = NULL;
size_t data_size = 0;
if (handler->GetDataResource(resource_id, data, data_size))
value = base::StringPiece(static_cast<char*>(data), data_size);
}
}
#if defined(OS_WIN)
if (value.empty()) {
FilePath file_path;
HMODULE hModule = NULL;
// Try to load the resource from the DLL.
if (PathService::Get(base::FILE_MODULE, &file_path))
hModule = ::GetModuleHandle(file_path.value().c_str());
if (!hModule)
hModule = ::GetModuleHandle(NULL);
value = GetRawDataResource(hModule, resource_id);
}
#elif defined(OS_MACOSX)
if (value.empty()) {
switch (resource_id) {
case IDR_BROKENIMAGE: {
// Use webkit's broken image icon (16x16)
static std::string broken_image_data;
if (broken_image_data.empty()) {
FilePath path = GetResourcesFilePath();
// In order to match WebKit's colors for the missing image, we have to
// use a PNG. The GIF doesn't have the color range needed to correctly
// match the TIFF they use in Safari.
path = path.AppendASCII("missingImage.png");
bool success = file_util::ReadFileToString(path, &broken_image_data);
if (!success) {
LOG(FATAL) << "Failed reading: " << path.value();
}
}
value = broken_image_data;
}
case IDR_TEXTAREA_RESIZER: {
// Use webkit's text area resizer image.
static std::string resize_corner_data;
if (resize_corner_data.empty()) {
FilePath path = GetResourcesFilePath();
path = path.AppendASCII("textAreaResizeCorner.png");
bool success = file_util::ReadFileToString(path, &resize_corner_data);
if (!success) {
LOG(FATAL) << "Failed reading: " << path.value();
}
}
value = resize_corner_data;
}
default:
break;
}
}
#endif // defined(OS_MACOSX)
if (value.empty() && !settings_.pack_loading_disabled)
value = ResourceBundle::GetSharedInstance().GetRawDataResource(resource_id);
if (value.empty())
LOG(ERROR) << "No data resource available for id " << resource_id;
return value;
}
#if defined(OS_MACOSX)
FilePath CefContext::GetResourcesFilePath() const {
FilePath path;
// We need to know if we're bundled or not to know which path to use.
if (base::mac::AmIBundled()) {
PathService::Get(base::DIR_EXE, &path);
path = path.Append(FilePath::kParentDirectory);
return path.AppendASCII("Resources");
} else {
// TODO(port): Allow the embedder to customize the resource path.
PathService::Get(base::DIR_SOURCE_ROOT, &path);
path = path.AppendASCII("src");
path = path.AppendASCII("cef");
path = path.AppendASCII("tests");
path = path.AppendASCII("cefclient");
return path.AppendASCII("res");
}
}
#endif // defined(OS_MACOSX)
std::string CefContext::locale() const {
std::string localeStr = CefString(&settings_.locale);
if (!localeStr.empty())

View File

@@ -52,6 +52,16 @@ class CefContext : public CefBase {
CefRefPtr<CefBrowserImpl> GetBrowserByID(int id);
BrowserList* GetBrowserList() { return &browserlist_; }
void InitializeResourceBundle();
void CleanupResourceBundle();
string16 GetLocalizedString(int message_id) const;
base::StringPiece GetDataResource(int resource_id) const;
#if defined(OS_MACOSX)
FilePath GetResourcesFilePath() const;
#endif
// Retrieve the path at which cache data will be stored on disk. If empty,
// cache data will be stored in-memory.
const FilePath& cache_path() const { return cache_path_; }

View File

@@ -34,10 +34,18 @@
#include <Objbase.h> // NOLINT(build/include_order)
#endif
namespace {
static const char* kStatsFilePrefix = "libcef_";
static int kStatsFileThreads = 20;
static int kStatsFileCounters = 200;
base::StringPiece ResourceProvider(int resource_id) {
return _Context->GetDataResource(resource_id);
}
} // namespace
CefProcessUIThread::CefProcessUIThread()
: CefThread(CefThread::UI), statstable_(NULL), webkit_init_(NULL) {}
@@ -88,7 +96,7 @@ void CefProcessUIThread::Init() {
// Provides path resolution required for locating locale pack files.
ui::RegisterPathProvider();
webkit_glue::InitializeResourceBundle(_Context->locale());
_Context->InitializeResourceBundle();
PlatformInit();
@@ -99,7 +107,7 @@ void CefProcessUIThread::Init() {
webkit_glue::InitializeTextEncoding();
// Config the network module so it has access to a limited set of resources.
net::NetModule::SetResourceProvider(webkit_glue::GetDataResource);
net::NetModule::SetResourceProvider(ResourceProvider);
// Load and initialize the stats table. Attempt to construct a somewhat
// unique name to isolate separate instances from each other.
@@ -202,7 +210,7 @@ void CefProcessUIThread::CleanUp() {
PlatformCleanUp();
webkit_glue::CleanupResourceBundle();
_Context->CleanupResourceBundle();
}
AudioManager* CefProcessUIThread::audio_manager() {

View File

@@ -6,8 +6,8 @@
#include <sys/param.h>
#include "libcef/browser_impl.h"
#include "libcef/browser_webkit_glue.h"
#import "libcef/browser_webview_mac.h"
#include "libcef/cef_context.h"
#include "libcef/drag_download_util.h"
#include "libcef/download_util.h"
#import "libcef/web_drag_source_mac.h"
@@ -143,7 +143,7 @@ void PromiseWriterTask::Run() {
if (image == nil) {
// No drag image was provided so create one.
FilePath path = webkit_glue::GetResourcesFilePath();
FilePath path = _Context->GetResourcesFilePath();
path = path.AppendASCII("urlIcon.png");
image = [[NSImage alloc]
initWithContentsOfFile:SysUTF8ToNSString(path.value())];