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