OLD | NEW |
| (Empty) |
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 CHROME_BROWSER_POLICY_CLOUD_EXTERNAL_POLICY_DATA_FETCHER_H_ | |
6 #define CHROME_BROWSER_POLICY_CLOUD_EXTERNAL_POLICY_DATA_FETCHER_H_ | |
7 | |
8 #include <map> | |
9 #include <set> | |
10 #include <string> | |
11 | |
12 #include "base/basictypes.h" | |
13 #include "base/callback.h" | |
14 #include "base/compiler_specific.h" | |
15 #include "base/memory/ref_counted.h" | |
16 #include "base/memory/scoped_ptr.h" | |
17 #include "base/memory/weak_ptr.h" | |
18 #include "net/url_request/url_fetcher_delegate.h" | |
19 #include "url/gurl.h" | |
20 | |
21 namespace base { | |
22 class SequencedTaskRunner; | |
23 } | |
24 | |
25 namespace net { | |
26 class URLFetcher; | |
27 class URLRequestContextGetter; | |
28 } | |
29 | |
30 namespace policy { | |
31 | |
32 class ExternalPolicyDataFetcherBackend; | |
33 | |
34 // This class handles network fetch jobs for the ExternalPolicyDataUpdater by | |
35 // forwarding them to an ExternalPolicyDataFetcherBackend running on a different | |
36 // thread. This is necessary because the ExternalPolicyDataUpdater runs on a | |
37 // background thread where network I/O is not allowed. | |
38 // The class can be instantiated on any thread but from then on, it must be | |
39 // accessed and destroyed on the background thread that the | |
40 // ExternalPolicyDataUpdater runs on only. | |
41 class ExternalPolicyDataFetcher { | |
42 public: | |
43 // The result of a fetch job. | |
44 enum Result { | |
45 // Successful fetch. | |
46 SUCCESS, | |
47 // The connection was interrupted. | |
48 CONNECTION_INTERRUPTED, | |
49 // Another network error occurred. | |
50 NETWORK_ERROR, | |
51 // Problem at the server. | |
52 SERVER_ERROR, | |
53 // Client error. | |
54 CLIENT_ERROR, | |
55 // Any other type of HTTP failure. | |
56 HTTP_ERROR, | |
57 // Received data exceeds maximum allowed size. | |
58 MAX_SIZE_EXCEEDED, | |
59 }; | |
60 | |
61 // Encapsulates the metadata for a fetch job. | |
62 struct Job; | |
63 | |
64 // Callback invoked when a fetch job finishes. If the fetch was successful, | |
65 // the Result is SUCCESS and the scoped_ptr contains the retrieved data. | |
66 // Otherwise, Result indicates the type of error that occurred and the | |
67 // scoped_ptr is NULL. | |
68 typedef base::Callback<void(Result, scoped_ptr<std::string>)> FetchCallback; | |
69 | |
70 // |task_runner| represents the background thread that |this| runs on. | |
71 // |backend| is used to perform network I/O. It will be dereferenced and | |
72 // accessed via |io_task_runner| only. | |
73 ExternalPolicyDataFetcher( | |
74 scoped_refptr<base::SequencedTaskRunner> task_runner, | |
75 scoped_refptr<base::SequencedTaskRunner> io_task_runner, | |
76 const base::WeakPtr<ExternalPolicyDataFetcherBackend>& backend); | |
77 ~ExternalPolicyDataFetcher(); | |
78 | |
79 // Fetch data from |url| and invoke |callback| with the result. See the | |
80 // documentation of FetchCallback and Result for more details. If a fetch | |
81 // should be retried after an error, it is the caller's responsibility to call | |
82 // StartJob() again. Returns an opaque job identifier. Ownership of the job | |
83 // identifier is retained by |this|. | |
84 Job* StartJob(const GURL& url, | |
85 int64 max_size, | |
86 const FetchCallback& callback); | |
87 | |
88 // Cancel the fetch job identified by |job|. The job is canceled silently, | |
89 // without invoking the |callback| that was passed to StartJob(). | |
90 void CancelJob(Job* job); | |
91 | |
92 private: | |
93 // Callback invoked when a fetch job finishes in the |backend_|. | |
94 void OnJobFinished(const FetchCallback& callback, | |
95 Job* job, | |
96 Result result, | |
97 scoped_ptr<std::string> data); | |
98 | |
99 // Task runner representing the thread that |this| runs on. | |
100 scoped_refptr<base::SequencedTaskRunner> task_runner_; | |
101 | |
102 // Task runner representing the thread on which the |backend_| runs and | |
103 // performs network I/O. | |
104 scoped_refptr<base::SequencedTaskRunner> io_task_runner_; | |
105 | |
106 // The |backend_| is used to perform network I/O. It may be dereferenced and | |
107 // accessed via |io_task_runner_| only. | |
108 base::WeakPtr<ExternalPolicyDataFetcherBackend> backend_; | |
109 | |
110 // Set that owns all currently running Jobs. | |
111 typedef std::set<Job*> JobSet; | |
112 JobSet jobs_; | |
113 | |
114 base::WeakPtrFactory<ExternalPolicyDataFetcher> weak_factory_; | |
115 | |
116 DISALLOW_COPY_AND_ASSIGN(ExternalPolicyDataFetcher); | |
117 }; | |
118 | |
119 // This class handles network I/O for one or more ExternalPolicyDataFetchers. It | |
120 // can be instantiated on any thread that is allowed to reference | |
121 // URLRequestContextGetters (in Chrome, these are the UI and IO threads) and | |
122 // CreateFrontend() may be called from the same thread after instantiation. From | |
123 // then on, it must be accessed and destroyed on the thread that handles network | |
124 // I/O only (in Chrome, this is the IO thread). | |
125 class ExternalPolicyDataFetcherBackend : public net::URLFetcherDelegate { | |
126 public: | |
127 // Callback invoked when a fetch job finishes. If the fetch was successful, | |
128 // the Result is SUCCESS and the scoped_ptr contains the retrieved data. | |
129 // Otherwise, Result indicates the type of error that occurred and the | |
130 // scoped_ptr is NULL. | |
131 typedef base::Callback<void(ExternalPolicyDataFetcher::Job*, | |
132 ExternalPolicyDataFetcher::Result, | |
133 scoped_ptr<std::string>)> FetchCallback; | |
134 | |
135 // |io_task_runner_| represents the thread that handles network I/O and that | |
136 // |this| runs on. |request_context| is used to construct URLFetchers. | |
137 ExternalPolicyDataFetcherBackend( | |
138 scoped_refptr<base::SequencedTaskRunner> io_task_runner, | |
139 scoped_refptr<net::URLRequestContextGetter> request_context); | |
140 virtual ~ExternalPolicyDataFetcherBackend(); | |
141 | |
142 // Create an ExternalPolicyDataFetcher that allows fetch jobs to be started | |
143 // from the thread represented by |task_runner|. | |
144 scoped_ptr<ExternalPolicyDataFetcher> CreateFrontend( | |
145 scoped_refptr<base::SequencedTaskRunner> task_runner); | |
146 | |
147 // Start a fetch job defined by |job|. The caller retains ownership of |job| | |
148 // and must ensure that it remains valid until the job ends, CancelJob() is | |
149 // called or |this| is destroyed. | |
150 void StartJob(ExternalPolicyDataFetcher::Job* job); | |
151 | |
152 // Cancel the fetch job defined by |job| and invoke |callback| to confirm. | |
153 void CancelJob(ExternalPolicyDataFetcher::Job* job, | |
154 const base::Closure& callback); | |
155 | |
156 // net::URLFetcherDelegate: | |
157 virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE; | |
158 virtual void OnURLFetchDownloadProgress(const net::URLFetcher* source, | |
159 int64 current, | |
160 int64 total) OVERRIDE; | |
161 | |
162 private: | |
163 scoped_refptr<base::SequencedTaskRunner> io_task_runner_; | |
164 scoped_refptr<net::URLRequestContextGetter> request_context_; | |
165 | |
166 // A monotonically increasing fetch ID. Used to identify fetches in tests. | |
167 int last_fetch_id_; | |
168 | |
169 // Map that owns the net::URLFetchers for all currently running jobs and maps | |
170 // from these to the corresponding Job. | |
171 typedef std::map<net::URLFetcher*, ExternalPolicyDataFetcher::Job*> JobMap; | |
172 JobMap job_map_; | |
173 | |
174 base::WeakPtrFactory<ExternalPolicyDataFetcherBackend> weak_factory_; | |
175 | |
176 DISALLOW_COPY_AND_ASSIGN(ExternalPolicyDataFetcherBackend); | |
177 }; | |
178 | |
179 | |
180 } // namespace policy | |
181 | |
182 #endif // CHROME_BROWSER_POLICY_CLOUD_EXTERNAL_POLICY_DATA_FETCHER_H_ | |
OLD | NEW |