Index: chrome/common/child_process_host.cc |
=================================================================== |
--- chrome/common/child_process_host.cc (revision 51593) |
+++ chrome/common/child_process_host.cc (working copy) |
@@ -5,6 +5,7 @@ |
#include "chrome/common/child_process_host.h" |
#include "base/command_line.h" |
+#include "base/histogram.h" |
#include "base/path_service.h" |
#include "chrome/common/child_process_info.h" |
#include "chrome/common/chrome_constants.h" |
@@ -53,6 +54,52 @@ |
return child_path; |
} |
+#if defined(OS_WIN) |
+// static |
+void ChildProcessHost::PreCacheFont(LOGFONT font) { |
+ // If a child process is running in a sandbox, GetTextMetrics() |
+ // can sometimes fail. If a font has not been loaded |
+ // previously, GetTextMetrics() will try to load the font |
+ // from the font file. However, the sandboxed process does |
+ // not have permissions to access any font files and |
+ // the call fails. So we make the browser pre-load the |
+ // font for us by using a dummy call to GetTextMetrics of |
+ // the same font. |
+ |
+ // Maintain a circular queue for the fonts and DCs to be cached. |
+ // font_index maintains next available location in the queue. |
+ static const int kFontCacheSize = 32; |
+ static HFONT fonts[kFontCacheSize] = {0}; |
+ static HDC hdcs[kFontCacheSize] = {0}; |
+ static size_t font_index = 0; |
+ |
+ UMA_HISTOGRAM_COUNTS_100("Memory.CachedFontAndDC", |
+ fonts[kFontCacheSize-1] ? kFontCacheSize : static_cast<int>(font_index)); |
+ |
+ HDC hdc = GetDC(NULL); |
+ HFONT font_handle = CreateFontIndirect(&font); |
+ DCHECK(NULL != font_handle); |
+ |
+ HGDIOBJ old_font = SelectObject(hdc, font_handle); |
+ DCHECK(NULL != old_font); |
+ |
+ TEXTMETRIC tm; |
+ BOOL ret = GetTextMetrics(hdc, &tm); |
+ DCHECK(ret); |
+ |
+ if (fonts[font_index] || hdcs[font_index]) { |
+ // We already have too many fonts, we will delete one and take it's place. |
+ DeleteObject(fonts[font_index]); |
+ ReleaseDC(NULL, hdcs[font_index]); |
+ } |
+ |
+ fonts[font_index] = font_handle; |
+ hdcs[font_index] = hdc; |
+ font_index = (font_index + 1) % kFontCacheSize; |
+} |
+#endif // OS_WIN |
+ |
+ |
bool ChildProcessHost::CreateChannel() { |
channel_id_ = ChildProcessInfo::GenerateRandomChannelID(this); |
channel_.reset(new IPC::Channel( |
@@ -60,6 +107,14 @@ |
if (!channel_->Connect()) |
return false; |
+ // Make sure these messages get sent first. |
+#if defined(IPC_MESSAGE_LOG_ENABLED) |
+ bool enabled = IPC::Logging::current()->Enabled(); |
+ SendOnChannel(new PluginProcessMsg_SetIPCLoggingEnabled(enabled)); |
+#endif |
+ |
+ SendOnChannel(new PluginProcessMsg_AskBeforeShutdown()); |
+ |
opening_channel_ = true; |
return true; |
@@ -118,14 +173,6 @@ |
void ChildProcessHost::ListenerHook::OnChannelConnected(int32 peer_pid) { |
host_->opening_channel_ = false; |
host_->OnChannelConnected(peer_pid); |
- |
-#if defined(IPC_MESSAGE_LOG_ENABLED) |
- bool enabled = IPC::Logging::current()->Enabled(); |
- host_->SendOnChannel(new PluginProcessMsg_SetIPCLoggingEnabled(enabled)); |
-#endif |
- |
- host_->SendOnChannel(new PluginProcessMsg_AskBeforeShutdown()); |
- |
// Notify in the main loop of the connection. |
host_->Notify(NotificationType::CHILD_PROCESS_HOST_CONNECTED); |
} |