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