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.
5 #include "webkit/glue/webkitplatformsupport_impl.h"
15 #include "base/bind.h"
16 #include "base/debug/trace_event.h"
17 #include "base/memory/scoped_ptr.h"
18 #include "base/memory/singleton.h"
19 #include "base/message_loop.h"
20 #include "base/metrics/histogram.h"
21 #include "base/metrics/stats_counters.h"
22 #include "base/platform_file.h"
23 #include "base/process_util.h"
24 #include "base/rand_util.h"
25 #include "base/string_number_conversions.h"
26 #include "base/string_util.h"
27 #include "base/synchronization/lock.h"
28 #include "base/sys_info.h"
29 #include "base/time.h"
30 #include "base/utf_string_conversions.h"
31 #include "grit/webkit_chromium_resources.h"
32 #include "grit/webkit_resources.h"
33 #include "grit/webkit_strings.h"
34 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrameClient.h"
35 #include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginListBuilder.h"
36 #include "third_party/WebKit/Source/WebKit/chromium/public/WebScreenInfo.h"
37 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebCookie.h"
38 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebData.h"
39 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h"
40 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURL.h"
41 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebVector.h"
42 #include "ui/base/layout.h"
43 #include "webkit/compositor_bindings/web_compositor_support_impl.h"
44 #include "webkit/glue/webkit_glue.h"
45 #include "webkit/glue/websocketstreamhandle_impl.h"
46 #include "webkit/glue/webthread_impl.h"
47 #include "webkit/glue/weburlloader_impl.h"
48 #include "webkit/glue/worker_task_runner.h"
49 #include "webkit/media/audio_decoder.h"
50 #include "webkit/plugins/npapi/plugin_instance.h"
51 #include "webkit/plugins/webplugininfo.h"
52 #include "webkit/user_agent/user_agent.h"
54 #if defined(OS_ANDROID)
55 #include "webkit/glue/fling_animator_impl_android.h"
59 #include "v8/include/v8.h"
62 using WebKit::WebAudioBus
;
63 using WebKit::WebCookie
;
64 using WebKit::WebData
;
65 using WebKit::WebLocalizedString
;
66 using WebKit::WebPluginListBuilder
;
67 using WebKit::WebString
;
68 using WebKit::WebSocketStreamHandle
;
69 using WebKit::WebThemeEngine
;
71 using WebKit::WebURLLoader
;
72 using WebKit::WebVector
;
76 // A simple class to cache the memory usage for a given amount of time.
77 class MemoryUsageCache
{
79 // Retrieves the Singleton.
80 static MemoryUsageCache
* GetInstance() {
81 return Singleton
<MemoryUsageCache
>::get();
84 MemoryUsageCache() : memory_value_(0) { Init(); }
85 ~MemoryUsageCache() {}
88 const unsigned int kCacheSeconds
= 1;
89 cache_valid_time_
= base::TimeDelta::FromSeconds(kCacheSeconds
);
92 // Returns true if the cached value is fresh.
93 // Returns false if the cached value is stale, or if |cached_value| is NULL.
94 bool IsCachedValueValid(size_t* cached_value
) {
95 base::AutoLock
scoped_lock(lock_
);
98 if (base::Time::Now() - last_updated_time_
> cache_valid_time_
)
100 *cached_value
= memory_value_
;
104 // Setter for |memory_value_|, refreshes |last_updated_time_|.
105 void SetMemoryValue(const size_t value
) {
106 base::AutoLock
scoped_lock(lock_
);
107 memory_value_
= value
;
108 last_updated_time_
= base::Time::Now();
112 // The cached memory value.
113 size_t memory_value_
;
115 // How long the cached value should remain valid.
116 base::TimeDelta cache_valid_time_
;
118 // The last time the cached value was updated.
119 base::Time last_updated_time_
;
124 } // anonymous namespace
126 namespace webkit_glue
{
128 static int ToMessageID(WebLocalizedString::Name name
) {
130 case WebLocalizedString::AXAMPMFieldText
:
131 return IDS_AX_AM_PM_FIELD_TEXT
;
132 case WebLocalizedString::AXButtonActionVerb
:
133 return IDS_AX_BUTTON_ACTION_VERB
;
134 case WebLocalizedString::AXCheckedCheckBoxActionVerb
:
135 return IDS_AX_CHECKED_CHECK_BOX_ACTION_VERB
;
136 case WebLocalizedString::AXDateTimeFieldEmptyValueText
:
137 return IDS_AX_DATE_TIME_FIELD_EMPTY_VALUE_TEXT
;
138 case WebLocalizedString::AXDayOfMonthFieldText
:
139 return IDS_AX_DAY_OF_MONTH_FIELD_TEXT
;
140 case WebLocalizedString::AXHeadingText
:
141 return IDS_AX_ROLE_HEADING
;
142 case WebLocalizedString::AXHourFieldText
:
143 return IDS_AX_HOUR_FIELD_TEXT
;
144 case WebLocalizedString::AXImageMapText
:
145 return IDS_AX_ROLE_IMAGE_MAP
;
146 case WebLocalizedString::AXLinkActionVerb
:
147 return IDS_AX_LINK_ACTION_VERB
;
148 case WebLocalizedString::AXLinkText
:
149 return IDS_AX_ROLE_LINK
;
150 case WebLocalizedString::AXListMarkerText
:
151 return IDS_AX_ROLE_LIST_MARKER
;
152 case WebLocalizedString::AXMillisecondFieldText
:
153 return IDS_AX_MILLISECOND_FIELD_TEXT
;
154 case WebLocalizedString::AXMinuteFieldText
:
155 return IDS_AX_MINUTE_FIELD_TEXT
;
156 case WebLocalizedString::AXMonthFieldText
:
157 return IDS_AX_MONTH_FIELD_TEXT
;
158 case WebLocalizedString::AXRadioButtonActionVerb
:
159 return IDS_AX_RADIO_BUTTON_ACTION_VERB
;
160 case WebLocalizedString::AXSecondFieldText
:
161 return IDS_AX_SECOND_FIELD_TEXT
;
162 case WebLocalizedString::AXTextFieldActionVerb
:
163 return IDS_AX_TEXT_FIELD_ACTION_VERB
;
164 case WebLocalizedString::AXUncheckedCheckBoxActionVerb
:
165 return IDS_AX_UNCHECKED_CHECK_BOX_ACTION_VERB
;
166 case WebLocalizedString::AXWebAreaText
:
167 return IDS_AX_ROLE_WEB_AREA
;
168 case WebLocalizedString::AXWeekOfYearFieldText
:
169 return IDS_AX_WEEK_OF_YEAR_FIELD_TEXT
;
170 case WebLocalizedString::AXYearFieldText
:
171 return IDS_AX_YEAR_FIELD_TEXT
;
172 case WebLocalizedString::CalendarClear
:
173 return IDS_FORM_CALENDAR_CLEAR
;
174 case WebLocalizedString::CalendarToday
:
175 return IDS_FORM_CALENDAR_TODAY
;
176 case WebLocalizedString::DateFormatDayInMonthLabel
:
177 return IDS_FORM_DATE_FORMAT_DAY_IN_MONTH
;
178 case WebLocalizedString::DateFormatMonthLabel
:
179 return IDS_FORM_DATE_FORMAT_MONTH
;
180 case WebLocalizedString::DateFormatYearLabel
:
181 return IDS_FORM_DATE_FORMAT_YEAR
;
182 case WebLocalizedString::DetailsLabel
:
183 return IDS_DETAILS_WITHOUT_SUMMARY_LABEL
;
184 case WebLocalizedString::FileButtonChooseFileLabel
:
185 return IDS_FORM_FILE_BUTTON_LABEL
;
186 case WebLocalizedString::FileButtonChooseMultipleFilesLabel
:
187 return IDS_FORM_MULTIPLE_FILES_BUTTON_LABEL
;
188 case WebLocalizedString::FileButtonNoFileSelectedLabel
:
189 return IDS_FORM_FILE_NO_FILE_LABEL
;
190 case WebLocalizedString::InputElementAltText
:
191 return IDS_FORM_INPUT_ALT
;
192 case WebLocalizedString::KeygenMenuHighGradeKeySize
:
193 return IDS_KEYGEN_HIGH_GRADE_KEY
;
194 case WebLocalizedString::KeygenMenuMediumGradeKeySize
:
195 return IDS_KEYGEN_MED_GRADE_KEY
;
196 case WebLocalizedString::MissingPluginText
:
197 return IDS_PLUGIN_INITIALIZATION_ERROR
;
198 case WebLocalizedString::MultipleFileUploadText
:
199 return IDS_FORM_FILE_MULTIPLE_UPLOAD
;
200 case WebLocalizedString::OtherColorLabel
:
201 return IDS_FORM_OTHER_COLOR_LABEL
;
202 case WebLocalizedString::OtherDateLabel
:
203 return IDS_FORM_OTHER_DATE_LABEL
;
204 case WebLocalizedString::OtherMonthLabel
:
205 return IDS_FORM_OTHER_MONTH_LABEL
;
206 case WebLocalizedString::OtherTimeLabel
:
207 return IDS_FORM_OTHER_TIME_LABEL
;
208 case WebLocalizedString::OtherWeekLabel
:
209 return IDS_FORM_OTHER_WEEK_LABEL
;
210 case WebLocalizedString::PlaceholderForDayOfMonthField
:
211 return IDS_FORM_PLACEHOLDER_FOR_DAY_OF_MONTH_FIELD
;
212 case WebLocalizedString::PlaceholderForMonthField
:
213 return IDS_FORM_PLACEHOLDER_FOR_MONTH_FIELD
;
214 case WebLocalizedString::PlaceholderForYearField
:
215 return IDS_FORM_PLACEHOLDER_FOR_YEAR_FIELD
;
216 case WebLocalizedString::ResetButtonDefaultLabel
:
217 return IDS_FORM_RESET_LABEL
;
218 case WebLocalizedString::SearchableIndexIntroduction
:
219 return IDS_SEARCHABLE_INDEX_INTRO
;
220 case WebLocalizedString::SearchMenuClearRecentSearchesText
:
221 return IDS_RECENT_SEARCHES_CLEAR
;
222 case WebLocalizedString::SearchMenuNoRecentSearchesText
:
223 return IDS_RECENT_SEARCHES_NONE
;
224 case WebLocalizedString::SearchMenuRecentSearchesText
:
225 return IDS_RECENT_SEARCHES
;
226 case WebLocalizedString::SubmitButtonDefaultLabel
:
227 return IDS_FORM_SUBMIT_LABEL
;
228 case WebLocalizedString::ThisMonthButtonLabel
:
229 return IDS_FORM_THIS_MONTH_LABEL
;
230 case WebLocalizedString::ThisWeekButtonLabel
:
231 return IDS_FORM_THIS_WEEK_LABEL
;
232 case WebLocalizedString::ValidationPatternMismatch
:
233 return IDS_FORM_VALIDATION_PATTERN_MISMATCH
;
234 case WebLocalizedString::ValidationRangeOverflow
:
235 return IDS_FORM_VALIDATION_RANGE_OVERFLOW
;
236 case WebLocalizedString::ValidationRangeUnderflow
:
237 return IDS_FORM_VALIDATION_RANGE_UNDERFLOW
;
238 case WebLocalizedString::ValidationStepMismatch
:
239 return IDS_FORM_VALIDATION_STEP_MISMATCH
;
240 case WebLocalizedString::ValidationTooLong
:
241 return IDS_FORM_VALIDATION_TOO_LONG
;
242 case WebLocalizedString::ValidationTypeMismatch
:
243 return IDS_FORM_VALIDATION_TYPE_MISMATCH
;
244 case WebLocalizedString::ValidationTypeMismatchForEmail
:
245 return IDS_FORM_VALIDATION_TYPE_MISMATCH_EMAIL
;
246 case WebLocalizedString::ValidationTypeMismatchForMultipleEmail
:
247 return IDS_FORM_VALIDATION_TYPE_MISMATCH_MULTIPLE_EMAIL
;
248 case WebLocalizedString::ValidationTypeMismatchForURL
:
249 return IDS_FORM_VALIDATION_TYPE_MISMATCH_URL
;
250 case WebLocalizedString::ValidationValueMissing
:
251 return IDS_FORM_VALIDATION_VALUE_MISSING
;
252 case WebLocalizedString::ValidationValueMissingForCheckbox
:
253 return IDS_FORM_VALIDATION_VALUE_MISSING_CHECKBOX
;
254 case WebLocalizedString::ValidationValueMissingForFile
:
255 return IDS_FORM_VALIDATION_VALUE_MISSING_FILE
;
256 case WebLocalizedString::ValidationValueMissingForMultipleFile
:
257 return IDS_FORM_VALIDATION_VALUE_MISSING_MULTIPLE_FILE
;
258 case WebLocalizedString::ValidationValueMissingForRadio
:
259 return IDS_FORM_VALIDATION_VALUE_MISSING_RADIO
;
260 case WebLocalizedString::ValidationValueMissingForSelect
:
261 return IDS_FORM_VALIDATION_VALUE_MISSING_SELECT
;
262 // This "default:" line exists to avoid compile warnings about enum
263 // coverage when we add a new symbol to WebLocalizedString.h in WebKit.
264 // After a planned WebKit patch is landed, we need to add a case statement
265 // for the added symbol here.
272 WebKitPlatformSupportImpl::WebKitPlatformSupportImpl()
273 : main_loop_(MessageLoop::current()),
274 shared_timer_func_(NULL
),
275 shared_timer_fire_time_(0.0),
276 shared_timer_suspended_(0),
277 current_thread_slot_(&DestroyCurrentThread
),
278 compositor_support_(new webkit::WebCompositorSupportImpl
) {
281 WebKitPlatformSupportImpl::~WebKitPlatformSupportImpl() {
284 WebThemeEngine
* WebKitPlatformSupportImpl::themeEngine() {
285 return &theme_engine_
;
288 WebURLLoader
* WebKitPlatformSupportImpl::createURLLoader() {
289 return new WebURLLoaderImpl(this);
292 WebSocketStreamHandle
* WebKitPlatformSupportImpl::createSocketStreamHandle() {
293 return new WebSocketStreamHandleImpl(this);
296 WebString
WebKitPlatformSupportImpl::userAgent(const WebURL
& url
) {
297 return WebString::fromUTF8(webkit_glue::GetUserAgent(url
));
300 void WebKitPlatformSupportImpl::getPluginList(bool refresh
,
301 WebPluginListBuilder
* builder
) {
302 std::vector
<webkit::WebPluginInfo
> plugins
;
303 GetPlugins(refresh
, &plugins
);
305 for (size_t i
= 0; i
< plugins
.size(); ++i
) {
306 const webkit::WebPluginInfo
& plugin
= plugins
[i
];
309 plugin
.name
, plugin
.desc
,
310 FilePathStringToWebString(plugin
.path
.BaseName().value()));
312 for (size_t j
= 0; j
< plugin
.mime_types
.size(); ++j
) {
313 const webkit::WebPluginMimeType
& mime_type
= plugin
.mime_types
[j
];
315 builder
->addMediaTypeToLastPlugin(
316 WebString::fromUTF8(mime_type
.mime_type
), mime_type
.description
);
318 for (size_t k
= 0; k
< mime_type
.file_extensions
.size(); ++k
) {
319 builder
->addFileExtensionToLastMediaType(
320 UTF8ToUTF16(mime_type
.file_extensions
[k
]));
326 void WebKitPlatformSupportImpl::decrementStatsCounter(const char* name
) {
327 base::StatsCounter(name
).Decrement();
330 void WebKitPlatformSupportImpl::incrementStatsCounter(const char* name
) {
331 base::StatsCounter(name
).Increment();
334 void WebKitPlatformSupportImpl::histogramCustomCounts(
335 const char* name
, int sample
, int min
, int max
, int bucket_count
) {
336 // Copied from histogram macro, but without the static variable caching
337 // the histogram because name is dynamic.
338 base::Histogram
* counter
=
339 base::Histogram::FactoryGet(name
, min
, max
, bucket_count
,
340 base::Histogram::kUmaTargetedHistogramFlag
);
341 DCHECK_EQ(name
, counter
->histogram_name());
342 counter
->Add(sample
);
345 void WebKitPlatformSupportImpl::histogramEnumeration(
346 const char* name
, int sample
, int boundary_value
) {
347 // Copied from histogram macro, but without the static variable caching
348 // the histogram because name is dynamic.
349 base::Histogram
* counter
=
350 base::LinearHistogram::FactoryGet(name
, 1, boundary_value
,
351 boundary_value
+ 1, base::Histogram::kUmaTargetedHistogramFlag
);
352 DCHECK_EQ(name
, counter
->histogram_name());
353 counter
->Add(sample
);
356 const unsigned char* WebKitPlatformSupportImpl::getTraceCategoryEnabledFlag(
357 const char* category_name
) {
358 return TRACE_EVENT_API_GET_CATEGORY_ENABLED(category_name
);
361 int WebKitPlatformSupportImpl::addTraceEvent(
363 const unsigned char* category_enabled
,
365 unsigned long long id
,
367 const char** arg_names
,
368 const unsigned char* arg_types
,
369 const unsigned long long* arg_values
,
370 int threshold_begin_id
,
372 unsigned char flags
) {
373 return TRACE_EVENT_API_ADD_TRACE_EVENT(phase
, category_enabled
, name
, id
,
374 num_args
, arg_names
, arg_types
,
375 arg_values
, threshold_begin_id
,
381 WebData
loadAudioSpatializationResource(WebKitPlatformSupportImpl
* platform
,
383 #ifdef IDR_AUDIO_SPATIALIZATION_T000_P000
384 const size_t kExpectedSpatializationNameLength
= 31;
385 if (strlen(name
) != kExpectedSpatializationNameLength
) {
389 // Extract the azimuth and elevation from the resource name.
393 sscanf(name
, "IRC_Composite_C_R0195_T%3d_P%3d", &azimuth
, &elevation
);
394 if (values_parsed
!= 2) {
398 // The resource index values go through the elevations first, then azimuths.
399 const int kAngleSpacing
= 15;
401 // 0 <= elevation <= 90 (or 315 <= elevation <= 345)
402 // in increments of 15 degrees.
403 int elevation_index
=
404 elevation
<= 90 ? elevation
/ kAngleSpacing
:
405 7 + (elevation
- 315) / kAngleSpacing
;
406 bool is_elevation_index_good
= 0 <= elevation_index
&& elevation_index
< 10;
408 // 0 <= azimuth < 360 in increments of 15 degrees.
409 int azimuth_index
= azimuth
/ kAngleSpacing
;
410 bool is_azimuth_index_good
= 0 <= azimuth_index
&& azimuth_index
< 24;
412 const int kNumberOfElevations
= 10;
413 const int kNumberOfAudioResources
= 240;
414 int resource_index
= kNumberOfElevations
* azimuth_index
+ elevation_index
;
415 bool is_resource_index_good
= 0 <= resource_index
&&
416 resource_index
< kNumberOfAudioResources
;
418 if (is_azimuth_index_good
&& is_elevation_index_good
&&
419 is_resource_index_good
) {
420 const int kFirstAudioResourceIndex
= IDR_AUDIO_SPATIALIZATION_T000_P000
;
421 base::StringPiece resource
=
422 platform
->GetDataResource(kFirstAudioResourceIndex
+ resource_index
,
423 ui::SCALE_FACTOR_NONE
);
424 return WebData(resource
.data(), resource
.size());
426 #endif // IDR_AUDIO_SPATIALIZATION_T000_P000
432 struct DataResource
{
435 ui::ScaleFactor scale_factor
;
438 const DataResource kDataResources
[] = {
439 { "missingImage", IDR_BROKENIMAGE
, ui::SCALE_FACTOR_100P
},
440 { "missingImage@2x", IDR_BROKENIMAGE
, ui::SCALE_FACTOR_200P
},
441 { "mediaPause", IDR_MEDIA_PAUSE_BUTTON
, ui::SCALE_FACTOR_100P
},
442 { "mediaPlay", IDR_MEDIA_PLAY_BUTTON
, ui::SCALE_FACTOR_100P
},
443 { "mediaPlayDisabled",
444 IDR_MEDIA_PLAY_BUTTON_DISABLED
, ui::SCALE_FACTOR_100P
},
445 { "mediaSoundDisabled", IDR_MEDIA_SOUND_DISABLED
, ui::SCALE_FACTOR_100P
},
446 { "mediaSoundFull", IDR_MEDIA_SOUND_FULL_BUTTON
, ui::SCALE_FACTOR_100P
},
447 { "mediaSoundNone", IDR_MEDIA_SOUND_NONE_BUTTON
, ui::SCALE_FACTOR_100P
},
448 { "mediaSliderThumb", IDR_MEDIA_SLIDER_THUMB
, ui::SCALE_FACTOR_100P
},
449 { "mediaVolumeSliderThumb",
450 IDR_MEDIA_VOLUME_SLIDER_THUMB
, ui::SCALE_FACTOR_100P
},
451 { "mediaplayerPause", IDR_MEDIAPLAYER_PAUSE_BUTTON
, ui::SCALE_FACTOR_100P
},
452 { "mediaplayerPauseHover",
453 IDR_MEDIAPLAYER_PAUSE_BUTTON_HOVER
, ui::SCALE_FACTOR_100P
},
454 { "mediaplayerPauseDown",
455 IDR_MEDIAPLAYER_PAUSE_BUTTON_DOWN
, ui::SCALE_FACTOR_100P
},
456 { "mediaplayerPlay", IDR_MEDIAPLAYER_PLAY_BUTTON
, ui::SCALE_FACTOR_100P
},
457 { "mediaplayerPlayHover",
458 IDR_MEDIAPLAYER_PLAY_BUTTON_HOVER
, ui::SCALE_FACTOR_100P
},
459 { "mediaplayerPlayDown",
460 IDR_MEDIAPLAYER_PLAY_BUTTON_DOWN
, ui::SCALE_FACTOR_100P
},
461 { "mediaplayerPlayDisabled",
462 IDR_MEDIAPLAYER_PLAY_BUTTON_DISABLED
, ui::SCALE_FACTOR_100P
},
463 { "mediaplayerSoundLevel3",
464 IDR_MEDIAPLAYER_SOUND_LEVEL3_BUTTON
, ui::SCALE_FACTOR_100P
},
465 { "mediaplayerSoundLevel3Hover",
466 IDR_MEDIAPLAYER_SOUND_LEVEL3_BUTTON_HOVER
, ui::SCALE_FACTOR_100P
},
467 { "mediaplayerSoundLevel3Down",
468 IDR_MEDIAPLAYER_SOUND_LEVEL3_BUTTON_DOWN
, ui::SCALE_FACTOR_100P
},
469 { "mediaplayerSoundLevel2",
470 IDR_MEDIAPLAYER_SOUND_LEVEL2_BUTTON
, ui::SCALE_FACTOR_100P
},
471 { "mediaplayerSoundLevel2Hover",
472 IDR_MEDIAPLAYER_SOUND_LEVEL2_BUTTON_HOVER
, ui::SCALE_FACTOR_100P
},
473 { "mediaplayerSoundLevel2Down",
474 IDR_MEDIAPLAYER_SOUND_LEVEL2_BUTTON_DOWN
, ui::SCALE_FACTOR_100P
},
475 { "mediaplayerSoundLevel1",
476 IDR_MEDIAPLAYER_SOUND_LEVEL1_BUTTON
, ui::SCALE_FACTOR_100P
},
477 { "mediaplayerSoundLevel1Hover",
478 IDR_MEDIAPLAYER_SOUND_LEVEL1_BUTTON_HOVER
, ui::SCALE_FACTOR_100P
},
479 { "mediaplayerSoundLevel1Down",
480 IDR_MEDIAPLAYER_SOUND_LEVEL1_BUTTON_DOWN
, ui::SCALE_FACTOR_100P
},
481 { "mediaplayerSoundLevel0",
482 IDR_MEDIAPLAYER_SOUND_LEVEL0_BUTTON
, ui::SCALE_FACTOR_100P
},
483 { "mediaplayerSoundLevel0Hover",
484 IDR_MEDIAPLAYER_SOUND_LEVEL0_BUTTON_HOVER
, ui::SCALE_FACTOR_100P
},
485 { "mediaplayerSoundLevel0Down",
486 IDR_MEDIAPLAYER_SOUND_LEVEL0_BUTTON_DOWN
, ui::SCALE_FACTOR_100P
},
487 { "mediaplayerSoundDisabled",
488 IDR_MEDIAPLAYER_SOUND_DISABLED
, ui::SCALE_FACTOR_100P
},
489 { "mediaplayerSliderThumb",
490 IDR_MEDIAPLAYER_SLIDER_THUMB
, ui::SCALE_FACTOR_100P
},
491 { "mediaplayerSliderThumbHover",
492 IDR_MEDIAPLAYER_SLIDER_THUMB_HOVER
, ui::SCALE_FACTOR_100P
},
493 { "mediaplayerSliderThumbDown",
494 IDR_MEDIAPLAYER_SLIDER_THUMB_DOWN
, ui::SCALE_FACTOR_100P
},
495 { "mediaplayerVolumeSliderThumb",
496 IDR_MEDIAPLAYER_VOLUME_SLIDER_THUMB
, ui::SCALE_FACTOR_100P
},
497 { "mediaplayerVolumeSliderThumbHover",
498 IDR_MEDIAPLAYER_VOLUME_SLIDER_THUMB_HOVER
, ui::SCALE_FACTOR_100P
},
499 { "mediaplayerVolumeSliderThumbDown",
500 IDR_MEDIAPLAYER_VOLUME_SLIDER_THUMB_DOWN
, ui::SCALE_FACTOR_100P
},
501 { "mediaplayerVolumeSliderThumbDisabled",
502 IDR_MEDIAPLAYER_VOLUME_SLIDER_THUMB_DISABLED
, ui::SCALE_FACTOR_100P
},
503 { "mediaplayerClosedCaption",
504 IDR_MEDIAPLAYER_CLOSEDCAPTION_BUTTON
, ui::SCALE_FACTOR_100P
},
505 { "mediaplayerClosedCaptionHover",
506 IDR_MEDIAPLAYER_CLOSEDCAPTION_BUTTON_HOVER
, ui::SCALE_FACTOR_100P
},
507 { "mediaplayerClosedCaptionDown",
508 IDR_MEDIAPLAYER_CLOSEDCAPTION_BUTTON_DOWN
, ui::SCALE_FACTOR_100P
},
509 { "mediaplayerClosedCaptionDisabled",
510 IDR_MEDIAPLAYER_CLOSEDCAPTION_BUTTON_DISABLED
, ui::SCALE_FACTOR_100P
},
511 { "mediaplayerFullscreen",
512 IDR_MEDIAPLAYER_FULLSCREEN_BUTTON
, ui::SCALE_FACTOR_100P
},
513 { "mediaplayerFullscreenHover",
514 IDR_MEDIAPLAYER_FULLSCREEN_BUTTON_HOVER
, ui::SCALE_FACTOR_100P
},
515 { "mediaplayerFullscreenDown",
516 IDR_MEDIAPLAYER_FULLSCREEN_BUTTON_DOWN
, ui::SCALE_FACTOR_100P
},
517 { "mediaplayerFullscreenDisabled",
518 IDR_MEDIAPLAYER_FULLSCREEN_BUTTON_DISABLED
, ui::SCALE_FACTOR_100P
},
519 #if defined(OS_ANDROID)
520 { "mediaplayerOverlayPlay",
521 IDR_MEDIAPLAYER_OVERLAY_PLAY_BUTTON
, ui::SCALE_FACTOR_100P
},
523 #if defined(OS_MACOSX)
524 { "overhangPattern", IDR_OVERHANG_PATTERN
, ui::SCALE_FACTOR_100P
},
526 { "panIcon", IDR_PAN_SCROLL_ICON
, ui::SCALE_FACTOR_100P
},
527 { "searchCancel", IDR_SEARCH_CANCEL
, ui::SCALE_FACTOR_100P
},
528 { "searchCancelPressed", IDR_SEARCH_CANCEL_PRESSED
, ui::SCALE_FACTOR_100P
},
529 { "searchMagnifier", IDR_SEARCH_MAGNIFIER
, ui::SCALE_FACTOR_100P
},
530 { "searchMagnifierResults",
531 IDR_SEARCH_MAGNIFIER_RESULTS
, ui::SCALE_FACTOR_100P
},
532 { "textAreaResizeCorner", IDR_TEXTAREA_RESIZER
, ui::SCALE_FACTOR_100P
},
533 { "textAreaResizeCorner@2x", IDR_TEXTAREA_RESIZER
, ui::SCALE_FACTOR_200P
},
534 { "inputSpeech", IDR_INPUT_SPEECH
, ui::SCALE_FACTOR_100P
},
535 { "inputSpeechRecording", IDR_INPUT_SPEECH_RECORDING
, ui::SCALE_FACTOR_100P
},
536 { "inputSpeechWaiting", IDR_INPUT_SPEECH_WAITING
, ui::SCALE_FACTOR_100P
},
537 { "americanExpressCC", IDR_AUTOFILL_CC_AMEX
, ui::SCALE_FACTOR_100P
},
538 { "dinersCC", IDR_AUTOFILL_CC_DINERS
, ui::SCALE_FACTOR_100P
},
539 { "discoverCC", IDR_AUTOFILL_CC_DISCOVER
, ui::SCALE_FACTOR_100P
},
540 { "genericCC", IDR_AUTOFILL_CC_GENERIC
, ui::SCALE_FACTOR_100P
},
541 { "jcbCC", IDR_AUTOFILL_CC_JCB
, ui::SCALE_FACTOR_100P
},
542 { "masterCardCC", IDR_AUTOFILL_CC_MASTERCARD
, ui::SCALE_FACTOR_100P
},
543 { "soloCC", IDR_AUTOFILL_CC_SOLO
, ui::SCALE_FACTOR_100P
},
544 { "visaCC", IDR_AUTOFILL_CC_VISA
, ui::SCALE_FACTOR_100P
},
545 { "generatePassword", IDR_PASSWORD_GENERATION_ICON
, ui::SCALE_FACTOR_100P
},
546 { "generatePasswordHover",
547 IDR_PASSWORD_GENERATION_ICON_HOVER
, ui::SCALE_FACTOR_100P
},
552 WebData
WebKitPlatformSupportImpl::loadResource(const char* name
) {
553 // Some clients will call into this method with an empty |name| when they have
554 // optional resources. For example, the PopupMenuChromium code can have icons
555 // for some Autofill items but not for others.
559 // Check the name prefix to see if it's an audio resource.
560 if (StartsWithASCII(name
, "IRC_Composite", true))
561 return loadAudioSpatializationResource(this, name
);
563 // TODO(flackr): We should use a better than linear search here, a trie would
565 for (size_t i
= 0; i
< arraysize(kDataResources
); ++i
) {
566 if (!strcmp(name
, kDataResources
[i
].name
)) {
567 base::StringPiece resource
=
568 GetDataResource(kDataResources
[i
].id
,
569 kDataResources
[i
].scale_factor
);
570 return WebData(resource
.data(), resource
.size());
574 NOTREACHED() << "Unknown image resource " << name
;
578 bool WebKitPlatformSupportImpl::loadAudioResource(
579 WebKit::WebAudioBus
* destination_bus
, const char* audio_file_data
,
580 size_t data_size
, double sample_rate
) {
581 return webkit_media::DecodeAudioFileData(destination_bus
,
587 WebString
WebKitPlatformSupportImpl::queryLocalizedString(
588 WebLocalizedString::Name name
) {
589 int message_id
= ToMessageID(name
);
592 return GetLocalizedString(message_id
);
595 WebString
WebKitPlatformSupportImpl::queryLocalizedString(
596 WebLocalizedString::Name name
, int numeric_value
) {
597 return queryLocalizedString(name
, base::IntToString16(numeric_value
));
600 WebString
WebKitPlatformSupportImpl::queryLocalizedString(
601 WebLocalizedString::Name name
, const WebString
& value
) {
602 int message_id
= ToMessageID(name
);
605 return ReplaceStringPlaceholders(GetLocalizedString(message_id
), value
, NULL
);
608 WebString
WebKitPlatformSupportImpl::queryLocalizedString(
609 WebLocalizedString::Name name
,
610 const WebString
& value1
,
611 const WebString
& value2
) {
612 int message_id
= ToMessageID(name
);
615 std::vector
<string16
> values
;
617 values
.push_back(value1
);
618 values
.push_back(value2
);
619 return ReplaceStringPlaceholders(
620 GetLocalizedString(message_id
), values
, NULL
);
623 double WebKitPlatformSupportImpl::currentTime() {
624 return base::Time::Now().ToDoubleT();
627 double WebKitPlatformSupportImpl::monotonicallyIncreasingTime() {
628 return base::TimeTicks::Now().ToInternalValue() /
629 static_cast<double>(base::Time::kMicrosecondsPerSecond
);
632 void WebKitPlatformSupportImpl::cryptographicallyRandomValues(
633 unsigned char* buffer
, size_t length
) {
634 base::RandBytes(buffer
, length
);
637 void WebKitPlatformSupportImpl::setSharedTimerFiredFunction(void (*func
)()) {
638 shared_timer_func_
= func
;
641 void WebKitPlatformSupportImpl::setSharedTimerFireInterval(
642 double interval_seconds
) {
643 shared_timer_fire_time_
= interval_seconds
+ monotonicallyIncreasingTime();
644 if (shared_timer_suspended_
)
647 // By converting between double and int64 representation, we run the risk
648 // of losing precision due to rounding errors. Performing computations in
649 // microseconds reduces this risk somewhat. But there still is the potential
650 // of us computing a fire time for the timer that is shorter than what we
652 // As the event loop will check event deadlines prior to actually firing
653 // them, there is a risk of needlessly rescheduling events and of
654 // needlessly looping if sleep times are too short even by small amounts.
655 // This results in measurable performance degradation unless we use ceil() to
656 // always round up the sleep times.
657 int64 interval
= static_cast<int64
>(
658 ceil(interval_seconds
* base::Time::kMillisecondsPerSecond
)
659 * base::Time::kMicrosecondsPerMillisecond
);
664 shared_timer_
.Stop();
665 shared_timer_
.Start(FROM_HERE
, base::TimeDelta::FromMicroseconds(interval
),
666 this, &WebKitPlatformSupportImpl::DoTimeout
);
667 OnStartSharedTimer(base::TimeDelta::FromMicroseconds(interval
));
670 void WebKitPlatformSupportImpl::stopSharedTimer() {
671 shared_timer_
.Stop();
674 void WebKitPlatformSupportImpl::callOnMainThread(
675 void (*func
)(void*), void* context
) {
676 main_loop_
->PostTask(FROM_HERE
, base::Bind(func
, context
));
679 WebKit::WebThread
* WebKitPlatformSupportImpl::createThread(const char* name
) {
680 return new WebThreadImpl(name
);
683 WebKit::WebThread
* WebKitPlatformSupportImpl::currentThread() {
684 WebThreadImplForMessageLoop
* thread
=
685 static_cast<WebThreadImplForMessageLoop
*>(current_thread_slot_
.Get());
689 scoped_refptr
<base::MessageLoopProxy
> message_loop
=
690 base::MessageLoopProxy::current();
694 thread
= new WebThreadImplForMessageLoop(message_loop
);
695 current_thread_slot_
.Set(thread
);
699 WebKit::WebCompositorSupport
* WebKitPlatformSupportImpl::compositorSupport() {
700 return compositor_support_
.get();
703 base::PlatformFile
WebKitPlatformSupportImpl::databaseOpenFile(
704 const WebKit::WebString
& vfs_file_name
, int desired_flags
) {
705 return base::kInvalidPlatformFileValue
;
708 int WebKitPlatformSupportImpl::databaseDeleteFile(
709 const WebKit::WebString
& vfs_file_name
, bool sync_dir
) {
713 long WebKitPlatformSupportImpl::databaseGetFileAttributes(
714 const WebKit::WebString
& vfs_file_name
) {
718 long long WebKitPlatformSupportImpl::databaseGetFileSize(
719 const WebKit::WebString
& vfs_file_name
) {
723 long long WebKitPlatformSupportImpl::databaseGetSpaceAvailableForOrigin(
724 const WebKit::WebString
& origin_identifier
) {
728 WebKit::WebString
WebKitPlatformSupportImpl::signedPublicKeyAndChallengeString(
729 unsigned key_size_index
,
730 const WebKit::WebString
& challenge
,
731 const WebKit::WebURL
& url
) {
732 return WebKit::WebString("");
735 static scoped_ptr
<base::ProcessMetrics
> CurrentProcessMetrics() {
736 using base::ProcessMetrics
;
737 #if defined(OS_MACOSX)
738 return scoped_ptr
<ProcessMetrics
>(
739 // The default port provider is sufficient to get data for the current
741 ProcessMetrics::CreateProcessMetrics(base::GetCurrentProcessHandle(),
744 return scoped_ptr
<ProcessMetrics
>(
745 ProcessMetrics::CreateProcessMetrics(base::GetCurrentProcessHandle()));
749 #if defined(OS_LINUX) || defined(OS_ANDROID)
750 static size_t memoryUsageMB() {
751 struct mallinfo minfo
= mallinfo();
753 #if defined(USE_TCMALLOC)
756 (minfo
.hblkhd
+ minfo
.arena
)
760 v8::HeapStatistics stat
;
761 v8::V8::GetHeapStatistics(&stat
);
762 return mem_usage
+ (static_cast<uint64_t>(stat
.total_heap_size()) >> 20);
764 #elif defined(OS_MACOSX)
765 static size_t memoryUsageMB() {
766 return CurrentProcessMetrics()->GetWorkingSetSize() >> 20;
769 static size_t memoryUsageMB() {
770 return CurrentProcessMetrics()->GetPagefileUsage() >> 20;
774 static size_t getMemoryUsageMB(bool bypass_cache
) {
775 size_t current_mem_usage
= 0;
776 MemoryUsageCache
* mem_usage_cache_singleton
= MemoryUsageCache::GetInstance();
778 mem_usage_cache_singleton
->IsCachedValueValid(¤t_mem_usage
))
779 return current_mem_usage
;
781 current_mem_usage
= memoryUsageMB();
782 mem_usage_cache_singleton
->SetMemoryValue(current_mem_usage
);
783 return current_mem_usage
;
786 size_t WebKitPlatformSupportImpl::memoryUsageMB() {
787 return getMemoryUsageMB(false);
790 size_t WebKitPlatformSupportImpl::actualMemoryUsageMB() {
791 return getMemoryUsageMB(true);
794 #if defined(OS_ANDROID)
795 size_t WebKitPlatformSupportImpl::lowMemoryUsageMB() {
796 // If memory usage is below this threshold, do not bother forcing GC.
797 // Allow us to use up to our memory class value before V8's GC kicks in.
798 // These values have been determined by experimentation.
799 return base::SysInfo::DalvikHeapSizeMB() / 2;
802 size_t WebKitPlatformSupportImpl::highMemoryUsageMB() {
803 // If memory usage is above this threshold, force GC more aggressively.
804 return base::SysInfo::DalvikHeapSizeMB() * 3 / 4;
807 size_t WebKitPlatformSupportImpl::highUsageDeltaMB() {
808 // If memory usage is above highMemoryUsageMB() and memory usage increased by
809 // more than highUsageDeltaMB() since the last GC, then force GC.
810 // Note that this limit should be greater than the amount of memory for V8
811 // internal data structures that are released on GC and reallocated during JS
812 // execution (about 8MB). Otherwise, it will cause too aggressive GCs.
813 return base::SysInfo::DalvikHeapSizeMB() / 8;
817 bool WebKitPlatformSupportImpl::processMemorySizesInBytes(
818 size_t* private_bytes
,
819 size_t* shared_bytes
) {
820 return CurrentProcessMetrics()->GetMemoryBytes(private_bytes
, shared_bytes
);
823 void WebKitPlatformSupportImpl::SuspendSharedTimer() {
824 ++shared_timer_suspended_
;
827 void WebKitPlatformSupportImpl::ResumeSharedTimer() {
828 // The shared timer may have fired or been adjusted while we were suspended.
829 if (--shared_timer_suspended_
== 0 && !shared_timer_
.IsRunning()) {
830 setSharedTimerFireInterval(
831 shared_timer_fire_time_
- monotonicallyIncreasingTime());
836 void WebKitPlatformSupportImpl::DestroyCurrentThread(void* thread
) {
837 WebThreadImplForMessageLoop
* impl
=
838 static_cast<WebThreadImplForMessageLoop
*>(thread
);
842 void WebKitPlatformSupportImpl::didStartWorkerRunLoop(
843 const WebKit::WebWorkerRunLoop
& runLoop
) {
844 WorkerTaskRunner
* worker_task_runner
= WorkerTaskRunner::Instance();
845 worker_task_runner
->OnWorkerRunLoopStarted(runLoop
);
848 void WebKitPlatformSupportImpl::didStopWorkerRunLoop(
849 const WebKit::WebWorkerRunLoop
& runLoop
) {
850 WorkerTaskRunner
* worker_task_runner
= WorkerTaskRunner::Instance();
851 worker_task_runner
->OnWorkerRunLoopStopped(runLoop
);
854 #if defined(OS_ANDROID)
855 WebKit::WebFlingAnimator
* WebKitPlatformSupportImpl::createFlingAnimator() {
856 return new FlingAnimatorImpl();
860 } // namespace webkit_glue