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

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

Issue 2660003003: Add MediaError.message (Closed)
Patch Set: Address dalecurtis@'s comment: undef STRINGIFY_STATUS_CASE 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 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
214 Document* document) { 214 Document* document) {
215 DocumentElementSetMap& map = DocumentToElementSetMap(); 215 DocumentElementSetMap& map = DocumentToElementSetMap();
216 auto it = map.Find(document); 216 auto it = map.Find(document);
217 DCHECK(it != map.end()); 217 DCHECK(it != map.end());
218 WeakMediaElementSet* set = it->value; 218 WeakMediaElementSet* set = it->value;
219 set->erase(element); 219 set->erase(element);
220 if (set->IsEmpty()) 220 if (set->IsEmpty())
221 map.erase(it); 221 map.erase(it);
222 } 222 }
223 223
224 String BuildElementErrorMessage(const String& error) {
mlamouri (slow - plz ping) 2017/04/21 10:26:24 In the future, we might want to move this to Media
225 // Prepend a UA-specific-error code before the first ':', to enable better
226 // collection and aggregation of UA-specific-error codes from
227 // MediaError.message by web apps. WebMediaPlayer::GetErrorMessage() should
228 // similarly conform to this format.
229 DEFINE_STATIC_LOCAL(const String, element_error_prefix,
230 ("MEDIA_ELEMENT_ERROR: "));
231 StringBuilder builder;
232 builder.Append(element_error_prefix);
233 builder.Append(error);
234 return builder.ToString();
235 }
236
224 class AudioSourceProviderClientLockScope { 237 class AudioSourceProviderClientLockScope {
225 STACK_ALLOCATED(); 238 STACK_ALLOCATED();
226 239
227 public: 240 public:
228 AudioSourceProviderClientLockScope(HTMLMediaElement& element) 241 AudioSourceProviderClientLockScope(HTMLMediaElement& element)
229 : client_(element.AudioSourceNode()) { 242 : client_(element.AudioSourceNode()) {
230 if (client_) 243 if (client_)
231 client_->lock(); 244 client_->lock();
232 } 245 }
233 ~AudioSourceProviderClientLockScope() { 246 ~AudioSourceProviderClientLockScope() {
(...skipping 874 matching lines...) Expand 10 before | Expand all | Expand 10 after
1108 LoadResource(WebMediaPlayerSource(WebMediaStream(src_object_)), String()); 1121 LoadResource(WebMediaPlayerSource(WebMediaStream(src_object_)), String());
1109 } 1122 }
1110 1123
1111 void HTMLMediaElement::LoadSourceFromAttribute() { 1124 void HTMLMediaElement::LoadSourceFromAttribute() {
1112 load_state_ = kLoadingFromSrcAttr; 1125 load_state_ = kLoadingFromSrcAttr;
1113 const AtomicString& src_value = FastGetAttribute(srcAttr); 1126 const AtomicString& src_value = FastGetAttribute(srcAttr);
1114 1127
1115 // If the src attribute's value is the empty string ... jump down to the 1128 // If the src attribute's value is the empty string ... jump down to the
1116 // failed step below 1129 // failed step below
1117 if (src_value.IsEmpty()) { 1130 if (src_value.IsEmpty()) {
1118 MediaLoadingFailed(WebMediaPlayer::kNetworkStateFormatError); 1131 BLINK_MEDIA_LOG << "LoadSourceFromAttribute(" << (void*)this
1119 BLINK_MEDIA_LOG << "loadSourceFromAttribute(" << (void*)this
1120 << "), empty 'src'"; 1132 << "), empty 'src'";
1133 MediaLoadingFailed(WebMediaPlayer::kNetworkStateFormatError,
1134 BuildElementErrorMessage("Empty src attribute"));
1121 return; 1135 return;
1122 } 1136 }
1123 1137
1124 KURL media_url = GetDocument().CompleteURL(src_value); 1138 KURL media_url = GetDocument().CompleteURL(src_value);
1125 if (!IsSafeToLoadURL(media_url, kComplain)) { 1139 if (!IsSafeToLoadURL(media_url, kComplain)) {
1126 MediaLoadingFailed(WebMediaPlayer::kNetworkStateFormatError); 1140 MediaLoadingFailed(
1141 WebMediaPlayer::kNetworkStateFormatError,
1142 BuildElementErrorMessage("Media load rejected by URL safety check"));
1127 return; 1143 return;
1128 } 1144 }
1129 1145
1130 // No type is available when the url comes from the 'src' attribute so 1146 // No type is available when the url comes from the 'src' attribute so
1131 // MediaPlayer will have to pick a media engine based on the file extension. 1147 // MediaPlayer will have to pick a media engine based on the file extension.
1132 LoadResource(WebMediaPlayerSource(WebURL(media_url)), String()); 1148 LoadResource(WebMediaPlayerSource(WebURL(media_url)), String());
1133 } 1149 }
1134 1150
1135 void HTMLMediaElement::LoadNextSourceChild() { 1151 void HTMLMediaElement::LoadNextSourceChild() {
1136 String content_type; 1152 String content_type;
(...skipping 16 matching lines...) Expand all
1153 KURL url; 1169 KURL url;
1154 if (source.IsURL()) { 1170 if (source.IsURL()) {
1155 url = source.GetAsURL(); 1171 url = source.GetAsURL();
1156 DCHECK(IsSafeToLoadURL(url, kComplain)); 1172 DCHECK(IsSafeToLoadURL(url, kComplain));
1157 BLINK_MEDIA_LOG << "loadResource(" << (void*)this << ", " 1173 BLINK_MEDIA_LOG << "loadResource(" << (void*)this << ", "
1158 << UrlForLoggingMedia(url) << ", " << content_type << ")"; 1174 << UrlForLoggingMedia(url) << ", " << content_type << ")";
1159 } 1175 }
1160 1176
1161 LocalFrame* frame = GetDocument().GetFrame(); 1177 LocalFrame* frame = GetDocument().GetFrame();
1162 if (!frame) { 1178 if (!frame) {
1163 MediaLoadingFailed(WebMediaPlayer::kNetworkStateFormatError); 1179 MediaLoadingFailed(WebMediaPlayer::kNetworkStateFormatError,
1180 BuildElementErrorMessage(
1181 "Resource load failure: document has no frame"));
1164 return; 1182 return;
1165 } 1183 }
1166 1184
1167 // The resource fetch algorithm 1185 // The resource fetch algorithm
1168 SetNetworkState(kNetworkLoading); 1186 SetNetworkState(kNetworkLoading);
1169 1187
1170 // Set m_currentSrc *before* changing to the cache url, the fact that we are 1188 // Set m_currentSrc *before* changing to the cache url, the fact that we are
1171 // loading from the app cache is an internal detail not exposed through the 1189 // loading from the app cache is an internal detail not exposed through the
1172 // media element API. 1190 // media element API.
1173 current_src_ = url; 1191 current_src_ = url;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1211 // including MediaSource blob URLs. 1229 // including MediaSource blob URLs.
1212 if (!source.IsMediaStream() && !url.ProtocolIs("blob") && 1230 if (!source.IsMediaStream() && !url.ProtocolIs("blob") &&
1213 EffectivePreloadType() == WebMediaPlayer::kPreloadNone) { 1231 EffectivePreloadType() == WebMediaPlayer::kPreloadNone) {
1214 BLINK_MEDIA_LOG << "loadResource(" << (void*)this 1232 BLINK_MEDIA_LOG << "loadResource(" << (void*)this
1215 << ") : Delaying load because preload == 'none'"; 1233 << ") : Delaying load because preload == 'none'";
1216 DeferLoad(); 1234 DeferLoad();
1217 } else { 1235 } else {
1218 StartPlayerLoad(); 1236 StartPlayerLoad();
1219 } 1237 }
1220 } else { 1238 } else {
1221 MediaLoadingFailed(WebMediaPlayer::kNetworkStateFormatError); 1239 MediaLoadingFailed(
1240 WebMediaPlayer::kNetworkStateFormatError,
1241 BuildElementErrorMessage(attempt_load
1242 ? "Unable to load URL due to content type"
1243 : "Unable to attach MediaSource"));
1222 } 1244 }
1223 1245
1224 // If there is no poster to display, allow the media engine to render video 1246 // If there is no poster to display, allow the media engine to render video
1225 // frames as soon as they are available. 1247 // frames as soon as they are available.
1226 UpdateDisplayState(); 1248 UpdateDisplayState();
1227 1249
1228 if (GetLayoutObject()) 1250 if (GetLayoutObject())
1229 GetLayoutObject()->UpdateFromElement(); 1251 GetLayoutObject()->UpdateFromElement();
1230 } 1252 }
1231 1253
(...skipping 25 matching lines...) Expand all
1257 request_url.SetPass(String()); 1279 request_url.SetPass(String());
1258 1280
1259 KURL kurl(kParsedURLString, request_url); 1281 KURL kurl(kParsedURLString, request_url);
1260 source = WebMediaPlayerSource(WebURL(kurl)); 1282 source = WebMediaPlayerSource(WebURL(kurl));
1261 } 1283 }
1262 1284
1263 LocalFrame* frame = GetDocument().GetFrame(); 1285 LocalFrame* frame = GetDocument().GetFrame();
1264 // TODO(srirama.m): Figure out how frame can be null when 1286 // TODO(srirama.m): Figure out how frame can be null when
1265 // coming from executeDeferredLoad() 1287 // coming from executeDeferredLoad()
1266 if (!frame) { 1288 if (!frame) {
1267 MediaLoadingFailed(WebMediaPlayer::kNetworkStateFormatError); 1289 MediaLoadingFailed(
1290 WebMediaPlayer::kNetworkStateFormatError,
1291 BuildElementErrorMessage("Player load failure: document has no frame"));
1268 return; 1292 return;
1269 } 1293 }
1270 1294
1271 web_media_player_ = 1295 web_media_player_ =
1272 frame->Loader().Client()->CreateWebMediaPlayer(*this, source, this); 1296 frame->Loader().Client()->CreateWebMediaPlayer(*this, source, this);
1273 if (!web_media_player_) { 1297 if (!web_media_player_) {
1274 MediaLoadingFailed(WebMediaPlayer::kNetworkStateFormatError); 1298 MediaLoadingFailed(WebMediaPlayer::kNetworkStateFormatError,
1299 BuildElementErrorMessage(
1300 "Player load failure: error creating media player"));
1275 return; 1301 return;
1276 } 1302 }
1277 1303
1278 if (GetLayoutObject()) 1304 if (GetLayoutObject())
1279 GetLayoutObject()->SetShouldDoFullPaintInvalidation(); 1305 GetLayoutObject()->SetShouldDoFullPaintInvalidation();
1280 // Make sure if we create/re-create the WebMediaPlayer that we update our 1306 // Make sure if we create/re-create the WebMediaPlayer that we update our
1281 // wrapper. 1307 // wrapper.
1282 audio_source_provider_.Wrap(web_media_player_->GetAudioSourceProvider()); 1308 audio_source_provider_.Wrap(web_media_player_->GetAudioSourceProvider());
1283 web_media_player_->SetVolume(EffectiveMediaVolume()); 1309 web_media_player_->SetVolume(EffectiveMediaVolume());
1284 1310
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
1507 // 6.18 - Set the element's delaying-the-load-event flag to false. This stops 1533 // 6.18 - Set the element's delaying-the-load-event flag to false. This stops
1508 // delaying the load event. 1534 // delaying the load event.
1509 SetShouldDelayLoadEvent(false); 1535 SetShouldDelayLoadEvent(false);
1510 1536
1511 UpdateDisplayState(); 1537 UpdateDisplayState();
1512 1538
1513 if (GetLayoutObject()) 1539 if (GetLayoutObject())
1514 GetLayoutObject()->UpdateFromElement(); 1540 GetLayoutObject()->UpdateFromElement();
1515 } 1541 }
1516 1542
1517 void HTMLMediaElement::NoneSupported() { 1543 void HTMLMediaElement::NoneSupported(const String& message) {
1518 BLINK_MEDIA_LOG << "noneSupported(" << (void*)this << ")"; 1544 BLINK_MEDIA_LOG << "NoneSupported(" << (void*)this << ", message='" << message
1545 << "')";
1519 1546
1520 StopPeriodicTimers(); 1547 StopPeriodicTimers();
1521 load_state_ = kWaitingForSource; 1548 load_state_ = kWaitingForSource;
1522 current_source_node_ = nullptr; 1549 current_source_node_ = nullptr;
1523 1550
1524 // 4.8.12.5 1551 // 4.8.12.5
1525 // The dedicated media source failure steps are the following steps: 1552 // The dedicated media source failure steps are the following steps:
1526 1553
1527 // 1 - Set the error attribute to a new MediaError object whose code attribute 1554 // 1 - Set the error attribute to a new MediaError object whose code attribute
1528 // is set to MEDIA_ERR_SRC_NOT_SUPPORTED. 1555 // is set to MEDIA_ERR_SRC_NOT_SUPPORTED.
1529 error_ = MediaError::Create(MediaError::kMediaErrSrcNotSupported); 1556 error_ = MediaError::Create(MediaError::kMediaErrSrcNotSupported, message);
1530 1557
1531 // 2 - Forget the media element's media-resource-specific text tracks. 1558 // 2 - Forget the media element's media-resource-specific text tracks.
1532 ForgetResourceSpecificTracks(); 1559 ForgetResourceSpecificTracks();
1533 1560
1534 // 3 - Set the element's networkState attribute to the NETWORK_NO_SOURCE 1561 // 3 - Set the element's networkState attribute to the NETWORK_NO_SOURCE
1535 // value. 1562 // value.
1536 SetNetworkState(kNetworkNoSource); 1563 SetNetworkState(kNetworkNoSource);
1537 1564
1538 // 4 - Set the element's show poster flag to true. 1565 // 4 - Set the element's show poster flag to true.
1539 UpdateDisplayState(); 1566 UpdateDisplayState();
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1588 for (HTMLSourceElement* source = 1615 for (HTMLSourceElement* source =
1589 Traversal<HTMLSourceElement>::FirstChild(*this); 1616 Traversal<HTMLSourceElement>::FirstChild(*this);
1590 source; source = Traversal<HTMLSourceElement>::NextSibling(*source)) 1617 source; source = Traversal<HTMLSourceElement>::NextSibling(*source))
1591 source->CancelPendingErrorEvent(); 1618 source->CancelPendingErrorEvent();
1592 } 1619 }
1593 1620
1594 void HTMLMediaElement::NetworkStateChanged() { 1621 void HTMLMediaElement::NetworkStateChanged() {
1595 SetNetworkState(GetWebMediaPlayer()->GetNetworkState()); 1622 SetNetworkState(GetWebMediaPlayer()->GetNetworkState());
1596 } 1623 }
1597 1624
1598 void HTMLMediaElement::MediaLoadingFailed(WebMediaPlayer::NetworkState error) { 1625 void HTMLMediaElement::MediaLoadingFailed(WebMediaPlayer::NetworkState error,
1626 const String& message) {
1627 BLINK_MEDIA_LOG << "MediaLoadingFailed(" << (void*)this << ", "
1628 << static_cast<int>(error) << ", message='" << message
1629 << "')";
1630
1599 StopPeriodicTimers(); 1631 StopPeriodicTimers();
1600 1632
1601 // If we failed while trying to load a <source> element, the movie was never 1633 // If we failed while trying to load a <source> element, the movie was never
1602 // parsed, and there are more <source> children, schedule the next one 1634 // parsed, and there are more <source> children, schedule the next one
1603 if (ready_state_ < kHaveMetadata && 1635 if (ready_state_ < kHaveMetadata &&
1604 load_state_ == kLoadingFromSourceElement) { 1636 load_state_ == kLoadingFromSourceElement) {
1605 // resource selection algorithm 1637 // resource selection algorithm
1606 // Step 9.Otherwise.9 - Failed with elements: Queue a task, using the DOM 1638 // Step 9.Otherwise.9 - Failed with elements: Queue a task, using the DOM
1607 // manipulation task source, to fire a simple event named error at the 1639 // manipulation task source, to fire a simple event named error at the
1608 // candidate element. 1640 // candidate element.
(...skipping 19 matching lines...) Expand all
1628 BLINK_MEDIA_LOG << "mediaLoadingFailed(" << (void*)this 1660 BLINK_MEDIA_LOG << "mediaLoadingFailed(" << (void*)this
1629 << ") - no more <source> elements, waiting"; 1661 << ") - no more <source> elements, waiting";
1630 WaitForSourceChange(); 1662 WaitForSourceChange();
1631 } 1663 }
1632 1664
1633 return; 1665 return;
1634 } 1666 }
1635 1667
1636 if (error == WebMediaPlayer::kNetworkStateNetworkError && 1668 if (error == WebMediaPlayer::kNetworkStateNetworkError &&
1637 ready_state_ >= kHaveMetadata) { 1669 ready_state_ >= kHaveMetadata) {
1638 MediaEngineError(MediaError::Create(MediaError::kMediaErrNetwork)); 1670 MediaEngineError(MediaError::Create(MediaError::kMediaErrNetwork, message));
1639 } else if (error == WebMediaPlayer::kNetworkStateDecodeError) { 1671 } else if (error == WebMediaPlayer::kNetworkStateDecodeError) {
1640 MediaEngineError(MediaError::Create(MediaError::kMediaErrDecode)); 1672 MediaEngineError(MediaError::Create(MediaError::kMediaErrDecode, message));
1641 } else if ((error == WebMediaPlayer::kNetworkStateFormatError || 1673 } else if ((error == WebMediaPlayer::kNetworkStateFormatError ||
1642 error == WebMediaPlayer::kNetworkStateNetworkError) && 1674 error == WebMediaPlayer::kNetworkStateNetworkError) &&
1643 load_state_ == kLoadingFromSrcAttr) { 1675 load_state_ == kLoadingFromSrcAttr) {
1644 NoneSupported(); 1676 if (message.IsEmpty()) {
1677 // Generate a more meaningful error message to differentiate the two types
1678 // of MEDIA_SRC_ERR_NOT_SUPPORTED.
1679 NoneSupported(BuildElementErrorMessage(
1680 error == WebMediaPlayer::kNetworkStateFormatError ? "Format error"
1681 : "Network error"));
1682 } else {
1683 NoneSupported(message);
1684 }
1645 } 1685 }
1646 1686
1647 UpdateDisplayState(); 1687 UpdateDisplayState();
1648 } 1688 }
1649 1689
1650 void HTMLMediaElement::SetNetworkState(WebMediaPlayer::NetworkState state) { 1690 void HTMLMediaElement::SetNetworkState(WebMediaPlayer::NetworkState state) {
1651 BLINK_MEDIA_LOG << "setNetworkState(" << (void*)this << ", " 1691 BLINK_MEDIA_LOG << "setNetworkState(" << (void*)this << ", "
1652 << static_cast<int>(state) << ") - current state is " 1692 << static_cast<int>(state) << ") - current state is "
1653 << static_cast<int>(network_state_); 1693 << static_cast<int>(network_state_);
1654 1694
1655 if (state == WebMediaPlayer::kNetworkStateEmpty) { 1695 if (state == WebMediaPlayer::kNetworkStateEmpty) {
1656 // Just update the cached state and leave, we can't do anything. 1696 // Just update the cached state and leave, we can't do anything.
1657 SetNetworkState(kNetworkEmpty); 1697 SetNetworkState(kNetworkEmpty);
1658 return; 1698 return;
1659 } 1699 }
1660 1700
1661 if (state == WebMediaPlayer::kNetworkStateFormatError || 1701 if (state == WebMediaPlayer::kNetworkStateFormatError ||
1662 state == WebMediaPlayer::kNetworkStateNetworkError || 1702 state == WebMediaPlayer::kNetworkStateNetworkError ||
1663 state == WebMediaPlayer::kNetworkStateDecodeError) { 1703 state == WebMediaPlayer::kNetworkStateDecodeError) {
1664 MediaLoadingFailed(state); 1704 MediaLoadingFailed(state, web_media_player_->GetErrorMessage());
1665 return; 1705 return;
1666 } 1706 }
1667 1707
1668 if (state == WebMediaPlayer::kNetworkStateIdle) { 1708 if (state == WebMediaPlayer::kNetworkStateIdle) {
1669 if (network_state_ > kNetworkIdle) { 1709 if (network_state_ > kNetworkIdle) {
1670 ChangeNetworkStateFromLoadingToIdle(); 1710 ChangeNetworkStateFromLoadingToIdle();
1671 SetShouldDelayLoadEvent(false); 1711 SetShouldDelayLoadEvent(false);
1672 } else { 1712 } else {
1673 SetNetworkState(kNetworkIdle); 1713 SetNetworkState(kNetworkIdle);
1674 } 1714 }
(...skipping 2614 matching lines...) Expand 10 before | Expand all | Expand 10 after
4289 kMostlyFillViewportBecomeStableSeconds, BLINK_FROM_HERE); 4329 kMostlyFillViewportBecomeStableSeconds, BLINK_FROM_HERE);
4290 } 4330 }
4291 4331
4292 void HTMLMediaElement::ViewportFillDebouncerTimerFired(TimerBase*) { 4332 void HTMLMediaElement::ViewportFillDebouncerTimerFired(TimerBase*) {
4293 mostly_filling_viewport_ = true; 4333 mostly_filling_viewport_ = true;
4294 if (web_media_player_) 4334 if (web_media_player_)
4295 web_media_player_->BecameDominantVisibleContent(mostly_filling_viewport_); 4335 web_media_player_->BecameDominantVisibleContent(mostly_filling_viewport_);
4296 } 4336 }
4297 4337
4298 } // namespace blink 4338 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698