• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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 WEBKIT_GLUE_MEDIA_BUFFERED_RESOURCE_LOADER_H_
6 #define WEBKIT_GLUE_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.h"
13 #include "googleurl/src/gurl.h"
14 #include "media/base/seekable_buffer.h"
15 #include "net/base/file_stream.h"
16 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
17 #include "third_party/WebKit/Source/WebKit/chromium/public/WebURLLoader.h"
18 #include "third_party/WebKit/Source/WebKit/chromium/public/WebURLLoaderClient.h"
19 #include "third_party/WebKit/Source/WebKit/chromium/public/WebURLRequest.h"
20 #include "webkit/glue/media/web_data_source.h"
21 #include "webkit/glue/webmediaplayer_impl.h"
22 
23 namespace webkit_glue {
24 
25 const int64 kPositionNotSpecified = -1;
26 
27 const char kHttpScheme[] = "http";
28 const char kHttpsScheme[] = "https";
29 const char kDataScheme[] = "data";
30 
31 // This class works inside demuxer thread and render thread. It contains a
32 // WebURLLoader and does the actual resource loading. This object does
33 // buffering internally, it defers the resource loading if buffer is full
34 // and un-defers the resource loading if it is under buffered.
35 class BufferedResourceLoader :
36     public base::RefCountedThreadSafe<BufferedResourceLoader>,
37     public WebKit::WebURLLoaderClient {
38  public:
39   // kNeverDefer - Aggresively buffer; never defer loading while paused.
40   // kReadThenDefer - Request only enough data to fulfill read requests.
41   // kThresholdDefer - Try to keep amount of buffered data at a threshold.
42   enum DeferStrategy {
43     kNeverDefer,
44     kReadThenDefer,
45     kThresholdDefer,
46   };
47 
48   typedef Callback0::Type NetworkEventCallback;
49 
50   // |url| - URL for the resource to be loaded.
51   // |first_byte_position| - First byte to start loading from,
52   // |kPositionNotSpecified| for not specified.
53   // |last_byte_position| - Last byte to be loaded,
54   // |kPositionNotSpecified| for not specified.
55   BufferedResourceLoader(const GURL& url,
56                          int64 first_byte_position,
57                          int64 last_byte_position);
58 
59   // Start the resource loading with the specified URL and range.
60   // This method operates in asynchronous mode. Once there's a response from the
61   // server, success or fail |callback| is called with the result.
62   // |callback| is called with the following values:
63   // - net::OK
64   //   The request has started successfully.
65   // - net::ERR_FAILED
66   //   The request has failed because of an error with the network.
67   // - net::ERR_INVALID_RESPONSE
68   //   An invalid response is received from the server.
69   // - (Anything else)
70   //   An error code that indicates the request has failed.
71   // |event_callback| is called when the response is completed, data is
72   // received, the request is suspended or resumed.
73   virtual void Start(net::CompletionCallback* callback,
74                      NetworkEventCallback* event_callback,
75                      WebKit::WebFrame* frame);
76 
77   // Stop this loader, cancels and request and release internal buffer.
78   virtual void Stop();
79 
80   // Reads the specified |read_size| from |position| into |buffer| and when
81   // the operation is done invoke |callback| with number of bytes read or an
82   // error code.
83   // |callback| is called with the following values:
84   // - (Anything greater than or equal 0)
85   //   Read was successful with the indicated number of bytes read.
86   // - net::ERR_FAILED
87   //   The read has failed because of an error with the network.
88   // - net::ERR_CACHE_MISS
89   //   The read was made too far away from the current buffered position.
90   virtual void Read(int64 position, int read_size,
91                     uint8* buffer, net::CompletionCallback* callback);
92 
93   // Returns the position of the last byte buffered. Returns
94   // |kPositionNotSpecified| if such value is not available.
95   virtual int64 GetBufferedPosition();
96 
97   // Gets the content length in bytes of the instance after this loader has been
98   // started. If this value is |kPositionNotSpecified|, then content length is
99   // unknown.
100   virtual int64 content_length();
101 
102   // Gets the original size of the file requested. If this value is
103   // |kPositionNotSpecified|, then the size is unknown.
104   virtual int64 instance_size();
105 
106   // Returns true if the server supports byte range requests.
107   virtual bool range_supported();
108 
109   // Returns true if network is currently active.
110   virtual bool network_activity();
111 
112   // Returns resulting URL.
113   virtual const GURL& url();
114 
115   // Used to inject a mock used for unittests.
116   virtual void SetURLLoaderForTest(WebKit::WebURLLoader* mock_loader);
117 
118   // WebKit::WebURLLoaderClient implementation.
119   virtual void willSendRequest(
120       WebKit::WebURLLoader* loader,
121       WebKit::WebURLRequest& newRequest,
122       const WebKit::WebURLResponse& redirectResponse);
123   virtual void didSendData(
124       WebKit::WebURLLoader* loader,
125       unsigned long long bytesSent,
126       unsigned long long totalBytesToBeSent);
127   virtual void didReceiveResponse(
128       WebKit::WebURLLoader* loader,
129       const WebKit::WebURLResponse& response);
130   virtual void didDownloadData(
131       WebKit::WebURLLoader* loader,
132       int data_length);
133   virtual void didReceiveData(
134       WebKit::WebURLLoader* loader,
135       const char* data,
136       int data_length,
137       int encoded_data_length);
138   virtual void didReceiveCachedMetadata(
139       WebKit::WebURLLoader* loader,
140       const char* data, int dataLength);
141   virtual void didFinishLoading(
142       WebKit::WebURLLoader* loader,
143       double finishTime);
144   virtual void didFail(
145       WebKit::WebURLLoader* loader,
146       const WebKit::WebURLError&);
147 
148   bool HasSingleOrigin() const;
149 
150   // Sets the defer strategy to the given value.
151   void UpdateDeferStrategy(DeferStrategy strategy);
152 
153  protected:
154   friend class base::RefCountedThreadSafe<BufferedResourceLoader>;
155   virtual ~BufferedResourceLoader();
156 
157  private:
158   friend class BufferedResourceLoaderTest;
159 
160   // Toggles whether the resource loading is deferred or not.
161   // Returns true if a network event was fired.
162   bool ToggleDeferring();
163 
164   // Returns true if we should defer resource loading, based
165   // on current buffering scheme.
166   bool ShouldEnableDefer();
167 
168   // Returns true if we should enable resource loading, based
169   // on current buffering scheme.
170   bool ShouldDisableDefer();
171 
172   // Updates deferring behavior based on current buffering scheme.
173   void UpdateDeferBehavior();
174 
175   // Returns true if the current read request can be fulfilled by what is in
176   // the buffer.
177   bool CanFulfillRead();
178 
179   // Returns true if the current read request will be fulfilled in the future.
180   bool WillFulfillRead();
181 
182   // Method that does the actual read and calls the |read_callback_|, assuming
183   // the request range is in |buffer_|.
184   void ReadInternal();
185 
186   // If we have made a range request, verify the response from the server.
187   bool VerifyPartialResponse(const WebKit::WebURLResponse& response);
188 
189   // Returns the value for a range request header using parameters
190   // |first_byte_position| and |last_byte_position|. Negative numbers other
191   // than |kPositionNotSpecified| are not allowed for |first_byte_position| and
192   // |last_byte_position|. |first_byte_position| should always be less than or
193   // equal to |last_byte_position| if they are both not |kPositionNotSpecified|.
194   // Empty string is returned on invalid parameters.
195   std::string GenerateHeaders(int64 first_byte_position,
196                               int64 last_byte_position);
197 
198   // Done with read. Invokes the read callback and reset parameters for the
199   // read request.
200   void DoneRead(int error);
201 
202   // Done with start. Invokes the start callback and reset it.
203   void DoneStart(int error);
204 
205   // Calls |event_callback_| in terms of a network event.
206   void NotifyNetworkEvent();
207 
HasPendingRead()208   bool HasPendingRead() { return read_callback_.get() != NULL; }
209 
210   // Helper function that returns true if a range request was specified.
211   bool IsRangeRequest() const;
212 
213   // A sliding window of buffer.
214   scoped_ptr<media::SeekableBuffer> buffer_;
215 
216   // True if resource loading was deferred.
217   bool deferred_;
218 
219   // Current buffering algorithm in place for resource loading.
220   DeferStrategy defer_strategy_;
221 
222   // True if resource loading has completed.
223   bool completed_;
224 
225   // True if a range request was made.
226   bool range_requested_;
227 
228   // True if Range header is supported.
229   bool range_supported_;
230 
231   // Does the work of loading and sends data back to this client.
232   scoped_ptr<WebKit::WebURLLoader> url_loader_;
233 
234   GURL url_;
235   int64 first_byte_position_;
236   int64 last_byte_position_;
237   bool single_origin_;
238 
239   // Callback method that listens to network events.
240   scoped_ptr<NetworkEventCallback> event_callback_;
241 
242   // Members used during request start.
243   scoped_ptr<net::CompletionCallback> start_callback_;
244   int64 offset_;
245   int64 content_length_;
246   int64 instance_size_;
247 
248   // Members used during a read operation. They should be reset after each
249   // read has completed or failed.
250   scoped_ptr<net::CompletionCallback> read_callback_;
251   int64 read_position_;
252   int read_size_;
253   uint8* read_buffer_;
254 
255   // Offsets of the requested first byte and last byte in |buffer_|. They are
256   // written by Read().
257   int first_offset_;
258   int last_offset_;
259 
260   // Used to ensure mocks for unittests are used instead of reset in Start().
261   bool keep_test_loader_;
262 
263   DISALLOW_COPY_AND_ASSIGN(BufferedResourceLoader);
264 };
265 
266 }  // namespace webkit_glue
267 
268 #endif  // WEBKIT_GLUE_MEDIA_BUFFERED_RESOURCE_LOADER_H_
269