- add sources.
[platform/framework/web/crosswalk.git] / src / content / renderer / media / buffered_resource_loader.h
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 #ifndef CONTENT_RENDERER_MEDIA_BUFFERED_RESOURCE_LOADER_H_
6 #define CONTENT_RENDERER_MEDIA_BUFFERED_RESOURCE_LOADER_H_
7
8 #include <string>
9
10 #include "base/callback.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/timer/timer.h"
13 #include "content/common/content_export.h"
14 #include "content/renderer/media/active_loader.h"
15 #include "media/base/seekable_buffer.h"
16 #include "third_party/WebKit/public/platform/WebURLLoader.h"
17 #include "third_party/WebKit/public/platform/WebURLLoaderClient.h"
18 #include "third_party/WebKit/public/platform/WebURLRequest.h"
19 #include "third_party/WebKit/public/web/WebFrame.h"
20 #include "url/gurl.h"
21
22 namespace media {
23 class MediaLog;
24 class SeekableBuffer;
25 }
26
27 namespace content {
28
29 const int64 kPositionNotSpecified = -1;
30
31 const char kHttpScheme[] = "http";
32 const char kHttpsScheme[] = "https";
33
34 // BufferedResourceLoader is single threaded and must be accessed on the
35 // render thread. It wraps a WebURLLoader and does in-memory buffering,
36 // pausing resource loading when the in-memory buffer is full and resuming
37 // resource loading when there is available capacity.
38 class CONTENT_EXPORT BufferedResourceLoader
39     : NON_EXPORTED_BASE(public WebKit::WebURLLoaderClient) {
40  public:
41   // kNeverDefer - Aggresively buffer; never defer loading while paused.
42   // kReadThenDefer - Request only enough data to fulfill read requests.
43   // kCapacityDefer - Try to keep amount of buffered data at capacity.
44   enum DeferStrategy {
45     kNeverDefer,
46     kReadThenDefer,
47     kCapacityDefer,
48   };
49
50   // Status codes for start/read operations on BufferedResourceLoader.
51   enum Status {
52     // Everything went as planned.
53     kOk,
54
55     // The operation failed, which may have been due to:
56     //   - Page navigation
57     //   - Server replied 4xx/5xx
58     //   - The response was invalid
59     //   - Connection was terminated
60     //
61     // At this point you should delete the loader.
62     kFailed,
63
64     // The loader will never be able to satisfy the read request. Please stop,
65     // delete, create a new loader, and try again.
66     kCacheMiss,
67   };
68
69   // Keep in sync with WebMediaPlayer::CORSMode.
70   enum CORSMode { kUnspecified, kAnonymous, kUseCredentials };
71
72   enum LoadingState {
73     kLoading,  // Actively attempting to download data.
74     kLoadingDeferred,  // Loading intentionally deferred.
75     kLoadingFinished,  // Loading finished normally; no more data will arrive.
76     kLoadingFailed,  // Loading finished abnormally; no more data will arrive.
77   };
78
79   // |url| - URL for the resource to be loaded.
80   // |cors_mode| - HTML media element's crossorigin attribute.
81   // |first_byte_position| - First byte to start loading from,
82   // |kPositionNotSpecified| for not specified.
83   // |last_byte_position| - Last byte to be loaded,
84   // |kPositionNotSpecified| for not specified.
85   // |strategy| is the initial loading strategy to use.
86   // |bitrate| is the bitrate of the media, 0 if unknown.
87   // |playback_rate| is the current playback rate of the media.
88   BufferedResourceLoader(
89       const GURL& url,
90       CORSMode cors_mode,
91       int64 first_byte_position,
92       int64 last_byte_position,
93       DeferStrategy strategy,
94       int bitrate,
95       float playback_rate,
96       media::MediaLog* media_log);
97   virtual ~BufferedResourceLoader();
98
99   // Start the resource loading with the specified URL and range.
100   //
101   // |loading_cb| is executed when the loading state has changed.
102   // |progress_cb| is executed when additional data has arrived.
103   typedef base::Callback<void(Status)> StartCB;
104   typedef base::Callback<void(LoadingState)> LoadingStateChangedCB;
105   typedef base::Callback<void(int64)> ProgressCB;
106   void Start(const StartCB& start_cb,
107              const LoadingStateChangedCB& loading_cb,
108              const ProgressCB& progress_cb,
109              WebKit::WebFrame* frame);
110
111   // Stops everything associated with this loader, including active URL loads
112   // and pending callbacks.
113   //
114   // It is safe to delete a BufferedResourceLoader after calling Stop().
115   void Stop();
116
117   // Copies |read_size| bytes from |position| into |buffer|, executing |read_cb|
118   // when the operation has completed.
119   //
120   // The callback will contain the number of bytes read iff the status is kOk,
121   // zero otherwise.
122   //
123   // If necessary will temporarily increase forward capacity of buffer to
124   // accomodate an unusually large read.
125   typedef base::Callback<void(Status, int)> ReadCB;
126   void Read(int64 position, int read_size,
127             uint8* buffer, const ReadCB& read_cb);
128
129   // Gets the content length in bytes of the instance after this loader has been
130   // started. If this value is |kPositionNotSpecified|, then content length is
131   // unknown.
132   int64 content_length();
133
134   // Gets the original size of the file requested. If this value is
135   // |kPositionNotSpecified|, then the size is unknown.
136   int64 instance_size();
137
138   // Returns true if the server supports byte range requests.
139   bool range_supported();
140
141   // WebKit::WebURLLoaderClient implementation.
142   virtual void willSendRequest(
143       WebKit::WebURLLoader* loader,
144       WebKit::WebURLRequest& newRequest,
145       const WebKit::WebURLResponse& redirectResponse);
146   virtual void didSendData(
147       WebKit::WebURLLoader* loader,
148       unsigned long long bytesSent,
149       unsigned long long totalBytesToBeSent);
150   virtual void didReceiveResponse(
151       WebKit::WebURLLoader* loader,
152       const WebKit::WebURLResponse& response);
153   virtual void didDownloadData(
154       WebKit::WebURLLoader* loader,
155       int data_length,
156       int encoded_data_length);
157   virtual void didReceiveData(
158       WebKit::WebURLLoader* loader,
159       const char* data,
160       int data_length,
161       int encoded_data_length);
162   virtual void didReceiveCachedMetadata(
163       WebKit::WebURLLoader* loader,
164       const char* data, int dataLength);
165   virtual void didFinishLoading(
166       WebKit::WebURLLoader* loader,
167       double finishTime);
168   virtual void didFail(
169       WebKit::WebURLLoader* loader,
170       const WebKit::WebURLError&);
171
172   // Returns true if the media resource has a single origin, false otherwise.
173   // Only valid to call after Start() has completed.
174   bool HasSingleOrigin() const;
175
176   // Returns true if the media resource passed a CORS access control check.
177   // Only valid to call after Start() has completed.
178   bool DidPassCORSAccessCheck() const;
179
180   // Sets the defer strategy to the given value unless it seems unwise.
181   // Specifically downgrade kNeverDefer to kCapacityDefer if we know the
182   // current response will not be used to satisfy future requests (the cache
183   // won't help us).
184   void UpdateDeferStrategy(DeferStrategy strategy);
185
186   // Sets the playback rate to the given value and updates buffer window
187   // accordingly.
188   void SetPlaybackRate(float playback_rate);
189
190   // Sets the bitrate to the given value and updates buffer window
191   // accordingly.
192   void SetBitrate(int bitrate);
193
194   // Return the |first_byte_position| passed into the ctor.
195   int64 first_byte_position() const;
196
197   // Parse a Content-Range header into its component pieces and return true if
198   // each of the expected elements was found & parsed correctly.
199   // |*instance_size| may be set to kPositionNotSpecified if the range ends in
200   // "/*".
201   // NOTE: only public for testing!  This is an implementation detail of
202   // VerifyPartialResponse (a private method).
203   static bool ParseContentRange(
204       const std::string& content_range_str, int64* first_byte_position,
205       int64* last_byte_position, int64* instance_size);
206
207  private:
208   friend class BufferedDataSourceTest;
209   friend class BufferedResourceLoaderTest;
210   friend class MockBufferedDataSource;
211
212   // Updates the |buffer_|'s forward and backward capacities.
213   void UpdateBufferWindow();
214
215   // Updates deferring behavior based on current buffering scheme.
216   void UpdateDeferBehavior();
217
218   // Sets |active_loader_|'s defer state and fires |loading_cb_| if the state
219   // changed.
220   void SetDeferred(bool deferred);
221
222   // Returns true if we should defer resource loading based on the current
223   // buffering scheme.
224   bool ShouldDefer() const;
225
226   // Returns true if the current read request can be fulfilled by what is in
227   // the buffer.
228   bool CanFulfillRead() const;
229
230   // Returns true if the current read request will be fulfilled in the future.
231   bool WillFulfillRead() const;
232
233   // Method that does the actual read and calls the |read_cb_|, assuming the
234   // request range is in |buffer_|.
235   void ReadInternal();
236
237   // If we have made a range request, verify the response from the server.
238   bool VerifyPartialResponse(const WebKit::WebURLResponse& response);
239
240   // Returns the value for a range request header using parameters
241   // |first_byte_position| and |last_byte_position|. Negative numbers other
242   // than |kPositionNotSpecified| are not allowed for |first_byte_position| and
243   // |last_byte_position|. |first_byte_position| should always be less than or
244   // equal to |last_byte_position| if they are both not |kPositionNotSpecified|.
245   // Empty string is returned on invalid parameters.
246   std::string GenerateHeaders(int64 first_byte_position,
247                               int64 last_byte_position);
248
249   // Done with read. Invokes the read callback and reset parameters for the
250   // read request.
251   void DoneRead(Status status, int bytes_read);
252
253   // Done with start. Invokes the start callback and reset it.
254   void DoneStart(Status status);
255
256   bool HasPendingRead() { return !read_cb_.is_null(); }
257
258   // Helper function that returns true if a range request was specified.
259   bool IsRangeRequest() const;
260
261   // Log everything interesting to |media_log_|.
262   void Log();
263
264   // A sliding window of buffer.
265   media::SeekableBuffer buffer_;
266
267   // Keeps track of an active WebURLLoader and associated state.
268   scoped_ptr<ActiveLoader> active_loader_;
269
270   // Tracks if |active_loader_| failed. If so, then all calls to Read() will
271   // fail.
272   bool loader_failed_;
273
274   // Current buffering algorithm in place for resource loading.
275   DeferStrategy defer_strategy_;
276
277   // True if the currently-reading response might be used to satisfy a future
278   // request from the cache.
279   bool might_be_reused_from_cache_in_future_;
280
281   // True if Range header is supported.
282   bool range_supported_;
283
284   // Forward capacity to reset to after an extension.
285   size_t saved_forward_capacity_;
286
287   GURL url_;
288   CORSMode cors_mode_;
289   const int64 first_byte_position_;
290   const int64 last_byte_position_;
291   bool single_origin_;
292
293   // Executed whenever the state of resource loading has changed.
294   LoadingStateChangedCB loading_cb_;
295
296   // Executed whenever additional data has been downloaded and reports the
297   // zero-indexed file offset of the furthest buffered byte.
298   ProgressCB progress_cb_;
299
300   // Members used during request start.
301   StartCB start_cb_;
302   int64 offset_;
303   int64 content_length_;
304   int64 instance_size_;
305
306   // Members used during a read operation. They should be reset after each
307   // read has completed or failed.
308   ReadCB read_cb_;
309   int64 read_position_;
310   int read_size_;
311   uint8* read_buffer_;
312
313   // Offsets of the requested first byte and last byte in |buffer_|. They are
314   // written by Read().
315   int first_offset_;
316   int last_offset_;
317
318   // Injected WebURLLoader instance for testing purposes.
319   scoped_ptr<WebKit::WebURLLoader> test_loader_;
320
321   // Bitrate of the media. Set to 0 if unknown.
322   int bitrate_;
323
324   // Playback rate of the media.
325   float playback_rate_;
326
327   scoped_refptr<media::MediaLog> media_log_;
328
329   DISALLOW_COPY_AND_ASSIGN(BufferedResourceLoader);
330 };
331
332 }  // namespace content
333
334 #endif  // CONTENT_RENDERER_MEDIA_BUFFERED_RESOURCE_LOADER_H_