Home | History | Annotate | Download | only in child
      1 // Copyright 2014 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 "content/child/blink_platform_impl.h"
      6 
      7 #include <math.h>
      8 
      9 #include <vector>
     10 
     11 #include "base/allocator/allocator_extension.h"
     12 #include "base/bind.h"
     13 #include "base/files/file_path.h"
     14 #include "base/memory/scoped_ptr.h"
     15 #include "base/memory/singleton.h"
     16 #include "base/message_loop/message_loop.h"
     17 #include "base/metrics/histogram.h"
     18 #include "base/metrics/sparse_histogram.h"
     19 #include "base/metrics/stats_counters.h"
     20 #include "base/process/process_metrics.h"
     21 #include "base/rand_util.h"
     22 #include "base/strings/string_number_conversions.h"
     23 #include "base/strings/string_util.h"
     24 #include "base/strings/utf_string_conversions.h"
     25 #include "base/synchronization/lock.h"
     26 #include "base/synchronization/waitable_event.h"
     27 #include "base/sys_info.h"
     28 #include "base/threading/platform_thread.h"
     29 #include "base/time/time.h"
     30 #include "blink/public/resources/grit/blink_resources.h"
     31 #include "content/app/resources/grit/content_resources.h"
     32 #include "content/app/strings/grit/content_strings.h"
     33 #include "content/child/child_thread.h"
     34 #include "content/child/content_child_helpers.h"
     35 #include "content/child/touch_fling_gesture_curve.h"
     36 #include "content/child/web_discardable_memory_impl.h"
     37 #include "content/child/web_socket_stream_handle_impl.h"
     38 #include "content/child/web_url_loader_impl.h"
     39 #include "content/child/websocket_bridge.h"
     40 #include "content/child/webthread_impl.h"
     41 #include "content/child/worker_task_runner.h"
     42 #include "content/public/common/content_client.h"
     43 #include "net/base/data_url.h"
     44 #include "net/base/mime_util.h"
     45 #include "net/base/net_errors.h"
     46 #include "net/base/net_util.h"
     47 #include "third_party/WebKit/public/platform/WebConvertableToTraceFormat.h"
     48 #include "third_party/WebKit/public/platform/WebData.h"
     49 #include "third_party/WebKit/public/platform/WebString.h"
     50 #include "third_party/WebKit/public/platform/WebURL.h"
     51 #include "third_party/WebKit/public/platform/WebWaitableEvent.h"
     52 #include "third_party/WebKit/public/web/WebSecurityOrigin.h"
     53 #include "ui/base/layout.h"
     54 
     55 #if defined(OS_ANDROID)
     56 #include "content/child/fling_animator_impl_android.h"
     57 #endif
     58 
     59 #if !defined(NO_TCMALLOC) && defined(USE_TCMALLOC) && !defined(OS_WIN)
     60 #include "third_party/tcmalloc/chromium/src/gperftools/heap-profiler.h"
     61 #endif
     62 
     63 using blink::WebData;
     64 using blink::WebFallbackThemeEngine;
     65 using blink::WebLocalizedString;
     66 using blink::WebString;
     67 using blink::WebSocketStreamHandle;
     68 using blink::WebThemeEngine;
     69 using blink::WebURL;
     70 using blink::WebURLError;
     71 using blink::WebURLLoader;
     72 
     73 namespace content {
     74 
     75 namespace {
     76 
     77 class WebWaitableEventImpl : public blink::WebWaitableEvent {
     78  public:
     79   WebWaitableEventImpl() : impl_(new base::WaitableEvent(false, false)) {}
     80   virtual ~WebWaitableEventImpl() {}
     81 
     82   virtual void wait() { impl_->Wait(); }
     83   virtual void signal() { impl_->Signal(); }
     84 
     85   base::WaitableEvent* impl() {
     86     return impl_.get();
     87   }
     88 
     89  private:
     90   scoped_ptr<base::WaitableEvent> impl_;
     91   DISALLOW_COPY_AND_ASSIGN(WebWaitableEventImpl);
     92 };
     93 
     94 // A simple class to cache the memory usage for a given amount of time.
     95 class MemoryUsageCache {
     96  public:
     97   // Retrieves the Singleton.
     98   static MemoryUsageCache* GetInstance() {
     99     return Singleton<MemoryUsageCache>::get();
    100   }
    101 
    102   MemoryUsageCache() : memory_value_(0) { Init(); }
    103   ~MemoryUsageCache() {}
    104 
    105   void Init() {
    106     const unsigned int kCacheSeconds = 1;
    107     cache_valid_time_ = base::TimeDelta::FromSeconds(kCacheSeconds);
    108   }
    109 
    110   // Returns true if the cached value is fresh.
    111   // Returns false if the cached value is stale, or if |cached_value| is NULL.
    112   bool IsCachedValueValid(size_t* cached_value) {
    113     base::AutoLock scoped_lock(lock_);
    114     if (!cached_value)
    115       return false;
    116     if (base::Time::Now() - last_updated_time_ > cache_valid_time_)
    117       return false;
    118     *cached_value = memory_value_;
    119     return true;
    120   };
    121 
    122   // Setter for |memory_value_|, refreshes |last_updated_time_|.
    123   void SetMemoryValue(const size_t value) {
    124     base::AutoLock scoped_lock(lock_);
    125     memory_value_ = value;
    126     last_updated_time_ = base::Time::Now();
    127   }
    128 
    129  private:
    130   // The cached memory value.
    131   size_t memory_value_;
    132 
    133   // How long the cached value should remain valid.
    134   base::TimeDelta cache_valid_time_;
    135 
    136   // The last time the cached value was updated.
    137   base::Time last_updated_time_;
    138 
    139   base::Lock lock_;
    140 };
    141 
    142 class ConvertableToTraceFormatWrapper
    143     : public base::debug::ConvertableToTraceFormat {
    144  public:
    145   explicit ConvertableToTraceFormatWrapper(
    146       const blink::WebConvertableToTraceFormat& convertable)
    147       : convertable_(convertable) {}
    148   virtual void AppendAsTraceFormat(std::string* out) const OVERRIDE {
    149     *out += convertable_.asTraceFormat().utf8();
    150   }
    151 
    152  private:
    153   virtual ~ConvertableToTraceFormatWrapper() {}
    154 
    155   blink::WebConvertableToTraceFormat convertable_;
    156 };
    157 
    158 bool isHostnameReservedIPAddress(const std::string& host) {
    159   net::IPAddressNumber address;
    160   if (!net::ParseURLHostnameToNumber(host, &address))
    161     return false;
    162   return net::IsIPAddressReserved(address);
    163 }
    164 
    165 }  // namespace
    166 
    167 static int ToMessageID(WebLocalizedString::Name name) {
    168   switch (name) {
    169     case WebLocalizedString::AXAMPMFieldText:
    170       return IDS_AX_AM_PM_FIELD_TEXT;
    171     case WebLocalizedString::AXButtonActionVerb:
    172       return IDS_AX_BUTTON_ACTION_VERB;
    173     case WebLocalizedString::AXCalendarShowMonthSelector:
    174       return IDS_AX_CALENDAR_SHOW_MONTH_SELECTOR;
    175     case WebLocalizedString::AXCalendarShowNextMonth:
    176       return IDS_AX_CALENDAR_SHOW_NEXT_MONTH;
    177     case WebLocalizedString::AXCalendarShowPreviousMonth:
    178       return IDS_AX_CALENDAR_SHOW_PREVIOUS_MONTH;
    179     case WebLocalizedString::AXCalendarWeekDescription:
    180       return IDS_AX_CALENDAR_WEEK_DESCRIPTION;
    181     case WebLocalizedString::AXCheckedCheckBoxActionVerb:
    182       return IDS_AX_CHECKED_CHECK_BOX_ACTION_VERB;
    183     case WebLocalizedString::AXDateTimeFieldEmptyValueText:
    184       return IDS_AX_DATE_TIME_FIELD_EMPTY_VALUE_TEXT;
    185     case WebLocalizedString::AXDayOfMonthFieldText:
    186       return IDS_AX_DAY_OF_MONTH_FIELD_TEXT;
    187     case WebLocalizedString::AXHeadingText:
    188       return IDS_AX_ROLE_HEADING;
    189     case WebLocalizedString::AXHourFieldText:
    190       return IDS_AX_HOUR_FIELD_TEXT;
    191     case WebLocalizedString::AXImageMapText:
    192       return IDS_AX_ROLE_IMAGE_MAP;
    193     case WebLocalizedString::AXLinkActionVerb:
    194       return IDS_AX_LINK_ACTION_VERB;
    195     case WebLocalizedString::AXLinkText:
    196       return IDS_AX_ROLE_LINK;
    197     case WebLocalizedString::AXListMarkerText:
    198       return IDS_AX_ROLE_LIST_MARKER;
    199     case WebLocalizedString::AXMediaDefault:
    200       return IDS_AX_MEDIA_DEFAULT;
    201     case WebLocalizedString::AXMediaAudioElement:
    202       return IDS_AX_MEDIA_AUDIO_ELEMENT;
    203     case WebLocalizedString::AXMediaVideoElement:
    204       return IDS_AX_MEDIA_VIDEO_ELEMENT;
    205     case WebLocalizedString::AXMediaMuteButton:
    206       return IDS_AX_MEDIA_MUTE_BUTTON;
    207     case WebLocalizedString::AXMediaUnMuteButton:
    208       return IDS_AX_MEDIA_UNMUTE_BUTTON;
    209     case WebLocalizedString::AXMediaPlayButton:
    210       return IDS_AX_MEDIA_PLAY_BUTTON;
    211     case WebLocalizedString::AXMediaPauseButton:
    212       return IDS_AX_MEDIA_PAUSE_BUTTON;
    213     case WebLocalizedString::AXMediaSlider:
    214       return IDS_AX_MEDIA_SLIDER;
    215     case WebLocalizedString::AXMediaSliderThumb:
    216       return IDS_AX_MEDIA_SLIDER_THUMB;
    217     case WebLocalizedString::AXMediaCurrentTimeDisplay:
    218       return IDS_AX_MEDIA_CURRENT_TIME_DISPLAY;
    219     case WebLocalizedString::AXMediaTimeRemainingDisplay:
    220       return IDS_AX_MEDIA_TIME_REMAINING_DISPLAY;
    221     case WebLocalizedString::AXMediaStatusDisplay:
    222       return IDS_AX_MEDIA_STATUS_DISPLAY;
    223     case WebLocalizedString::AXMediaEnterFullscreenButton:
    224       return IDS_AX_MEDIA_ENTER_FULL_SCREEN_BUTTON;
    225     case WebLocalizedString::AXMediaExitFullscreenButton:
    226       return IDS_AX_MEDIA_EXIT_FULL_SCREEN_BUTTON;
    227     case WebLocalizedString::AXMediaShowClosedCaptionsButton:
    228       return IDS_AX_MEDIA_SHOW_CLOSED_CAPTIONS_BUTTON;
    229     case WebLocalizedString::AXMediaHideClosedCaptionsButton:
    230       return IDS_AX_MEDIA_HIDE_CLOSED_CAPTIONS_BUTTON;
    231     case WebLocalizedString::AxMediaCastOffButton:
    232       return IDS_AX_MEDIA_CAST_OFF_BUTTON;
    233     case WebLocalizedString::AxMediaCastOnButton:
    234       return IDS_AX_MEDIA_CAST_ON_BUTTON;
    235     case WebLocalizedString::AXMediaAudioElementHelp:
    236       return IDS_AX_MEDIA_AUDIO_ELEMENT_HELP;
    237     case WebLocalizedString::AXMediaVideoElementHelp:
    238       return IDS_AX_MEDIA_VIDEO_ELEMENT_HELP;
    239     case WebLocalizedString::AXMediaMuteButtonHelp:
    240       return IDS_AX_MEDIA_MUTE_BUTTON_HELP;
    241     case WebLocalizedString::AXMediaUnMuteButtonHelp:
    242       return IDS_AX_MEDIA_UNMUTE_BUTTON_HELP;
    243     case WebLocalizedString::AXMediaPlayButtonHelp:
    244       return IDS_AX_MEDIA_PLAY_BUTTON_HELP;
    245     case WebLocalizedString::AXMediaPauseButtonHelp:
    246       return IDS_AX_MEDIA_PAUSE_BUTTON_HELP;
    247     case WebLocalizedString::AXMediaSliderHelp:
    248       return IDS_AX_MEDIA_SLIDER_HELP;
    249     case WebLocalizedString::AXMediaSliderThumbHelp:
    250       return IDS_AX_MEDIA_SLIDER_THUMB_HELP;
    251     case WebLocalizedString::AXMediaCurrentTimeDisplayHelp:
    252       return IDS_AX_MEDIA_CURRENT_TIME_DISPLAY_HELP;
    253     case WebLocalizedString::AXMediaTimeRemainingDisplayHelp:
    254       return IDS_AX_MEDIA_TIME_REMAINING_DISPLAY_HELP;
    255     case WebLocalizedString::AXMediaStatusDisplayHelp:
    256       return IDS_AX_MEDIA_STATUS_DISPLAY_HELP;
    257     case WebLocalizedString::AXMediaEnterFullscreenButtonHelp:
    258       return IDS_AX_MEDIA_ENTER_FULL_SCREEN_BUTTON_HELP;
    259     case WebLocalizedString::AXMediaExitFullscreenButtonHelp:
    260       return IDS_AX_MEDIA_EXIT_FULL_SCREEN_BUTTON_HELP;
    261     case WebLocalizedString::AXMediaShowClosedCaptionsButtonHelp:
    262       return IDS_AX_MEDIA_SHOW_CLOSED_CAPTIONS_BUTTON_HELP;
    263     case WebLocalizedString::AXMediaHideClosedCaptionsButtonHelp:
    264       return IDS_AX_MEDIA_HIDE_CLOSED_CAPTIONS_BUTTON_HELP;
    265     case WebLocalizedString::AxMediaCastOffButtonHelp:
    266       return IDS_AX_MEDIA_CAST_OFF_BUTTON_HELP;
    267     case WebLocalizedString::AxMediaCastOnButtonHelp:
    268       return IDS_AX_MEDIA_CAST_ON_BUTTON_HELP;
    269     case WebLocalizedString::AXMillisecondFieldText:
    270       return IDS_AX_MILLISECOND_FIELD_TEXT;
    271     case WebLocalizedString::AXMinuteFieldText:
    272       return IDS_AX_MINUTE_FIELD_TEXT;
    273     case WebLocalizedString::AXMonthFieldText:
    274       return IDS_AX_MONTH_FIELD_TEXT;
    275     case WebLocalizedString::AXRadioButtonActionVerb:
    276       return IDS_AX_RADIO_BUTTON_ACTION_VERB;
    277     case WebLocalizedString::AXSecondFieldText:
    278       return IDS_AX_SECOND_FIELD_TEXT;
    279     case WebLocalizedString::AXTextFieldActionVerb:
    280       return IDS_AX_TEXT_FIELD_ACTION_VERB;
    281     case WebLocalizedString::AXUncheckedCheckBoxActionVerb:
    282       return IDS_AX_UNCHECKED_CHECK_BOX_ACTION_VERB;
    283     case WebLocalizedString::AXWebAreaText:
    284       return IDS_AX_ROLE_WEB_AREA;
    285     case WebLocalizedString::AXWeekOfYearFieldText:
    286       return IDS_AX_WEEK_OF_YEAR_FIELD_TEXT;
    287     case WebLocalizedString::AXYearFieldText:
    288       return IDS_AX_YEAR_FIELD_TEXT;
    289     case WebLocalizedString::CalendarClear:
    290       return IDS_FORM_CALENDAR_CLEAR;
    291     case WebLocalizedString::CalendarToday:
    292       return IDS_FORM_CALENDAR_TODAY;
    293     case WebLocalizedString::DateFormatDayInMonthLabel:
    294       return IDS_FORM_DATE_FORMAT_DAY_IN_MONTH;
    295     case WebLocalizedString::DateFormatMonthLabel:
    296       return IDS_FORM_DATE_FORMAT_MONTH;
    297     case WebLocalizedString::DateFormatYearLabel:
    298       return IDS_FORM_DATE_FORMAT_YEAR;
    299     case WebLocalizedString::DetailsLabel:
    300       return IDS_DETAILS_WITHOUT_SUMMARY_LABEL;
    301     case WebLocalizedString::FileButtonChooseFileLabel:
    302       return IDS_FORM_FILE_BUTTON_LABEL;
    303     case WebLocalizedString::FileButtonChooseMultipleFilesLabel:
    304       return IDS_FORM_MULTIPLE_FILES_BUTTON_LABEL;
    305     case WebLocalizedString::FileButtonNoFileSelectedLabel:
    306       return IDS_FORM_FILE_NO_FILE_LABEL;
    307     case WebLocalizedString::InputElementAltText:
    308       return IDS_FORM_INPUT_ALT;
    309     case WebLocalizedString::KeygenMenuHighGradeKeySize:
    310       return IDS_KEYGEN_HIGH_GRADE_KEY;
    311     case WebLocalizedString::KeygenMenuMediumGradeKeySize:
    312       return IDS_KEYGEN_MED_GRADE_KEY;
    313     case WebLocalizedString::MissingPluginText:
    314       return IDS_PLUGIN_INITIALIZATION_ERROR;
    315     case WebLocalizedString::MultipleFileUploadText:
    316       return IDS_FORM_FILE_MULTIPLE_UPLOAD;
    317     case WebLocalizedString::OtherColorLabel:
    318       return IDS_FORM_OTHER_COLOR_LABEL;
    319     case WebLocalizedString::OtherDateLabel:
    320         return IDS_FORM_OTHER_DATE_LABEL;
    321     case WebLocalizedString::OtherMonthLabel:
    322       return IDS_FORM_OTHER_MONTH_LABEL;
    323     case WebLocalizedString::OtherTimeLabel:
    324       return IDS_FORM_OTHER_TIME_LABEL;
    325     case WebLocalizedString::OtherWeekLabel:
    326       return IDS_FORM_OTHER_WEEK_LABEL;
    327     case WebLocalizedString::PlaceholderForDayOfMonthField:
    328       return IDS_FORM_PLACEHOLDER_FOR_DAY_OF_MONTH_FIELD;
    329     case WebLocalizedString::PlaceholderForMonthField:
    330       return IDS_FORM_PLACEHOLDER_FOR_MONTH_FIELD;
    331     case WebLocalizedString::PlaceholderForYearField:
    332       return IDS_FORM_PLACEHOLDER_FOR_YEAR_FIELD;
    333     case WebLocalizedString::ResetButtonDefaultLabel:
    334       return IDS_FORM_RESET_LABEL;
    335     case WebLocalizedString::SearchableIndexIntroduction:
    336       return IDS_SEARCHABLE_INDEX_INTRO;
    337     case WebLocalizedString::SearchMenuClearRecentSearchesText:
    338       return IDS_RECENT_SEARCHES_CLEAR;
    339     case WebLocalizedString::SearchMenuNoRecentSearchesText:
    340       return IDS_RECENT_SEARCHES_NONE;
    341     case WebLocalizedString::SearchMenuRecentSearchesText:
    342       return IDS_RECENT_SEARCHES;
    343     case WebLocalizedString::SelectMenuListText:
    344       return IDS_FORM_SELECT_MENU_LIST_TEXT;
    345     case WebLocalizedString::SubmitButtonDefaultLabel:
    346       return IDS_FORM_SUBMIT_LABEL;
    347     case WebLocalizedString::ThisMonthButtonLabel:
    348       return IDS_FORM_THIS_MONTH_LABEL;
    349     case WebLocalizedString::ThisWeekButtonLabel:
    350       return IDS_FORM_THIS_WEEK_LABEL;
    351     case WebLocalizedString::ValidationBadInputForDateTime:
    352       return IDS_FORM_VALIDATION_BAD_INPUT_DATETIME;
    353     case WebLocalizedString::ValidationBadInputForNumber:
    354       return IDS_FORM_VALIDATION_BAD_INPUT_NUMBER;
    355     case WebLocalizedString::ValidationPatternMismatch:
    356       return IDS_FORM_VALIDATION_PATTERN_MISMATCH;
    357     case WebLocalizedString::ValidationRangeOverflow:
    358       return IDS_FORM_VALIDATION_RANGE_OVERFLOW;
    359     case WebLocalizedString::ValidationRangeOverflowDateTime:
    360       return IDS_FORM_VALIDATION_RANGE_OVERFLOW_DATETIME;
    361     case WebLocalizedString::ValidationRangeUnderflow:
    362       return IDS_FORM_VALIDATION_RANGE_UNDERFLOW;
    363     case WebLocalizedString::ValidationRangeUnderflowDateTime:
    364       return IDS_FORM_VALIDATION_RANGE_UNDERFLOW_DATETIME;
    365     case WebLocalizedString::ValidationStepMismatch:
    366       return IDS_FORM_VALIDATION_STEP_MISMATCH;
    367     case WebLocalizedString::ValidationStepMismatchCloseToLimit:
    368       return IDS_FORM_VALIDATION_STEP_MISMATCH_CLOSE_TO_LIMIT;
    369     case WebLocalizedString::ValidationTooLong:
    370       return IDS_FORM_VALIDATION_TOO_LONG;
    371     case WebLocalizedString::ValidationTypeMismatch:
    372       return IDS_FORM_VALIDATION_TYPE_MISMATCH;
    373     case WebLocalizedString::ValidationTypeMismatchForEmail:
    374       return IDS_FORM_VALIDATION_TYPE_MISMATCH_EMAIL;
    375     case WebLocalizedString::ValidationTypeMismatchForEmailEmpty:
    376       return IDS_FORM_VALIDATION_TYPE_MISMATCH_EMAIL_EMPTY;
    377     case WebLocalizedString::ValidationTypeMismatchForEmailEmptyDomain:
    378       return IDS_FORM_VALIDATION_TYPE_MISMATCH_EMAIL_EMPTY_DOMAIN;
    379     case WebLocalizedString::ValidationTypeMismatchForEmailEmptyLocal:
    380       return IDS_FORM_VALIDATION_TYPE_MISMATCH_EMAIL_EMPTY_LOCAL;
    381     case WebLocalizedString::ValidationTypeMismatchForEmailInvalidDomain:
    382       return IDS_FORM_VALIDATION_TYPE_MISMATCH_EMAIL_INVALID_DOMAIN;
    383     case WebLocalizedString::ValidationTypeMismatchForEmailInvalidDots:
    384       return IDS_FORM_VALIDATION_TYPE_MISMATCH_EMAIL_INVALID_DOTS;
    385     case WebLocalizedString::ValidationTypeMismatchForEmailInvalidLocal:
    386       return IDS_FORM_VALIDATION_TYPE_MISMATCH_EMAIL_INVALID_LOCAL;
    387     case WebLocalizedString::ValidationTypeMismatchForEmailNoAtSign:
    388       return IDS_FORM_VALIDATION_TYPE_MISMATCH_EMAIL_NO_AT_SIGN;
    389     case WebLocalizedString::ValidationTypeMismatchForMultipleEmail:
    390       return IDS_FORM_VALIDATION_TYPE_MISMATCH_MULTIPLE_EMAIL;
    391     case WebLocalizedString::ValidationTypeMismatchForURL:
    392       return IDS_FORM_VALIDATION_TYPE_MISMATCH_URL;
    393     case WebLocalizedString::ValidationValueMissing:
    394       return IDS_FORM_VALIDATION_VALUE_MISSING;
    395     case WebLocalizedString::ValidationValueMissingForCheckbox:
    396       return IDS_FORM_VALIDATION_VALUE_MISSING_CHECKBOX;
    397     case WebLocalizedString::ValidationValueMissingForFile:
    398       return IDS_FORM_VALIDATION_VALUE_MISSING_FILE;
    399     case WebLocalizedString::ValidationValueMissingForMultipleFile:
    400       return IDS_FORM_VALIDATION_VALUE_MISSING_MULTIPLE_FILE;
    401     case WebLocalizedString::ValidationValueMissingForRadio:
    402       return IDS_FORM_VALIDATION_VALUE_MISSING_RADIO;
    403     case WebLocalizedString::ValidationValueMissingForSelect:
    404       return IDS_FORM_VALIDATION_VALUE_MISSING_SELECT;
    405     case WebLocalizedString::WeekFormatTemplate:
    406       return IDS_FORM_INPUT_WEEK_TEMPLATE;
    407     case WebLocalizedString::WeekNumberLabel:
    408       return IDS_FORM_WEEK_NUMBER_LABEL;
    409     // This "default:" line exists to avoid compile warnings about enum
    410     // coverage when we add a new symbol to WebLocalizedString.h in WebKit.
    411     // After a planned WebKit patch is landed, we need to add a case statement
    412     // for the added symbol here.
    413     default:
    414       break;
    415   }
    416   return -1;
    417 }
    418 
    419 BlinkPlatformImpl::BlinkPlatformImpl()
    420     : main_loop_(base::MessageLoop::current()),
    421       shared_timer_func_(NULL),
    422       shared_timer_fire_time_(0.0),
    423       shared_timer_fire_time_was_set_while_suspended_(false),
    424       shared_timer_suspended_(0),
    425       current_thread_slot_(&DestroyCurrentThread) {}
    426 
    427 BlinkPlatformImpl::~BlinkPlatformImpl() {
    428 }
    429 
    430 WebURLLoader* BlinkPlatformImpl::createURLLoader() {
    431   ChildThread* child_thread = ChildThread::current();
    432   // There may be no child thread in RenderViewTests.  These tests can still use
    433   // data URLs to bypass the ResourceDispatcher.
    434   return new WebURLLoaderImpl(
    435       child_thread ? child_thread->resource_dispatcher() : NULL);
    436 }
    437 
    438 WebSocketStreamHandle* BlinkPlatformImpl::createSocketStreamHandle() {
    439   return new WebSocketStreamHandleImpl;
    440 }
    441 
    442 blink::WebSocketHandle* BlinkPlatformImpl::createWebSocketHandle() {
    443   return new WebSocketBridge;
    444 }
    445 
    446 WebString BlinkPlatformImpl::userAgent() {
    447   return WebString::fromUTF8(GetContentClient()->GetUserAgent());
    448 }
    449 
    450 WebData BlinkPlatformImpl::parseDataURL(const WebURL& url,
    451                                         WebString& mimetype_out,
    452                                         WebString& charset_out) {
    453   std::string mime_type, char_set, data;
    454   if (net::DataURL::Parse(url, &mime_type, &char_set, &data)
    455       && net::IsSupportedMimeType(mime_type)) {
    456     mimetype_out = WebString::fromUTF8(mime_type);
    457     charset_out = WebString::fromUTF8(char_set);
    458     return data;
    459   }
    460   return WebData();
    461 }
    462 
    463 WebURLError BlinkPlatformImpl::cancelledError(
    464     const WebURL& unreachableURL) const {
    465   return WebURLLoaderImpl::CreateError(unreachableURL, false, net::ERR_ABORTED);
    466 }
    467 
    468 bool BlinkPlatformImpl::isReservedIPAddress(
    469     const blink::WebSecurityOrigin& securityOrigin) const {
    470   return isHostnameReservedIPAddress(securityOrigin.host().utf8());
    471 }
    472 
    473 bool BlinkPlatformImpl::isReservedIPAddress(const blink::WebURL& url) const {
    474   return isHostnameReservedIPAddress(GURL(url).host());
    475 }
    476 
    477 blink::WebThread* BlinkPlatformImpl::createThread(const char* name) {
    478   return new WebThreadImpl(name);
    479 }
    480 
    481 blink::WebThread* BlinkPlatformImpl::currentThread() {
    482   WebThreadImplForMessageLoop* thread =
    483       static_cast<WebThreadImplForMessageLoop*>(current_thread_slot_.Get());
    484   if (thread)
    485     return (thread);
    486 
    487   scoped_refptr<base::MessageLoopProxy> message_loop =
    488       base::MessageLoopProxy::current();
    489   if (!message_loop.get())
    490     return NULL;
    491 
    492   thread = new WebThreadImplForMessageLoop(message_loop.get());
    493   current_thread_slot_.Set(thread);
    494   return thread;
    495 }
    496 
    497 void BlinkPlatformImpl::yieldCurrentThread() {
    498   base::PlatformThread::YieldCurrentThread();
    499 }
    500 
    501 blink::WebWaitableEvent* BlinkPlatformImpl::createWaitableEvent() {
    502   return new WebWaitableEventImpl();
    503 }
    504 
    505 blink::WebWaitableEvent* BlinkPlatformImpl::waitMultipleEvents(
    506     const blink::WebVector<blink::WebWaitableEvent*>& web_events) {
    507   std::vector<base::WaitableEvent*> events;
    508   for (size_t i = 0; i < web_events.size(); ++i)
    509     events.push_back(static_cast<WebWaitableEventImpl*>(web_events[i])->impl());
    510   size_t idx = base::WaitableEvent::WaitMany(
    511       vector_as_array(&events), events.size());
    512   DCHECK_LT(idx, web_events.size());
    513   return web_events[idx];
    514 }
    515 
    516 void BlinkPlatformImpl::decrementStatsCounter(const char* name) {
    517   base::StatsCounter(name).Decrement();
    518 }
    519 
    520 void BlinkPlatformImpl::incrementStatsCounter(const char* name) {
    521   base::StatsCounter(name).Increment();
    522 }
    523 
    524 void BlinkPlatformImpl::histogramCustomCounts(
    525     const char* name, int sample, int min, int max, int bucket_count) {
    526   // Copied from histogram macro, but without the static variable caching
    527   // the histogram because name is dynamic.
    528   base::HistogramBase* counter =
    529       base::Histogram::FactoryGet(name, min, max, bucket_count,
    530           base::HistogramBase::kUmaTargetedHistogramFlag);
    531   DCHECK_EQ(name, counter->histogram_name());
    532   counter->Add(sample);
    533 }
    534 
    535 void BlinkPlatformImpl::histogramEnumeration(
    536     const char* name, int sample, int boundary_value) {
    537   // Copied from histogram macro, but without the static variable caching
    538   // the histogram because name is dynamic.
    539   base::HistogramBase* counter =
    540       base::LinearHistogram::FactoryGet(name, 1, boundary_value,
    541           boundary_value + 1, base::HistogramBase::kUmaTargetedHistogramFlag);
    542   DCHECK_EQ(name, counter->histogram_name());
    543   counter->Add(sample);
    544 }
    545 
    546 void BlinkPlatformImpl::histogramSparse(const char* name, int sample) {
    547   // For sparse histograms, we can use the macro, as it does not incorporate a
    548   // static.
    549   UMA_HISTOGRAM_SPARSE_SLOWLY(name, sample);
    550 }
    551 
    552 const unsigned char* BlinkPlatformImpl::getTraceCategoryEnabledFlag(
    553     const char* category_group) {
    554   return TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(category_group);
    555 }
    556 
    557 long* BlinkPlatformImpl::getTraceSamplingState(
    558     const unsigned thread_bucket) {
    559   switch (thread_bucket) {
    560     case 0:
    561       return reinterpret_cast<long*>(&TRACE_EVENT_API_THREAD_BUCKET(0));
    562     case 1:
    563       return reinterpret_cast<long*>(&TRACE_EVENT_API_THREAD_BUCKET(1));
    564     case 2:
    565       return reinterpret_cast<long*>(&TRACE_EVENT_API_THREAD_BUCKET(2));
    566     default:
    567       NOTREACHED() << "Unknown thread bucket type.";
    568   }
    569   return NULL;
    570 }
    571 
    572 COMPILE_ASSERT(
    573     sizeof(blink::Platform::TraceEventHandle) ==
    574         sizeof(base::debug::TraceEventHandle),
    575     TraceEventHandle_types_must_be_same_size);
    576 
    577 blink::Platform::TraceEventHandle BlinkPlatformImpl::addTraceEvent(
    578     char phase,
    579     const unsigned char* category_group_enabled,
    580     const char* name,
    581     unsigned long long id,
    582     int num_args,
    583     const char** arg_names,
    584     const unsigned char* arg_types,
    585     const unsigned long long* arg_values,
    586     unsigned char flags) {
    587   base::debug::TraceEventHandle handle = TRACE_EVENT_API_ADD_TRACE_EVENT(
    588       phase, category_group_enabled, name, id,
    589       num_args, arg_names, arg_types, arg_values, NULL, flags);
    590   blink::Platform::TraceEventHandle result;
    591   memcpy(&result, &handle, sizeof(result));
    592   return result;
    593 }
    594 
    595 blink::Platform::TraceEventHandle BlinkPlatformImpl::addTraceEvent(
    596     char phase,
    597     const unsigned char* category_group_enabled,
    598     const char* name,
    599     unsigned long long id,
    600     int num_args,
    601     const char** arg_names,
    602     const unsigned char* arg_types,
    603     const unsigned long long* arg_values,
    604     const blink::WebConvertableToTraceFormat* convertable_values,
    605     unsigned char flags) {
    606   scoped_refptr<base::debug::ConvertableToTraceFormat> convertable_wrappers[2];
    607   if (convertable_values) {
    608     size_t size = std::min(static_cast<size_t>(num_args),
    609                            arraysize(convertable_wrappers));
    610     for (size_t i = 0; i < size; ++i) {
    611       if (arg_types[i] == TRACE_VALUE_TYPE_CONVERTABLE) {
    612         convertable_wrappers[i] =
    613             new ConvertableToTraceFormatWrapper(convertable_values[i]);
    614       }
    615     }
    616   }
    617   base::debug::TraceEventHandle handle =
    618       TRACE_EVENT_API_ADD_TRACE_EVENT(phase,
    619                                       category_group_enabled,
    620                                       name,
    621                                       id,
    622                                       num_args,
    623                                       arg_names,
    624                                       arg_types,
    625                                       arg_values,
    626                                       convertable_wrappers,
    627                                       flags);
    628   blink::Platform::TraceEventHandle result;
    629   memcpy(&result, &handle, sizeof(result));
    630   return result;
    631 }
    632 
    633 void BlinkPlatformImpl::updateTraceEventDuration(
    634     const unsigned char* category_group_enabled,
    635     const char* name,
    636     TraceEventHandle handle) {
    637   base::debug::TraceEventHandle traceEventHandle;
    638   memcpy(&traceEventHandle, &handle, sizeof(handle));
    639   TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(
    640       category_group_enabled, name, traceEventHandle);
    641 }
    642 
    643 namespace {
    644 
    645 WebData loadAudioSpatializationResource(const char* name) {
    646 #ifdef IDR_AUDIO_SPATIALIZATION_COMPOSITE
    647   if (!strcmp(name, "Composite")) {
    648     base::StringPiece resource = GetContentClient()->GetDataResource(
    649         IDR_AUDIO_SPATIALIZATION_COMPOSITE, ui::SCALE_FACTOR_NONE);
    650     return WebData(resource.data(), resource.size());
    651   }
    652 #endif
    653 
    654 #ifdef IDR_AUDIO_SPATIALIZATION_T000_P000
    655   const size_t kExpectedSpatializationNameLength = 31;
    656   if (strlen(name) != kExpectedSpatializationNameLength) {
    657     return WebData();
    658   }
    659 
    660   // Extract the azimuth and elevation from the resource name.
    661   int azimuth = 0;
    662   int elevation = 0;
    663   int values_parsed =
    664       sscanf(name, "IRC_Composite_C_R0195_T%3d_P%3d", &azimuth, &elevation);
    665   if (values_parsed != 2) {
    666     return WebData();
    667   }
    668 
    669   // The resource index values go through the elevations first, then azimuths.
    670   const int kAngleSpacing = 15;
    671 
    672   // 0 <= elevation <= 90 (or 315 <= elevation <= 345)
    673   // in increments of 15 degrees.
    674   int elevation_index =
    675       elevation <= 90 ? elevation / kAngleSpacing :
    676       7 + (elevation - 315) / kAngleSpacing;
    677   bool is_elevation_index_good = 0 <= elevation_index && elevation_index < 10;
    678 
    679   // 0 <= azimuth < 360 in increments of 15 degrees.
    680   int azimuth_index = azimuth / kAngleSpacing;
    681   bool is_azimuth_index_good = 0 <= azimuth_index && azimuth_index < 24;
    682 
    683   const int kNumberOfElevations = 10;
    684   const int kNumberOfAudioResources = 240;
    685   int resource_index = kNumberOfElevations * azimuth_index + elevation_index;
    686   bool is_resource_index_good = 0 <= resource_index &&
    687       resource_index < kNumberOfAudioResources;
    688 
    689   if (is_azimuth_index_good && is_elevation_index_good &&
    690       is_resource_index_good) {
    691     const int kFirstAudioResourceIndex = IDR_AUDIO_SPATIALIZATION_T000_P000;
    692     base::StringPiece resource = GetContentClient()->GetDataResource(
    693         kFirstAudioResourceIndex + resource_index, ui::SCALE_FACTOR_NONE);
    694     return WebData(resource.data(), resource.size());
    695   }
    696 #endif  // IDR_AUDIO_SPATIALIZATION_T000_P000
    697 
    698   NOTREACHED();
    699   return WebData();
    700 }
    701 
    702 struct DataResource {
    703   const char* name;
    704   int id;
    705   ui::ScaleFactor scale_factor;
    706 };
    707 
    708 const DataResource kDataResources[] = {
    709   { "missingImage", IDR_BROKENIMAGE, ui::SCALE_FACTOR_100P },
    710   { "missingImage@2x", IDR_BROKENIMAGE, ui::SCALE_FACTOR_200P },
    711   { "mediaplayerPause", IDR_MEDIAPLAYER_PAUSE_BUTTON, ui::SCALE_FACTOR_100P },
    712   { "mediaplayerPauseHover",
    713     IDR_MEDIAPLAYER_PAUSE_BUTTON_HOVER, ui::SCALE_FACTOR_100P },
    714   { "mediaplayerPauseDown",
    715     IDR_MEDIAPLAYER_PAUSE_BUTTON_DOWN, ui::SCALE_FACTOR_100P },
    716   { "mediaplayerPlay", IDR_MEDIAPLAYER_PLAY_BUTTON, ui::SCALE_FACTOR_100P },
    717   { "mediaplayerPlayHover",
    718     IDR_MEDIAPLAYER_PLAY_BUTTON_HOVER, ui::SCALE_FACTOR_100P },
    719   { "mediaplayerPlayDown",
    720     IDR_MEDIAPLAYER_PLAY_BUTTON_DOWN, ui::SCALE_FACTOR_100P },
    721   { "mediaplayerPlayDisabled",
    722     IDR_MEDIAPLAYER_PLAY_BUTTON_DISABLED, ui::SCALE_FACTOR_100P },
    723   { "mediaplayerSoundLevel3",
    724     IDR_MEDIAPLAYER_SOUND_LEVEL3_BUTTON, ui::SCALE_FACTOR_100P },
    725   { "mediaplayerSoundLevel3Hover",
    726     IDR_MEDIAPLAYER_SOUND_LEVEL3_BUTTON_HOVER, ui::SCALE_FACTOR_100P },
    727   { "mediaplayerSoundLevel3Down",
    728     IDR_MEDIAPLAYER_SOUND_LEVEL3_BUTTON_DOWN, ui::SCALE_FACTOR_100P },
    729   { "mediaplayerSoundLevel2",
    730     IDR_MEDIAPLAYER_SOUND_LEVEL2_BUTTON, ui::SCALE_FACTOR_100P },
    731   { "mediaplayerSoundLevel2Hover",
    732     IDR_MEDIAPLAYER_SOUND_LEVEL2_BUTTON_HOVER, ui::SCALE_FACTOR_100P },
    733   { "mediaplayerSoundLevel2Down",
    734     IDR_MEDIAPLAYER_SOUND_LEVEL2_BUTTON_DOWN, ui::SCALE_FACTOR_100P },
    735   { "mediaplayerSoundLevel1",
    736     IDR_MEDIAPLAYER_SOUND_LEVEL1_BUTTON, ui::SCALE_FACTOR_100P },
    737   { "mediaplayerSoundLevel1Hover",
    738     IDR_MEDIAPLAYER_SOUND_LEVEL1_BUTTON_HOVER, ui::SCALE_FACTOR_100P },
    739   { "mediaplayerSoundLevel1Down",
    740     IDR_MEDIAPLAYER_SOUND_LEVEL1_BUTTON_DOWN, ui::SCALE_FACTOR_100P },
    741   { "mediaplayerSoundLevel0",
    742     IDR_MEDIAPLAYER_SOUND_LEVEL0_BUTTON, ui::SCALE_FACTOR_100P },
    743   { "mediaplayerSoundLevel0Hover",
    744     IDR_MEDIAPLAYER_SOUND_LEVEL0_BUTTON_HOVER, ui::SCALE_FACTOR_100P },
    745   { "mediaplayerSoundLevel0Down",
    746     IDR_MEDIAPLAYER_SOUND_LEVEL0_BUTTON_DOWN, ui::SCALE_FACTOR_100P },
    747   { "mediaplayerSoundDisabled",
    748     IDR_MEDIAPLAYER_SOUND_DISABLED, ui::SCALE_FACTOR_100P },
    749   { "mediaplayerSliderThumb",
    750     IDR_MEDIAPLAYER_SLIDER_THUMB, ui::SCALE_FACTOR_100P },
    751   { "mediaplayerSliderThumbHover",
    752     IDR_MEDIAPLAYER_SLIDER_THUMB_HOVER, ui::SCALE_FACTOR_100P },
    753   { "mediaplayerSliderThumbDown",
    754     IDR_MEDIAPLAYER_SLIDER_THUMB_DOWN, ui::SCALE_FACTOR_100P },
    755   { "mediaplayerVolumeSliderThumb",
    756     IDR_MEDIAPLAYER_VOLUME_SLIDER_THUMB, ui::SCALE_FACTOR_100P },
    757   { "mediaplayerVolumeSliderThumbHover",
    758     IDR_MEDIAPLAYER_VOLUME_SLIDER_THUMB_HOVER, ui::SCALE_FACTOR_100P },
    759   { "mediaplayerVolumeSliderThumbDown",
    760     IDR_MEDIAPLAYER_VOLUME_SLIDER_THUMB_DOWN, ui::SCALE_FACTOR_100P },
    761   { "mediaplayerVolumeSliderThumbDisabled",
    762     IDR_MEDIAPLAYER_VOLUME_SLIDER_THUMB_DISABLED, ui::SCALE_FACTOR_100P },
    763   { "mediaplayerClosedCaption",
    764     IDR_MEDIAPLAYER_CLOSEDCAPTION_BUTTON, ui::SCALE_FACTOR_100P },
    765   { "mediaplayerClosedCaptionHover",
    766     IDR_MEDIAPLAYER_CLOSEDCAPTION_BUTTON_HOVER, ui::SCALE_FACTOR_100P },
    767   { "mediaplayerClosedCaptionDown",
    768     IDR_MEDIAPLAYER_CLOSEDCAPTION_BUTTON_DOWN, ui::SCALE_FACTOR_100P },
    769   { "mediaplayerClosedCaptionDisabled",
    770     IDR_MEDIAPLAYER_CLOSEDCAPTION_BUTTON_DISABLED, ui::SCALE_FACTOR_100P },
    771   { "mediaplayerFullscreen",
    772     IDR_MEDIAPLAYER_FULLSCREEN_BUTTON, ui::SCALE_FACTOR_100P },
    773   { "mediaplayerFullscreenHover",
    774     IDR_MEDIAPLAYER_FULLSCREEN_BUTTON_HOVER, ui::SCALE_FACTOR_100P },
    775   { "mediaplayerFullscreenDown",
    776     IDR_MEDIAPLAYER_FULLSCREEN_BUTTON_DOWN, ui::SCALE_FACTOR_100P },
    777   { "mediaplayerCastOff",
    778     IDR_MEDIAPLAYER_CAST_BUTTON_OFF, ui::SCALE_FACTOR_100P },
    779   { "mediaplayerCastOn",
    780     IDR_MEDIAPLAYER_CAST_BUTTON_ON, ui::SCALE_FACTOR_100P },
    781   { "mediaplayerFullscreenDisabled",
    782     IDR_MEDIAPLAYER_FULLSCREEN_BUTTON_DISABLED, ui::SCALE_FACTOR_100P },
    783   { "mediaplayerOverlayPlay",
    784     IDR_MEDIAPLAYER_OVERLAY_PLAY_BUTTON, ui::SCALE_FACTOR_100P },
    785 #if defined(OS_MACOSX)
    786   { "overhangPattern", IDR_OVERHANG_PATTERN, ui::SCALE_FACTOR_100P },
    787   { "overhangShadow", IDR_OVERHANG_SHADOW, ui::SCALE_FACTOR_100P },
    788 #endif
    789   { "panIcon", IDR_PAN_SCROLL_ICON, ui::SCALE_FACTOR_100P },
    790   { "searchCancel", IDR_SEARCH_CANCEL, ui::SCALE_FACTOR_100P },
    791   { "searchCancelPressed", IDR_SEARCH_CANCEL_PRESSED, ui::SCALE_FACTOR_100P },
    792   { "searchMagnifier", IDR_SEARCH_MAGNIFIER, ui::SCALE_FACTOR_100P },
    793   { "searchMagnifierResults",
    794     IDR_SEARCH_MAGNIFIER_RESULTS, ui::SCALE_FACTOR_100P },
    795   { "textAreaResizeCorner", IDR_TEXTAREA_RESIZER, ui::SCALE_FACTOR_100P },
    796   { "textAreaResizeCorner@2x", IDR_TEXTAREA_RESIZER, ui::SCALE_FACTOR_200P },
    797   { "generatePassword", IDR_PASSWORD_GENERATION_ICON, ui::SCALE_FACTOR_100P },
    798   { "generatePasswordHover",
    799     IDR_PASSWORD_GENERATION_ICON_HOVER, ui::SCALE_FACTOR_100P },
    800   { "html.css", IDR_UASTYLE_HTML_CSS, ui::SCALE_FACTOR_NONE },
    801   { "quirks.css", IDR_UASTYLE_QUIRKS_CSS, ui::SCALE_FACTOR_NONE },
    802   { "view-source.css", IDR_UASTYLE_VIEW_SOURCE_CSS, ui::SCALE_FACTOR_NONE },
    803   { "themeChromium.css", IDR_UASTYLE_THEME_CHROMIUM_CSS,
    804     ui::SCALE_FACTOR_NONE },
    805 #if defined(OS_ANDROID)
    806   { "themeChromiumAndroid.css", IDR_UASTYLE_THEME_CHROMIUM_ANDROID_CSS,
    807     ui::SCALE_FACTOR_NONE },
    808   { "mediaControlsAndroid.css", IDR_UASTYLE_MEDIA_CONTROLS_ANDROID_CSS,
    809     ui::SCALE_FACTOR_NONE },
    810 #endif
    811 #if !defined(OS_WIN)
    812   { "themeChromiumLinux.css", IDR_UASTYLE_THEME_CHROMIUM_LINUX_CSS,
    813     ui::SCALE_FACTOR_NONE },
    814 #endif
    815   { "themeChromiumSkia.css", IDR_UASTYLE_THEME_CHROMIUM_SKIA_CSS,
    816     ui::SCALE_FACTOR_NONE },
    817   { "themeInputMultipleFields.css",
    818     IDR_UASTYLE_THEME_INPUT_MULTIPLE_FIELDS_CSS, ui::SCALE_FACTOR_NONE },
    819 #if defined(OS_MACOSX)
    820   { "themeMac.css", IDR_UASTYLE_THEME_MAC_CSS, ui::SCALE_FACTOR_NONE },
    821 #endif
    822   { "themeWin.css", IDR_UASTYLE_THEME_WIN_CSS, ui::SCALE_FACTOR_NONE },
    823   { "themeWinQuirks.css", IDR_UASTYLE_THEME_WIN_QUIRKS_CSS,
    824     ui::SCALE_FACTOR_NONE },
    825   { "svg.css", IDR_UASTYLE_SVG_CSS, ui::SCALE_FACTOR_NONE},
    826   { "navigationTransitions.css", IDR_UASTYLE_NAVIGATION_TRANSITIONS_CSS,
    827     ui::SCALE_FACTOR_NONE },
    828   { "mathml.css", IDR_UASTYLE_MATHML_CSS, ui::SCALE_FACTOR_NONE},
    829   { "mediaControls.css", IDR_UASTYLE_MEDIA_CONTROLS_CSS,
    830     ui::SCALE_FACTOR_NONE },
    831   { "fullscreen.css", IDR_UASTYLE_FULLSCREEN_CSS, ui::SCALE_FACTOR_NONE},
    832   { "xhtmlmp.css", IDR_UASTYLE_XHTMLMP_CSS, ui::SCALE_FACTOR_NONE},
    833   { "viewportAndroid.css", IDR_UASTYLE_VIEWPORT_ANDROID_CSS,
    834     ui::SCALE_FACTOR_NONE},
    835   { "InspectorOverlayPage.html", IDR_INSPECTOR_OVERLAY_PAGE_HTML,
    836     ui::SCALE_FACTOR_NONE },
    837   { "InjectedScriptCanvasModuleSource.js",
    838     IDR_INSPECTOR_INJECTED_SCRIPT_CANVAS_MODULE_SOURCE_JS,
    839     ui::SCALE_FACTOR_NONE },
    840   { "InjectedScriptSource.js", IDR_INSPECTOR_INJECTED_SCRIPT_SOURCE_JS,
    841     ui::SCALE_FACTOR_NONE },
    842   { "DebuggerScriptSource.js", IDR_INSPECTOR_DEBUGGER_SCRIPT_SOURCE_JS,
    843     ui::SCALE_FACTOR_NONE },
    844   { "DocumentXMLTreeViewer.js", IDR_PRIVATE_SCRIPT_DOCUMENTXMLTREEVIEWER_JS,
    845     ui::SCALE_FACTOR_NONE },
    846   { "HTMLMarqueeElement.js", IDR_PRIVATE_SCRIPT_HTMLMARQUEEELEMENT_JS,
    847     ui::SCALE_FACTOR_NONE },
    848   { "PluginPlaceholderElement.js",
    849     IDR_PRIVATE_SCRIPT_PLUGINPLACEHOLDERELEMENT_JS, ui::SCALE_FACTOR_NONE },
    850   { "PrivateScriptRunner.js", IDR_PRIVATE_SCRIPT_PRIVATESCRIPTRUNNER_JS,
    851     ui::SCALE_FACTOR_NONE },
    852 #ifdef IDR_PICKER_COMMON_JS
    853   { "pickerCommon.js", IDR_PICKER_COMMON_JS, ui::SCALE_FACTOR_NONE },
    854   { "pickerCommon.css", IDR_PICKER_COMMON_CSS, ui::SCALE_FACTOR_NONE },
    855   { "calendarPicker.js", IDR_CALENDAR_PICKER_JS, ui::SCALE_FACTOR_NONE },
    856   { "calendarPicker.css", IDR_CALENDAR_PICKER_CSS, ui::SCALE_FACTOR_NONE },
    857   { "pickerButton.css", IDR_PICKER_BUTTON_CSS, ui::SCALE_FACTOR_NONE },
    858   { "suggestionPicker.js", IDR_SUGGESTION_PICKER_JS, ui::SCALE_FACTOR_NONE },
    859   { "suggestionPicker.css", IDR_SUGGESTION_PICKER_CSS, ui::SCALE_FACTOR_NONE },
    860   { "colorSuggestionPicker.js",
    861     IDR_COLOR_SUGGESTION_PICKER_JS, ui::SCALE_FACTOR_NONE },
    862   { "colorSuggestionPicker.css",
    863     IDR_COLOR_SUGGESTION_PICKER_CSS, ui::SCALE_FACTOR_NONE },
    864 #endif
    865 };
    866 
    867 }  // namespace
    868 
    869 WebData BlinkPlatformImpl::loadResource(const char* name) {
    870   // Some clients will call into this method with an empty |name| when they have
    871   // optional resources.  For example, the PopupMenuChromium code can have icons
    872   // for some Autofill items but not for others.
    873   if (!strlen(name))
    874     return WebData();
    875 
    876   // Check the name prefix to see if it's an audio resource.
    877   if (StartsWithASCII(name, "IRC_Composite", true) ||
    878       StartsWithASCII(name, "Composite", true))
    879     return loadAudioSpatializationResource(name);
    880 
    881   // TODO(flackr): We should use a better than linear search here, a trie would
    882   // be ideal.
    883   for (size_t i = 0; i < arraysize(kDataResources); ++i) {
    884     if (!strcmp(name, kDataResources[i].name)) {
    885       base::StringPiece resource = GetContentClient()->GetDataResource(
    886           kDataResources[i].id, kDataResources[i].scale_factor);
    887       return WebData(resource.data(), resource.size());
    888     }
    889   }
    890 
    891   NOTREACHED() << "Unknown image resource " << name;
    892   return WebData();
    893 }
    894 
    895 WebString BlinkPlatformImpl::queryLocalizedString(
    896     WebLocalizedString::Name name) {
    897   int message_id = ToMessageID(name);
    898   if (message_id < 0)
    899     return WebString();
    900   return GetContentClient()->GetLocalizedString(message_id);
    901 }
    902 
    903 WebString BlinkPlatformImpl::queryLocalizedString(
    904     WebLocalizedString::Name name, int numeric_value) {
    905   return queryLocalizedString(name, base::IntToString16(numeric_value));
    906 }
    907 
    908 WebString BlinkPlatformImpl::queryLocalizedString(
    909     WebLocalizedString::Name name, const WebString& value) {
    910   int message_id = ToMessageID(name);
    911   if (message_id < 0)
    912     return WebString();
    913   return ReplaceStringPlaceholders(GetContentClient()->GetLocalizedString(
    914       message_id), value, NULL);
    915 }
    916 
    917 WebString BlinkPlatformImpl::queryLocalizedString(
    918     WebLocalizedString::Name name,
    919     const WebString& value1,
    920     const WebString& value2) {
    921   int message_id = ToMessageID(name);
    922   if (message_id < 0)
    923     return WebString();
    924   std::vector<base::string16> values;
    925   values.reserve(2);
    926   values.push_back(value1);
    927   values.push_back(value2);
    928   return ReplaceStringPlaceholders(
    929       GetContentClient()->GetLocalizedString(message_id), values, NULL);
    930 }
    931 
    932 double BlinkPlatformImpl::currentTime() {
    933   return base::Time::Now().ToDoubleT();
    934 }
    935 
    936 double BlinkPlatformImpl::monotonicallyIncreasingTime() {
    937   return base::TimeTicks::Now().ToInternalValue() /
    938       static_cast<double>(base::Time::kMicrosecondsPerSecond);
    939 }
    940 
    941 void BlinkPlatformImpl::cryptographicallyRandomValues(
    942     unsigned char* buffer, size_t length) {
    943   base::RandBytes(buffer, length);
    944 }
    945 
    946 void BlinkPlatformImpl::setSharedTimerFiredFunction(void (*func)()) {
    947   shared_timer_func_ = func;
    948 }
    949 
    950 void BlinkPlatformImpl::setSharedTimerFireInterval(
    951     double interval_seconds) {
    952   shared_timer_fire_time_ = interval_seconds + monotonicallyIncreasingTime();
    953   if (shared_timer_suspended_) {
    954     shared_timer_fire_time_was_set_while_suspended_ = true;
    955     return;
    956   }
    957 
    958   // By converting between double and int64 representation, we run the risk
    959   // of losing precision due to rounding errors. Performing computations in
    960   // microseconds reduces this risk somewhat. But there still is the potential
    961   // of us computing a fire time for the timer that is shorter than what we
    962   // need.
    963   // As the event loop will check event deadlines prior to actually firing
    964   // them, there is a risk of needlessly rescheduling events and of
    965   // needlessly looping if sleep times are too short even by small amounts.
    966   // This results in measurable performance degradation unless we use ceil() to
    967   // always round up the sleep times.
    968   int64 interval = static_cast<int64>(
    969       ceil(interval_seconds * base::Time::kMillisecondsPerSecond)
    970       * base::Time::kMicrosecondsPerMillisecond);
    971 
    972   if (interval < 0)
    973     interval = 0;
    974 
    975   shared_timer_.Stop();
    976   shared_timer_.Start(FROM_HERE, base::TimeDelta::FromMicroseconds(interval),
    977                       this, &BlinkPlatformImpl::DoTimeout);
    978   OnStartSharedTimer(base::TimeDelta::FromMicroseconds(interval));
    979 }
    980 
    981 void BlinkPlatformImpl::stopSharedTimer() {
    982   shared_timer_.Stop();
    983 }
    984 
    985 void BlinkPlatformImpl::callOnMainThread(
    986     void (*func)(void*), void* context) {
    987   main_loop_->PostTask(FROM_HERE, base::Bind(func, context));
    988 }
    989 
    990 blink::WebGestureCurve* BlinkPlatformImpl::createFlingAnimationCurve(
    991     blink::WebGestureDevice device_source,
    992     const blink::WebFloatPoint& velocity,
    993     const blink::WebSize& cumulative_scroll) {
    994 #if defined(OS_ANDROID)
    995   return FlingAnimatorImpl::CreateAndroidGestureCurve(
    996       velocity,
    997       cumulative_scroll);
    998 #endif
    999 
   1000   return TouchFlingGestureCurve::Create(velocity, cumulative_scroll);
   1001 }
   1002 
   1003 void BlinkPlatformImpl::didStartWorkerRunLoop(
   1004     const blink::WebWorkerRunLoop& runLoop) {
   1005   WorkerTaskRunner* worker_task_runner = WorkerTaskRunner::Instance();
   1006   worker_task_runner->OnWorkerRunLoopStarted(runLoop);
   1007 }
   1008 
   1009 void BlinkPlatformImpl::didStopWorkerRunLoop(
   1010     const blink::WebWorkerRunLoop& runLoop) {
   1011   WorkerTaskRunner* worker_task_runner = WorkerTaskRunner::Instance();
   1012   worker_task_runner->OnWorkerRunLoopStopped(runLoop);
   1013 }
   1014 
   1015 blink::WebCrypto* BlinkPlatformImpl::crypto() {
   1016   return &web_crypto_;
   1017 }
   1018 
   1019 
   1020 WebThemeEngine* BlinkPlatformImpl::themeEngine() {
   1021   return &native_theme_engine_;
   1022 }
   1023 
   1024 WebFallbackThemeEngine* BlinkPlatformImpl::fallbackThemeEngine() {
   1025   return &fallback_theme_engine_;
   1026 }
   1027 
   1028 blink::Platform::FileHandle BlinkPlatformImpl::databaseOpenFile(
   1029     const blink::WebString& vfs_file_name, int desired_flags) {
   1030 #if defined(OS_WIN)
   1031   return INVALID_HANDLE_VALUE;
   1032 #elif defined(OS_POSIX)
   1033   return -1;
   1034 #endif
   1035 }
   1036 
   1037 int BlinkPlatformImpl::databaseDeleteFile(
   1038     const blink::WebString& vfs_file_name, bool sync_dir) {
   1039   return -1;
   1040 }
   1041 
   1042 long BlinkPlatformImpl::databaseGetFileAttributes(
   1043     const blink::WebString& vfs_file_name) {
   1044   return 0;
   1045 }
   1046 
   1047 long long BlinkPlatformImpl::databaseGetFileSize(
   1048     const blink::WebString& vfs_file_name) {
   1049   return 0;
   1050 }
   1051 
   1052 long long BlinkPlatformImpl::databaseGetSpaceAvailableForOrigin(
   1053     const blink::WebString& origin_identifier) {
   1054   return 0;
   1055 }
   1056 
   1057 blink::WebString BlinkPlatformImpl::signedPublicKeyAndChallengeString(
   1058     unsigned key_size_index,
   1059     const blink::WebString& challenge,
   1060     const blink::WebURL& url) {
   1061   return blink::WebString("");
   1062 }
   1063 
   1064 static scoped_ptr<base::ProcessMetrics> CurrentProcessMetrics() {
   1065   using base::ProcessMetrics;
   1066 #if defined(OS_MACOSX)
   1067   return scoped_ptr<ProcessMetrics>(
   1068       // The default port provider is sufficient to get data for the current
   1069       // process.
   1070       ProcessMetrics::CreateProcessMetrics(base::GetCurrentProcessHandle(),
   1071                                            NULL));
   1072 #else
   1073   return scoped_ptr<ProcessMetrics>(
   1074       ProcessMetrics::CreateProcessMetrics(base::GetCurrentProcessHandle()));
   1075 #endif
   1076 }
   1077 
   1078 static size_t getMemoryUsageMB(bool bypass_cache) {
   1079   size_t current_mem_usage = 0;
   1080   MemoryUsageCache* mem_usage_cache_singleton = MemoryUsageCache::GetInstance();
   1081   if (!bypass_cache &&
   1082       mem_usage_cache_singleton->IsCachedValueValid(&current_mem_usage))
   1083     return current_mem_usage;
   1084 
   1085   current_mem_usage = GetMemoryUsageKB() >> 10;
   1086   mem_usage_cache_singleton->SetMemoryValue(current_mem_usage);
   1087   return current_mem_usage;
   1088 }
   1089 
   1090 size_t BlinkPlatformImpl::memoryUsageMB() {
   1091   return getMemoryUsageMB(false);
   1092 }
   1093 
   1094 size_t BlinkPlatformImpl::actualMemoryUsageMB() {
   1095   return getMemoryUsageMB(true);
   1096 }
   1097 
   1098 size_t BlinkPlatformImpl::physicalMemoryMB() {
   1099   return static_cast<size_t>(base::SysInfo::AmountOfPhysicalMemoryMB());
   1100 }
   1101 
   1102 size_t BlinkPlatformImpl::virtualMemoryLimitMB() {
   1103   return static_cast<size_t>(base::SysInfo::AmountOfVirtualMemoryMB());
   1104 }
   1105 
   1106 size_t BlinkPlatformImpl::numberOfProcessors() {
   1107   return static_cast<size_t>(base::SysInfo::NumberOfProcessors());
   1108 }
   1109 
   1110 void BlinkPlatformImpl::startHeapProfiling(
   1111   const blink::WebString& prefix) {
   1112   // FIXME(morrita): Make this built on windows.
   1113 #if !defined(NO_TCMALLOC) && defined(USE_TCMALLOC) && !defined(OS_WIN)
   1114   HeapProfilerStart(prefix.utf8().data());
   1115 #endif
   1116 }
   1117 
   1118 void BlinkPlatformImpl::stopHeapProfiling() {
   1119 #if !defined(NO_TCMALLOC) && defined(USE_TCMALLOC) && !defined(OS_WIN)
   1120   HeapProfilerStop();
   1121 #endif
   1122 }
   1123 
   1124 void BlinkPlatformImpl::dumpHeapProfiling(
   1125   const blink::WebString& reason) {
   1126 #if !defined(NO_TCMALLOC) && defined(USE_TCMALLOC) && !defined(OS_WIN)
   1127   HeapProfilerDump(reason.utf8().data());
   1128 #endif
   1129 }
   1130 
   1131 WebString BlinkPlatformImpl::getHeapProfile() {
   1132 #if !defined(NO_TCMALLOC) && defined(USE_TCMALLOC) && !defined(OS_WIN)
   1133   char* data = GetHeapProfile();
   1134   WebString result = WebString::fromUTF8(std::string(data));
   1135   free(data);
   1136   return result;
   1137 #else
   1138   return WebString();
   1139 #endif
   1140 }
   1141 
   1142 bool BlinkPlatformImpl::processMemorySizesInBytes(
   1143     size_t* private_bytes,
   1144     size_t* shared_bytes) {
   1145   return CurrentProcessMetrics()->GetMemoryBytes(private_bytes, shared_bytes);
   1146 }
   1147 
   1148 bool BlinkPlatformImpl::memoryAllocatorWasteInBytes(size_t* size) {
   1149   return base::allocator::GetAllocatorWasteSize(size);
   1150 }
   1151 
   1152 blink::WebDiscardableMemory*
   1153 BlinkPlatformImpl::allocateAndLockDiscardableMemory(size_t bytes) {
   1154   base::DiscardableMemoryType type =
   1155       base::DiscardableMemory::GetPreferredType();
   1156   if (type == base::DISCARDABLE_MEMORY_TYPE_EMULATED)
   1157     return NULL;
   1158   return content::WebDiscardableMemoryImpl::CreateLockedMemory(bytes).release();
   1159 }
   1160 
   1161 size_t BlinkPlatformImpl::maxDecodedImageBytes() {
   1162 #if defined(OS_ANDROID)
   1163   if (base::SysInfo::IsLowEndDevice()) {
   1164     // Limit image decoded size to 3M pixels on low end devices.
   1165     // 4 is maximum number of bytes per pixel.
   1166     return 3 * 1024 * 1024 * 4;
   1167   }
   1168   // For other devices, limit decoded image size based on the amount of physical
   1169   // memory.
   1170   // In some cases all physical memory is not accessible by Chromium, as it can
   1171   // be reserved for direct use by certain hardware. Thus, we set the limit so
   1172   // that 1.6GB of reported physical memory on a 2GB device is enough to set the
   1173   // limit at 16M pixels, which is a desirable value since 4K*4K is a relatively
   1174   // common texture size.
   1175   return base::SysInfo::AmountOfPhysicalMemory() / 25;
   1176 #else
   1177   return noDecodedImageByteLimit;
   1178 #endif
   1179 }
   1180 
   1181 void BlinkPlatformImpl::SuspendSharedTimer() {
   1182   ++shared_timer_suspended_;
   1183 }
   1184 
   1185 void BlinkPlatformImpl::ResumeSharedTimer() {
   1186   DCHECK_GT(shared_timer_suspended_, 0);
   1187 
   1188   // The shared timer may have fired or been adjusted while we were suspended.
   1189   if (--shared_timer_suspended_ == 0 &&
   1190       (!shared_timer_.IsRunning() ||
   1191        shared_timer_fire_time_was_set_while_suspended_)) {
   1192     shared_timer_fire_time_was_set_while_suspended_ = false;
   1193     setSharedTimerFireInterval(
   1194         shared_timer_fire_time_ - monotonicallyIncreasingTime());
   1195   }
   1196 }
   1197 
   1198 // static
   1199 void BlinkPlatformImpl::DestroyCurrentThread(void* thread) {
   1200   WebThreadImplForMessageLoop* impl =
   1201       static_cast<WebThreadImplForMessageLoop*>(thread);
   1202   delete impl;
   1203 }
   1204 
   1205 }  // namespace content
   1206