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

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: changes (+rebase) Created 3 years, 9 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 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 #include "core/page/ChromeClient.h" 74 #include "core/page/ChromeClient.h"
75 #include "platform/Histogram.h" 75 #include "platform/Histogram.h"
76 #include "platform/LayoutTestSupport.h" 76 #include "platform/LayoutTestSupport.h"
77 #include "platform/RuntimeEnabledFeatures.h" 77 #include "platform/RuntimeEnabledFeatures.h"
78 #include "platform/UserGestureIndicator.h" 78 #include "platform/UserGestureIndicator.h"
79 #include "platform/audio/AudioBus.h" 79 #include "platform/audio/AudioBus.h"
80 #include "platform/audio/AudioSourceProviderClient.h" 80 #include "platform/audio/AudioSourceProviderClient.h"
81 #include "platform/graphics/GraphicsLayer.h" 81 #include "platform/graphics/GraphicsLayer.h"
82 #include "platform/mediastream/MediaStreamDescriptor.h" 82 #include "platform/mediastream/MediaStreamDescriptor.h"
83 #include "platform/network/NetworkStateNotifier.h" 83 #include "platform/network/NetworkStateNotifier.h"
84 #include "platform/network/ParsedContentType.h"
84 #include "platform/network/mime/ContentType.h" 85 #include "platform/network/mime/ContentType.h"
85 #include "platform/network/mime/MIMETypeFromURL.h" 86 #include "platform/network/mime/MIMETypeFromURL.h"
86 #include "platform/weborigin/SecurityOrigin.h" 87 #include "platform/weborigin/SecurityOrigin.h"
87 #include "public/platform/Platform.h" 88 #include "public/platform/Platform.h"
88 #include "public/platform/WebAudioSourceProvider.h" 89 #include "public/platform/WebAudioSourceProvider.h"
89 #include "public/platform/WebContentDecryptionModule.h" 90 #include "public/platform/WebContentDecryptionModule.h"
90 #include "public/platform/WebInbandTextTrack.h" 91 #include "public/platform/WebInbandTextTrack.h"
91 #include "public/platform/WebMediaPlayerSource.h" 92 #include "public/platform/WebMediaPlayerSource.h"
92 #include "public/platform/WebMediaStream.h" 93 #include "public/platform/WebMediaStream.h"
93 #include "public/platform/modules/remoteplayback/WebRemotePlaybackAvailability.h " 94 #include "public/platform/modules/remoteplayback/WebRemotePlaybackAvailability.h "
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 132
132 enum MediaControlsShow { 133 enum MediaControlsShow {
133 MediaControlsShowAttribute = 0, 134 MediaControlsShowAttribute = 0,
134 MediaControlsShowFullscreen, 135 MediaControlsShowFullscreen,
135 MediaControlsShowNoScript, 136 MediaControlsShowNoScript,
136 MediaControlsShowNotShown, 137 MediaControlsShowNotShown,
137 MediaControlsShowDisabledSettings, 138 MediaControlsShowDisabledSettings,
138 MediaControlsShowMax 139 MediaControlsShowMax
139 }; 140 };
140 141
142 // These values are used for the Media.MediaElement.ContentTypeResult histogram.
143 // Do not reorder.
144 enum ContentTypeParseableResult {
145 IsSupportedParseable = 0,
146 MayBeSupportedParseable,
147 IsNotSupportedParseable,
148 IsSupportedNotParseable,
149 MayBeSupportedNotParseable,
150 IsNotSupportedNotParseable,
151 ContentTypeParseableMax
152 };
153
154 void ReportContentTypeResultToUMA(String contentType,
155 MIMETypeRegistry::SupportsType result) {
156 DEFINE_THREAD_SAFE_STATIC_LOCAL(
157 EnumerationHistogram, contentTypeParseableHistogram,
158 new EnumerationHistogram("Media.MediaElement.ContentTypeParseable",
159 ContentTypeParseableMax));
160 ParsedContentType parsedContentType(contentType);
161 ContentTypeParseableResult umaResult;
162 switch (result) {
163 case MIMETypeRegistry::IsSupported:
164 umaResult = parsedContentType.isValid() ? IsSupportedParseable
165 : IsSupportedNotParseable;
166 break;
167 case MIMETypeRegistry::MayBeSupported:
168 umaResult = parsedContentType.isValid() ? MayBeSupportedParseable
169 : MayBeSupportedNotParseable;
170 break;
171 case MIMETypeRegistry::IsNotSupported:
172 umaResult = parsedContentType.isValid() ? IsNotSupportedParseable
173 : IsNotSupportedNotParseable;
174 break;
175 }
176 contentTypeParseableHistogram.count(umaResult);
177 }
178
141 String urlForLoggingMedia(const KURL& url) { 179 String urlForLoggingMedia(const KURL& url) {
142 static const unsigned maximumURLLengthForLogging = 128; 180 static const unsigned maximumURLLengthForLogging = 128;
143 181
144 if (url.getString().length() < maximumURLLengthForLogging) 182 if (url.getString().length() < maximumURLLengthForLogging)
145 return url.getString(); 183 return url.getString();
146 return url.getString().substring(0, maximumURLLengthForLogging) + "..."; 184 return url.getString().substring(0, maximumURLLengthForLogging) + "...";
147 } 185 }
148 186
149 const char* boolString(bool val) { 187 const char* boolString(bool val) {
150 return val ? "true" : "false"; 188 return val ? "true" : "false";
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
236 case WebMediaPlayerClient::VideoTrackKindSubtitles: 274 case WebMediaPlayerClient::VideoTrackKindSubtitles:
237 return VideoTrack::subtitlesKeyword(); 275 return VideoTrack::subtitlesKeyword();
238 case WebMediaPlayerClient::VideoTrackKindCommentary: 276 case WebMediaPlayerClient::VideoTrackKindCommentary:
239 return VideoTrack::commentaryKeyword(); 277 return VideoTrack::commentaryKeyword();
240 } 278 }
241 279
242 NOTREACHED(); 280 NOTREACHED();
243 return emptyAtom; 281 return emptyAtom;
244 } 282 }
245 283
246 bool canLoadURL(const KURL& url, const ContentType& contentType) { 284 bool canLoadURL(const KURL& url, const String& contentType) {
mlamouri (slow - plz ping) 2017/03/16 12:00:35 nit: maybe you should rename the argument to `cont
jrummell 2017/03/17 17:40:35 Done.
247 DEFINE_STATIC_LOCAL(const String, codecs, ("codecs")); 285 DEFINE_STATIC_LOCAL(const String, codecs, ("codecs"));
248 286
249 String contentMIMEType = contentType.type().lower(); 287 ContentType type(contentType);
250 String contentTypeCodecs = contentType.parameter(codecs); 288 String contentMIMEType = type.type().lower();
289 String contentTypeCodecs = type.parameter(codecs);
251 290
252 // If the MIME type is missing or is not meaningful, try to figure it out from 291 // If the MIME type is missing or is not meaningful, try to figure it out from
253 // the URL. 292 // the URL.
254 if (contentMIMEType.isEmpty() || 293 if (contentMIMEType.isEmpty() ||
255 contentMIMEType == "application/octet-stream" || 294 contentMIMEType == "application/octet-stream" ||
256 contentMIMEType == "text/plain") { 295 contentMIMEType == "text/plain") {
257 if (url.protocolIsData()) 296 if (url.protocolIsData())
258 contentMIMEType = mimeTypeFromDataURL(url.getString()); 297 contentMIMEType = mimeTypeFromDataURL(url.getString());
259 } 298 }
260 299
261 // If no MIME type is specified, always attempt to load. 300 // If no MIME type is specified, always attempt to load.
262 if (contentMIMEType.isEmpty()) 301 if (contentMIMEType.isEmpty())
263 return true; 302 return true;
264 303
265 // 4.8.12.3 MIME types - In the absence of a specification to the contrary, 304 // 4.8.12.3 MIME types - In the absence of a specification to the contrary,
266 // the MIME type "application/octet-stream" when used with parameters, e.g. 305 // the MIME type "application/octet-stream" when used with parameters, e.g.
267 // "application/octet-stream;codecs=theora", is a type that the user agent 306 // "application/octet-stream;codecs=theora", is a type that the user agent
268 // knows it cannot render. 307 // knows it cannot render.
269 if (contentMIMEType != "application/octet-stream" || 308 if (contentMIMEType != "application/octet-stream" ||
270 contentTypeCodecs.isEmpty()) { 309 contentTypeCodecs.isEmpty()) {
271 return MIMETypeRegistry::supportsMediaMIMEType(contentMIMEType, 310 return MIMETypeRegistry::supportsMediaMIMEType(contentMIMEType,
272 contentTypeCodecs); 311 contentTypeCodecs) !=
312 MIMETypeRegistry::IsNotSupported;
273 } 313 }
274 314
275 return false; 315 return false;
276 } 316 }
277 317
278 String preloadTypeToString(WebMediaPlayer::Preload preloadType) { 318 String preloadTypeToString(WebMediaPlayer::Preload preloadType) {
279 switch (preloadType) { 319 switch (preloadType) {
280 case WebMediaPlayer::PreloadNone: 320 case WebMediaPlayer::PreloadNone:
281 return "none"; 321 return "none";
282 case WebMediaPlayer::PreloadMetaData: 322 case WebMediaPlayer::PreloadMetaData:
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
336 376
337 if (type.isEmpty()) 377 if (type.isEmpty())
338 return MIMETypeRegistry::IsNotSupported; 378 return MIMETypeRegistry::IsNotSupported;
339 379
340 // 4.8.12.3 MIME types - The canPlayType(type) method must return the empty 380 // 4.8.12.3 MIME types - The canPlayType(type) method must return the empty
341 // string if type is a type that the user agent knows it cannot render or is 381 // string if type is a type that the user agent knows it cannot render or is
342 // the type "application/octet-stream" 382 // the type "application/octet-stream"
343 if (type == "application/octet-stream") 383 if (type == "application/octet-stream")
344 return MIMETypeRegistry::IsNotSupported; 384 return MIMETypeRegistry::IsNotSupported;
345 385
346 return MIMETypeRegistry::supportsMediaMIMEType(type, typeCodecs); 386 // Check if stricter parsing of |contentType| will cause problems.
387 // TODO(jrummell): Either switch to ParsedContentType or remove this UMA,
388 // depending on the results reported.
389 MIMETypeRegistry::SupportsType result =
390 MIMETypeRegistry::supportsMediaMIMEType(type, typeCodecs);
391 ReportContentTypeResultToUMA(contentType.raw(), result);
392 return result;
347 } 393 }
348 394
349 URLRegistry* HTMLMediaElement::s_mediaStreamRegistry = 0; 395 URLRegistry* HTMLMediaElement::s_mediaStreamRegistry = 0;
350 396
351 void HTMLMediaElement::setMediaStreamRegistry(URLRegistry* registry) { 397 void HTMLMediaElement::setMediaStreamRegistry(URLRegistry* registry) {
352 DCHECK(!s_mediaStreamRegistry); 398 DCHECK(!s_mediaStreamRegistry);
353 s_mediaStreamRegistry = registry; 399 s_mediaStreamRegistry = registry;
354 } 400 }
355 401
356 bool HTMLMediaElement::isMediaStreamURL(const String& url) { 402 bool HTMLMediaElement::isMediaStreamURL(const String& url) {
(...skipping 672 matching lines...) Expand 10 before | Expand all | Expand 10 after
1029 NOTREACHED(); 1075 NOTREACHED();
1030 } 1076 }
1031 } 1077 }
1032 1078
1033 void HTMLMediaElement::loadSourceFromObject() { 1079 void HTMLMediaElement::loadSourceFromObject() {
1034 DCHECK(m_srcObject); 1080 DCHECK(m_srcObject);
1035 m_loadState = LoadingFromSrcObject; 1081 m_loadState = LoadingFromSrcObject;
1036 1082
1037 // No type is available when the resource comes from the 'srcObject' 1083 // No type is available when the resource comes from the 'srcObject'
1038 // attribute. 1084 // attribute.
1039 loadResource(WebMediaPlayerSource(WebMediaStream(m_srcObject)), 1085 loadResource(WebMediaPlayerSource(WebMediaStream(m_srcObject)), String());
1040 ContentType((String())));
1041 } 1086 }
1042 1087
1043 void HTMLMediaElement::loadSourceFromAttribute() { 1088 void HTMLMediaElement::loadSourceFromAttribute() {
1044 m_loadState = LoadingFromSrcAttr; 1089 m_loadState = LoadingFromSrcAttr;
1045 const AtomicString& srcValue = fastGetAttribute(srcAttr); 1090 const AtomicString& srcValue = fastGetAttribute(srcAttr);
1046 1091
1047 // If the src attribute's value is the empty string ... jump down to the 1092 // If the src attribute's value is the empty string ... jump down to the
1048 // failed step below 1093 // failed step below
1049 if (srcValue.isEmpty()) { 1094 if (srcValue.isEmpty()) {
1050 mediaLoadingFailed(WebMediaPlayer::NetworkStateFormatError); 1095 mediaLoadingFailed(WebMediaPlayer::NetworkStateFormatError);
1051 BLINK_MEDIA_LOG << "loadSourceFromAttribute(" << (void*)this 1096 BLINK_MEDIA_LOG << "loadSourceFromAttribute(" << (void*)this
1052 << "), empty 'src'"; 1097 << "), empty 'src'";
1053 return; 1098 return;
1054 } 1099 }
1055 1100
1056 KURL mediaURL = document().completeURL(srcValue); 1101 KURL mediaURL = document().completeURL(srcValue);
1057 if (!isSafeToLoadURL(mediaURL, Complain)) { 1102 if (!isSafeToLoadURL(mediaURL, Complain)) {
1058 mediaLoadingFailed(WebMediaPlayer::NetworkStateFormatError); 1103 mediaLoadingFailed(WebMediaPlayer::NetworkStateFormatError);
1059 return; 1104 return;
1060 } 1105 }
1061 1106
1062 // No type is available when the url comes from the 'src' attribute so 1107 // No type is available when the url comes from the 'src' attribute so
1063 // MediaPlayer will have to pick a media engine based on the file extension. 1108 // MediaPlayer will have to pick a media engine based on the file extension.
1064 loadResource(WebMediaPlayerSource(WebURL(mediaURL)), ContentType((String()))); 1109 loadResource(WebMediaPlayerSource(WebURL(mediaURL)), String());
1065 } 1110 }
1066 1111
1067 void HTMLMediaElement::loadNextSourceChild() { 1112 void HTMLMediaElement::loadNextSourceChild() {
1068 ContentType contentType((String())); 1113 String contentType;
1069 KURL mediaURL = selectNextSourceChild(&contentType, Complain); 1114 KURL mediaURL = selectNextSourceChild(&contentType, Complain);
1070 if (!mediaURL.isValid()) { 1115 if (!mediaURL.isValid()) {
1071 waitForSourceChange(); 1116 waitForSourceChange();
1072 return; 1117 return;
1073 } 1118 }
1074 1119
1075 // Reset the MediaPlayer and MediaSource if any 1120 // Reset the MediaPlayer and MediaSource if any
1076 resetMediaPlayerAndMediaSource(); 1121 resetMediaPlayerAndMediaSource();
1077 1122
1078 m_loadState = LoadingFromSourceElement; 1123 m_loadState = LoadingFromSourceElement;
1079 loadResource(WebMediaPlayerSource(WebURL(mediaURL)), contentType); 1124 loadResource(WebMediaPlayerSource(WebURL(mediaURL)), contentType);
1080 } 1125 }
1081 1126
1082 void HTMLMediaElement::loadResource(const WebMediaPlayerSource& source, 1127 void HTMLMediaElement::loadResource(const WebMediaPlayerSource& source,
1083 const ContentType& contentType) { 1128 const String& contentType) {
1084 DCHECK(isMainThread()); 1129 DCHECK(isMainThread());
1085 KURL url; 1130 KURL url;
1086 if (source.isURL()) { 1131 if (source.isURL()) {
1087 url = source.getAsURL(); 1132 url = source.getAsURL();
1088 DCHECK(isSafeToLoadURL(url, Complain)); 1133 DCHECK(isSafeToLoadURL(url, Complain));
1089 BLINK_MEDIA_LOG << "loadResource(" << (void*)this << ", " 1134 BLINK_MEDIA_LOG << "loadResource(" << (void*)this << ", "
1090 << urlForLoggingMedia(url) << ", " << contentType.raw() 1135 << urlForLoggingMedia(url) << ", " << contentType << ")";
1091 << ")";
1092 } 1136 }
1093 1137
1094 LocalFrame* frame = document().frame(); 1138 LocalFrame* frame = document().frame();
1095 if (!frame) { 1139 if (!frame) {
1096 mediaLoadingFailed(WebMediaPlayer::NetworkStateFormatError); 1140 mediaLoadingFailed(WebMediaPlayer::NetworkStateFormatError);
1097 return; 1141 return;
1098 } 1142 }
1099 1143
1100 // The resource fetch algorithm 1144 // The resource fetch algorithm
1101 setNetworkState(kNetworkLoading); 1145 setNetworkState(kNetworkLoading);
(...skipping 1783 matching lines...) Expand 10 before | Expand all | Expand 10 after
2885 AutomaticTrackSelection trackSelection(configuration); 2929 AutomaticTrackSelection trackSelection(configuration);
2886 trackSelection.perform(*m_textTracks); 2930 trackSelection.perform(*m_textTracks);
2887 } 2931 }
2888 2932
2889 bool HTMLMediaElement::havePotentialSourceChild() { 2933 bool HTMLMediaElement::havePotentialSourceChild() {
2890 // Stash the current <source> node and next nodes so we can restore them after 2934 // Stash the current <source> node and next nodes so we can restore them after
2891 // checking to see there is another potential. 2935 // checking to see there is another potential.
2892 HTMLSourceElement* currentSourceNode = m_currentSourceNode; 2936 HTMLSourceElement* currentSourceNode = m_currentSourceNode;
2893 Node* nextNode = m_nextChildNodeToConsider; 2937 Node* nextNode = m_nextChildNodeToConsider;
2894 2938
2895 KURL nextURL = selectNextSourceChild(0, DoNothing); 2939 KURL nextURL = selectNextSourceChild(nullptr, DoNothing);
2896 2940
2897 m_currentSourceNode = currentSourceNode; 2941 m_currentSourceNode = currentSourceNode;
2898 m_nextChildNodeToConsider = nextNode; 2942 m_nextChildNodeToConsider = nextNode;
2899 2943
2900 return nextURL.isValid(); 2944 return nextURL.isValid();
2901 } 2945 }
2902 2946
2903 KURL HTMLMediaElement::selectNextSourceChild(ContentType* contentType, 2947 KURL HTMLMediaElement::selectNextSourceChild(String* contentType,
2904 InvalidURLAction actionIfInvalid) { 2948 InvalidURLAction actionIfInvalid) {
2905 // Don't log if this was just called to find out if there are any valid 2949 // Don't log if this was just called to find out if there are any valid
2906 // <source> elements. 2950 // <source> elements.
2907 bool shouldLog = actionIfInvalid != DoNothing; 2951 bool shouldLog = actionIfInvalid != DoNothing;
2908 if (shouldLog) 2952 if (shouldLog)
2909 BLINK_MEDIA_LOG << "selectNextSourceChild(" << (void*)this << ")"; 2953 BLINK_MEDIA_LOG << "selectNextSourceChild(" << (void*)this << ")";
2910 2954
2911 if (!m_nextChildNodeToConsider) { 2955 if (!m_nextChildNodeToConsider) {
2912 if (shouldLog) 2956 if (shouldLog)
2913 BLINK_MEDIA_LOG << "selectNextSourceChild(" << (void*)this 2957 BLINK_MEDIA_LOG << "selectNextSourceChild(" << (void*)this
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
2977 // Making it this far means the <source> looks reasonable. 3021 // Making it this far means the <source> looks reasonable.
2978 canUseSourceElement = true; 3022 canUseSourceElement = true;
2979 3023
2980 checkAgain: 3024 checkAgain:
2981 if (!canUseSourceElement && actionIfInvalid == Complain && source) 3025 if (!canUseSourceElement && actionIfInvalid == Complain && source)
2982 source->scheduleErrorEvent(); 3026 source->scheduleErrorEvent();
2983 } 3027 }
2984 3028
2985 if (canUseSourceElement) { 3029 if (canUseSourceElement) {
2986 if (contentType) 3030 if (contentType)
2987 *contentType = ContentType(type); 3031 *contentType = type;
2988 m_currentSourceNode = source; 3032 m_currentSourceNode = source;
2989 m_nextChildNodeToConsider = source->nextSibling(); 3033 m_nextChildNodeToConsider = source->nextSibling();
2990 } else { 3034 } else {
2991 m_currentSourceNode = nullptr; 3035 m_currentSourceNode = nullptr;
2992 m_nextChildNodeToConsider = nullptr; 3036 m_nextChildNodeToConsider = nullptr;
2993 } 3037 }
2994 3038
2995 if (shouldLog) 3039 if (shouldLog)
2996 BLINK_MEDIA_LOG << "selectNextSourceChild(" << (void*)this << ") -> " 3040 BLINK_MEDIA_LOG << "selectNextSourceChild(" << (void*)this << ") -> "
2997 << m_currentSourceNode.get() << ", " 3041 << m_currentSourceNode.get() << ", "
(...skipping 1200 matching lines...) Expand 10 before | Expand all | Expand 10 after
4198 kMostlyFillViewportBecomeStableSeconds, BLINK_FROM_HERE); 4242 kMostlyFillViewportBecomeStableSeconds, BLINK_FROM_HERE);
4199 } 4243 }
4200 4244
4201 void HTMLMediaElement::viewportFillDebouncerTimerFired(TimerBase*) { 4245 void HTMLMediaElement::viewportFillDebouncerTimerFired(TimerBase*) {
4202 m_mostlyFillingViewport = true; 4246 m_mostlyFillingViewport = true;
4203 if (m_webMediaPlayer) 4247 if (m_webMediaPlayer)
4204 m_webMediaPlayer->becameDominantVisibleContent(m_mostlyFillingViewport); 4248 m_webMediaPlayer->becameDominantVisibleContent(m_mostlyFillingViewport);
4205 } 4249 }
4206 4250
4207 } // namespace blink 4251 } // 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