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