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(¤t_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