Update V8 to version 4.7.56.
[chromium-blink-merge.git] / media / blink / webmediaplayer_util.cc
blob96de408bbcf64412f31bd95aa10580a9817cd540
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "media/blink/webmediaplayer_util.h"
7 #include <math.h>
9 #include "base/metrics/histogram.h"
10 #include "media/base/bind_to_current_loop.h"
11 #include "media/base/media_client.h"
12 #include "media/base/media_keys.h"
13 #include "third_party/WebKit/public/platform/WebMediaPlayerEncryptedMediaClient.h"
15 namespace media {
17 // Compile asserts shared by all platforms.
19 #define STATIC_ASSERT_MATCHING_ENUM(name) \
20 static_assert(static_cast<int>(blink::WebMediaPlayerEncryptedMediaClient:: \
21 MediaKeyErrorCode##name) == \
22 static_cast<int>(MediaKeys::k##name##Error), \
23 "mismatching enum values: " #name)
24 STATIC_ASSERT_MATCHING_ENUM(Unknown);
25 STATIC_ASSERT_MATCHING_ENUM(Client);
26 #undef STATIC_ASSERT_MATCHING_ENUM
28 blink::WebTimeRanges ConvertToWebTimeRanges(
29 const Ranges<base::TimeDelta>& ranges) {
30 blink::WebTimeRanges result(ranges.size());
31 for (size_t i = 0; i < ranges.size(); ++i) {
32 result[i].start = ranges.start(i).InSecondsF();
33 result[i].end = ranges.end(i).InSecondsF();
35 return result;
38 blink::WebMediaPlayer::NetworkState PipelineErrorToNetworkState(
39 PipelineStatus error) {
40 DCHECK_NE(error, PIPELINE_OK);
42 switch (error) {
43 case PIPELINE_ERROR_NETWORK:
44 case PIPELINE_ERROR_READ:
45 return blink::WebMediaPlayer::NetworkStateNetworkError;
47 // TODO(vrk): Because OnPipelineInitialize() directly reports the
48 // NetworkStateFormatError instead of calling OnPipelineError(), I believe
49 // this block can be deleted. Should look into it! (crbug.com/126070)
50 case PIPELINE_ERROR_INITIALIZATION_FAILED:
51 case PIPELINE_ERROR_COULD_NOT_RENDER:
52 case PIPELINE_ERROR_URL_NOT_FOUND:
53 case DEMUXER_ERROR_COULD_NOT_OPEN:
54 case DEMUXER_ERROR_COULD_NOT_PARSE:
55 case DEMUXER_ERROR_NO_SUPPORTED_STREAMS:
56 case DECODER_ERROR_NOT_SUPPORTED:
57 return blink::WebMediaPlayer::NetworkStateFormatError;
59 case PIPELINE_ERROR_DECODE:
60 case PIPELINE_ERROR_ABORT:
61 case PIPELINE_ERROR_OPERATION_PENDING:
62 case PIPELINE_ERROR_INVALID_STATE:
63 return blink::WebMediaPlayer::NetworkStateDecodeError;
65 case PIPELINE_OK:
66 NOTREACHED() << "Unexpected status! " << error;
68 return blink::WebMediaPlayer::NetworkStateFormatError;
71 namespace {
73 // Helper enum for reporting scheme histograms.
74 enum URLSchemeForHistogram {
75 kUnknownURLScheme,
76 kMissingURLScheme,
77 kHttpURLScheme,
78 kHttpsURLScheme,
79 kFtpURLScheme,
80 kChromeExtensionURLScheme,
81 kJavascriptURLScheme,
82 kFileURLScheme,
83 kBlobURLScheme,
84 kDataURLScheme,
85 kFileSystemScheme,
86 kMaxURLScheme = kFileSystemScheme // Must be equal to highest enum value.
89 URLSchemeForHistogram URLScheme(const GURL& url) {
90 if (!url.has_scheme()) return kMissingURLScheme;
91 if (url.SchemeIs("http")) return kHttpURLScheme;
92 if (url.SchemeIs("https")) return kHttpsURLScheme;
93 if (url.SchemeIs("ftp")) return kFtpURLScheme;
94 if (url.SchemeIs("chrome-extension")) return kChromeExtensionURLScheme;
95 if (url.SchemeIs("javascript")) return kJavascriptURLScheme;
96 if (url.SchemeIs("file")) return kFileURLScheme;
97 if (url.SchemeIs("blob")) return kBlobURLScheme;
98 if (url.SchemeIs("data")) return kDataURLScheme;
99 if (url.SchemeIs("filesystem")) return kFileSystemScheme;
101 return kUnknownURLScheme;
104 std::string LoadTypeToString(blink::WebMediaPlayer::LoadType load_type) {
105 switch (load_type) {
106 case blink::WebMediaPlayer::LoadTypeURL:
107 return "SRC";
108 case blink::WebMediaPlayer::LoadTypeMediaSource:
109 return "MSE";
110 case blink::WebMediaPlayer::LoadTypeMediaStream:
111 return "MS";
114 NOTREACHED();
115 return "Unknown";
118 } // namespace
120 // TODO(xhwang): Call this from WebMediaPlayerMS to report metrics for
121 // MediaStream as well.
122 void ReportMetrics(blink::WebMediaPlayer::LoadType load_type,
123 const GURL& url,
124 const GURL& origin_url) {
125 // Report URL scheme, such as http, https, file, blob etc.
126 UMA_HISTOGRAM_ENUMERATION("Media.URLScheme", URLScheme(url),
127 kMaxURLScheme + 1);
129 // Report load type, such as URL, MediaSource or MediaStream.
130 UMA_HISTOGRAM_ENUMERATION("Media.LoadType", load_type,
131 blink::WebMediaPlayer::LoadTypeMax + 1);
133 // Report the origin from where the media player is created.
134 if (GetMediaClient()) {
135 GetMediaClient()->RecordRapporURL(
136 "Media.OriginUrl." + LoadTypeToString(load_type), origin_url);
140 void RecordOriginOfHLSPlayback(const GURL& origin_url) {
141 if (media::GetMediaClient())
142 GetMediaClient()->RecordRapporURL("Media.OriginUrl.HLS", origin_url);
145 EmeInitDataType ConvertToEmeInitDataType(
146 blink::WebEncryptedMediaInitDataType init_data_type) {
147 switch (init_data_type) {
148 case blink::WebEncryptedMediaInitDataType::Webm:
149 return EmeInitDataType::WEBM;
150 case blink::WebEncryptedMediaInitDataType::Cenc:
151 return EmeInitDataType::CENC;
152 case blink::WebEncryptedMediaInitDataType::Keyids:
153 return EmeInitDataType::KEYIDS;
154 case blink::WebEncryptedMediaInitDataType::Unknown:
155 return EmeInitDataType::UNKNOWN;
158 NOTREACHED();
159 return EmeInitDataType::UNKNOWN;
162 blink::WebEncryptedMediaInitDataType ConvertToWebInitDataType(
163 EmeInitDataType init_data_type) {
164 switch (init_data_type) {
165 case EmeInitDataType::WEBM:
166 return blink::WebEncryptedMediaInitDataType::Webm;
167 case EmeInitDataType::CENC:
168 return blink::WebEncryptedMediaInitDataType::Cenc;
169 case EmeInitDataType::KEYIDS:
170 return blink::WebEncryptedMediaInitDataType::Keyids;
171 case EmeInitDataType::UNKNOWN:
172 return blink::WebEncryptedMediaInitDataType::Unknown;
175 NOTREACHED();
176 return blink::WebEncryptedMediaInitDataType::Unknown;
179 namespace {
180 // This class wraps a scoped WebSetSinkIdCB pointer such that
181 // copying objects of this class actually performs moving, thus
182 // maintaining clear ownership of the WebSetSinkIdCB pointer.
183 // The rationale for this class is that the SwichOutputDevice method
184 // can make a copy of its base::Callback parameter, which implies
185 // copying its bound parameters.
186 // SwitchOutputDevice actually wants to move its base::Callback
187 // parameter since only the final copy will be run, but base::Callback
188 // does not support move semantics and there is no base::MovableCallback.
189 // Since scoped pointers are not copyable, we cannot bind them directly
190 // to a base::Callback in this case. Thus, we use this helper class,
191 // whose copy constructor transfers ownership of the scoped pointer.
193 class SetSinkIdCallback {
194 public:
195 explicit SetSinkIdCallback(WebSetSinkIdCB* web_callback)
196 : web_callback_(web_callback) {}
197 SetSinkIdCallback(const SetSinkIdCallback& other)
198 : web_callback_(other.web_callback_.Pass()) {}
199 ~SetSinkIdCallback() {}
200 friend void RunSetSinkIdCallback(const SetSinkIdCallback& callback,
201 SwitchOutputDeviceResult result);
203 private:
204 // Mutable is required so that Pass() can be called in the copy
205 // constructor.
206 mutable scoped_ptr<WebSetSinkIdCB> web_callback_;
209 void RunSetSinkIdCallback(const SetSinkIdCallback& callback,
210 SwitchOutputDeviceResult result) {
211 DVLOG(1) << __FUNCTION__;
212 if (!callback.web_callback_)
213 return;
215 switch (result) {
216 case SWITCH_OUTPUT_DEVICE_RESULT_SUCCESS:
217 callback.web_callback_->onSuccess();
218 break;
219 case SWITCH_OUTPUT_DEVICE_RESULT_ERROR_NOT_FOUND:
220 callback.web_callback_->onError(new blink::WebSetSinkIdError(
221 blink::WebSetSinkIdError::ErrorTypeNotFound, "Device not found"));
222 break;
223 case SWITCH_OUTPUT_DEVICE_RESULT_ERROR_NOT_AUTHORIZED:
224 callback.web_callback_->onError(new blink::WebSetSinkIdError(
225 blink::WebSetSinkIdError::ErrorTypeSecurity,
226 "No permission to access device"));
227 break;
228 case SWITCH_OUTPUT_DEVICE_RESULT_ERROR_OBSOLETE:
229 callback.web_callback_->onError(new blink::WebSetSinkIdError(
230 blink::WebSetSinkIdError::ErrorTypeAbort,
231 "The requested operation became obsolete and was aborted"));
232 break;
233 case SWITCH_OUTPUT_DEVICE_RESULT_ERROR_NOT_SUPPORTED:
234 callback.web_callback_->onError(new blink::WebSetSinkIdError(
235 blink::WebSetSinkIdError::ErrorTypeAbort,
236 "The requested operation cannot be performed and was aborted"));
237 break;
238 default:
239 NOTREACHED();
242 callback.web_callback_ = nullptr;
245 } // namespace
247 SwitchOutputDeviceCB ConvertToSwitchOutputDeviceCB(
248 WebSetSinkIdCB* web_callbacks) {
249 return media::BindToCurrentLoop(
250 base::Bind(RunSetSinkIdCallback, SetSinkIdCallback(web_callbacks)));
253 } // namespace media