Home | History | Annotate | Download | only in media
      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 
    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