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

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: 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 "core/page/NetworkStateNotifier.h" 75 #include "core/page/NetworkStateNotifier.h"
76 #include "platform/Histogram.h" 76 #include "platform/Histogram.h"
77 #include "platform/LayoutTestSupport.h" 77 #include "platform/LayoutTestSupport.h"
78 #include "platform/RuntimeEnabledFeatures.h" 78 #include "platform/RuntimeEnabledFeatures.h"
79 #include "platform/UserGestureIndicator.h" 79 #include "platform/UserGestureIndicator.h"
80 #include "platform/audio/AudioBus.h" 80 #include "platform/audio/AudioBus.h"
81 #include "platform/audio/AudioSourceProviderClient.h" 81 #include "platform/audio/AudioSourceProviderClient.h"
82 #include "platform/graphics/GraphicsLayer.h" 82 #include "platform/graphics/GraphicsLayer.h"
83 #include "platform/mediastream/MediaStreamDescriptor.h" 83 #include "platform/mediastream/MediaStreamDescriptor.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) {
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::IsSupported;
jrummell 2017/03/03 21:52:47 This is wrong (should be != 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 663 matching lines...) Expand 10 before | Expand all | Expand 10 after
1020 NOTREACHED(); 1066 NOTREACHED();
1021 } 1067 }
1022 } 1068 }
1023 1069
1024 void HTMLMediaElement::loadSourceFromObject() { 1070 void HTMLMediaElement::loadSourceFromObject() {
1025 DCHECK(m_srcObject); 1071 DCHECK(m_srcObject);
1026 m_loadState = LoadingFromSrcObject; 1072 m_loadState = LoadingFromSrcObject;
1027 1073
1028 // No type is available when the resource comes from the 'srcObject' 1074 // No type is available when the resource comes from the 'srcObject'
1029 // attribute. 1075 // attribute.
1030 loadResource(WebMediaPlayerSource(WebMediaStream(m_srcObject)), 1076 loadResource(WebMediaPlayerSource(WebMediaStream(m_srcObject)), String());
1031 ContentType((String())));
1032 } 1077 }
1033 1078
1034 void HTMLMediaElement::loadSourceFromAttribute() { 1079 void HTMLMediaElement::loadSourceFromAttribute() {
1035 m_loadState = LoadingFromSrcAttr; 1080 m_loadState = LoadingFromSrcAttr;
1036 const AtomicString& srcValue = fastGetAttribute(srcAttr); 1081 const AtomicString& srcValue = fastGetAttribute(srcAttr);
1037 1082
1038 // If the src attribute's value is the empty string ... jump down to the 1083 // If the src attribute's value is the empty string ... jump down to the
1039 // failed step below 1084 // failed step below
1040 if (srcValue.isEmpty()) { 1085 if (srcValue.isEmpty()) {
1041 mediaLoadingFailed(WebMediaPlayer::NetworkStateFormatError); 1086 mediaLoadingFailed(WebMediaPlayer::NetworkStateFormatError);
1042 BLINK_MEDIA_LOG << "loadSourceFromAttribute(" << (void*)this 1087 BLINK_MEDIA_LOG << "loadSourceFromAttribute(" << (void*)this
1043 << "), empty 'src'"; 1088 << "), empty 'src'";
1044 return; 1089 return;
1045 } 1090 }
1046 1091
1047 KURL mediaURL = document().completeURL(srcValue); 1092 KURL mediaURL = document().completeURL(srcValue);
1048 if (!isSafeToLoadURL(mediaURL, Complain)) { 1093 if (!isSafeToLoadURL(mediaURL, Complain)) {
1049 mediaLoadingFailed(WebMediaPlayer::NetworkStateFormatError); 1094 mediaLoadingFailed(WebMediaPlayer::NetworkStateFormatError);
1050 return; 1095 return;
1051 } 1096 }
1052 1097
1053 // No type is available when the url comes from the 'src' attribute so 1098 // No type is available when the url comes from the 'src' attribute so
1054 // MediaPlayer will have to pick a media engine based on the file extension. 1099 // MediaPlayer will have to pick a media engine based on the file extension.
1055 loadResource(WebMediaPlayerSource(WebURL(mediaURL)), ContentType((String()))); 1100 loadResource(WebMediaPlayerSource(WebURL(mediaURL)), String());
1056 } 1101 }
1057 1102
1058 void HTMLMediaElement::loadNextSourceChild() { 1103 void HTMLMediaElement::loadNextSourceChild() {
1059 ContentType contentType((String())); 1104 String contentType;
1060 KURL mediaURL = selectNextSourceChild(&contentType, Complain); 1105 KURL mediaURL = selectNextSourceChild(&contentType, Complain);
1061 if (!mediaURL.isValid()) { 1106 if (!mediaURL.isValid()) {
1062 waitForSourceChange(); 1107 waitForSourceChange();
1063 return; 1108 return;
1064 } 1109 }
1065 1110
1066 // Reset the MediaPlayer and MediaSource if any 1111 // Reset the MediaPlayer and MediaSource if any
1067 resetMediaPlayerAndMediaSource(); 1112 resetMediaPlayerAndMediaSource();
1068 1113
1069 m_loadState = LoadingFromSourceElement; 1114 m_loadState = LoadingFromSourceElement;
1070 loadResource(WebMediaPlayerSource(WebURL(mediaURL)), contentType); 1115 loadResource(WebMediaPlayerSource(WebURL(mediaURL)), contentType);
1071 } 1116 }
1072 1117
1073 void HTMLMediaElement::loadResource(const WebMediaPlayerSource& source, 1118 void HTMLMediaElement::loadResource(const WebMediaPlayerSource& source,
1074 const ContentType& contentType) { 1119 const String& contentType) {
1075 DCHECK(isMainThread()); 1120 DCHECK(isMainThread());
1076 KURL url; 1121 KURL url;
1077 if (source.isURL()) { 1122 if (source.isURL()) {
1078 url = source.getAsURL(); 1123 url = source.getAsURL();
1079 DCHECK(isSafeToLoadURL(url, Complain)); 1124 DCHECK(isSafeToLoadURL(url, Complain));
1080 BLINK_MEDIA_LOG << "loadResource(" << (void*)this << ", " 1125 BLINK_MEDIA_LOG << "loadResource(" << (void*)this << ", "
1081 << urlForLoggingMedia(url) << ", " << contentType.raw() 1126 << urlForLoggingMedia(url) << ", " << contentType << ")";
1082 << ")";
1083 } 1127 }
1084 1128
1085 LocalFrame* frame = document().frame(); 1129 LocalFrame* frame = document().frame();
1086 if (!frame) { 1130 if (!frame) {
1087 mediaLoadingFailed(WebMediaPlayer::NetworkStateFormatError); 1131 mediaLoadingFailed(WebMediaPlayer::NetworkStateFormatError);
1088 return; 1132 return;
1089 } 1133 }
1090 1134
1091 // The resource fetch algorithm 1135 // The resource fetch algorithm
1092 setNetworkState(kNetworkLoading); 1136 setNetworkState(kNetworkLoading);
(...skipping 1770 matching lines...) Expand 10 before | Expand all | Expand 10 after
2863 AutomaticTrackSelection trackSelection(configuration); 2907 AutomaticTrackSelection trackSelection(configuration);
2864 trackSelection.perform(*m_textTracks); 2908 trackSelection.perform(*m_textTracks);
2865 } 2909 }
2866 2910
2867 bool HTMLMediaElement::havePotentialSourceChild() { 2911 bool HTMLMediaElement::havePotentialSourceChild() {
2868 // Stash the current <source> node and next nodes so we can restore them after 2912 // Stash the current <source> node and next nodes so we can restore them after
2869 // checking to see there is another potential. 2913 // checking to see there is another potential.
2870 HTMLSourceElement* currentSourceNode = m_currentSourceNode; 2914 HTMLSourceElement* currentSourceNode = m_currentSourceNode;
2871 Node* nextNode = m_nextChildNodeToConsider; 2915 Node* nextNode = m_nextChildNodeToConsider;
2872 2916
2873 KURL nextURL = selectNextSourceChild(0, DoNothing); 2917 KURL nextURL = selectNextSourceChild(nullptr, DoNothing);
2874 2918
2875 m_currentSourceNode = currentSourceNode; 2919 m_currentSourceNode = currentSourceNode;
2876 m_nextChildNodeToConsider = nextNode; 2920 m_nextChildNodeToConsider = nextNode;
2877 2921
2878 return nextURL.isValid(); 2922 return nextURL.isValid();
2879 } 2923 }
2880 2924
2881 KURL HTMLMediaElement::selectNextSourceChild(ContentType* contentType, 2925 KURL HTMLMediaElement::selectNextSourceChild(String* contentType,
2882 InvalidURLAction actionIfInvalid) { 2926 InvalidURLAction actionIfInvalid) {
2883 // Don't log if this was just called to find out if there are any valid 2927 // Don't log if this was just called to find out if there are any valid
2884 // <source> elements. 2928 // <source> elements.
2885 bool shouldLog = actionIfInvalid != DoNothing; 2929 bool shouldLog = actionIfInvalid != DoNothing;
2886 if (shouldLog) 2930 if (shouldLog)
2887 BLINK_MEDIA_LOG << "selectNextSourceChild(" << (void*)this << ")"; 2931 BLINK_MEDIA_LOG << "selectNextSourceChild(" << (void*)this << ")";
2888 2932
2889 if (!m_nextChildNodeToConsider) { 2933 if (!m_nextChildNodeToConsider) {
2890 if (shouldLog) 2934 if (shouldLog)
2891 BLINK_MEDIA_LOG << "selectNextSourceChild(" << (void*)this 2935 BLINK_MEDIA_LOG << "selectNextSourceChild(" << (void*)this
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
2955 // Making it this far means the <source> looks reasonable. 2999 // Making it this far means the <source> looks reasonable.
2956 canUseSourceElement = true; 3000 canUseSourceElement = true;
2957 3001
2958 checkAgain: 3002 checkAgain:
2959 if (!canUseSourceElement && actionIfInvalid == Complain && source) 3003 if (!canUseSourceElement && actionIfInvalid == Complain && source)
2960 source->scheduleErrorEvent(); 3004 source->scheduleErrorEvent();
2961 } 3005 }
2962 3006
2963 if (canUseSourceElement) { 3007 if (canUseSourceElement) {
2964 if (contentType) 3008 if (contentType)
2965 *contentType = ContentType(type); 3009 *contentType = type;
2966 m_currentSourceNode = source; 3010 m_currentSourceNode = source;
2967 m_nextChildNodeToConsider = source->nextSibling(); 3011 m_nextChildNodeToConsider = source->nextSibling();
2968 } else { 3012 } else {
2969 m_currentSourceNode = nullptr; 3013 m_currentSourceNode = nullptr;
2970 m_nextChildNodeToConsider = nullptr; 3014 m_nextChildNodeToConsider = nullptr;
2971 } 3015 }
2972 3016
2973 if (shouldLog) 3017 if (shouldLog)
2974 BLINK_MEDIA_LOG << "selectNextSourceChild(" << (void*)this << ") -> " 3018 BLINK_MEDIA_LOG << "selectNextSourceChild(" << (void*)this << ") -> "
2975 << m_currentSourceNode.get() << ", " 3019 << m_currentSourceNode.get() << ", "
(...skipping 1199 matching lines...) Expand 10 before | Expand all | Expand 10 after
4175 kMostlyFillViewportBecomeStableSeconds, BLINK_FROM_HERE); 4219 kMostlyFillViewportBecomeStableSeconds, BLINK_FROM_HERE);
4176 } 4220 }
4177 4221
4178 void HTMLMediaElement::viewportFillDebouncerTimerFired(TimerBase*) { 4222 void HTMLMediaElement::viewportFillDebouncerTimerFired(TimerBase*) {
4179 m_mostlyFillingViewport = true; 4223 m_mostlyFillingViewport = true;
4180 if (m_webMediaPlayer) 4224 if (m_webMediaPlayer)
4181 m_webMediaPlayer->becameDominantVisibleContent(m_mostlyFillingViewport); 4225 m_webMediaPlayer->becameDominantVisibleContent(m_mostlyFillingViewport);
4182 } 4226 }
4183 4227
4184 } // namespace blink 4228 } // 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