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