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

Unified Diff: third_party/WebKit/Source/core/html/HTMLMediaElement.cpp

Issue 2660003003: Add MediaError.message (Closed)
Patch Set: --flakiness by using std::map, update virtual/stable/[win,mac] global interface listing too 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 side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
diff --git a/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp b/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
index fd0253d4b2ba2749411fa315a8644f330c73c0ee..3997b9e26c8fd084b3bf10f43a99231639fe0a21 100644
--- a/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
@@ -82,6 +82,7 @@
#include "platform/audio/AudioBus.h"
#include "platform/audio/AudioSourceProviderClient.h"
#include "platform/graphics/GraphicsLayer.h"
+#include "platform/json/JSONValues.h"
#include "platform/mediastream/MediaStreamDescriptor.h"
#include "platform/network/NetworkStateNotifier.h"
#include "platform/network/ParsedContentType.h"
@@ -221,6 +222,29 @@ void RemoveElementFromDocumentMap(HTMLMediaElement* element,
map.erase(it);
}
+std::unique_ptr<JSONObject> BuildSimpleErrorMessage(const String& error) {
+ DEFINE_STATIC_LOCAL(const String, element_error_label, ("MediaElementError"));
+ std::unique_ptr<JSONObject> json_message = JSONObject::Create();
+ std::unique_ptr<JSONArray> errors = JSONArray::Create();
+ errors->PushString(error);
+ json_message->SetArray(element_error_label, std::move(errors));
+ return json_message;
+}
+
+std::unique_ptr<JSONObject> BuildErrorMessage(
+ const std::map<std::string, std::vector<std::string>>& messages) {
+ std::unique_ptr<JSONObject> json_messages = JSONObject::Create();
+ for (const auto& entry : messages) {
+ std::unique_ptr<JSONArray> errors = JSONArray::Create();
+ for (const auto& error : entry.second)
+ errors->PushString(WebString::FromUTF8(error));
+ json_messages->SetArray(WebString::FromUTF8(entry.first),
+ std::move(errors));
+ }
+
+ return json_messages;
+}
+
class AudioSourceProviderClientLockScope {
STACK_ALLOCATED();
@@ -1115,15 +1139,18 @@ void HTMLMediaElement::LoadSourceFromAttribute() {
// If the src attribute's value is the empty string ... jump down to the
// failed step below
if (src_value.IsEmpty()) {
- MediaLoadingFailed(WebMediaPlayer::kNetworkStateFormatError);
- BLINK_MEDIA_LOG << "loadSourceFromAttribute(" << (void*)this
+ BLINK_MEDIA_LOG << "LoadSourceFromAttribute(" << (void*)this
<< "), empty 'src'";
+ MediaLoadingFailed(WebMediaPlayer::kNetworkStateFormatError,
+ BuildSimpleErrorMessage("Empty src attribute"));
return;
}
KURL media_url = GetDocument().CompleteURL(src_value);
if (!IsSafeToLoadURL(media_url, kComplain)) {
- MediaLoadingFailed(WebMediaPlayer::kNetworkStateFormatError);
+ MediaLoadingFailed(
+ WebMediaPlayer::kNetworkStateFormatError,
+ BuildSimpleErrorMessage("Media load rejected by URL safety check"));
return;
}
@@ -1160,7 +1187,9 @@ void HTMLMediaElement::LoadResource(const WebMediaPlayerSource& source,
LocalFrame* frame = GetDocument().GetFrame();
if (!frame) {
- MediaLoadingFailed(WebMediaPlayer::kNetworkStateFormatError);
+ MediaLoadingFailed(WebMediaPlayer::kNetworkStateFormatError,
+ BuildSimpleErrorMessage(
+ "Resource load failure: document has no frame"));
return;
}
@@ -1218,7 +1247,11 @@ void HTMLMediaElement::LoadResource(const WebMediaPlayerSource& source,
StartPlayerLoad();
}
} else {
- MediaLoadingFailed(WebMediaPlayer::kNetworkStateFormatError);
+ MediaLoadingFailed(
+ WebMediaPlayer::kNetworkStateFormatError,
+ BuildSimpleErrorMessage(attempt_load
+ ? "Unable to load URL due to content type"
+ : "Unable to attach MediaSource"));
}
// If there is no poster to display, allow the media engine to render video
@@ -1264,14 +1297,18 @@ void HTMLMediaElement::StartPlayerLoad(const KURL& player_provided_url) {
// TODO(srirama.m): Figure out how frame can be null when
// coming from executeDeferredLoad()
if (!frame) {
- MediaLoadingFailed(WebMediaPlayer::kNetworkStateFormatError);
+ MediaLoadingFailed(
+ WebMediaPlayer::kNetworkStateFormatError,
+ BuildSimpleErrorMessage("Player load failure: document has no frame"));
return;
}
web_media_player_ =
frame->Loader().Client()->CreateWebMediaPlayer(*this, source, this);
if (!web_media_player_) {
- MediaLoadingFailed(WebMediaPlayer::kNetworkStateFormatError);
+ MediaLoadingFailed(WebMediaPlayer::kNetworkStateFormatError,
+ BuildSimpleErrorMessage(
+ "Player load failure: error creating media player"));
return;
}
@@ -1514,8 +1551,9 @@ void HTMLMediaElement::WaitForSourceChange() {
GetLayoutObject()->UpdateFromElement();
}
-void HTMLMediaElement::NoneSupported() {
- BLINK_MEDIA_LOG << "noneSupported(" << (void*)this << ")";
+void HTMLMediaElement::NoneSupported(std::unique_ptr<JSONObject> messages) {
+ BLINK_MEDIA_LOG << "NoneSupported(" << (void*)this << ", messages='"
+ << messages->ToJSONString() << "')";
StopPeriodicTimers();
load_state_ = kWaitingForSource;
@@ -1526,7 +1564,8 @@ void HTMLMediaElement::NoneSupported() {
// 1 - Set the error attribute to a new MediaError object whose code attribute
// is set to MEDIA_ERR_SRC_NOT_SUPPORTED.
- error_ = MediaError::Create(MediaError::kMediaErrSrcNotSupported);
+ error_ =
+ MediaError::Create(MediaError::kMediaErrSrcNotSupported, messages.get());
// 2 - Forget the media element's media-resource-specific text tracks.
ForgetResourceSpecificTracks();
@@ -1595,7 +1634,13 @@ void HTMLMediaElement::NetworkStateChanged() {
SetNetworkState(GetWebMediaPlayer()->GetNetworkState());
}
-void HTMLMediaElement::MediaLoadingFailed(WebMediaPlayer::NetworkState error) {
+void HTMLMediaElement::MediaLoadingFailed(
+ WebMediaPlayer::NetworkState error,
+ std::unique_ptr<JSONObject> messages) {
+ BLINK_MEDIA_LOG << "MediaLoadingFailed(" << (void*)this << ", "
+ << static_cast<int>(error) << ", messages='"
+ << messages->ToJSONString() << "')";
+
StopPeriodicTimers();
// If we failed while trying to load a <source> element, the movie was never
@@ -1635,13 +1680,23 @@ void HTMLMediaElement::MediaLoadingFailed(WebMediaPlayer::NetworkState error) {
if (error == WebMediaPlayer::kNetworkStateNetworkError &&
ready_state_ >= kHaveMetadata) {
- MediaEngineError(MediaError::Create(MediaError::kMediaErrNetwork));
+ MediaEngineError(
+ MediaError::Create(MediaError::kMediaErrNetwork, messages.get()));
} else if (error == WebMediaPlayer::kNetworkStateDecodeError) {
- MediaEngineError(MediaError::Create(MediaError::kMediaErrDecode));
+ MediaEngineError(
+ MediaError::Create(MediaError::kMediaErrDecode, messages.get()));
} else if ((error == WebMediaPlayer::kNetworkStateFormatError ||
error == WebMediaPlayer::kNetworkStateNetworkError) &&
load_state_ == kLoadingFromSrcAttr) {
- NoneSupported();
+ if (!messages->size()) {
+ // Generate a more meaningful error message to differentiate the two types
+ // of MEDIA_SRC_ERR_NOT_SUPPORTED.
+ NoneSupported(BuildSimpleErrorMessage(
+ error == WebMediaPlayer::kNetworkStateFormatError ? "Format error"
+ : "Network error"));
+ } else {
+ NoneSupported(std::move(messages));
+ }
}
UpdateDisplayState();
@@ -1661,7 +1716,8 @@ void HTMLMediaElement::SetNetworkState(WebMediaPlayer::NetworkState state) {
if (state == WebMediaPlayer::kNetworkStateFormatError ||
state == WebMediaPlayer::kNetworkStateNetworkError ||
state == WebMediaPlayer::kNetworkStateDecodeError) {
- MediaLoadingFailed(state);
+ MediaLoadingFailed(
+ state, BuildErrorMessage(web_media_player_->GetErrorMessages()));
return;
}

Powered by Google App Engine
This is Rietveld 408576698