blink_platform_impl.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
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/platform_file.h" 21#include "base/process/process_metrics.h" 22#include "base/rand_util.h" 23#include "base/strings/string_number_conversions.h" 24#include "base/strings/string_util.h" 25#include "base/strings/utf_string_conversions.h" 26#include "base/synchronization/lock.h" 27#include "base/sys_info.h" 28#include "base/time/time.h" 29#include "content/child/content_child_helpers.h" 30#include "content/child/web_socket_stream_handle_impl.h" 31#include "content/child/web_url_loader_impl.h" 32#include "content/public/common/content_client.h" 33#include "grit/blink_resources.h" 34#include "grit/webkit_resources.h" 35#include "grit/webkit_strings.h" 36#include "net/base/data_url.h" 37#include "net/base/mime_util.h" 38#include "net/base/net_errors.h" 39#include "third_party/WebKit/public/platform/WebData.h" 40#include "third_party/WebKit/public/platform/WebString.h" 41#include "ui/base/layout.h" 42 43#if defined(OS_ANDROID) 44#include "base/android/sys_utils.h" 45#endif 46 47#if !defined(NO_TCMALLOC) && defined(USE_TCMALLOC) && !defined(OS_WIN) 48#include "third_party/tcmalloc/chromium/src/gperftools/heap-profiler.h" 49#endif 50 51using blink::WebData; 52using blink::WebLocalizedString; 53using blink::WebString; 54using blink::WebSocketStreamHandle; 55using blink::WebURL; 56using blink::WebURLError; 57using blink::WebURLLoader; 58 59namespace { 60 61// A simple class to cache the memory usage for a given amount of time. 62class MemoryUsageCache { 63 public: 64 // Retrieves the Singleton. 65 static MemoryUsageCache* GetInstance() { 66 return Singleton<MemoryUsageCache>::get(); 67 } 68 69 MemoryUsageCache() : memory_value_(0) { Init(); } 70 ~MemoryUsageCache() {} 71 72 void Init() { 73 const unsigned int kCacheSeconds = 1; 74 cache_valid_time_ = base::TimeDelta::FromSeconds(kCacheSeconds); 75 } 76 77 // Returns true if the cached value is fresh. 78 // Returns false if the cached value is stale, or if |cached_value| is NULL. 79 bool IsCachedValueValid(size_t* cached_value) { 80 base::AutoLock scoped_lock(lock_); 81 if (!cached_value) 82 return false; 83 if (base::Time::Now() - last_updated_time_ > cache_valid_time_) 84 return false; 85 *cached_value = memory_value_; 86 return true; 87 }; 88 89 // Setter for |memory_value_|, refreshes |last_updated_time_|. 90 void SetMemoryValue(const size_t value) { 91 base::AutoLock scoped_lock(lock_); 92 memory_value_ = value; 93 last_updated_time_ = base::Time::Now(); 94 } 95 96 private: 97 // The cached memory value. 98 size_t memory_value_; 99 100 // How long the cached value should remain valid. 101 base::TimeDelta cache_valid_time_; 102 103 // The last time the cached value was updated. 104 base::Time last_updated_time_; 105 106 base::Lock lock_; 107}; 108 109} // namespace 110 111namespace content { 112 113static int ToMessageID(WebLocalizedString::Name name) { 114 switch (name) { 115 case WebLocalizedString::AXAMPMFieldText: 116 return IDS_AX_AM_PM_FIELD_TEXT; 117 case WebLocalizedString::AXButtonActionVerb: 118 return IDS_AX_BUTTON_ACTION_VERB; 119 case WebLocalizedString::AXCheckedCheckBoxActionVerb: 120 return IDS_AX_CHECKED_CHECK_BOX_ACTION_VERB; 121 case WebLocalizedString::AXDateTimeFieldEmptyValueText: 122 return IDS_AX_DATE_TIME_FIELD_EMPTY_VALUE_TEXT; 123 case WebLocalizedString::AXDayOfMonthFieldText: 124 return IDS_AX_DAY_OF_MONTH_FIELD_TEXT; 125 case WebLocalizedString::AXHeadingText: 126 return IDS_AX_ROLE_HEADING; 127 case WebLocalizedString::AXHourFieldText: 128 return IDS_AX_HOUR_FIELD_TEXT; 129 case WebLocalizedString::AXImageMapText: 130 return IDS_AX_ROLE_IMAGE_MAP; 131 case WebLocalizedString::AXLinkActionVerb: 132 return IDS_AX_LINK_ACTION_VERB; 133 case WebLocalizedString::AXLinkText: 134 return IDS_AX_ROLE_LINK; 135 case WebLocalizedString::AXListMarkerText: 136 return IDS_AX_ROLE_LIST_MARKER; 137 case WebLocalizedString::AXMediaDefault: 138 return IDS_AX_MEDIA_DEFAULT; 139 case WebLocalizedString::AXMediaAudioElement: 140 return IDS_AX_MEDIA_AUDIO_ELEMENT; 141 case WebLocalizedString::AXMediaVideoElement: 142 return IDS_AX_MEDIA_VIDEO_ELEMENT; 143 case WebLocalizedString::AXMediaMuteButton: 144 return IDS_AX_MEDIA_MUTE_BUTTON; 145 case WebLocalizedString::AXMediaUnMuteButton: 146 return IDS_AX_MEDIA_UNMUTE_BUTTON; 147 case WebLocalizedString::AXMediaPlayButton: 148 return IDS_AX_MEDIA_PLAY_BUTTON; 149 case WebLocalizedString::AXMediaPauseButton: 150 return IDS_AX_MEDIA_PAUSE_BUTTON; 151 case WebLocalizedString::AXMediaSlider: 152 return IDS_AX_MEDIA_SLIDER; 153 case WebLocalizedString::AXMediaSliderThumb: 154 return IDS_AX_MEDIA_SLIDER_THUMB; 155 case WebLocalizedString::AXMediaCurrentTimeDisplay: 156 return IDS_AX_MEDIA_CURRENT_TIME_DISPLAY; 157 case WebLocalizedString::AXMediaTimeRemainingDisplay: 158 return IDS_AX_MEDIA_TIME_REMAINING_DISPLAY; 159 case WebLocalizedString::AXMediaStatusDisplay: 160 return IDS_AX_MEDIA_STATUS_DISPLAY; 161 case WebLocalizedString::AXMediaEnterFullscreenButton: 162 return IDS_AX_MEDIA_ENTER_FULL_SCREEN_BUTTON; 163 case WebLocalizedString::AXMediaExitFullscreenButton: 164 return IDS_AX_MEDIA_EXIT_FULL_SCREEN_BUTTON; 165 case WebLocalizedString::AXMediaShowClosedCaptionsButton: 166 return IDS_AX_MEDIA_SHOW_CLOSED_CAPTIONS_BUTTON; 167 case WebLocalizedString::AXMediaHideClosedCaptionsButton: 168 return IDS_AX_MEDIA_HIDE_CLOSED_CAPTIONS_BUTTON; 169 case WebLocalizedString::AXMediaAudioElementHelp: 170 return IDS_AX_MEDIA_AUDIO_ELEMENT_HELP; 171 case WebLocalizedString::AXMediaVideoElementHelp: 172 return IDS_AX_MEDIA_VIDEO_ELEMENT_HELP; 173 case WebLocalizedString::AXMediaMuteButtonHelp: 174 return IDS_AX_MEDIA_MUTE_BUTTON_HELP; 175 case WebLocalizedString::AXMediaUnMuteButtonHelp: 176 return IDS_AX_MEDIA_UNMUTE_BUTTON_HELP; 177 case WebLocalizedString::AXMediaPlayButtonHelp: 178 return IDS_AX_MEDIA_PLAY_BUTTON_HELP; 179 case WebLocalizedString::AXMediaPauseButtonHelp: 180 return IDS_AX_MEDIA_PAUSE_BUTTON_HELP; 181 case WebLocalizedString::AXMediaSliderHelp: 182 return IDS_AX_MEDIA_SLIDER_HELP; 183 case WebLocalizedString::AXMediaSliderThumbHelp: 184 return IDS_AX_MEDIA_SLIDER_THUMB_HELP; 185 case WebLocalizedString::AXMediaCurrentTimeDisplayHelp: 186 return IDS_AX_MEDIA_CURRENT_TIME_DISPLAY_HELP; 187 case WebLocalizedString::AXMediaTimeRemainingDisplayHelp: 188 return IDS_AX_MEDIA_TIME_REMAINING_DISPLAY_HELP; 189 case WebLocalizedString::AXMediaStatusDisplayHelp: 190 return IDS_AX_MEDIA_STATUS_DISPLAY_HELP; 191 case WebLocalizedString::AXMediaEnterFullscreenButtonHelp: 192 return IDS_AX_MEDIA_ENTER_FULL_SCREEN_BUTTON_HELP; 193 case WebLocalizedString::AXMediaExitFullscreenButtonHelp: 194 return IDS_AX_MEDIA_EXIT_FULL_SCREEN_BUTTON_HELP; 195 case WebLocalizedString::AXMediaShowClosedCaptionsButtonHelp: 196 return IDS_AX_MEDIA_SHOW_CLOSED_CAPTIONS_BUTTON_HELP; 197 case WebLocalizedString::AXMediaHideClosedCaptionsButtonHelp: 198 return IDS_AX_MEDIA_HIDE_CLOSED_CAPTIONS_BUTTON_HELP; 199 case WebLocalizedString::AXMillisecondFieldText: 200 return IDS_AX_MILLISECOND_FIELD_TEXT; 201 case WebLocalizedString::AXMinuteFieldText: 202 return IDS_AX_MINUTE_FIELD_TEXT; 203 case WebLocalizedString::AXMonthFieldText: 204 return IDS_AX_MONTH_FIELD_TEXT; 205 case WebLocalizedString::AXRadioButtonActionVerb: 206 return IDS_AX_RADIO_BUTTON_ACTION_VERB; 207 case WebLocalizedString::AXSecondFieldText: 208 return IDS_AX_SECOND_FIELD_TEXT; 209 case WebLocalizedString::AXTextFieldActionVerb: 210 return IDS_AX_TEXT_FIELD_ACTION_VERB; 211 case WebLocalizedString::AXUncheckedCheckBoxActionVerb: 212 return IDS_AX_UNCHECKED_CHECK_BOX_ACTION_VERB; 213 case WebLocalizedString::AXWebAreaText: 214 return IDS_AX_ROLE_WEB_AREA; 215 case WebLocalizedString::AXWeekOfYearFieldText: 216 return IDS_AX_WEEK_OF_YEAR_FIELD_TEXT; 217 case WebLocalizedString::AXYearFieldText: 218 return IDS_AX_YEAR_FIELD_TEXT; 219 case WebLocalizedString::CalendarClear: 220 return IDS_FORM_CALENDAR_CLEAR; 221 case WebLocalizedString::CalendarToday: 222 return IDS_FORM_CALENDAR_TODAY; 223 case WebLocalizedString::DateFormatDayInMonthLabel: 224 return IDS_FORM_DATE_FORMAT_DAY_IN_MONTH; 225 case WebLocalizedString::DateFormatMonthLabel: 226 return IDS_FORM_DATE_FORMAT_MONTH; 227 case WebLocalizedString::DateFormatYearLabel: 228 return IDS_FORM_DATE_FORMAT_YEAR; 229 case WebLocalizedString::DetailsLabel: 230 return IDS_DETAILS_WITHOUT_SUMMARY_LABEL; 231 case WebLocalizedString::FileButtonChooseFileLabel: 232 return IDS_FORM_FILE_BUTTON_LABEL; 233 case WebLocalizedString::FileButtonChooseMultipleFilesLabel: 234 return IDS_FORM_MULTIPLE_FILES_BUTTON_LABEL; 235 case WebLocalizedString::FileButtonNoFileSelectedLabel: 236 return IDS_FORM_FILE_NO_FILE_LABEL; 237 case WebLocalizedString::InputElementAltText: 238 return IDS_FORM_INPUT_ALT; 239 case WebLocalizedString::KeygenMenuHighGradeKeySize: 240 return IDS_KEYGEN_HIGH_GRADE_KEY; 241 case WebLocalizedString::KeygenMenuMediumGradeKeySize: 242 return IDS_KEYGEN_MED_GRADE_KEY; 243 case WebLocalizedString::MissingPluginText: 244 return IDS_PLUGIN_INITIALIZATION_ERROR; 245 case WebLocalizedString::MultipleFileUploadText: 246 return IDS_FORM_FILE_MULTIPLE_UPLOAD; 247 case WebLocalizedString::OtherColorLabel: 248 return IDS_FORM_OTHER_COLOR_LABEL; 249 case WebLocalizedString::OtherDateLabel: 250 return IDS_FORM_OTHER_DATE_LABEL; 251 case WebLocalizedString::OtherMonthLabel: 252 return IDS_FORM_OTHER_MONTH_LABEL; 253 case WebLocalizedString::OtherTimeLabel: 254 return IDS_FORM_OTHER_TIME_LABEL; 255 case WebLocalizedString::OtherWeekLabel: 256 return IDS_FORM_OTHER_WEEK_LABEL; 257 case WebLocalizedString::PlaceholderForDayOfMonthField: 258 return IDS_FORM_PLACEHOLDER_FOR_DAY_OF_MONTH_FIELD; 259 case WebLocalizedString::PlaceholderForMonthField: 260 return IDS_FORM_PLACEHOLDER_FOR_MONTH_FIELD; 261 case WebLocalizedString::PlaceholderForYearField: 262 return IDS_FORM_PLACEHOLDER_FOR_YEAR_FIELD; 263 case WebLocalizedString::ResetButtonDefaultLabel: 264 return IDS_FORM_RESET_LABEL; 265 case WebLocalizedString::SearchableIndexIntroduction: 266 return IDS_SEARCHABLE_INDEX_INTRO; 267 case WebLocalizedString::SearchMenuClearRecentSearchesText: 268 return IDS_RECENT_SEARCHES_CLEAR; 269 case WebLocalizedString::SearchMenuNoRecentSearchesText: 270 return IDS_RECENT_SEARCHES_NONE; 271 case WebLocalizedString::SearchMenuRecentSearchesText: 272 return IDS_RECENT_SEARCHES; 273 case WebLocalizedString::SubmitButtonDefaultLabel: 274 return IDS_FORM_SUBMIT_LABEL; 275 case WebLocalizedString::ThisMonthButtonLabel: 276 return IDS_FORM_THIS_MONTH_LABEL; 277 case WebLocalizedString::ThisWeekButtonLabel: 278 return IDS_FORM_THIS_WEEK_LABEL; 279 case WebLocalizedString::ValidationBadInputForDateTime: 280 return IDS_FORM_VALIDATION_BAD_INPUT_DATETIME; 281 case WebLocalizedString::ValidationBadInputForNumber: 282 return IDS_FORM_VALIDATION_BAD_INPUT_NUMBER; 283 case WebLocalizedString::ValidationPatternMismatch: 284 return IDS_FORM_VALIDATION_PATTERN_MISMATCH; 285 case WebLocalizedString::ValidationRangeOverflow: 286 return IDS_FORM_VALIDATION_RANGE_OVERFLOW; 287 case WebLocalizedString::ValidationRangeOverflowDateTime: 288 return IDS_FORM_VALIDATION_RANGE_OVERFLOW_DATETIME; 289 case WebLocalizedString::ValidationRangeUnderflow: 290 return IDS_FORM_VALIDATION_RANGE_UNDERFLOW; 291 case WebLocalizedString::ValidationRangeUnderflowDateTime: 292 return IDS_FORM_VALIDATION_RANGE_UNDERFLOW_DATETIME; 293 case WebLocalizedString::ValidationStepMismatch: 294 return IDS_FORM_VALIDATION_STEP_MISMATCH; 295 case WebLocalizedString::ValidationStepMismatchCloseToLimit: 296 return IDS_FORM_VALIDATION_STEP_MISMATCH_CLOSE_TO_LIMIT; 297 case WebLocalizedString::ValidationTooLong: 298 return IDS_FORM_VALIDATION_TOO_LONG; 299 case WebLocalizedString::ValidationTypeMismatch: 300 return IDS_FORM_VALIDATION_TYPE_MISMATCH; 301 case WebLocalizedString::ValidationTypeMismatchForEmail: 302 return IDS_FORM_VALIDATION_TYPE_MISMATCH_EMAIL; 303 case WebLocalizedString::ValidationTypeMismatchForEmailEmpty: 304 return IDS_FORM_VALIDATION_TYPE_MISMATCH_EMAIL_EMPTY; 305 case WebLocalizedString::ValidationTypeMismatchForEmailEmptyDomain: 306 return IDS_FORM_VALIDATION_TYPE_MISMATCH_EMAIL_EMPTY_DOMAIN; 307 case WebLocalizedString::ValidationTypeMismatchForEmailEmptyLocal: 308 return IDS_FORM_VALIDATION_TYPE_MISMATCH_EMAIL_EMPTY_LOCAL; 309 case WebLocalizedString::ValidationTypeMismatchForEmailInvalidDomain: 310 return IDS_FORM_VALIDATION_TYPE_MISMATCH_EMAIL_INVALID_DOMAIN; 311 case WebLocalizedString::ValidationTypeMismatchForEmailInvalidDots: 312 return IDS_FORM_VALIDATION_TYPE_MISMATCH_EMAIL_INVALID_DOTS; 313 case WebLocalizedString::ValidationTypeMismatchForEmailInvalidLocal: 314 return IDS_FORM_VALIDATION_TYPE_MISMATCH_EMAIL_INVALID_LOCAL; 315 case WebLocalizedString::ValidationTypeMismatchForEmailNoAtSign: 316 return IDS_FORM_VALIDATION_TYPE_MISMATCH_EMAIL_NO_AT_SIGN; 317 case WebLocalizedString::ValidationTypeMismatchForMultipleEmail: 318 return IDS_FORM_VALIDATION_TYPE_MISMATCH_MULTIPLE_EMAIL; 319 case WebLocalizedString::ValidationTypeMismatchForURL: 320 return IDS_FORM_VALIDATION_TYPE_MISMATCH_URL; 321 case WebLocalizedString::ValidationValueMissing: 322 return IDS_FORM_VALIDATION_VALUE_MISSING; 323 case WebLocalizedString::ValidationValueMissingForCheckbox: 324 return IDS_FORM_VALIDATION_VALUE_MISSING_CHECKBOX; 325 case WebLocalizedString::ValidationValueMissingForFile: 326 return IDS_FORM_VALIDATION_VALUE_MISSING_FILE; 327 case WebLocalizedString::ValidationValueMissingForMultipleFile: 328 return IDS_FORM_VALIDATION_VALUE_MISSING_MULTIPLE_FILE; 329 case WebLocalizedString::ValidationValueMissingForRadio: 330 return IDS_FORM_VALIDATION_VALUE_MISSING_RADIO; 331 case WebLocalizedString::ValidationValueMissingForSelect: 332 return IDS_FORM_VALIDATION_VALUE_MISSING_SELECT; 333 case WebLocalizedString::WeekFormatTemplate: 334 return IDS_FORM_INPUT_WEEK_TEMPLATE; 335 case WebLocalizedString::WeekNumberLabel: 336 return IDS_FORM_WEEK_NUMBER_LABEL; 337 // This "default:" line exists to avoid compile warnings about enum 338 // coverage when we add a new symbol to WebLocalizedString.h in WebKit. 339 // After a planned WebKit patch is landed, we need to add a case statement 340 // for the added symbol here. 341 default: 342 break; 343 } 344 return -1; 345} 346 347BlinkPlatformImpl::BlinkPlatformImpl() 348 : main_loop_(base::MessageLoop::current()), 349 shared_timer_func_(NULL), 350 shared_timer_fire_time_(0.0), 351 shared_timer_fire_time_was_set_while_suspended_(false), 352 shared_timer_suspended_(0) {} 353 354BlinkPlatformImpl::~BlinkPlatformImpl() { 355} 356 357WebURLLoader* BlinkPlatformImpl::createURLLoader() { 358 return new WebURLLoaderImpl(this); 359} 360 361WebSocketStreamHandle* BlinkPlatformImpl::createSocketStreamHandle() { 362 return new WebSocketStreamHandleImpl(this); 363} 364 365WebString BlinkPlatformImpl::userAgent() { 366 return WebString::fromUTF8(GetContentClient()->GetUserAgent()); 367} 368 369WebString BlinkPlatformImpl::userAgent(const WebURL& url) { 370 return userAgent(); 371} 372 373WebData BlinkPlatformImpl::parseDataURL(const WebURL& url, 374 WebString& mimetype_out, 375 WebString& charset_out) { 376 std::string mime_type, char_set, data; 377 if (net::DataURL::Parse(url, &mime_type, &char_set, &data) 378 && net::IsSupportedMimeType(mime_type)) { 379 mimetype_out = WebString::fromUTF8(mime_type); 380 charset_out = WebString::fromUTF8(char_set); 381 return data; 382 } 383 return WebData(); 384} 385 386WebURLError BlinkPlatformImpl::cancelledError( 387 const WebURL& unreachableURL) const { 388 return WebURLLoaderImpl::CreateError(unreachableURL, false, net::ERR_ABORTED); 389} 390 391void BlinkPlatformImpl::decrementStatsCounter(const char* name) { 392 base::StatsCounter(name).Decrement(); 393} 394 395void BlinkPlatformImpl::incrementStatsCounter(const char* name) { 396 base::StatsCounter(name).Increment(); 397} 398 399void BlinkPlatformImpl::histogramCustomCounts( 400 const char* name, int sample, int min, int max, int bucket_count) { 401 // Copied from histogram macro, but without the static variable caching 402 // the histogram because name is dynamic. 403 base::HistogramBase* counter = 404 base::Histogram::FactoryGet(name, min, max, bucket_count, 405 base::HistogramBase::kUmaTargetedHistogramFlag); 406 DCHECK_EQ(name, counter->histogram_name()); 407 counter->Add(sample); 408} 409 410void BlinkPlatformImpl::histogramEnumeration( 411 const char* name, int sample, int boundary_value) { 412 // Copied from histogram macro, but without the static variable caching 413 // the histogram because name is dynamic. 414 base::HistogramBase* counter = 415 base::LinearHistogram::FactoryGet(name, 1, boundary_value, 416 boundary_value + 1, base::HistogramBase::kUmaTargetedHistogramFlag); 417 DCHECK_EQ(name, counter->histogram_name()); 418 counter->Add(sample); 419} 420 421void BlinkPlatformImpl::histogramSparse(const char* name, int sample) { 422 // For sparse histograms, we can use the macro, as it does not incorporate a 423 // static. 424 UMA_HISTOGRAM_SPARSE_SLOWLY(name, sample); 425} 426 427const unsigned char* BlinkPlatformImpl::getTraceCategoryEnabledFlag( 428 const char* category_group) { 429 return TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(category_group); 430} 431 432long* BlinkPlatformImpl::getTraceSamplingState( 433 const unsigned thread_bucket) { 434 switch (thread_bucket) { 435 case 0: 436 return reinterpret_cast<long*>(&TRACE_EVENT_API_THREAD_BUCKET(0)); 437 case 1: 438 return reinterpret_cast<long*>(&TRACE_EVENT_API_THREAD_BUCKET(1)); 439 case 2: 440 return reinterpret_cast<long*>(&TRACE_EVENT_API_THREAD_BUCKET(2)); 441 default: 442 NOTREACHED() << "Unknown thread bucket type."; 443 } 444 return NULL; 445} 446 447COMPILE_ASSERT( 448 sizeof(blink::Platform::TraceEventHandle) == 449 sizeof(base::debug::TraceEventHandle), 450 TraceEventHandle_types_must_be_same_size); 451 452blink::Platform::TraceEventHandle BlinkPlatformImpl::addTraceEvent( 453 char phase, 454 const unsigned char* category_group_enabled, 455 const char* name, 456 unsigned long long id, 457 int num_args, 458 const char** arg_names, 459 const unsigned char* arg_types, 460 const unsigned long long* arg_values, 461 unsigned char flags) { 462 base::debug::TraceEventHandle handle = TRACE_EVENT_API_ADD_TRACE_EVENT( 463 phase, category_group_enabled, name, id, 464 num_args, arg_names, arg_types, arg_values, NULL, flags); 465 blink::Platform::TraceEventHandle result; 466 memcpy(&result, &handle, sizeof(result)); 467 return result; 468} 469 470void BlinkPlatformImpl::updateTraceEventDuration( 471 const unsigned char* category_group_enabled, 472 const char* name, 473 TraceEventHandle handle) { 474 base::debug::TraceEventHandle traceEventHandle; 475 memcpy(&traceEventHandle, &handle, sizeof(handle)); 476 TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION( 477 category_group_enabled, name, traceEventHandle); 478} 479 480namespace { 481 482WebData loadAudioSpatializationResource(BlinkPlatformImpl* platform, 483 const char* name) { 484#ifdef IDR_AUDIO_SPATIALIZATION_COMPOSITE 485 if (!strcmp(name, "Composite")) { 486 base::StringPiece resource = 487 platform->GetDataResource(IDR_AUDIO_SPATIALIZATION_COMPOSITE, 488 ui::SCALE_FACTOR_NONE); 489 return WebData(resource.data(), resource.size()); 490 } 491#endif 492 493#ifdef IDR_AUDIO_SPATIALIZATION_T000_P000 494 const size_t kExpectedSpatializationNameLength = 31; 495 if (strlen(name) != kExpectedSpatializationNameLength) { 496 return WebData(); 497 } 498 499 // Extract the azimuth and elevation from the resource name. 500 int azimuth = 0; 501 int elevation = 0; 502 int values_parsed = 503 sscanf(name, "IRC_Composite_C_R0195_T%3d_P%3d", &azimuth, &elevation); 504 if (values_parsed != 2) { 505 return WebData(); 506 } 507 508 // The resource index values go through the elevations first, then azimuths. 509 const int kAngleSpacing = 15; 510 511 // 0 <= elevation <= 90 (or 315 <= elevation <= 345) 512 // in increments of 15 degrees. 513 int elevation_index = 514 elevation <= 90 ? elevation / kAngleSpacing : 515 7 + (elevation - 315) / kAngleSpacing; 516 bool is_elevation_index_good = 0 <= elevation_index && elevation_index < 10; 517 518 // 0 <= azimuth < 360 in increments of 15 degrees. 519 int azimuth_index = azimuth / kAngleSpacing; 520 bool is_azimuth_index_good = 0 <= azimuth_index && azimuth_index < 24; 521 522 const int kNumberOfElevations = 10; 523 const int kNumberOfAudioResources = 240; 524 int resource_index = kNumberOfElevations * azimuth_index + elevation_index; 525 bool is_resource_index_good = 0 <= resource_index && 526 resource_index < kNumberOfAudioResources; 527 528 if (is_azimuth_index_good && is_elevation_index_good && 529 is_resource_index_good) { 530 const int kFirstAudioResourceIndex = IDR_AUDIO_SPATIALIZATION_T000_P000; 531 base::StringPiece resource = 532 platform->GetDataResource(kFirstAudioResourceIndex + resource_index, 533 ui::SCALE_FACTOR_NONE); 534 return WebData(resource.data(), resource.size()); 535 } 536#endif // IDR_AUDIO_SPATIALIZATION_T000_P000 537 538 NOTREACHED(); 539 return WebData(); 540} 541 542struct DataResource { 543 const char* name; 544 int id; 545 ui::ScaleFactor scale_factor; 546}; 547 548const DataResource kDataResources[] = { 549 { "missingImage", IDR_BROKENIMAGE, ui::SCALE_FACTOR_100P }, 550 { "missingImage@2x", IDR_BROKENIMAGE, ui::SCALE_FACTOR_200P }, 551 { "mediaplayerPause", IDR_MEDIAPLAYER_PAUSE_BUTTON, ui::SCALE_FACTOR_100P }, 552 { "mediaplayerPauseHover", 553 IDR_MEDIAPLAYER_PAUSE_BUTTON_HOVER, ui::SCALE_FACTOR_100P }, 554 { "mediaplayerPauseDown", 555 IDR_MEDIAPLAYER_PAUSE_BUTTON_DOWN, ui::SCALE_FACTOR_100P }, 556 { "mediaplayerPlay", IDR_MEDIAPLAYER_PLAY_BUTTON, ui::SCALE_FACTOR_100P }, 557 { "mediaplayerPlayHover", 558 IDR_MEDIAPLAYER_PLAY_BUTTON_HOVER, ui::SCALE_FACTOR_100P }, 559 { "mediaplayerPlayDown", 560 IDR_MEDIAPLAYER_PLAY_BUTTON_DOWN, ui::SCALE_FACTOR_100P }, 561 { "mediaplayerPlayDisabled", 562 IDR_MEDIAPLAYER_PLAY_BUTTON_DISABLED, ui::SCALE_FACTOR_100P }, 563 { "mediaplayerSoundLevel3", 564 IDR_MEDIAPLAYER_SOUND_LEVEL3_BUTTON, ui::SCALE_FACTOR_100P }, 565 { "mediaplayerSoundLevel3Hover", 566 IDR_MEDIAPLAYER_SOUND_LEVEL3_BUTTON_HOVER, ui::SCALE_FACTOR_100P }, 567 { "mediaplayerSoundLevel3Down", 568 IDR_MEDIAPLAYER_SOUND_LEVEL3_BUTTON_DOWN, ui::SCALE_FACTOR_100P }, 569 { "mediaplayerSoundLevel2", 570 IDR_MEDIAPLAYER_SOUND_LEVEL2_BUTTON, ui::SCALE_FACTOR_100P }, 571 { "mediaplayerSoundLevel2Hover", 572 IDR_MEDIAPLAYER_SOUND_LEVEL2_BUTTON_HOVER, ui::SCALE_FACTOR_100P }, 573 { "mediaplayerSoundLevel2Down", 574 IDR_MEDIAPLAYER_SOUND_LEVEL2_BUTTON_DOWN, ui::SCALE_FACTOR_100P }, 575 { "mediaplayerSoundLevel1", 576 IDR_MEDIAPLAYER_SOUND_LEVEL1_BUTTON, ui::SCALE_FACTOR_100P }, 577 { "mediaplayerSoundLevel1Hover", 578 IDR_MEDIAPLAYER_SOUND_LEVEL1_BUTTON_HOVER, ui::SCALE_FACTOR_100P }, 579 { "mediaplayerSoundLevel1Down", 580 IDR_MEDIAPLAYER_SOUND_LEVEL1_BUTTON_DOWN, ui::SCALE_FACTOR_100P }, 581 { "mediaplayerSoundLevel0", 582 IDR_MEDIAPLAYER_SOUND_LEVEL0_BUTTON, ui::SCALE_FACTOR_100P }, 583 { "mediaplayerSoundLevel0Hover", 584 IDR_MEDIAPLAYER_SOUND_LEVEL0_BUTTON_HOVER, ui::SCALE_FACTOR_100P }, 585 { "mediaplayerSoundLevel0Down", 586 IDR_MEDIAPLAYER_SOUND_LEVEL0_BUTTON_DOWN, ui::SCALE_FACTOR_100P }, 587 { "mediaplayerSoundDisabled", 588 IDR_MEDIAPLAYER_SOUND_DISABLED, ui::SCALE_FACTOR_100P }, 589 { "mediaplayerSliderThumb", 590 IDR_MEDIAPLAYER_SLIDER_THUMB, ui::SCALE_FACTOR_100P }, 591 { "mediaplayerSliderThumbHover", 592 IDR_MEDIAPLAYER_SLIDER_THUMB_HOVER, ui::SCALE_FACTOR_100P }, 593 { "mediaplayerSliderThumbDown", 594 IDR_MEDIAPLAYER_SLIDER_THUMB_DOWN, ui::SCALE_FACTOR_100P }, 595 { "mediaplayerVolumeSliderThumb", 596 IDR_MEDIAPLAYER_VOLUME_SLIDER_THUMB, ui::SCALE_FACTOR_100P }, 597 { "mediaplayerVolumeSliderThumbHover", 598 IDR_MEDIAPLAYER_VOLUME_SLIDER_THUMB_HOVER, ui::SCALE_FACTOR_100P }, 599 { "mediaplayerVolumeSliderThumbDown", 600 IDR_MEDIAPLAYER_VOLUME_SLIDER_THUMB_DOWN, ui::SCALE_FACTOR_100P }, 601 { "mediaplayerVolumeSliderThumbDisabled", 602 IDR_MEDIAPLAYER_VOLUME_SLIDER_THUMB_DISABLED, ui::SCALE_FACTOR_100P }, 603 { "mediaplayerClosedCaption", 604 IDR_MEDIAPLAYER_CLOSEDCAPTION_BUTTON, ui::SCALE_FACTOR_100P }, 605 { "mediaplayerClosedCaptionHover", 606 IDR_MEDIAPLAYER_CLOSEDCAPTION_BUTTON_HOVER, ui::SCALE_FACTOR_100P }, 607 { "mediaplayerClosedCaptionDown", 608 IDR_MEDIAPLAYER_CLOSEDCAPTION_BUTTON_DOWN, ui::SCALE_FACTOR_100P }, 609 { "mediaplayerClosedCaptionDisabled", 610 IDR_MEDIAPLAYER_CLOSEDCAPTION_BUTTON_DISABLED, ui::SCALE_FACTOR_100P }, 611 { "mediaplayerFullscreen", 612 IDR_MEDIAPLAYER_FULLSCREEN_BUTTON, ui::SCALE_FACTOR_100P }, 613 { "mediaplayerFullscreenHover", 614 IDR_MEDIAPLAYER_FULLSCREEN_BUTTON_HOVER, ui::SCALE_FACTOR_100P }, 615 { "mediaplayerFullscreenDown", 616 IDR_MEDIAPLAYER_FULLSCREEN_BUTTON_DOWN, ui::SCALE_FACTOR_100P }, 617 { "mediaplayerFullscreenDisabled", 618 IDR_MEDIAPLAYER_FULLSCREEN_BUTTON_DISABLED, ui::SCALE_FACTOR_100P }, 619#if defined(OS_ANDROID) 620 { "mediaplayerOverlayPlay", 621 IDR_MEDIAPLAYER_OVERLAY_PLAY_BUTTON, ui::SCALE_FACTOR_100P }, 622#endif 623#if defined(OS_MACOSX) 624 { "overhangPattern", IDR_OVERHANG_PATTERN, ui::SCALE_FACTOR_100P }, 625 { "overhangShadow", IDR_OVERHANG_SHADOW, ui::SCALE_FACTOR_100P }, 626#endif 627 { "panIcon", IDR_PAN_SCROLL_ICON, ui::SCALE_FACTOR_100P }, 628 { "searchCancel", IDR_SEARCH_CANCEL, ui::SCALE_FACTOR_100P }, 629 { "searchCancelPressed", IDR_SEARCH_CANCEL_PRESSED, ui::SCALE_FACTOR_100P }, 630 { "searchMagnifier", IDR_SEARCH_MAGNIFIER, ui::SCALE_FACTOR_100P }, 631 { "searchMagnifierResults", 632 IDR_SEARCH_MAGNIFIER_RESULTS, ui::SCALE_FACTOR_100P }, 633 { "textAreaResizeCorner", IDR_TEXTAREA_RESIZER, ui::SCALE_FACTOR_100P }, 634 { "textAreaResizeCorner@2x", IDR_TEXTAREA_RESIZER, ui::SCALE_FACTOR_200P }, 635 { "inputSpeech", IDR_INPUT_SPEECH, ui::SCALE_FACTOR_100P }, 636 { "inputSpeechRecording", IDR_INPUT_SPEECH_RECORDING, ui::SCALE_FACTOR_100P }, 637 { "inputSpeechWaiting", IDR_INPUT_SPEECH_WAITING, ui::SCALE_FACTOR_100P }, 638 { "generatePassword", IDR_PASSWORD_GENERATION_ICON, ui::SCALE_FACTOR_100P }, 639 { "generatePasswordHover", 640 IDR_PASSWORD_GENERATION_ICON_HOVER, ui::SCALE_FACTOR_100P }, 641 { "syntheticTouchCursor", 642 IDR_SYNTHETIC_TOUCH_CURSOR, ui::SCALE_FACTOR_100P }, 643}; 644 645} // namespace 646 647WebData BlinkPlatformImpl::loadResource(const char* name) { 648 // Some clients will call into this method with an empty |name| when they have 649 // optional resources. For example, the PopupMenuChromium code can have icons 650 // for some Autofill items but not for others. 651 if (!strlen(name)) 652 return WebData(); 653 654 // Check the name prefix to see if it's an audio resource. 655 if (StartsWithASCII(name, "IRC_Composite", true) || 656 StartsWithASCII(name, "Composite", true)) 657 return loadAudioSpatializationResource(this, name); 658 659 // TODO(flackr): We should use a better than linear search here, a trie would 660 // be ideal. 661 for (size_t i = 0; i < arraysize(kDataResources); ++i) { 662 if (!strcmp(name, kDataResources[i].name)) { 663 base::StringPiece resource = 664 GetDataResource(kDataResources[i].id, 665 kDataResources[i].scale_factor); 666 return WebData(resource.data(), resource.size()); 667 } 668 } 669 670 NOTREACHED() << "Unknown image resource " << name; 671 return WebData(); 672} 673 674WebString BlinkPlatformImpl::queryLocalizedString( 675 WebLocalizedString::Name name) { 676 int message_id = ToMessageID(name); 677 if (message_id < 0) 678 return WebString(); 679 return GetLocalizedString(message_id); 680} 681 682WebString BlinkPlatformImpl::queryLocalizedString( 683 WebLocalizedString::Name name, int numeric_value) { 684 return queryLocalizedString(name, base::IntToString16(numeric_value)); 685} 686 687WebString BlinkPlatformImpl::queryLocalizedString( 688 WebLocalizedString::Name name, const WebString& value) { 689 int message_id = ToMessageID(name); 690 if (message_id < 0) 691 return WebString(); 692 return ReplaceStringPlaceholders(GetLocalizedString(message_id), value, NULL); 693} 694 695WebString BlinkPlatformImpl::queryLocalizedString( 696 WebLocalizedString::Name name, 697 const WebString& value1, 698 const WebString& value2) { 699 int message_id = ToMessageID(name); 700 if (message_id < 0) 701 return WebString(); 702 std::vector<base::string16> values; 703 values.reserve(2); 704 values.push_back(value1); 705 values.push_back(value2); 706 return ReplaceStringPlaceholders( 707 GetLocalizedString(message_id), values, NULL); 708} 709 710double BlinkPlatformImpl::currentTime() { 711 return base::Time::Now().ToDoubleT(); 712} 713 714double BlinkPlatformImpl::monotonicallyIncreasingTime() { 715 return base::TimeTicks::Now().ToInternalValue() / 716 static_cast<double>(base::Time::kMicrosecondsPerSecond); 717} 718 719void BlinkPlatformImpl::cryptographicallyRandomValues( 720 unsigned char* buffer, size_t length) { 721 base::RandBytes(buffer, length); 722} 723 724void BlinkPlatformImpl::setSharedTimerFiredFunction(void (*func)()) { 725 shared_timer_func_ = func; 726} 727 728void BlinkPlatformImpl::setSharedTimerFireInterval( 729 double interval_seconds) { 730 shared_timer_fire_time_ = interval_seconds + monotonicallyIncreasingTime(); 731 if (shared_timer_suspended_) { 732 shared_timer_fire_time_was_set_while_suspended_ = true; 733 return; 734 } 735 736 // By converting between double and int64 representation, we run the risk 737 // of losing precision due to rounding errors. Performing computations in 738 // microseconds reduces this risk somewhat. But there still is the potential 739 // of us computing a fire time for the timer that is shorter than what we 740 // need. 741 // As the event loop will check event deadlines prior to actually firing 742 // them, there is a risk of needlessly rescheduling events and of 743 // needlessly looping if sleep times are too short even by small amounts. 744 // This results in measurable performance degradation unless we use ceil() to 745 // always round up the sleep times. 746 int64 interval = static_cast<int64>( 747 ceil(interval_seconds * base::Time::kMillisecondsPerSecond) 748 * base::Time::kMicrosecondsPerMillisecond); 749 750 if (interval < 0) 751 interval = 0; 752 753 shared_timer_.Stop(); 754 shared_timer_.Start(FROM_HERE, base::TimeDelta::FromMicroseconds(interval), 755 this, &BlinkPlatformImpl::DoTimeout); 756 OnStartSharedTimer(base::TimeDelta::FromMicroseconds(interval)); 757} 758 759void BlinkPlatformImpl::stopSharedTimer() { 760 shared_timer_.Stop(); 761} 762 763void BlinkPlatformImpl::callOnMainThread( 764 void (*func)(void*), void* context) { 765 main_loop_->PostTask(FROM_HERE, base::Bind(func, context)); 766} 767 768base::PlatformFile BlinkPlatformImpl::databaseOpenFile( 769 const blink::WebString& vfs_file_name, int desired_flags) { 770 return base::kInvalidPlatformFileValue; 771} 772 773int BlinkPlatformImpl::databaseDeleteFile( 774 const blink::WebString& vfs_file_name, bool sync_dir) { 775 return -1; 776} 777 778long BlinkPlatformImpl::databaseGetFileAttributes( 779 const blink::WebString& vfs_file_name) { 780 return 0; 781} 782 783long long BlinkPlatformImpl::databaseGetFileSize( 784 const blink::WebString& vfs_file_name) { 785 return 0; 786} 787 788long long BlinkPlatformImpl::databaseGetSpaceAvailableForOrigin( 789 const blink::WebString& origin_identifier) { 790 return 0; 791} 792 793blink::WebString BlinkPlatformImpl::signedPublicKeyAndChallengeString( 794 unsigned key_size_index, 795 const blink::WebString& challenge, 796 const blink::WebURL& url) { 797 return blink::WebString(""); 798} 799 800static scoped_ptr<base::ProcessMetrics> CurrentProcessMetrics() { 801 using base::ProcessMetrics; 802#if defined(OS_MACOSX) 803 return scoped_ptr<ProcessMetrics>( 804 // The default port provider is sufficient to get data for the current 805 // process. 806 ProcessMetrics::CreateProcessMetrics(base::GetCurrentProcessHandle(), 807 NULL)); 808#else 809 return scoped_ptr<ProcessMetrics>( 810 ProcessMetrics::CreateProcessMetrics(base::GetCurrentProcessHandle())); 811#endif 812} 813 814static size_t getMemoryUsageMB(bool bypass_cache) { 815 size_t current_mem_usage = 0; 816 MemoryUsageCache* mem_usage_cache_singleton = MemoryUsageCache::GetInstance(); 817 if (!bypass_cache && 818 mem_usage_cache_singleton->IsCachedValueValid(¤t_mem_usage)) 819 return current_mem_usage; 820 821 current_mem_usage = GetMemoryUsageKB() >> 10; 822 mem_usage_cache_singleton->SetMemoryValue(current_mem_usage); 823 return current_mem_usage; 824} 825 826size_t BlinkPlatformImpl::memoryUsageMB() { 827 return getMemoryUsageMB(false); 828} 829 830size_t BlinkPlatformImpl::actualMemoryUsageMB() { 831 return getMemoryUsageMB(true); 832} 833 834size_t BlinkPlatformImpl::physicalMemoryMB() { 835 return static_cast<size_t>(base::SysInfo::AmountOfPhysicalMemoryMB()); 836} 837 838size_t BlinkPlatformImpl::numberOfProcessors() { 839 return static_cast<size_t>(base::SysInfo::NumberOfProcessors()); 840} 841 842void BlinkPlatformImpl::startHeapProfiling( 843 const blink::WebString& prefix) { 844 // FIXME(morrita): Make this built on windows. 845#if !defined(NO_TCMALLOC) && defined(USE_TCMALLOC) && !defined(OS_WIN) 846 HeapProfilerStart(prefix.utf8().data()); 847#endif 848} 849 850void BlinkPlatformImpl::stopHeapProfiling() { 851#if !defined(NO_TCMALLOC) && defined(USE_TCMALLOC) && !defined(OS_WIN) 852 HeapProfilerStop(); 853#endif 854} 855 856void BlinkPlatformImpl::dumpHeapProfiling( 857 const blink::WebString& reason) { 858#if !defined(NO_TCMALLOC) && defined(USE_TCMALLOC) && !defined(OS_WIN) 859 HeapProfilerDump(reason.utf8().data()); 860#endif 861} 862 863WebString BlinkPlatformImpl::getHeapProfile() { 864#if !defined(NO_TCMALLOC) && defined(USE_TCMALLOC) && !defined(OS_WIN) 865 char* data = GetHeapProfile(); 866 WebString result = WebString::fromUTF8(std::string(data)); 867 free(data); 868 return result; 869#else 870 return WebString(); 871#endif 872} 873 874bool BlinkPlatformImpl::processMemorySizesInBytes( 875 size_t* private_bytes, 876 size_t* shared_bytes) { 877 return CurrentProcessMetrics()->GetMemoryBytes(private_bytes, shared_bytes); 878} 879 880bool BlinkPlatformImpl::memoryAllocatorWasteInBytes(size_t* size) { 881 return base::allocator::GetAllocatorWasteSize(size); 882} 883 884size_t BlinkPlatformImpl::maxDecodedImageBytes() { 885#if defined(OS_ANDROID) 886 if (base::android::SysUtils::IsLowEndDevice()) { 887 // Limit image decoded size to 3M pixels on low end devices. 888 // 4 is maximum number of bytes per pixel. 889 return 3 * 1024 * 1024 * 4; 890 } 891 // For other devices, limit decoded image size based on the amount of physical 892 // memory. For a device with 2GB physical memory the limit is 16M pixels. 893 return base::SysInfo::AmountOfPhysicalMemory() / 32; 894#else 895 return noDecodedImageByteLimit; 896#endif 897} 898 899void BlinkPlatformImpl::SuspendSharedTimer() { 900 ++shared_timer_suspended_; 901} 902 903void BlinkPlatformImpl::ResumeSharedTimer() { 904 DCHECK_GT(shared_timer_suspended_, 0); 905 906 // The shared timer may have fired or been adjusted while we were suspended. 907 if (--shared_timer_suspended_ == 0 && 908 (!shared_timer_.IsRunning() || 909 shared_timer_fire_time_was_set_while_suspended_)) { 910 shared_timer_fire_time_was_set_while_suspended_ = false; 911 setSharedTimerFireInterval( 912 shared_timer_fire_time_ - monotonicallyIncreasingTime()); 913 } 914} 915 916} // namespace content 917