- add sources.
[platform/framework/web/crosswalk.git] / src / ppapi / native_client / src / trusted / plugin / file_downloader.h
1 // Copyright (c) 2012 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 NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_FILE_DOWNLOADER_H_
6 #define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_FILE_DOWNLOADER_H_
7
8 #include <deque>
9
10 #include "native_client/src/include/nacl_macros.h"
11 #include "native_client/src/include/nacl_string.h"
12 #include "native_client/src/trusted/validator/nacl_file_info.h"
13 #include "ppapi/c/private/pp_file_handle.h"
14 #include "ppapi/c/private/ppb_file_io_private.h"
15 #include "ppapi/c/trusted/ppb_url_loader_trusted.h"
16 #include "ppapi/cpp/file_io.h"
17 #include "ppapi/cpp/instance.h"
18 #include "ppapi/cpp/url_loader.h"
19 #include "ppapi/cpp/url_response_info.h"
20 #include "ppapi/native_client/src/trusted/plugin/callback_source.h"
21 #include "ppapi/utility/completion_callback_factory.h"
22
23 namespace plugin {
24
25 class Plugin;
26
27 typedef enum {
28   DOWNLOAD_TO_FILE = 0,
29   DOWNLOAD_TO_BUFFER,
30   DOWNLOAD_STREAM,
31   DOWNLOAD_NONE
32 } DownloadMode;
33
34 typedef enum {
35   SCHEME_CHROME_EXTENSION,
36   SCHEME_DATA,
37   SCHEME_OTHER
38 } UrlSchemeType;
39
40 typedef std::vector<char>* FileStreamData;
41 typedef CallbackSource<FileStreamData> StreamCallbackSource;
42 typedef pp::CompletionCallbackWithOutput<FileStreamData> StreamCallback;
43
44 // A class that wraps PPAPI URLLoader and FileIO functionality for downloading
45 // the url into a file and providing an open file descriptor.
46 class FileDownloader {
47  public:
48   // Ctor initializes |instance_| to NULL, be sure to call Initialize() before
49   // calling Open(), or Open() will fail.
50   FileDownloader()
51       : instance_(NULL),
52         file_open_notify_callback_(pp::BlockUntilComplete()),
53         stream_finish_callback_(pp::BlockUntilComplete()),
54         file_handle_(PP_kInvalidFileHandle),
55         file_io_private_interface_(NULL),
56         url_loader_trusted_interface_(NULL),
57         open_time_(-1),
58         mode_(DOWNLOAD_NONE),
59         open_and_stream_(true),
60         url_scheme_(SCHEME_OTHER),
61         data_stream_callback_source_(NULL) {}
62   ~FileDownloader() {}
63
64   // Initialize() can only be called once during the lifetime of this instance.
65   void Initialize(Plugin* instance);
66
67   // Issues a GET on |url| to start downloading the response into a file,
68   // and finish streaming it. |callback| will be run after streaming is
69   // done or if an error prevents streaming from completing.
70   // Returns true when callback is scheduled to be called on success or failure.
71   // Returns false if callback is NULL, Initialize() has not been called or if
72   // the PPB_FileIO_Trusted interface is not available.
73   // If |record_progress| is true, then download progress will be recorded,
74   // and can be polled through GetDownloadProgress().
75   // If |progress_callback| is not NULL and |record_progress| is true,
76   // then the callback will be invoked for every progress update received
77   // by the loader.
78   bool Open(const nacl::string& url,
79             DownloadMode mode,
80             const pp::CompletionCallback& callback,
81             bool record_progress,
82             PP_URLLoaderTrusted_StatusCallback progress_callback);
83
84   // Similar to Open(), but used for streaming the |url| data directly to the
85   // caller without writing to a temporary file. The callbacks provided by
86   // |stream_callback_source| are expected to copy the data before returning.
87   // |callback| is called once the response headers are received,
88   // and streaming must be completed separately via FinishStreaming().
89   bool OpenStream(const nacl::string& url,
90                   const pp::CompletionCallback& callback,
91                   StreamCallbackSource* stream_callback_source);
92
93   // Finish streaming the response body for a URL request started by either
94   // Open() or OpenStream().  If DownloadMode is DOWNLOAD_TO_FILE,
95   // then the response body is streamed to a file, the file is opened and
96   // a file descriptor is made available.  Runs the given |callback| when
97   // streaming is done.
98   void FinishStreaming(const pp::CompletionCallback& callback);
99
100   // Bypasses downloading and takes a handle to the open file. To get the fd,
101   // call GetFileInfo().
102   void OpenFast(const nacl::string& url, PP_FileHandle file_handle,
103                 uint64_t file_token_lo, uint64_t file_token_hi);
104
105   // Return a structure describing the file opened, including a file desc.
106   // If downloading and opening succeeded, this returns a valid read-only
107   // POSIX file descriptor.  On failure, the return value is an invalid
108   // descriptor.  The file descriptor is owned by this instance, so the
109   // delegate does not have to close it.
110   struct NaClFileInfo GetFileInfo();
111
112   // Returns the time delta between the call to Open() and this function.
113   int64_t TimeSinceOpenMilliseconds() const;
114
115   // The value of |url_| changes over the life of this instance.  When the file
116   // is first opened, |url_| is a copy of the URL used to open the file, which
117   // can be a relative URL.  Once the GET request has finished, and the contents
118   // of the file represented by |url_| are available, |url_| is the full URL
119   // including the scheme, host and full path.
120   const nacl::string& url() const { return url_; }
121
122   // Returns the url passed to Open().
123   const nacl::string& url_to_open() const { return url_to_open_; }
124
125   // Returns the PP_Resource of the active URL loader, or kInvalidResource.
126   PP_Resource url_loader() const { return url_loader_.pp_resource(); }
127
128   // GetDownloadProgress() returns the current download progress, which is
129   // meaningful after Open() has been called. Progress only refers to the
130   // response body and does not include the headers.
131   //
132   // This data is only available if the |record_progress| true in the
133   // Open() call.  If progress is being recorded, then |bytes_received|
134   // will be set to the number of bytes received thus far,
135   // and |total_bytes_to_be_received| will be set to the total number
136   // of bytes to be received.  The total bytes to be received may be unknown,
137   // in which case |total_bytes_to_be_received| will be set to -1.
138   bool GetDownloadProgress(int64_t* bytes_received,
139                            int64_t* total_bytes_to_be_received) const;
140
141   // Returns the buffer used for DOWNLOAD_TO_BUFFER mode.
142   const std::deque<char>& buffer() const { return buffer_; }
143
144   bool streaming_to_file() const;
145   bool streaming_to_buffer() const;
146   bool streaming_to_user() const;
147   bool not_streaming() const;
148
149   int status_code() const { return status_code_; }
150   nacl::string GetResponseHeaders() const;
151
152   void set_request_headers(const nacl::string& extra_request_headers) {
153     extra_request_headers_ = extra_request_headers;
154   }
155
156
157  private:
158   NACL_DISALLOW_COPY_AND_ASSIGN(FileDownloader);
159   // This class loads and opens the file in three steps for DOWNLOAD_TO_FILE:
160   //   1) Ask the browser to start streaming |url_| as a file.
161   //   2) Ask the browser to finish streaming if headers indicate success.
162   //   3) Ask the browser to open the file, so we can get the file descriptor.
163   // For DOWNLOAD_TO_BUFFER, the process is very similar:
164   //   1) Ask the browser to start streaming |url_| to an internal buffer.
165   //   2) Ask the browser to finish streaming to |temp_buffer_| on success.
166   //   3) Wait for streaming to finish, filling |buffer_| incrementally.
167   // Each step is done asynchronously using callbacks.  We create callbacks
168   // through a factory to take advantage of ref-counting.
169   // DOWNLOAD_STREAM is similar to DOWNLOAD_TO_BUFFER except the downloaded
170   // data is passed directly to the user instead of saved in a buffer.
171   // The public Open*() functions start step 1), and the public FinishStreaming
172   // function proceeds to step 2) and 3).
173   bool InitialResponseIsValid();
174   void URLLoadStartNotify(int32_t pp_error);
175   void URLLoadFinishNotify(int32_t pp_error);
176   void URLReadBodyNotify(int32_t pp_error);
177   void StreamFinishNotify(int32_t pp_error);
178   void GotFileHandleNotify(int32_t pp_error, PP_FileHandle handle);
179
180   Plugin* instance_;
181   nacl::string url_to_open_;
182   nacl::string url_;
183   nacl::string extra_request_headers_;
184   pp::URLResponseInfo url_response_;
185   pp::CompletionCallback file_open_notify_callback_;
186   pp::CompletionCallback stream_finish_callback_;
187   pp::FileIO file_reader_;
188   PP_FileHandle file_handle_;
189   struct NaClFileToken file_token_;
190   const PPB_FileIO_Private* file_io_private_interface_;
191   const PPB_URLLoaderTrusted* url_loader_trusted_interface_;
192   pp::URLLoader url_loader_;
193   pp::CompletionCallbackFactory<FileDownloader> callback_factory_;
194   int64_t open_time_;
195   int32_t status_code_;
196   DownloadMode mode_;
197   bool open_and_stream_;
198   static const uint32_t kTempBufferSize = 2048;
199   std::vector<char> temp_buffer_;
200   std::deque<char> buffer_;
201   UrlSchemeType url_scheme_;
202   StreamCallbackSource* data_stream_callback_source_;
203   NaClFileInfo cached_file_info_;
204 };
205 }  // namespace plugin;
206 #endif  // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_FILE_DOWNLOADER_H_