• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(&current_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