Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(15)

Side by Side Diff: third_party/WebKit/Source/core/html/HTMLMediaElement.cpp

Issue 2730853002: Add UMA logging to track bad MIME types passed to HTMLMediaElement (Closed)
Patch Set: rebase only Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights 2 * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights
3 * reserved. 3 * reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
7 * are met: 7 * are met:
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
77 #include "core/page/ChromeClient.h" 77 #include "core/page/ChromeClient.h"
78 #include "platform/Histogram.h" 78 #include "platform/Histogram.h"
79 #include "platform/LayoutTestSupport.h" 79 #include "platform/LayoutTestSupport.h"
80 #include "platform/RuntimeEnabledFeatures.h" 80 #include "platform/RuntimeEnabledFeatures.h"
81 #include "platform/UserGestureIndicator.h" 81 #include "platform/UserGestureIndicator.h"
82 #include "platform/audio/AudioBus.h" 82 #include "platform/audio/AudioBus.h"
83 #include "platform/audio/AudioSourceProviderClient.h" 83 #include "platform/audio/AudioSourceProviderClient.h"
84 #include "platform/graphics/GraphicsLayer.h" 84 #include "platform/graphics/GraphicsLayer.h"
85 #include "platform/mediastream/MediaStreamDescriptor.h" 85 #include "platform/mediastream/MediaStreamDescriptor.h"
86 #include "platform/network/NetworkStateNotifier.h" 86 #include "platform/network/NetworkStateNotifier.h"
87 #include "platform/network/ParsedContentType.h"
87 #include "platform/network/mime/ContentType.h" 88 #include "platform/network/mime/ContentType.h"
88 #include "platform/network/mime/MIMETypeFromURL.h" 89 #include "platform/network/mime/MIMETypeFromURL.h"
89 #include "platform/weborigin/SecurityOrigin.h" 90 #include "platform/weborigin/SecurityOrigin.h"
90 #include "public/platform/Platform.h" 91 #include "public/platform/Platform.h"
91 #include "public/platform/WebAudioSourceProvider.h" 92 #include "public/platform/WebAudioSourceProvider.h"
92 #include "public/platform/WebContentDecryptionModule.h" 93 #include "public/platform/WebContentDecryptionModule.h"
93 #include "public/platform/WebInbandTextTrack.h" 94 #include "public/platform/WebInbandTextTrack.h"
94 #include "public/platform/WebMediaPlayerSource.h" 95 #include "public/platform/WebMediaPlayerSource.h"
95 #include "public/platform/WebMediaStream.h" 96 #include "public/platform/WebMediaStream.h"
96 #include "public/platform/modules/remoteplayback/WebRemotePlaybackAvailability.h " 97 #include "public/platform/modules/remoteplayback/WebRemotePlaybackAvailability.h "
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
135 // This enum is used to record histograms. Do not reorder. 136 // This enum is used to record histograms. Do not reorder.
136 enum MediaControlsShow { 137 enum MediaControlsShow {
137 MediaControlsShowAttribute = 0, 138 MediaControlsShowAttribute = 0,
138 MediaControlsShowFullscreen, 139 MediaControlsShowFullscreen,
139 MediaControlsShowNoScript, 140 MediaControlsShowNoScript,
140 MediaControlsShowNotShown, 141 MediaControlsShowNotShown,
141 MediaControlsShowDisabledSettings, 142 MediaControlsShowDisabledSettings,
142 MediaControlsShowMax 143 MediaControlsShowMax
143 }; 144 };
144 145
146 // These values are used for the Media.MediaElement.ContentTypeResult histogram.
147 // Do not reorder.
148 enum ContentTypeParseableResult {
149 IsSupportedParseable = 0,
150 MayBeSupportedParseable,
151 IsNotSupportedParseable,
152 IsSupportedNotParseable,
153 MayBeSupportedNotParseable,
154 IsNotSupportedNotParseable,
155 ContentTypeParseableMax
156 };
157
158 void ReportContentTypeResultToUMA(String contentType,
159 MIMETypeRegistry::SupportsType result) {
160 DEFINE_THREAD_SAFE_STATIC_LOCAL(
161 EnumerationHistogram, contentTypeParseableHistogram,
162 new EnumerationHistogram("Media.MediaElement.ContentTypeParseable",
163 ContentTypeParseableMax));
164 ParsedContentType parsedContentType(contentType);
165 ContentTypeParseableResult umaResult = IsNotSupportedNotParseable;
166 switch (result) {
167 case MIMETypeRegistry::IsSupported:
168 umaResult = parsedContentType.isValid() ? IsSupportedParseable
169 : IsSupportedNotParseable;
170 break;
171 case MIMETypeRegistry::MayBeSupported:
172 umaResult = parsedContentType.isValid() ? MayBeSupportedParseable
173 : MayBeSupportedNotParseable;
174 break;
175 case MIMETypeRegistry::IsNotSupported:
176 umaResult = parsedContentType.isValid() ? IsNotSupportedParseable
177 : IsNotSupportedNotParseable;
178 break;
179 }
180 contentTypeParseableHistogram.count(umaResult);
181 }
182
145 String urlForLoggingMedia(const KURL& url) { 183 String urlForLoggingMedia(const KURL& url) {
146 static const unsigned maximumURLLengthForLogging = 128; 184 static const unsigned maximumURLLengthForLogging = 128;
147 185
148 if (url.getString().length() < maximumURLLengthForLogging) 186 if (url.getString().length() < maximumURLLengthForLogging)
149 return url.getString(); 187 return url.getString();
150 return url.getString().substring(0, maximumURLLengthForLogging) + "..."; 188 return url.getString().substring(0, maximumURLLengthForLogging) + "...";
151 } 189 }
152 190
153 const char* boolString(bool val) { 191 const char* boolString(bool val) {
154 return val ? "true" : "false"; 192 return val ? "true" : "false";
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 case WebMediaPlayerClient::VideoTrackKindSubtitles: 278 case WebMediaPlayerClient::VideoTrackKindSubtitles:
241 return VideoTrack::subtitlesKeyword(); 279 return VideoTrack::subtitlesKeyword();
242 case WebMediaPlayerClient::VideoTrackKindCommentary: 280 case WebMediaPlayerClient::VideoTrackKindCommentary:
243 return VideoTrack::commentaryKeyword(); 281 return VideoTrack::commentaryKeyword();
244 } 282 }
245 283
246 NOTREACHED(); 284 NOTREACHED();
247 return emptyAtom; 285 return emptyAtom;
248 } 286 }
249 287
250 bool canLoadURL(const KURL& url, const ContentType& contentType) { 288 bool canLoadURL(const KURL& url, const String& contentTypeStr) {
251 DEFINE_STATIC_LOCAL(const String, codecs, ("codecs")); 289 DEFINE_STATIC_LOCAL(const String, codecs, ("codecs"));
252 290
291 ContentType contentType(contentTypeStr);
253 String contentMIMEType = contentType.type().lower(); 292 String contentMIMEType = contentType.type().lower();
254 String contentTypeCodecs = contentType.parameter(codecs); 293 String contentTypeCodecs = contentType.parameter(codecs);
255 294
256 // If the MIME type is missing or is not meaningful, try to figure it out from 295 // If the MIME type is missing or is not meaningful, try to figure it out from
257 // the URL. 296 // the URL.
258 if (contentMIMEType.isEmpty() || 297 if (contentMIMEType.isEmpty() ||
259 contentMIMEType == "application/octet-stream" || 298 contentMIMEType == "application/octet-stream" ||
260 contentMIMEType == "text/plain") { 299 contentMIMEType == "text/plain") {
261 if (url.protocolIsData()) 300 if (url.protocolIsData())
262 contentMIMEType = mimeTypeFromDataURL(url.getString()); 301 contentMIMEType = mimeTypeFromDataURL(url.getString());
263 } 302 }
264 303
265 // If no MIME type is specified, always attempt to load. 304 // If no MIME type is specified, always attempt to load.
266 if (contentMIMEType.isEmpty()) 305 if (contentMIMEType.isEmpty())
267 return true; 306 return true;
268 307
269 // 4.8.12.3 MIME types - In the absence of a specification to the contrary, 308 // 4.8.12.3 MIME types - In the absence of a specification to the contrary,
270 // the MIME type "application/octet-stream" when used with parameters, e.g. 309 // the MIME type "application/octet-stream" when used with parameters, e.g.
271 // "application/octet-stream;codecs=theora", is a type that the user agent 310 // "application/octet-stream;codecs=theora", is a type that the user agent
272 // knows it cannot render. 311 // knows it cannot render.
273 if (contentMIMEType != "application/octet-stream" || 312 if (contentMIMEType != "application/octet-stream" ||
274 contentTypeCodecs.isEmpty()) { 313 contentTypeCodecs.isEmpty()) {
275 return MIMETypeRegistry::supportsMediaMIMEType(contentMIMEType, 314 return MIMETypeRegistry::supportsMediaMIMEType(contentMIMEType,
276 contentTypeCodecs); 315 contentTypeCodecs) !=
316 MIMETypeRegistry::IsNotSupported;
277 } 317 }
278 318
279 return false; 319 return false;
280 } 320 }
281 321
282 String preloadTypeToString(WebMediaPlayer::Preload preloadType) { 322 String preloadTypeToString(WebMediaPlayer::Preload preloadType) {
283 switch (preloadType) { 323 switch (preloadType) {
284 case WebMediaPlayer::PreloadNone: 324 case WebMediaPlayer::PreloadNone:
285 return "none"; 325 return "none";
286 case WebMediaPlayer::PreloadMetaData: 326 case WebMediaPlayer::PreloadMetaData:
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
346 386
347 if (type.isEmpty()) 387 if (type.isEmpty())
348 return MIMETypeRegistry::IsNotSupported; 388 return MIMETypeRegistry::IsNotSupported;
349 389
350 // 4.8.12.3 MIME types - The canPlayType(type) method must return the empty 390 // 4.8.12.3 MIME types - The canPlayType(type) method must return the empty
351 // string if type is a type that the user agent knows it cannot render or is 391 // string if type is a type that the user agent knows it cannot render or is
352 // the type "application/octet-stream" 392 // the type "application/octet-stream"
353 if (type == "application/octet-stream") 393 if (type == "application/octet-stream")
354 return MIMETypeRegistry::IsNotSupported; 394 return MIMETypeRegistry::IsNotSupported;
355 395
356 return MIMETypeRegistry::supportsMediaMIMEType(type, typeCodecs); 396 // Check if stricter parsing of |contentType| will cause problems.
397 // TODO(jrummell): Either switch to ParsedContentType or remove this UMA,
398 // depending on the results reported.
399 MIMETypeRegistry::SupportsType result =
400 MIMETypeRegistry::supportsMediaMIMEType(type, typeCodecs);
401 ReportContentTypeResultToUMA(contentType.raw(), result);
402 return result;
357 } 403 }
358 404
359 URLRegistry* HTMLMediaElement::s_mediaStreamRegistry = 0; 405 URLRegistry* HTMLMediaElement::s_mediaStreamRegistry = 0;
360 406
361 void HTMLMediaElement::setMediaStreamRegistry(URLRegistry* registry) { 407 void HTMLMediaElement::setMediaStreamRegistry(URLRegistry* registry) {
362 DCHECK(!s_mediaStreamRegistry); 408 DCHECK(!s_mediaStreamRegistry);
363 s_mediaStreamRegistry = registry; 409 s_mediaStreamRegistry = registry;
364 } 410 }
365 411
366 bool HTMLMediaElement::isMediaStreamURL(const String& url) { 412 bool HTMLMediaElement::isMediaStreamURL(const String& url) {
(...skipping 680 matching lines...) Expand 10 before | Expand all | Expand 10 after
1047 NOTREACHED(); 1093 NOTREACHED();
1048 } 1094 }
1049 } 1095 }
1050 1096
1051 void HTMLMediaElement::loadSourceFromObject() { 1097 void HTMLMediaElement::loadSourceFromObject() {
1052 DCHECK(m_srcObject); 1098 DCHECK(m_srcObject);
1053 m_loadState = LoadingFromSrcObject; 1099 m_loadState = LoadingFromSrcObject;
1054 1100
1055 // No type is available when the resource comes from the 'srcObject' 1101 // No type is available when the resource comes from the 'srcObject'
1056 // attribute. 1102 // attribute.
1057 loadResource(WebMediaPlayerSource(WebMediaStream(m_srcObject)), 1103 loadResource(WebMediaPlayerSource(WebMediaStream(m_srcObject)), String());
1058 ContentType((String())));
1059 } 1104 }
1060 1105
1061 void HTMLMediaElement::loadSourceFromAttribute() { 1106 void HTMLMediaElement::loadSourceFromAttribute() {
1062 m_loadState = LoadingFromSrcAttr; 1107 m_loadState = LoadingFromSrcAttr;
1063 const AtomicString& srcValue = fastGetAttribute(srcAttr); 1108 const AtomicString& srcValue = fastGetAttribute(srcAttr);
1064 1109
1065 // If the src attribute's value is the empty string ... jump down to the 1110 // If the src attribute's value is the empty string ... jump down to the
1066 // failed step below 1111 // failed step below
1067 if (srcValue.isEmpty()) { 1112 if (srcValue.isEmpty()) {
1068 mediaLoadingFailed(WebMediaPlayer::NetworkStateFormatError); 1113 mediaLoadingFailed(WebMediaPlayer::NetworkStateFormatError);
1069 BLINK_MEDIA_LOG << "loadSourceFromAttribute(" << (void*)this 1114 BLINK_MEDIA_LOG << "loadSourceFromAttribute(" << (void*)this
1070 << "), empty 'src'"; 1115 << "), empty 'src'";
1071 return; 1116 return;
1072 } 1117 }
1073 1118
1074 KURL mediaURL = document().completeURL(srcValue); 1119 KURL mediaURL = document().completeURL(srcValue);
1075 if (!isSafeToLoadURL(mediaURL, Complain)) { 1120 if (!isSafeToLoadURL(mediaURL, Complain)) {
1076 mediaLoadingFailed(WebMediaPlayer::NetworkStateFormatError); 1121 mediaLoadingFailed(WebMediaPlayer::NetworkStateFormatError);
1077 return; 1122 return;
1078 } 1123 }
1079 1124
1080 // No type is available when the url comes from the 'src' attribute so 1125 // No type is available when the url comes from the 'src' attribute so
1081 // MediaPlayer will have to pick a media engine based on the file extension. 1126 // MediaPlayer will have to pick a media engine based on the file extension.
1082 loadResource(WebMediaPlayerSource(WebURL(mediaURL)), ContentType((String()))); 1127 loadResource(WebMediaPlayerSource(WebURL(mediaURL)), String());
1083 } 1128 }
1084 1129
1085 void HTMLMediaElement::loadNextSourceChild() { 1130 void HTMLMediaElement::loadNextSourceChild() {
1086 ContentType contentType((String())); 1131 String contentType;
1087 KURL mediaURL = selectNextSourceChild(&contentType, Complain); 1132 KURL mediaURL = selectNextSourceChild(&contentType, Complain);
1088 if (!mediaURL.isValid()) { 1133 if (!mediaURL.isValid()) {
1089 waitForSourceChange(); 1134 waitForSourceChange();
1090 return; 1135 return;
1091 } 1136 }
1092 1137
1093 // Reset the MediaPlayer and MediaSource if any 1138 // Reset the MediaPlayer and MediaSource if any
1094 resetMediaPlayerAndMediaSource(); 1139 resetMediaPlayerAndMediaSource();
1095 1140
1096 m_loadState = LoadingFromSourceElement; 1141 m_loadState = LoadingFromSourceElement;
1097 loadResource(WebMediaPlayerSource(WebURL(mediaURL)), contentType); 1142 loadResource(WebMediaPlayerSource(WebURL(mediaURL)), contentType);
1098 } 1143 }
1099 1144
1100 void HTMLMediaElement::loadResource(const WebMediaPlayerSource& source, 1145 void HTMLMediaElement::loadResource(const WebMediaPlayerSource& source,
1101 const ContentType& contentType) { 1146 const String& contentType) {
1102 DCHECK(isMainThread()); 1147 DCHECK(isMainThread());
1103 KURL url; 1148 KURL url;
1104 if (source.isURL()) { 1149 if (source.isURL()) {
1105 url = source.getAsURL(); 1150 url = source.getAsURL();
1106 DCHECK(isSafeToLoadURL(url, Complain)); 1151 DCHECK(isSafeToLoadURL(url, Complain));
1107 BLINK_MEDIA_LOG << "loadResource(" << (void*)this << ", " 1152 BLINK_MEDIA_LOG << "loadResource(" << (void*)this << ", "
1108 << urlForLoggingMedia(url) << ", " << contentType.raw() 1153 << urlForLoggingMedia(url) << ", " << contentType << ")";
1109 << ")";
1110 } 1154 }
1111 1155
1112 LocalFrame* frame = document().frame(); 1156 LocalFrame* frame = document().frame();
1113 if (!frame) { 1157 if (!frame) {
1114 mediaLoadingFailed(WebMediaPlayer::NetworkStateFormatError); 1158 mediaLoadingFailed(WebMediaPlayer::NetworkStateFormatError);
1115 return; 1159 return;
1116 } 1160 }
1117 1161
1118 // The resource fetch algorithm 1162 // The resource fetch algorithm
1119 setNetworkState(kNetworkLoading); 1163 setNetworkState(kNetworkLoading);
(...skipping 1774 matching lines...) Expand 10 before | Expand all | Expand 10 after
2894 AutomaticTrackSelection trackSelection(configuration); 2938 AutomaticTrackSelection trackSelection(configuration);
2895 trackSelection.perform(*m_textTracks); 2939 trackSelection.perform(*m_textTracks);
2896 } 2940 }
2897 2941
2898 bool HTMLMediaElement::havePotentialSourceChild() { 2942 bool HTMLMediaElement::havePotentialSourceChild() {
2899 // Stash the current <source> node and next nodes so we can restore them after 2943 // Stash the current <source> node and next nodes so we can restore them after
2900 // checking to see there is another potential. 2944 // checking to see there is another potential.
2901 HTMLSourceElement* currentSourceNode = m_currentSourceNode; 2945 HTMLSourceElement* currentSourceNode = m_currentSourceNode;
2902 Node* nextNode = m_nextChildNodeToConsider; 2946 Node* nextNode = m_nextChildNodeToConsider;
2903 2947
2904 KURL nextURL = selectNextSourceChild(0, DoNothing); 2948 KURL nextURL = selectNextSourceChild(nullptr, DoNothing);
2905 2949
2906 m_currentSourceNode = currentSourceNode; 2950 m_currentSourceNode = currentSourceNode;
2907 m_nextChildNodeToConsider = nextNode; 2951 m_nextChildNodeToConsider = nextNode;
2908 2952
2909 return nextURL.isValid(); 2953 return nextURL.isValid();
2910 } 2954 }
2911 2955
2912 KURL HTMLMediaElement::selectNextSourceChild(ContentType* contentType, 2956 KURL HTMLMediaElement::selectNextSourceChild(String* contentType,
2913 InvalidURLAction actionIfInvalid) { 2957 InvalidURLAction actionIfInvalid) {
2914 // Don't log if this was just called to find out if there are any valid 2958 // Don't log if this was just called to find out if there are any valid
2915 // <source> elements. 2959 // <source> elements.
2916 bool shouldLog = actionIfInvalid != DoNothing; 2960 bool shouldLog = actionIfInvalid != DoNothing;
2917 if (shouldLog) 2961 if (shouldLog)
2918 BLINK_MEDIA_LOG << "selectNextSourceChild(" << (void*)this << ")"; 2962 BLINK_MEDIA_LOG << "selectNextSourceChild(" << (void*)this << ")";
2919 2963
2920 if (!m_nextChildNodeToConsider) { 2964 if (!m_nextChildNodeToConsider) {
2921 if (shouldLog) 2965 if (shouldLog)
2922 BLINK_MEDIA_LOG << "selectNextSourceChild(" << (void*)this 2966 BLINK_MEDIA_LOG << "selectNextSourceChild(" << (void*)this
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
2986 // Making it this far means the <source> looks reasonable. 3030 // Making it this far means the <source> looks reasonable.
2987 canUseSourceElement = true; 3031 canUseSourceElement = true;
2988 3032
2989 checkAgain: 3033 checkAgain:
2990 if (!canUseSourceElement && actionIfInvalid == Complain && source) 3034 if (!canUseSourceElement && actionIfInvalid == Complain && source)
2991 source->scheduleErrorEvent(); 3035 source->scheduleErrorEvent();
2992 } 3036 }
2993 3037
2994 if (canUseSourceElement) { 3038 if (canUseSourceElement) {
2995 if (contentType) 3039 if (contentType)
2996 *contentType = ContentType(type); 3040 *contentType = type;
2997 m_currentSourceNode = source; 3041 m_currentSourceNode = source;
2998 m_nextChildNodeToConsider = source->nextSibling(); 3042 m_nextChildNodeToConsider = source->nextSibling();
2999 } else { 3043 } else {
3000 m_currentSourceNode = nullptr; 3044 m_currentSourceNode = nullptr;
3001 m_nextChildNodeToConsider = nullptr; 3045 m_nextChildNodeToConsider = nullptr;
3002 } 3046 }
3003 3047
3004 if (shouldLog) 3048 if (shouldLog)
3005 BLINK_MEDIA_LOG << "selectNextSourceChild(" << (void*)this << ") -> " 3049 BLINK_MEDIA_LOG << "selectNextSourceChild(" << (void*)this << ") -> "
3006 << m_currentSourceNode.get() << ", " 3050 << m_currentSourceNode.get() << ", "
(...skipping 1199 matching lines...) Expand 10 before | Expand all | Expand 10 after
4206 kMostlyFillViewportBecomeStableSeconds, BLINK_FROM_HERE); 4250 kMostlyFillViewportBecomeStableSeconds, BLINK_FROM_HERE);
4207 } 4251 }
4208 4252
4209 void HTMLMediaElement::viewportFillDebouncerTimerFired(TimerBase*) { 4253 void HTMLMediaElement::viewportFillDebouncerTimerFired(TimerBase*) {
4210 m_mostlyFillingViewport = true; 4254 m_mostlyFillingViewport = true;
4211 if (m_webMediaPlayer) 4255 if (m_webMediaPlayer)
4212 m_webMediaPlayer->becameDominantVisibleContent(m_mostlyFillingViewport); 4256 m_webMediaPlayer->becameDominantVisibleContent(m_mostlyFillingViewport);
4213 } 4257 }
4214 4258
4215 } // namespace blink 4259 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/html/HTMLMediaElement.h ('k') | tools/metrics/histograms/histograms.xml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698