Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / content / renderer / media / android / media_info_loader.cc
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.
4
5 #include "content/renderer/media/android/media_info_loader.h"
6
7 #include "base/bits.h"
8 #include "base/callback_helpers.h"
9 #include "base/metrics/histogram.h"
10 #include "third_party/WebKit/public/platform/WebURLError.h"
11 #include "third_party/WebKit/public/platform/WebURLLoader.h"
12 #include "third_party/WebKit/public/platform/WebURLResponse.h"
13 #include "third_party/WebKit/public/web/WebFrame.h"
14
15 using blink::WebFrame;
16 using blink::WebURLError;
17 using blink::WebURLLoader;
18 using blink::WebURLLoaderOptions;
19 using blink::WebURLRequest;
20 using blink::WebURLResponse;
21
22 namespace content {
23
24 static const int kHttpOK = 200;
25
26 MediaInfoLoader::MediaInfoLoader(
27     const GURL& url,
28     blink::WebMediaPlayer::CORSMode cors_mode,
29     const ReadyCB& ready_cb)
30     : loader_failed_(false),
31       url_(url),
32       cors_mode_(cors_mode),
33       single_origin_(true),
34       ready_cb_(ready_cb) {}
35
36 MediaInfoLoader::~MediaInfoLoader() {}
37
38 void MediaInfoLoader::Start(blink::WebFrame* frame) {
39   // Make sure we have not started.
40   DCHECK(!ready_cb_.is_null());
41   CHECK(frame);
42
43   start_time_ = base::TimeTicks::Now();
44
45   // Prepare the request.
46   WebURLRequest request(url_);
47   request.setTargetType(WebURLRequest::TargetIsMedia);
48   frame->setReferrerForRequest(request, blink::WebURL());
49
50   scoped_ptr<WebURLLoader> loader;
51   if (test_loader_) {
52     loader = test_loader_.Pass();
53   } else {
54     WebURLLoaderOptions options;
55     if (cors_mode_ == blink::WebMediaPlayer::CORSModeUnspecified) {
56       options.allowCredentials = true;
57       options.crossOriginRequestPolicy =
58           WebURLLoaderOptions::CrossOriginRequestPolicyAllow;
59     } else {
60       options.exposeAllResponseHeaders = true;
61       // The author header set is empty, no preflight should go ahead.
62       options.preflightPolicy = WebURLLoaderOptions::PreventPreflight;
63       options.crossOriginRequestPolicy =
64           WebURLLoaderOptions::CrossOriginRequestPolicyUseAccessControl;
65       if (cors_mode_ == blink::WebMediaPlayer::CORSModeUseCredentials)
66         options.allowCredentials = true;
67     }
68     loader.reset(frame->createAssociatedURLLoader(options));
69   }
70
71   // Start the resource loading.
72   loader->loadAsynchronously(request, this);
73   active_loader_.reset(new ActiveLoader(loader.Pass()));
74 }
75
76 /////////////////////////////////////////////////////////////////////////////
77 // blink::WebURLLoaderClient implementation.
78 void MediaInfoLoader::willSendRequest(
79     WebURLLoader* loader,
80     WebURLRequest& newRequest,
81     const WebURLResponse& redirectResponse) {
82   // The load may have been stopped and |ready_cb| is destroyed.
83   // In this case we shouldn't do anything.
84   if (ready_cb_.is_null()) {
85     // Set the url in the request to an invalid value (empty url).
86     newRequest.setURL(blink::WebURL());
87     return;
88   }
89
90   // Only allow |single_origin_| if we haven't seen a different origin yet.
91   if (single_origin_)
92     single_origin_ = url_.GetOrigin() == GURL(newRequest.url()).GetOrigin();
93
94   url_ = newRequest.url();
95 }
96
97 void MediaInfoLoader::didSendData(
98     WebURLLoader* loader,
99     unsigned long long bytes_sent,
100     unsigned long long total_bytes_to_be_sent) {
101   NOTIMPLEMENTED();
102 }
103
104 void MediaInfoLoader::didReceiveResponse(
105     WebURLLoader* loader,
106     const WebURLResponse& response) {
107   DVLOG(1) << "didReceiveResponse: HTTP/"
108            << (response.httpVersion() == WebURLResponse::HTTP_0_9 ? "0.9" :
109                response.httpVersion() == WebURLResponse::HTTP_1_0 ? "1.0" :
110                response.httpVersion() == WebURLResponse::HTTP_1_1 ? "1.1" :
111                "Unknown")
112            << " " << response.httpStatusCode();
113   DCHECK(active_loader_.get());
114   if (!url_.SchemeIs("http") && !url_.SchemeIs("https")) {
115       DidBecomeReady(kOk);
116       return;
117   }
118   if (response.httpStatusCode() == kHttpOK) {
119     DidBecomeReady(kOk);
120     return;
121   }
122   loader_failed_ = true;
123   DidBecomeReady(kFailed);
124 }
125
126 void MediaInfoLoader::didReceiveData(
127     WebURLLoader* loader,
128     const char* data,
129     int data_length,
130     int encoded_data_length) {
131   // Ignored.
132 }
133
134 void MediaInfoLoader::didDownloadData(
135     blink::WebURLLoader* loader,
136     int dataLength,
137     int encodedDataLength) {
138   NOTIMPLEMENTED();
139 }
140
141 void MediaInfoLoader::didReceiveCachedMetadata(
142     WebURLLoader* loader,
143     const char* data,
144     int data_length) {
145   NOTIMPLEMENTED();
146 }
147
148 void MediaInfoLoader::didFinishLoading(
149     WebURLLoader* loader,
150     double finishTime,
151     int64_t total_encoded_data_length) {
152   DCHECK(active_loader_.get());
153   DidBecomeReady(kOk);
154 }
155
156 void MediaInfoLoader::didFail(
157     WebURLLoader* loader,
158     const WebURLError& error) {
159   DVLOG(1) << "didFail: reason=" << error.reason
160            << ", isCancellation=" << error.isCancellation
161            << ", domain=" << error.domain.utf8().data()
162            << ", localizedDescription="
163            << error.localizedDescription.utf8().data();
164   DCHECK(active_loader_.get());
165   loader_failed_ = true;
166   DidBecomeReady(kFailed);
167 }
168
169 bool MediaInfoLoader::HasSingleOrigin() const {
170   DCHECK(ready_cb_.is_null())
171       << "Must become ready before calling HasSingleOrigin()";
172   return single_origin_;
173 }
174
175 bool MediaInfoLoader::DidPassCORSAccessCheck() const {
176   DCHECK(ready_cb_.is_null())
177       << "Must become ready before calling DidPassCORSAccessCheck()";
178   return !loader_failed_ &&
179       cors_mode_ != blink::WebMediaPlayer::CORSModeUnspecified;
180 }
181
182 /////////////////////////////////////////////////////////////////////////////
183 // Helper methods.
184
185 void MediaInfoLoader::DidBecomeReady(Status status) {
186   UMA_HISTOGRAM_TIMES("Media.InfoLoadDelay",
187                       base::TimeTicks::Now() - start_time_);
188   active_loader_.reset();
189   if (!ready_cb_.is_null())
190     base::ResetAndReturn(&ready_cb_).Run(status);
191 }
192
193 }  // namespace content