OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/common/child_process_host.h" | 5 #include "chrome/common/child_process_host.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "base/histogram.h" |
8 #include "base/path_service.h" | 9 #include "base/path_service.h" |
9 #include "chrome/common/child_process_info.h" | 10 #include "chrome/common/child_process_info.h" |
10 #include "chrome/common/chrome_constants.h" | 11 #include "chrome/common/chrome_constants.h" |
11 #include "chrome/common/chrome_paths_internal.h" | 12 #include "chrome/common/chrome_paths_internal.h" |
12 #include "chrome/common/chrome_switches.h" | 13 #include "chrome/common/chrome_switches.h" |
13 #include "chrome/common/plugin_messages.h" | 14 #include "chrome/common/plugin_messages.h" |
14 | 15 |
15 #if defined(OS_LINUX) | 16 #if defined(OS_LINUX) |
16 #include "base/linux_util.h" | 17 #include "base/linux_util.h" |
17 #endif // OS_LINUX | 18 #endif // OS_LINUX |
(...skipping 28 matching lines...) Expand all Loading... |
46 if (allow_self) | 47 if (allow_self) |
47 return FilePath("/proc/self/exe"); | 48 return FilePath("/proc/self/exe"); |
48 #endif | 49 #endif |
49 | 50 |
50 // On most platforms, the child executable is the same as the current | 51 // On most platforms, the child executable is the same as the current |
51 // executable. | 52 // executable. |
52 PathService::Get(base::FILE_EXE, &child_path); | 53 PathService::Get(base::FILE_EXE, &child_path); |
53 return child_path; | 54 return child_path; |
54 } | 55 } |
55 | 56 |
| 57 #if defined(OS_WIN) |
| 58 // static |
| 59 void ChildProcessHost::PreCacheFont(LOGFONT font) { |
| 60 // If a child process is running in a sandbox, GetTextMetrics() |
| 61 // can sometimes fail. If a font has not been loaded |
| 62 // previously, GetTextMetrics() will try to load the font |
| 63 // from the font file. However, the sandboxed process does |
| 64 // not have permissions to access any font files and |
| 65 // the call fails. So we make the browser pre-load the |
| 66 // font for us by using a dummy call to GetTextMetrics of |
| 67 // the same font. |
| 68 |
| 69 // Maintain a circular queue for the fonts and DCs to be cached. |
| 70 // font_index maintains next available location in the queue. |
| 71 static const int kFontCacheSize = 32; |
| 72 static HFONT fonts[kFontCacheSize] = {0}; |
| 73 static HDC hdcs[kFontCacheSize] = {0}; |
| 74 static size_t font_index = 0; |
| 75 |
| 76 UMA_HISTOGRAM_COUNTS_100("Memory.CachedFontAndDC", |
| 77 fonts[kFontCacheSize-1] ? kFontCacheSize : static_cast<int>(font_index)); |
| 78 |
| 79 HDC hdc = GetDC(NULL); |
| 80 HFONT font_handle = CreateFontIndirect(&font); |
| 81 DCHECK(NULL != font_handle); |
| 82 |
| 83 HGDIOBJ old_font = SelectObject(hdc, font_handle); |
| 84 DCHECK(NULL != old_font); |
| 85 |
| 86 TEXTMETRIC tm; |
| 87 BOOL ret = GetTextMetrics(hdc, &tm); |
| 88 DCHECK(ret); |
| 89 |
| 90 if (fonts[font_index] || hdcs[font_index]) { |
| 91 // We already have too many fonts, we will delete one and take it's place. |
| 92 DeleteObject(fonts[font_index]); |
| 93 ReleaseDC(NULL, hdcs[font_index]); |
| 94 } |
| 95 |
| 96 fonts[font_index] = font_handle; |
| 97 hdcs[font_index] = hdc; |
| 98 font_index = (font_index + 1) % kFontCacheSize; |
| 99 } |
| 100 #endif // OS_WIN |
| 101 |
| 102 |
56 bool ChildProcessHost::CreateChannel() { | 103 bool ChildProcessHost::CreateChannel() { |
57 channel_id_ = ChildProcessInfo::GenerateRandomChannelID(this); | 104 channel_id_ = ChildProcessInfo::GenerateRandomChannelID(this); |
58 channel_.reset(new IPC::Channel( | 105 channel_.reset(new IPC::Channel( |
59 channel_id_, IPC::Channel::MODE_SERVER, &listener_)); | 106 channel_id_, IPC::Channel::MODE_SERVER, &listener_)); |
60 if (!channel_->Connect()) | 107 if (!channel_->Connect()) |
61 return false; | 108 return false; |
62 | 109 |
| 110 // Make sure these messages get sent first. |
| 111 #if defined(IPC_MESSAGE_LOG_ENABLED) |
| 112 bool enabled = IPC::Logging::current()->Enabled(); |
| 113 SendOnChannel(new PluginProcessMsg_SetIPCLoggingEnabled(enabled)); |
| 114 #endif |
| 115 |
| 116 SendOnChannel(new PluginProcessMsg_AskBeforeShutdown()); |
| 117 |
63 opening_channel_ = true; | 118 opening_channel_ = true; |
64 | 119 |
65 return true; | 120 return true; |
66 } | 121 } |
67 | 122 |
68 void ChildProcessHost::InstanceCreated() { | 123 void ChildProcessHost::InstanceCreated() { |
69 Notify(NotificationType::CHILD_INSTANCE_CREATED); | 124 Notify(NotificationType::CHILD_INSTANCE_CREATED); |
70 } | 125 } |
71 | 126 |
72 bool ChildProcessHost::SendOnChannel(IPC::Message* msg) { | 127 bool ChildProcessHost::SendOnChannel(IPC::Message* msg) { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
111 | 166 |
112 #ifdef IPC_MESSAGE_LOG_ENABLED | 167 #ifdef IPC_MESSAGE_LOG_ENABLED |
113 if (logger->Enabled()) | 168 if (logger->Enabled()) |
114 logger->OnPostDispatchMessage(msg, host_->channel_id_); | 169 logger->OnPostDispatchMessage(msg, host_->channel_id_); |
115 #endif | 170 #endif |
116 } | 171 } |
117 | 172 |
118 void ChildProcessHost::ListenerHook::OnChannelConnected(int32 peer_pid) { | 173 void ChildProcessHost::ListenerHook::OnChannelConnected(int32 peer_pid) { |
119 host_->opening_channel_ = false; | 174 host_->opening_channel_ = false; |
120 host_->OnChannelConnected(peer_pid); | 175 host_->OnChannelConnected(peer_pid); |
121 | |
122 #if defined(IPC_MESSAGE_LOG_ENABLED) | |
123 bool enabled = IPC::Logging::current()->Enabled(); | |
124 host_->SendOnChannel(new PluginProcessMsg_SetIPCLoggingEnabled(enabled)); | |
125 #endif | |
126 | |
127 host_->SendOnChannel(new PluginProcessMsg_AskBeforeShutdown()); | |
128 | |
129 // Notify in the main loop of the connection. | 176 // Notify in the main loop of the connection. |
130 host_->Notify(NotificationType::CHILD_PROCESS_HOST_CONNECTED); | 177 host_->Notify(NotificationType::CHILD_PROCESS_HOST_CONNECTED); |
131 } | 178 } |
132 | 179 |
133 void ChildProcessHost::ListenerHook::OnChannelError() { | 180 void ChildProcessHost::ListenerHook::OnChannelError() { |
134 host_->opening_channel_ = false; | 181 host_->opening_channel_ = false; |
135 host_->OnChannelError(); | 182 host_->OnChannelError(); |
136 | 183 |
137 // This will delete host_, which will also destroy this! | 184 // This will delete host_, which will also destroy this! |
138 host_->OnChildDied(); | 185 host_->OnChildDied(); |
139 } | 186 } |
140 | 187 |
141 void ChildProcessHost::ForceShutdown() { | 188 void ChildProcessHost::ForceShutdown() { |
142 SendOnChannel(new PluginProcessMsg_Shutdown()); | 189 SendOnChannel(new PluginProcessMsg_Shutdown()); |
143 } | 190 } |
OLD | NEW |