Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(62)

Side by Side Diff: chrome/browser/extensions/extension_downloads.cc

Issue 7192016: chrome.experimental.downloads (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: merged db_handle, id; onCreated, onErased Created 9 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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 #include "chrome/browser/extensions/extension_downloads.h"
6
7 #include <algorithm>
8
9 #include "base/bind.h"
10 #include "base/logging.h"
11 #include "base/stl_util-inl.h"
12 #include "base/values.h"
13 #include "chrome/browser/browser_process.h"
14 #include "chrome/browser/download/download_create_info.h"
15 #include "chrome/browser/extensions/extension_event_router.h"
16 #include "chrome/browser/download/download_file_manager.h"
17 #include "chrome/browser/download/download_item.h"
18 #include "chrome/browser/download/download_manager.h"
19 #include "chrome/browser/download/download_query.h"
20 #include "chrome/browser/download/download_util.h"
21 #include "chrome/browser/icon_loader.h"
22 #include "chrome/browser/icon_manager.h"
23 #include "chrome/browser/renderer_host/chrome_render_message_filter.h"
24 #include "chrome/browser/ui/browser_list.h"
25 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
26 #include "content/browser/renderer_host/render_view_host.h"
27 #include "content/browser/renderer_host/resource_dispatcher_host.h"
28
29 bool DownloadsDownloadFunction::RunImpl() {
30 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &options_));
31 EXTENSION_FUNCTION_VALIDATE(options_->GetString("url", &url_));
32 if (url_.empty()) {
33 error_ = "'url' cannot be empty.";
34 return false;
35 }
36 rdh_ = g_browser_process->resource_dispatcher_host();
37 if (rdh_ == NULL) {
38 error_ = "I'm afraid I can't do that.";
39 return false;
40 }
41 VLOG(1) << __FUNCTION__ << " " << url_;
42 products_ = new DictionaryValue();
43 result_.reset(products_);
44 options_->GetString("filename", &filename_);
45 options_->GetBoolean("save_as", &save_as_);
46 options_->GetString("method", &method_);
47 options_->GetDictionary("headers", &extra_headers_);
48 options_->GetString("body", &post_body_);
49 // TODO sanity check method_, extra_headers_, filename_
50 dl_man_ = profile()->GetDownloadManager();
51 tab_contents_ = BrowserList::GetLastActive()->GetSelectedTabContentsWrapper()
52 ->tab_contents();
53 resource_context_ = &profile()->GetResourceContext();
54 render_process_host_id_ = tab_contents_->GetRenderProcessHost()->id();
55 render_view_host_routing_id_ = tab_contents_->render_view_host()
56 ->routing_id();
57 VLOG(1) << __FUNCTION__ << " " << url_;
58 if (!BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, NewRunnableMethod(
59 this, &DownloadsDownloadFunction::BeginDownloadOnIOThread))) {
60 error_ = "I'm afraid I can't do that.";
61 return false;
62 }
63 return true;
64 }
65
66 void DownloadsDownloadFunction::BeginDownloadOnIOThread() {
67 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
68 DVLOG(1) << __FUNCTION__ << " " << url_;
69 DownloadSaveInfo save_info;
70 save_info.file_path = FilePath(filename_);
71 net::URLRequest* request = new net::URLRequest(GURL(url_), rdh_);
72 if (method_.empty()) {
73 method_ = "GET";
74 }
75 request->set_method(method_);
76 if (extra_headers_ != NULL) {
77 DictionaryValue::key_iterator headers_end = extra_headers_->end_keys();
78 for (DictionaryValue::key_iterator headers_iter =
79 extra_headers_->begin_keys();
80 headers_iter != headers_end; ++headers_iter) {
81 std::string value;
82 if (extra_headers_->GetStringWithoutPathExpansion(
83 *headers_iter, &value)) {
84 request->SetExtraRequestHeaderByName(
85 *headers_iter, value, false/*overwrite*/);
86 }
87 }
88 }
89 if (!post_body_.empty()) {
90 request->AppendBytesToUpload(post_body_.data(), post_body_.size());
91 }
92 rdh_->BeginDownload(
93 request,
94 save_info,
95 save_as_,
96 base::Bind(&DownloadsDownloadFunction::OnStarted, this),
97 render_process_host_id_,
98 render_view_host_routing_id_,
99 *resource_context_);
100 }
101
102 void DownloadsDownloadFunction::OnStarted(int dl_id, int error) {
103 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
104 VLOG(1) << __FUNCTION__ << " " << url_ << " " << dl_id << " " << error;
105 dl_id_ = dl_id;
106 dl_error_ = error;
107 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, NewRunnableMethod(
108 this, &DownloadsDownloadFunction::RespondOnUIThread));
109 }
110
111 void DownloadsDownloadFunction::RespondOnUIThread() {
112 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
113 VLOG(1) << __FUNCTION__ << " " << url_ << " " << dl_man_ << " " << filename_
114 << " " << dl_id_ << " " << dl_error_ << " " << method_;
115 if (dl_id_ >= 0) {
116 products_->Set("id", Value::CreateIntegerValue(dl_id_));
117 } else {
118 products_->Set("error", Value::CreateIntegerValue(dl_error_));
119 }
120 SendResponse(true);
121 }
122
123 bool DownloadsSearchFunction::RunImpl() {
124 DictionaryValue* query_json = NULL;
125 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &query_json));
126 CHECK(query_json);
127 download_util::DownloadQuery query(*query_json);
128 DownloadManager* dlman = profile()->GetDownloadManager();
129 if (dlman == NULL) {
130 error_ = "I'm afraid I can't do that.";
131 return false;
132 }
133 ListValue* results = new ListValue();
134 if (!dlman->Search(
135 download_util::DownloadQuery(*query_json),
136 NULL/*DownloadItem results*/,
137 true/*merge_parent_manager*/,
138 &error_,
139 results)) {
140 VLOG(1) << __PRETTY_FUNCTION__ << " " << error_;
141 return false;
142 }
143 result_.reset(results);
144 return true;
145 }
146
147 bool DownloadsPauseFunction::RunImpl() {
148 int dl_id = 0;
149 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &dl_id));
150 DownloadManager* dlman = profile()->GetDownloadManager();
151 if (dlman == NULL) {
152 error_ = "I'm afraid I can't do that.";
153 return false;
154 }
155 DownloadItem* item = dlman->GetDownloadItem(dl_id);
156 if (item == NULL) {
157 error_ = "Non-existent download";
158 return false;
159 }
160 VLOG(1) << __FUNCTION__ << " " << item;
161 if (!item->is_paused()) {
162 item->TogglePause();
163 }
164 return true;
165 }
166
167 bool DownloadsResumeFunction::RunImpl() {
168 int dl_id = 0;
169 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &dl_id));
170 DownloadManager* dlman = profile()->GetDownloadManager();
171 if (dlman == NULL) {
172 error_ = "I'm afraid I can't do that.";
173 return false;
174 }
175 DownloadItem* item = dlman->GetDownloadItem(dl_id);
176 if (item == NULL) {
177 error_ = "Non-existent download";
178 return false;
179 }
180 VLOG(1) << __FUNCTION__ << " " << item;
181 if (item->is_paused()) {
182 item->TogglePause();
183 }
184 return true;
185 }
186
187 bool DownloadsCancelFunction::RunImpl() {
188 int dl_id = 0;
189 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &dl_id));
190 DownloadManager* dlman = profile()->GetDownloadManager();
191 if (dlman == NULL) {
192 error_ = "I'm afraid I can't do that.";
193 return false;
194 }
195 DownloadItem* item = dlman->GetDownloadItem(dl_id);
196 if (item == NULL) {
197 error_ = "Non-existent download";
198 return false;
199 }
200 VLOG(1) << __FUNCTION__ << " " << item;
201 item->Cancel(true);
202 return true;
203 }
204
205 bool DownloadsEraseFunction::RunImpl() {
206 return true;
207 }
208
209 bool DownloadsSetDestinationFunction::RunImpl() {
210 int dl_id = 0;
211 std::string rel_dest_path;
212 if ((args_.get() == NULL) ||
213 (args_->GetSize() < 2) ||
214 !args_->GetInteger(0, &dl_id) ||
215 (dl_id == 0) ||
216 !args_->GetString(1, &rel_dest_path) ||
217 rel_dest_path.empty()) return false;
218 DownloadManager* dlman = profile()->GetDownloadManager();
219 DownloadItem* item = dlman->GetDownloadItem(dl_id);
220 if (item == NULL) return false;
221 VLOG(1) << __FUNCTION__ << " " << dl_id << " " << item << " "
222 << rel_dest_path;
223 return true;
224 }
225
226 bool DownloadsAcceptDangerFunction::RunImpl() {
227 int dl_id = 0;
228 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &dl_id));
229 DownloadManager* dlman = profile()->GetDownloadManager();
230 if (dlman == NULL) {
231 error_ = "I'm afraid I can't do that.";
232 return false;
233 }
234 DownloadItem* item = dlman->GetDownloadItem(dl_id);
235 if (item == NULL) {
236 error_ = "Non-existent download";
237 return false;
238 }
239 VLOG(1) << __FUNCTION__ << " " << item;
240 item->Cancel(true);
241 return true;
242 }
243
244 bool DownloadsShowFunction::RunImpl() {
245 int dl_id = 0;
246 if ((args_.get() == NULL) ||
247 (args_->GetSize() < 1) ||
248 !args_->GetInteger(0, &dl_id) ||
249 (dl_id == 0)) return false;
250 DownloadManager* dlman = profile()->GetDownloadManager();
251 DownloadItem* item = dlman->GetDownloadItem(dl_id);
252 if (item == NULL) return false;
253 VLOG(1) << __FUNCTION__ << " " << item;
254 return true;
255 }
256
257 bool DownloadsDragFunction::RunImpl() {
258 int dl_id = 0;
259 if ((args_.get() == NULL) ||
260 (args_->GetSize() < 1) ||
261 !args_->GetInteger(0, &dl_id) ||
262 (dl_id == 0)) return false;
263 DownloadManager* dlman = profile()->GetDownloadManager();
264 DownloadItem* item = dlman->GetDownloadItem(dl_id);
265 if (item == NULL) return false;
266 IconManager* im = g_browser_process->icon_manager();
267 gfx::Image* icon = im->LookupIcon(item->GetUserVerifiedFilePath(),
268 IconLoader::NORMAL);
269 gfx::NativeView view = BrowserList::GetLastActive()
270 ->GetSelectedTabContentsWrapper()->tab_contents()->GetNativeView();
271 download_util::DragDownload(item, icon, view);
272 VLOG(1) << __FUNCTION__ << " " << dl_id;
273 return true;
274 }
275
276 struct DownloadsEventRouter::EventListener {
277 std::string ext_id;
278 base::WeakPtr<IPC::Message::Sender> ipc_sender;
279
280 EventListener(std::string eid, base::WeakPtr<IPC::Message::Sender> ipcs)
281 : ext_id(eid),
282 ipc_sender(ipcs) {
283 }
284 ~EventListener() {}
285
286 void SendEvent() {
287 }
288
289 // Comparator to work with std::set.
290 bool operator<(const EventListener& that) const {
291 return ext_id < that.ext_id;
292 }
293
294 // Allow copy and assign.
295 };
296
297 class DownloadsEventRouter::ManagerObserver
298 : public DownloadManager::Observer {
299 public:
300 ManagerObserver(DownloadsEventRouter* router,
301 ProfileId profile_id,
302 DownloadManager* manager)
303 : router_(router),
304 profile_id_(profile_id),
305 manager_(manager) {
306 DCHECK(router);
307 DCHECK(manager_);
308 manager_->AddObserver(this);
309 }
310 ~ManagerObserver() {
311 if (manager_) manager_->RemoveObserver(this);
312 }
313
314 virtual void ModelChanged() {
315 DCHECK(manager_);
316 DVLOG(1) << __FUNCTION__ << " " << manager_ << " " << profile_id_ << " " << router_;
317 router_->DispatchEvent(DownloadsEventRouter::CHANGED, profile_id_, 0);
318 }
319
320 virtual void ManagerGoingDown() {
321 manager_ = NULL;
322 }
323
324 private:
325 DownloadsEventRouter* router_;
326 ProfileId profile_id_;
327 DownloadManager* manager_;
328
329 DISALLOW_COPY_AND_ASSIGN(ManagerObserver);
330 };
331
332 class DownloadsEventRouter::ItemObserver : public DownloadItem::Observer {
333 public:
334 ItemObserver() {}
335 ~ItemObserver() {}
336
337 virtual void OnDownloadUpdated(DownloadItem* download) {
338 DVLOG(1) << __FUNCTION__ << " " << download->id();
339 }
340
341 virtual void OnDownloadOpened(DownloadItem* download) {
342 DVLOG(1) << __FUNCTION__ << " " << download->id();
343 }
344
345 private:
346 DISALLOW_COPY_AND_ASSIGN(ItemObserver);
347 };
348
349 DownloadsEventRouter::DownloadsEventRouter() {
350 }
351
352 DownloadsEventRouter::~DownloadsEventRouter() {
353 }
354
355 DownloadsEventRouter* DownloadsEventRouter::GetInstance() {
356 return Singleton<DownloadsEventRouter>::get();
357 }
358
359 void DownloadsEventRouter::AddEventListener(
360 EventType event_type,
361 ProfileId profile_id,
362 const std::string& extension_id,
363 base::WeakPtr<IPC::Message::Sender> ipc_sender) {
364 DVLOG(1) << __FUNCTION__
365 << " " << event_type
366 << " " << profile_id
367 << " " << extension_id
368 << " " << BrowserThread::CurrentlyOn(BrowserThread::UI);
369 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
370 DCHECK(BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
371 NewRunnableMethod(this, &DownloadsEventRouter::AddEventListener,
372 event_type, profile_id, extension_id, ipc_sender)));
373 return;
374 }
375 Profile* profile = reinterpret_cast<Profile*>(profile_id); // XXX
376 DownloadManager* dlman = profile->GetDownloadManager();
377 DCHECK(dlman);
378 listeners_[profile_id][event_type].insert(EventListener(
379 extension_id, ipc_sender));
380 if (manager_observers_.find(profile_id) == manager_observers_.end()) {
381 manager_observers_[profile_id] = new ManagerObserver(this, profile_id, dlman );
382 }
383 }
384
385 void DownloadsEventRouter::DispatchEvent(
386 EventType event_type,
387 ProfileId profile_id,
388 int download_id) {
389 DVLOG(1) << __FUNCTION__
390 << " " << event_type
391 << " " << profile_id
392 << " " << download_id
393 << " " << BrowserThread::CurrentlyOn(BrowserThread::IO);
394 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
395 DCHECK(BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
396 NewRunnableMethod(this, &DownloadsEventRouter::DispatchEvent,
397 event_type, profile_id, download_id)));
398 return;
399 }
400 LOG(ERROR) << __FUNCTION__ << " " << event_type << " " << profile_id << " " << download_id;
401 if (event_type == CREATED) {
402 //item_observers_[profile_id].insert(ItemObserver(this, profile_id));
403 } else if (event_type == ERASED) {
404 //item_observers_[profile_id];
405 }
406 const ListenerSet& listeners = listeners_[profile_id][event_type];
407 for (ListenerSet::iterator listener = listeners.begin();
408 listener != listeners.end(); ++listener) {
409 //(*listener)->ipc_sender->Send(new ExtensionMsg_MessageInvoke(
410 //MSG_ROUTING_CONTROL, (*listener)->ext_id, kDispatchEvent, args, event_ url));
411 //ExtensionEventRouter::DispatchEvent(
412 // (*listener)->ipc_sender.get(), (*listener)->ext_id, (*it)->sub_event_n ame,
413 // json_args, GURL());
414 }
415 }
OLDNEW
« no previous file with comments | « chrome/browser/extensions/extension_downloads.h ('k') | chrome/browser/extensions/extension_event_names.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698