1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "webkit/glue/webkitclient_impl.h"
6
7 #if defined(OS_LINUX)
8 #include <malloc.h>
9 #endif
10
11 #include <math.h>
12
13 #include <vector>
14
15 #include "base/debug/trace_event.h"
16 #include "base/memory/singleton.h"
17 #include "base/message_loop.h"
18 #include "base/metrics/histogram.h"
19 #include "base/metrics/stats_counters.h"
20 #include "base/platform_file.h"
21 #include "base/process_util.h"
22 #include "base/rand_util.h"
23 #include "base/string_number_conversions.h"
24 #include "base/string_util.h"
25 #include "base/synchronization/lock.h"
26 #include "base/time.h"
27 #include "base/utf_string_conversions.h"
28 #include "gpu/common/gpu_trace_event.h"
29 #include "grit/webkit_chromium_resources.h"
30 #include "grit/webkit_resources.h"
31 #include "grit/webkit_strings.h"
32 #include "third_party/WebKit/Source/WebKit/chromium/public/WebCookie.h"
33 #include "third_party/WebKit/Source/WebKit/chromium/public/WebData.h"
34 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrameClient.h"
35 #include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginListBuilder.h"
36 #include "third_party/WebKit/Source/WebKit/chromium/public/WebScreenInfo.h"
37 #include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h"
38 #include "third_party/WebKit/Source/WebKit/chromium/public/WebVector.h"
39 #include "third_party/WebKit/Source/WebKit/chromium/public/WebURL.h"
40 #include "webkit/glue/media/audio_decoder.h"
41 #include "webkit/plugins/npapi/plugin_instance.h"
42 #include "webkit/plugins/npapi/webplugininfo.h"
43 #include "webkit/glue/webkit_glue.h"
44 #include "webkit/glue/websocketstreamhandle_impl.h"
45 #include "webkit/glue/weburlloader_impl.h"
46
47 #if defined(OS_LINUX)
48 #include "v8/include/v8.h"
49 #endif
50
51 using WebKit::WebAudioBus;
52 using WebKit::WebCookie;
53 using WebKit::WebData;
54 using WebKit::WebLocalizedString;
55 using WebKit::WebPluginListBuilder;
56 using WebKit::WebString;
57 using WebKit::WebSocketStreamHandle;
58 using WebKit::WebThemeEngine;
59 using WebKit::WebURL;
60 using WebKit::WebURLLoader;
61 using WebKit::WebVector;
62
63 namespace {
64
65 // A simple class to cache the memory usage for a given amount of time.
66 class MemoryUsageCache {
67 public:
68 // Retrieves the Singleton.
GetInstance()69 static MemoryUsageCache* GetInstance() {
70 return Singleton<MemoryUsageCache>::get();
71 }
72
MemoryUsageCache()73 MemoryUsageCache() : memory_value_(0) { Init(); }
~MemoryUsageCache()74 ~MemoryUsageCache() {}
75
Init()76 void Init() {
77 const unsigned int kCacheSeconds = 1;
78 cache_valid_time_ = base::TimeDelta::FromSeconds(kCacheSeconds);
79 }
80
81 // Returns true if the cached value is fresh.
82 // Returns false if the cached value is stale, or if |cached_value| is NULL.
IsCachedValueValid(size_t * cached_value)83 bool IsCachedValueValid(size_t* cached_value) {
84 base::AutoLock scoped_lock(lock_);
85 if (!cached_value)
86 return false;
87 if (base::Time::Now() - last_updated_time_ > cache_valid_time_)
88 return false;
89 *cached_value = memory_value_;
90 return true;
91 };
92
93 // Setter for |memory_value_|, refreshes |last_updated_time_|.
SetMemoryValue(const size_t value)94 void SetMemoryValue(const size_t value) {
95 base::AutoLock scoped_lock(lock_);
96 memory_value_ = value;
97 last_updated_time_ = base::Time::Now();
98 }
99
100 private:
101 // The cached memory value.
102 size_t memory_value_;
103
104 // How long the cached value should remain valid.
105 base::TimeDelta cache_valid_time_;
106
107 // The last time the cached value was updated.
108 base::Time last_updated_time_;
109
110 base::Lock lock_;
111 };
112
113 } // anonymous namespace
114
115 namespace webkit_glue {
116
ToMessageID(WebLocalizedString::Name name)117 static int ToMessageID(WebLocalizedString::Name name) {
118 switch (name) {
119 case WebLocalizedString::SubmitButtonDefaultLabel:
120 return IDS_FORM_SUBMIT_LABEL;
121 case WebLocalizedString::InputElementAltText:
122 return IDS_FORM_INPUT_ALT;
123 case WebLocalizedString::ResetButtonDefaultLabel:
124 return IDS_FORM_RESET_LABEL;
125 case WebLocalizedString::FileButtonChooseFileLabel:
126 return IDS_FORM_FILE_BUTTON_LABEL;
127 case WebLocalizedString::FileButtonNoFileSelectedLabel:
128 return IDS_FORM_FILE_NO_FILE_LABEL;
129 case WebLocalizedString::MultipleFileUploadText:
130 return IDS_FORM_FILE_MULTIPLE_UPLOAD;
131 case WebLocalizedString::SearchableIndexIntroduction:
132 return IDS_SEARCHABLE_INDEX_INTRO;
133 case WebLocalizedString::SearchMenuNoRecentSearchesText:
134 return IDS_RECENT_SEARCHES_NONE;
135 case WebLocalizedString::SearchMenuRecentSearchesText:
136 return IDS_RECENT_SEARCHES;
137 case WebLocalizedString::SearchMenuClearRecentSearchesText:
138 return IDS_RECENT_SEARCHES_CLEAR;
139 case WebLocalizedString::AXWebAreaText:
140 return IDS_AX_ROLE_WEB_AREA;
141 case WebLocalizedString::AXLinkText:
142 return IDS_AX_ROLE_LINK;
143 case WebLocalizedString::AXListMarkerText:
144 return IDS_AX_ROLE_LIST_MARKER;
145 case WebLocalizedString::AXImageMapText:
146 return IDS_AX_ROLE_IMAGE_MAP;
147 case WebLocalizedString::AXHeadingText:
148 return IDS_AX_ROLE_HEADING;
149 case WebLocalizedString::AXButtonActionVerb:
150 return IDS_AX_BUTTON_ACTION_VERB;
151 case WebLocalizedString::AXRadioButtonActionVerb:
152 return IDS_AX_RADIO_BUTTON_ACTION_VERB;
153 case WebLocalizedString::AXTextFieldActionVerb:
154 return IDS_AX_TEXT_FIELD_ACTION_VERB;
155 case WebLocalizedString::AXCheckedCheckBoxActionVerb:
156 return IDS_AX_CHECKED_CHECK_BOX_ACTION_VERB;
157 case WebLocalizedString::AXUncheckedCheckBoxActionVerb:
158 return IDS_AX_UNCHECKED_CHECK_BOX_ACTION_VERB;
159 case WebLocalizedString::AXLinkActionVerb:
160 return IDS_AX_LINK_ACTION_VERB;
161 case WebLocalizedString::KeygenMenuHighGradeKeySize:
162 return IDS_KEYGEN_HIGH_GRADE_KEY;
163 case WebLocalizedString::KeygenMenuMediumGradeKeySize:
164 return IDS_KEYGEN_MED_GRADE_KEY;
165 case WebLocalizedString::ValidationValueMissing:
166 return IDS_FORM_VALIDATION_VALUE_MISSING;
167 case WebLocalizedString::ValidationValueMissingForCheckbox:
168 return IDS_FORM_VALIDATION_VALUE_MISSING_CHECKBOX;
169 case WebLocalizedString::ValidationValueMissingForFile:
170 return IDS_FORM_VALIDATION_VALUE_MISSING_FILE;
171 case WebLocalizedString::ValidationValueMissingForMultipleFile:
172 return IDS_FORM_VALIDATION_VALUE_MISSING_MULTIPLE_FILE;
173 case WebLocalizedString::ValidationValueMissingForRadio:
174 return IDS_FORM_VALIDATION_VALUE_MISSING_RADIO;
175 case WebLocalizedString::ValidationValueMissingForSelect:
176 return IDS_FORM_VALIDATION_VALUE_MISSING_SELECT;
177 case WebLocalizedString::ValidationTypeMismatch:
178 return IDS_FORM_VALIDATION_TYPE_MISMATCH;
179 case WebLocalizedString::ValidationTypeMismatchForEmail:
180 return IDS_FORM_VALIDATION_TYPE_MISMATCH_EMAIL;
181 case WebLocalizedString::ValidationTypeMismatchForMultipleEmail:
182 return IDS_FORM_VALIDATION_TYPE_MISMATCH_MULTIPLE_EMAIL;
183 case WebLocalizedString::ValidationTypeMismatchForURL:
184 return IDS_FORM_VALIDATION_TYPE_MISMATCH_URL;
185 case WebLocalizedString::ValidationPatternMismatch:
186 return IDS_FORM_VALIDATION_PATTERN_MISMATCH;
187 case WebLocalizedString::ValidationTooLong:
188 return IDS_FORM_VALIDATION_TOO_LONG;
189 case WebLocalizedString::ValidationRangeUnderflow:
190 return IDS_FORM_VALIDATION_RANGE_UNDERFLOW;
191 case WebLocalizedString::ValidationRangeOverflow:
192 return IDS_FORM_VALIDATION_RANGE_OVERFLOW;
193 case WebLocalizedString::ValidationStepMismatch:
194 return IDS_FORM_VALIDATION_STEP_MISMATCH;
195 }
196 return -1;
197 }
198
WebKitClientImpl()199 WebKitClientImpl::WebKitClientImpl()
200 : main_loop_(MessageLoop::current()),
201 shared_timer_func_(NULL),
202 shared_timer_fire_time_(0.0),
203 shared_timer_suspended_(0) {
204 }
205
~WebKitClientImpl()206 WebKitClientImpl::~WebKitClientImpl() {
207 }
208
themeEngine()209 WebThemeEngine* WebKitClientImpl::themeEngine() {
210 #if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_MACOSX)
211 return &theme_engine_;
212 #else
213 return NULL;
214 #endif
215 }
216
createURLLoader()217 WebURLLoader* WebKitClientImpl::createURLLoader() {
218 return new WebURLLoaderImpl();
219 }
220
createSocketStreamHandle()221 WebSocketStreamHandle* WebKitClientImpl::createSocketStreamHandle() {
222 return new WebSocketStreamHandleImpl();
223 }
224
userAgent(const WebURL & url)225 WebString WebKitClientImpl::userAgent(const WebURL& url) {
226 return WebString::fromUTF8(webkit_glue::GetUserAgent(url));
227 }
228
getPluginList(bool refresh,WebPluginListBuilder * builder)229 void WebKitClientImpl::getPluginList(bool refresh,
230 WebPluginListBuilder* builder) {
231 std::vector<webkit::npapi::WebPluginInfo> plugins;
232 GetPlugins(refresh, &plugins);
233
234 for (size_t i = 0; i < plugins.size(); ++i) {
235 const webkit::npapi::WebPluginInfo& plugin = plugins[i];
236
237 builder->addPlugin(
238 plugin.name, plugin.desc,
239 FilePathStringToWebString(plugin.path.BaseName().value()));
240
241 for (size_t j = 0; j < plugin.mime_types.size(); ++j) {
242 const webkit::npapi::WebPluginMimeType& mime_type = plugin.mime_types[j];
243
244 builder->addMediaTypeToLastPlugin(
245 WebString::fromUTF8(mime_type.mime_type), mime_type.description);
246
247 for (size_t k = 0; k < mime_type.file_extensions.size(); ++k) {
248 builder->addFileExtensionToLastMediaType(
249 UTF8ToUTF16(mime_type.file_extensions[k]));
250 }
251 }
252 }
253 }
254
decrementStatsCounter(const char * name)255 void WebKitClientImpl::decrementStatsCounter(const char* name) {
256 base::StatsCounter(name).Decrement();
257 }
258
incrementStatsCounter(const char * name)259 void WebKitClientImpl::incrementStatsCounter(const char* name) {
260 base::StatsCounter(name).Increment();
261 }
262
histogramCustomCounts(const char * name,int sample,int min,int max,int bucket_count)263 void WebKitClientImpl::histogramCustomCounts(
264 const char* name, int sample, int min, int max, int bucket_count) {
265 // Copied from histogram macro, but without the static variable caching
266 // the histogram because name is dynamic.
267 base::Histogram* counter =
268 base::Histogram::FactoryGet(name, min, max, bucket_count,
269 base::Histogram::kUmaTargetedHistogramFlag);
270 DCHECK_EQ(name, counter->histogram_name());
271 counter->Add(sample);
272 }
273
histogramEnumeration(const char * name,int sample,int boundary_value)274 void WebKitClientImpl::histogramEnumeration(
275 const char* name, int sample, int boundary_value) {
276 // Copied from histogram macro, but without the static variable caching
277 // the histogram because name is dynamic.
278 base::Histogram* counter =
279 base::LinearHistogram::FactoryGet(name, 1, boundary_value,
280 boundary_value + 1, base::Histogram::kUmaTargetedHistogramFlag);
281 DCHECK_EQ(name, counter->histogram_name());
282 counter->Add(sample);
283 }
284
traceEventBegin(const char * name,void * id,const char * extra)285 void WebKitClientImpl::traceEventBegin(const char* name, void* id,
286 const char* extra) {
287 TRACE_EVENT_BEGIN(name, id, extra);
288 GPU_TRACE_EVENT_BEGIN2("webkit", name,
289 "id", StringPrintf("%p", id).c_str(),
290 "extra", extra ? extra : "");
291 }
292
traceEventEnd(const char * name,void * id,const char * extra)293 void WebKitClientImpl::traceEventEnd(const char* name, void* id,
294 const char* extra) {
295 TRACE_EVENT_END(name, id, extra);
296 GPU_TRACE_EVENT_END0("webkit", name);
297 }
298
299 namespace {
300
loadAudioSpatializationResource(const char * name)301 WebData loadAudioSpatializationResource(const char* name) {
302 #ifdef IDR_AUDIO_SPATIALIZATION_T000_P000
303 const size_t kExpectedSpatializationNameLength = 31;
304 if (strlen(name) != kExpectedSpatializationNameLength) {
305 return WebData();
306 }
307
308 // Extract the azimuth and elevation from the resource name.
309 int azimuth = 0;
310 int elevation = 0;
311 int values_parsed =
312 sscanf(name, "IRC_Composite_C_R0195_T%3d_P%3d", &azimuth, &elevation);
313 if (values_parsed != 2) {
314 return WebData();
315 }
316
317 // The resource index values go through the elevations first, then azimuths.
318 const int kAngleSpacing = 15;
319
320 // 0 <= elevation <= 90 (or 315 <= elevation <= 345)
321 // in increments of 15 degrees.
322 int elevation_index =
323 elevation <= 90 ? elevation / kAngleSpacing :
324 7 + (elevation - 315) / kAngleSpacing;
325 bool is_elevation_index_good = 0 <= elevation_index && elevation_index < 10;
326
327 // 0 <= azimuth < 360 in increments of 15 degrees.
328 int azimuth_index = azimuth / kAngleSpacing;
329 bool is_azimuth_index_good = 0 <= azimuth_index && azimuth_index < 24;
330
331 const int kNumberOfElevations = 10;
332 const int kNumberOfAudioResources = 240;
333 int resource_index = kNumberOfElevations * azimuth_index + elevation_index;
334 bool is_resource_index_good = 0 <= resource_index &&
335 resource_index < kNumberOfAudioResources;
336
337 if (is_azimuth_index_good && is_elevation_index_good &&
338 is_resource_index_good) {
339 const int kFirstAudioResourceIndex = IDR_AUDIO_SPATIALIZATION_T000_P000;
340 base::StringPiece resource =
341 GetDataResource(kFirstAudioResourceIndex + resource_index);
342 return WebData(resource.data(), resource.size());
343 }
344 #endif // IDR_AUDIO_SPATIALIZATION_T000_P000
345
346 NOTREACHED();
347 return WebData();
348 }
349
350 } // namespace
351
loadResource(const char * name)352 WebData WebKitClientImpl::loadResource(const char* name) {
353 struct {
354 const char* name;
355 int id;
356 } resources[] = {
357 { "missingImage", IDR_BROKENIMAGE },
358 { "mediaPause", IDR_MEDIA_PAUSE_BUTTON },
359 { "mediaPlay", IDR_MEDIA_PLAY_BUTTON },
360 { "mediaPlayDisabled", IDR_MEDIA_PLAY_BUTTON_DISABLED },
361 { "mediaSoundDisabled", IDR_MEDIA_SOUND_DISABLED },
362 { "mediaSoundFull", IDR_MEDIA_SOUND_FULL_BUTTON },
363 { "mediaSoundNone", IDR_MEDIA_SOUND_NONE_BUTTON },
364 { "mediaSliderThumb", IDR_MEDIA_SLIDER_THUMB },
365 { "mediaVolumeSliderThumb", IDR_MEDIA_VOLUME_SLIDER_THUMB },
366 { "panIcon", IDR_PAN_SCROLL_ICON },
367 { "searchCancel", IDR_SEARCH_CANCEL },
368 { "searchCancelPressed", IDR_SEARCH_CANCEL_PRESSED },
369 { "searchMagnifier", IDR_SEARCH_MAGNIFIER },
370 { "searchMagnifierResults", IDR_SEARCH_MAGNIFIER_RESULTS },
371 { "textAreaResizeCorner", IDR_TEXTAREA_RESIZER },
372 { "tickmarkDash", IDR_TICKMARK_DASH },
373 { "inputSpeech", IDR_INPUT_SPEECH },
374 { "inputSpeechRecording", IDR_INPUT_SPEECH_RECORDING },
375 { "inputSpeechWaiting", IDR_INPUT_SPEECH_WAITING },
376 { "americanExpressCC", IDR_AUTOFILL_CC_AMEX },
377 { "dinersCC", IDR_AUTOFILL_CC_DINERS },
378 { "discoverCC", IDR_AUTOFILL_CC_DISCOVER },
379 { "genericCC", IDR_AUTOFILL_CC_GENERIC },
380 { "jcbCC", IDR_AUTOFILL_CC_JCB },
381 { "masterCardCC", IDR_AUTOFILL_CC_MASTERCARD },
382 { "soloCC", IDR_AUTOFILL_CC_SOLO },
383 { "visaCC", IDR_AUTOFILL_CC_VISA },
384 };
385
386 // Check the name prefix to see if it's an audio resource.
387 if (StartsWithASCII(name, "IRC_Composite", true)) {
388 return loadAudioSpatializationResource(name);
389 } else {
390 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(resources); ++i) {
391 if (!strcmp(name, resources[i].name)) {
392 base::StringPiece resource = GetDataResource(resources[i].id);
393 return WebData(resource.data(), resource.size());
394 }
395 }
396 }
397 // TODO(jhawkins): Restore this NOTREACHED once WK stops sending in empty
398 // strings. http://crbug.com/50675.
399 //NOTREACHED() << "Unknown image resource " << name;
400 return WebData();
401 }
402
loadAudioResource(WebKit::WebAudioBus * destination_bus,const char * audio_file_data,size_t data_size,double sample_rate)403 bool WebKitClientImpl::loadAudioResource(
404 WebKit::WebAudioBus* destination_bus, const char* audio_file_data,
405 size_t data_size, double sample_rate) {
406 return DecodeAudioFileData(destination_bus,
407 audio_file_data,
408 data_size,
409 sample_rate);
410 }
411
queryLocalizedString(WebLocalizedString::Name name)412 WebString WebKitClientImpl::queryLocalizedString(
413 WebLocalizedString::Name name) {
414 int message_id = ToMessageID(name);
415 if (message_id < 0)
416 return WebString();
417 return GetLocalizedString(message_id);
418 }
419
queryLocalizedString(WebLocalizedString::Name name,int numeric_value)420 WebString WebKitClientImpl::queryLocalizedString(
421 WebLocalizedString::Name name, int numeric_value) {
422 return queryLocalizedString(name, base::IntToString16(numeric_value));
423 }
424
queryLocalizedString(WebLocalizedString::Name name,const WebString & value)425 WebString WebKitClientImpl::queryLocalizedString(
426 WebLocalizedString::Name name, const WebString& value) {
427 int message_id = ToMessageID(name);
428 if (message_id < 0)
429 return WebString();
430 return ReplaceStringPlaceholders(GetLocalizedString(message_id), value, NULL);
431 }
432
queryLocalizedString(WebLocalizedString::Name name,const WebString & value1,const WebString & value2)433 WebString WebKitClientImpl::queryLocalizedString(
434 WebLocalizedString::Name name,
435 const WebString& value1,
436 const WebString& value2) {
437 int message_id = ToMessageID(name);
438 if (message_id < 0)
439 return WebString();
440 std::vector<string16> values;
441 values.reserve(2);
442 values.push_back(value1);
443 values.push_back(value2);
444 return ReplaceStringPlaceholders(
445 GetLocalizedString(message_id), values, NULL);
446 }
447
currentTime()448 double WebKitClientImpl::currentTime() {
449 return base::Time::Now().ToDoubleT();
450 }
451
cryptographicallyRandomValues(unsigned char * buffer,size_t length)452 void WebKitClientImpl::cryptographicallyRandomValues(
453 unsigned char* buffer, size_t length) {
454 uint64 bytes = 0;
455 for (size_t i = 0; i < length; ++i) {
456 size_t offset = i % sizeof(bytes);
457 if (!offset)
458 bytes = base::RandUint64();
459 buffer[i] = reinterpret_cast<unsigned char*>(&bytes)[offset];
460 }
461 }
462
setSharedTimerFiredFunction(void (* func)())463 void WebKitClientImpl::setSharedTimerFiredFunction(void (*func)()) {
464 shared_timer_func_ = func;
465 }
466
setSharedTimerFireTime(double fire_time)467 void WebKitClientImpl::setSharedTimerFireTime(double fire_time) {
468 shared_timer_fire_time_ = fire_time;
469 if (shared_timer_suspended_)
470 return;
471
472 // By converting between double and int64 representation, we run the risk
473 // of losing precision due to rounding errors. Performing computations in
474 // microseconds reduces this risk somewhat. But there still is the potential
475 // of us computing a fire time for the timer that is shorter than what we
476 // need.
477 // As the event loop will check event deadlines prior to actually firing
478 // them, there is a risk of needlessly rescheduling events and of
479 // needlessly looping if sleep times are too short even by small amounts.
480 // This results in measurable performance degradation unless we use ceil() to
481 // always round up the sleep times.
482 int64 interval = static_cast<int64>(
483 ceil((fire_time - currentTime()) * base::Time::kMicrosecondsPerSecond));
484 if (interval < 0)
485 interval = 0;
486
487 shared_timer_.Stop();
488 shared_timer_.Start(base::TimeDelta::FromMicroseconds(interval), this,
489 &WebKitClientImpl::DoTimeout);
490 }
491
stopSharedTimer()492 void WebKitClientImpl::stopSharedTimer() {
493 shared_timer_.Stop();
494 }
495
callOnMainThread(void (* func)(void *),void * context)496 void WebKitClientImpl::callOnMainThread(void (*func)(void*), void* context) {
497 main_loop_->PostTask(FROM_HERE, NewRunnableFunction(func, context));
498 }
499
databaseOpenFile(const WebKit::WebString & vfs_file_name,int desired_flags)500 base::PlatformFile WebKitClientImpl::databaseOpenFile(
501 const WebKit::WebString& vfs_file_name, int desired_flags) {
502 return base::kInvalidPlatformFileValue;
503 }
504
databaseDeleteFile(const WebKit::WebString & vfs_file_name,bool sync_dir)505 int WebKitClientImpl::databaseDeleteFile(
506 const WebKit::WebString& vfs_file_name, bool sync_dir) {
507 return -1;
508 }
509
databaseGetFileAttributes(const WebKit::WebString & vfs_file_name)510 long WebKitClientImpl::databaseGetFileAttributes(
511 const WebKit::WebString& vfs_file_name) {
512 return 0;
513 }
514
databaseGetFileSize(const WebKit::WebString & vfs_file_name)515 long long WebKitClientImpl::databaseGetFileSize(
516 const WebKit::WebString& vfs_file_name) {
517 return 0;
518 }
519
signedPublicKeyAndChallengeString(unsigned key_size_index,const WebKit::WebString & challenge,const WebKit::WebURL & url)520 WebKit::WebString WebKitClientImpl::signedPublicKeyAndChallengeString(
521 unsigned key_size_index,
522 const WebKit::WebString& challenge,
523 const WebKit::WebURL& url) {
524 NOTREACHED();
525 return WebKit::WebString();
526 }
527
528 #if defined(OS_LINUX)
memoryUsageMBLinux()529 static size_t memoryUsageMBLinux() {
530 struct mallinfo minfo = mallinfo();
531 uint64_t mem_usage =
532 #if defined(USE_TCMALLOC)
533 minfo.uordblks
534 #else
535 (minfo.hblkhd + minfo.arena)
536 #endif
537 >> 20;
538
539 v8::HeapStatistics stat;
540 v8::V8::GetHeapStatistics(&stat);
541 return mem_usage + (static_cast<uint64_t>(stat.total_heap_size()) >> 20);
542 }
543 #endif
544
545 #if defined(OS_MACOSX)
memoryUsageMBMac()546 static size_t memoryUsageMBMac() {
547 using base::ProcessMetrics;
548 static ProcessMetrics* process_metrics =
549 // The default port provider is sufficient to get data for the current
550 // process.
551 ProcessMetrics::CreateProcessMetrics(base::GetCurrentProcessHandle(),
552 NULL);
553 DCHECK(process_metrics);
554 return process_metrics->GetPagefileUsage() >> 20;
555 }
556 #endif
557
558 #if !defined(OS_LINUX) && !defined(OS_MACOSX)
memoryUsageMBGeneric()559 static size_t memoryUsageMBGeneric() {
560 using base::ProcessMetrics;
561 static ProcessMetrics* process_metrics =
562 ProcessMetrics::CreateProcessMetrics(base::GetCurrentProcessHandle());
563 DCHECK(process_metrics);
564 return process_metrics->GetPagefileUsage() >> 20;
565 }
566 #endif
567
getMemoryUsageMB(bool bypass_cache)568 static size_t getMemoryUsageMB(bool bypass_cache) {
569 size_t current_mem_usage = 0;
570 MemoryUsageCache* mem_usage_cache_singleton = MemoryUsageCache::GetInstance();
571 if (!bypass_cache &&
572 mem_usage_cache_singleton->IsCachedValueValid(¤t_mem_usage))
573 return current_mem_usage;
574
575 current_mem_usage =
576 #if defined(OS_LINUX)
577 memoryUsageMBLinux();
578 #elif defined(OS_MACOSX)
579 memoryUsageMBMac();
580 #else
581 memoryUsageMBGeneric();
582 #endif
583 mem_usage_cache_singleton->SetMemoryValue(current_mem_usage);
584 return current_mem_usage;
585 }
586
memoryUsageMB()587 size_t WebKitClientImpl::memoryUsageMB() {
588 return getMemoryUsageMB(false);
589 }
590
actualMemoryUsageMB()591 size_t WebKitClientImpl::actualMemoryUsageMB() {
592 return getMemoryUsageMB(true);
593 }
594
SuspendSharedTimer()595 void WebKitClientImpl::SuspendSharedTimer() {
596 ++shared_timer_suspended_;
597 }
598
ResumeSharedTimer()599 void WebKitClientImpl::ResumeSharedTimer() {
600 // The shared timer may have fired or been adjusted while we were suspended.
601 if (--shared_timer_suspended_ == 0 && !shared_timer_.IsRunning())
602 setSharedTimerFireTime(shared_timer_fire_time_);
603 }
604
605 } // namespace webkit_glue
606