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 CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_RESOURCE_HANDLER_H_
6#define CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_RESOURCE_HANDLER_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/browser/loader/resource_handler.h"
14#include "content/public/browser/download_interrupt_reasons.h"
15#include "content/public/browser/download_manager.h"
16#include "content/public/browser/download_save_info.h"
17#include "content/public/browser/download_url_parameters.h"
18
19namespace net {
20class URLRequest;
21}  // namespace net
22
23namespace content {
24class ByteStreamReader;
25class ByteStreamWriter;
26class DownloadRequestHandle;
27class PowerSaveBlocker;
28struct DownloadCreateInfo;
29
30// Forwards data to the download thread.
31class CONTENT_EXPORT DownloadResourceHandler
32    : public ResourceHandler,
33      public base::SupportsWeakPtr<DownloadResourceHandler> {
34 public:
35  struct DownloadTabInfo;
36
37  // Size of the buffer used between the DownloadResourceHandler and the
38  // downstream receiver of its output.
39  static const int kDownloadByteStreamSize;
40
41  // started_cb will be called exactly once on the UI thread.
42  // |id| should be invalid if the id should be automatically assigned.
43  DownloadResourceHandler(
44      uint32 id,
45      net::URLRequest* request,
46      const DownloadUrlParameters::OnStartedCallback& started_cb,
47      scoped_ptr<DownloadSaveInfo> save_info);
48
49  virtual bool OnUploadProgress(uint64 position, uint64 size) OVERRIDE;
50
51  virtual bool OnRequestRedirected(const GURL& url,
52                                   ResourceResponse* response,
53                                   bool* defer) OVERRIDE;
54
55  // Send the download creation information to the download thread.
56  virtual bool OnResponseStarted(ResourceResponse* response,
57                                 bool* defer) OVERRIDE;
58
59  // Pass-through implementation.
60  virtual bool OnWillStart(const GURL& url, bool* defer) OVERRIDE;
61
62  // Pass-through implementation.
63  virtual bool OnBeforeNetworkStart(const GURL& url, bool* defer) OVERRIDE;
64
65  // Create a new buffer, which will be handed to the download thread for file
66  // writing and deletion.
67  virtual bool OnWillRead(scoped_refptr<net::IOBuffer>* buf,
68                          int* buf_size,
69                          int min_size) OVERRIDE;
70
71  virtual bool OnReadCompleted(int bytes_read, bool* defer) OVERRIDE;
72
73  virtual void OnResponseCompleted(const net::URLRequestStatus& status,
74                                   const std::string& security_info,
75                                   bool* defer) OVERRIDE;
76
77  // N/A to this flavor of DownloadHandler.
78  virtual void OnDataDownloaded(int bytes_downloaded) OVERRIDE;
79
80  void PauseRequest();
81  void ResumeRequest();
82
83  // May result in this object being deleted by its owner.
84  void CancelRequest();
85
86  std::string DebugString() const;
87
88 private:
89  virtual ~DownloadResourceHandler();
90
91  // Arrange for started_cb_ to be called on the UI thread with the
92  // below values, nulling out started_cb_.  Should only be called
93  // on the IO thread.
94  void CallStartedCB(DownloadItem* item,
95                     DownloadInterruptReason interrupt_reason);
96
97  uint32 download_id_;
98  // This is read only on the IO thread, but may only
99  // be called on the UI thread.
100  DownloadUrlParameters::OnStartedCallback started_cb_;
101  scoped_ptr<DownloadSaveInfo> save_info_;
102
103  // Stores information about the download that must be acquired on the UI
104  // thread before StartOnUIThread is called.
105  // Created on IO thread, but only accessed on UI thread. |tab_info_| holds
106  // the pointer until we pass it off to StartOnUIThread or DeleteSoon.
107  DownloadTabInfo* tab_info_;
108
109  // Data flow
110  scoped_refptr<net::IOBuffer> read_buffer_;       // From URLRequest.
111  scoped_ptr<ByteStreamWriter> stream_writer_; // To rest of system.
112
113  // Keeps the system from sleeping while this ResourceHandler is alive. If the
114  // system enters power saving mode while a request is alive, it can cause the
115  // request to fail and the associated download will be interrupted.
116  scoped_ptr<PowerSaveBlocker> power_save_blocker_;
117
118  // The following are used to collect stats.
119  base::TimeTicks download_start_time_;
120  base::TimeTicks last_read_time_;
121  base::TimeTicks last_stream_pause_time_;
122  base::TimeDelta total_pause_time_;
123  size_t last_buffer_size_;
124  int64 bytes_read_;
125
126  int pause_count_;
127  bool was_deferred_;
128
129  // For DCHECKing
130  bool on_response_started_called_;
131
132  static const int kReadBufSize = 32768;  // bytes
133  static const int kThrottleTimeMs = 200;  // milliseconds
134
135  DISALLOW_COPY_AND_ASSIGN(DownloadResourceHandler);
136};
137
138}  // namespace content
139
140#endif  // CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_RESOURCE_HANDLER_H_
141