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 CHROME_BROWSER_DOWNLOAD_DRAG_DOWNLOAD_FILE_H_
6#define CHROME_BROWSER_DOWNLOAD_DRAG_DOWNLOAD_FILE_H_
7#pragma once
8
9#include "base/file_path.h"
10#include "base/memory/linked_ptr.h"
11#include "chrome/browser/download/download_file.h"
12#include "chrome/browser/download/download_item.h"
13#include "chrome/browser/download/download_manager.h"
14#include "googleurl/src/gurl.h"
15#include "ui/base/dragdrop/download_file_interface.h"
16
17class TabContents;
18
19namespace net {
20class FileStream;
21}
22
23class DragDownloadFile : public ui::DownloadFileProvider,
24                         public DownloadManager::Observer,
25                         public DownloadItem::Observer {
26 public:
27  // On Windows, we need to download into a temporary file. Two threads are
28  // involved: background drag-and-drop thread and UI thread.
29  // The first parameter file_name_or_path should contain file name while the
30  // second parameter file_stream should be NULL.
31  //
32  // On MacOSX, we need to download into a file stream that has already been
33  // created. Only UI thread is involved.
34  // The file path and file stream should be provided as the first two
35  // parameters.
36  DragDownloadFile(const FilePath& file_name_or_path,
37                   linked_ptr<net::FileStream> file_stream,
38                   const GURL& url,
39                   const GURL& referrer,
40                   const std::string& referrer_encoding,
41                   TabContents* tab_contents);
42
43  // DownloadFileProvider methods.
44  // Called on drag-and-drop thread (Windows).
45  // Called on UI thread (MacOSX).
46  virtual bool Start(ui::DownloadFileObserver* observer);
47  virtual void Stop();
48#if defined(OS_WIN)
49  virtual IStream* GetStream() { return NULL; }
50#endif
51
52  // DownloadManager::Observer methods.
53  // Called on UI thread.
54  virtual void ModelChanged();
55
56  // DownloadItem::Observer methods.
57  // Called on UI thread.
58  virtual void OnDownloadUpdated(DownloadItem* download);
59  virtual void OnDownloadOpened(DownloadItem* download) { }
60
61 private:
62  // Called on drag-and-drop thread (Windows).
63  // Called on UI thread (Windows).
64  virtual ~DragDownloadFile();
65
66  // Called on drag-and-drop thread (Windows only).
67#if defined(OS_WIN)
68  void StartNestedMessageLoop();
69  void QuitNestedMessageLoop();
70#endif
71
72  // Called on either drag-and-drop thread or UI thread (Windows).
73  // Called on UI thread (MacOSX).
74  void InitiateDownload();
75  void DownloadCompleted(bool is_successful);
76
77  // Helper methods to make sure we're in the correct thread.
78  void AssertCurrentlyOnDragThread();
79  void AssertCurrentlyOnUIThread();
80
81  // Initialized on drag-and-drop thread. Accessed on either thread after that
82  // (Windows).
83  // Accessed on UI thread (MacOSX).
84  FilePath file_path_;
85  FilePath file_name_;
86  linked_ptr<net::FileStream> file_stream_;
87  GURL url_;
88  GURL referrer_;
89  std::string referrer_encoding_;
90  TabContents* tab_contents_;
91  MessageLoop* drag_message_loop_;
92  FilePath temp_dir_path_;
93
94  // Accessed on drag-and-drop thread (Windows).
95  // Accessed on UI thread (MacOSX).
96  bool is_started_;
97  bool is_successful_;
98  scoped_refptr<ui::DownloadFileObserver> observer_;
99
100  // Accessed on drag-and-drop thread (Windows only).
101#if defined(OS_WIN)
102  bool is_running_nested_message_loop_;
103#endif
104
105  // Access on UI thread.
106  DownloadManager* download_manager_;
107  bool download_item_observer_added_;
108
109  DISALLOW_COPY_AND_ASSIGN(DragDownloadFile);
110};
111
112#endif  // CHROME_BROWSER_DOWNLOAD_DRAG_DOWNLOAD_FILE_H_
113