OLD | NEW |
---|---|
(Empty) | |
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 #include "chrome/browser/download/download_ui_controller.h" | |
6 | |
7 #include "base/stl_util.h" | |
8 #include "chrome/browser/ui/browser_finder.h" | |
9 #include "chrome/browser/ui/browser_tabstrip.h" | |
10 #include "content/public/browser/download_item.h" | |
11 #include "content/public/browser/web_contents.h" | |
12 #include "content/public/browser/web_contents_delegate.h" | |
13 | |
14 #if defined(OS_ANDROID) | |
15 #include "content/public/browser/android/download_controller_android.h" | |
16 #else | |
17 #include "chrome/browser/ui/blocked_content/blocked_content_tab_helper.h" | |
18 #include "chrome/browser/ui/blocked_content/blocked_content_tab_helper_delegate. h" | |
19 #endif | |
20 | |
21 namespace { | |
22 | |
23 // The presence of this UserData in a DownloadItem signals that the UI should be | |
24 // notified of this download. | |
25 class ShouldNotifyData : public base::SupportsUserData::Data { | |
26 public: | |
27 static void Set(content::DownloadItem* item) { | |
28 new ShouldNotifyData(item); | |
29 } | |
30 | |
31 static bool IsSet(content::DownloadItem* item) { | |
32 return item->GetUserData(kKey) != NULL; | |
33 } | |
34 | |
35 static void Clear(content::DownloadItem* item) { | |
36 item->RemoveUserData(kKey); | |
37 } | |
38 | |
39 private: | |
40 explicit ShouldNotifyData(content::DownloadItem* item) { | |
41 item->SetUserData(kKey, this); | |
42 } | |
43 | |
44 static const char kKey[]; | |
45 DISALLOW_COPY_AND_ASSIGN(ShouldNotifyData); | |
46 }; | |
47 | |
48 const char ShouldNotifyData::kKey[] = "DownloadUIConroller ShouldNotifyData"; | |
49 | |
50 } // namespace | |
51 | |
52 DownloadUIController::DownloadUIController(Profile* profile, | |
53 content::DownloadManager* manager) | |
54 : ALLOW_THIS_IN_INITIALIZER_LIST(notifier_(manager, this)), | |
55 profile_(profile) { | |
56 } | |
57 | |
58 DownloadUIController::~DownloadUIController() { | |
59 } | |
60 | |
61 void DownloadUIController::OnDownloadCreated(content::DownloadManager* manager, | |
62 content::DownloadItem* item) { | |
63 // If this isn't a new download, there's nothing to do. | |
64 if (!item->IsInProgress()) | |
65 return; | |
66 | |
67 ShouldNotifyData::Set(item); | |
68 // SavePackage downloads are created in a state where they can be shown | |
69 // immediately in the browser. | |
70 OnDownloadUpdated(manager, item); | |
71 } | |
72 | |
73 void DownloadUIController::OnDownloadUpdated(content::DownloadManager* manager, | |
74 content::DownloadItem* item) { | |
75 | |
76 // Ignore if we've already notified the UI about |item| or if it isn't a new | |
77 // download. | |
78 if (!ShouldNotifyData::IsSet(item)) | |
79 return; | |
80 | |
81 // Wait until the target path is determined. | |
82 if (item->GetTargetFilePath().empty()) | |
83 return; | |
84 | |
85 // For a download that is in-progress, wait until the intermediate rename is | |
86 // complete. | |
87 // TODO(asanka): Get rid of remaining users of GetFullPath() in ui/. | |
88 if (item->IsInProgress() && item->GetFullPath().empty()) | |
89 return; | |
90 | |
91 // At this point, we expect that the download is either interrupted, or | |
92 // in-progress and the path is known. | |
93 | |
94 // Can't be complete. That would imply that we didn't receive an | |
95 // OnDownloadUpdated() after the intermediate rename was completed. | |
96 DCHECK(!item->IsComplete()); | |
97 | |
98 ShouldNotifyData::Clear(item); | |
99 NotifyDownloadStarting(item); | |
100 } | |
101 | |
102 void DownloadUIController::NotifyDownloadStarting(content::DownloadItem* item) { | |
103 #if defined(OS_ANDROID) | |
104 // GET downloads are delegated to and Android DownloadManager. Chrome is only | |
benjhayden
2012/12/20 21:09:14
to an
asanka
2012/12/20 22:41:19
Done.
| |
105 // responsible for POST downloads. | |
106 // See ChromeWebContentsDelegateAndroid::CanDownload(). | |
107 content::DownloadControllerAndroid::Get()->OnPostDownloadStarted(item); | |
108 #else | |
109 content::WebContents* web_contents = item->GetWebContents(); | |
110 | |
111 // If the tab requesting the download is a constrained popup that is not | |
112 // shown, treat the request as if it came from the parent. | |
113 if (web_contents != NULL) { | |
114 BlockedContentTabHelper* blocked_content_tab_helper = | |
115 BlockedContentTabHelper::FromWebContents(web_contents); | |
116 if (blocked_content_tab_helper && | |
117 blocked_content_tab_helper->delegate()) { | |
118 content::WebContents* constraining_web_contents = | |
119 blocked_content_tab_helper->delegate()-> | |
120 GetConstrainingWebContents(web_contents); | |
121 if (constraining_web_contents) | |
122 web_contents = constraining_web_contents; | |
123 } | |
124 } | |
125 | |
126 Browser* browser = | |
127 web_contents ? chrome::FindBrowserWithWebContents(web_contents) : NULL; | |
128 | |
129 // As a last resort, use the last active browser for this profile. Not ideal, | |
130 // but better than not showing the download at all. | |
131 if (browser == NULL) { | |
132 browser = chrome::FindLastActiveWithProfile(profile_, | |
133 chrome::GetActiveDesktop()); | |
134 } | |
135 | |
136 if (browser) | |
137 browser->ShowDownload(item); | |
138 #endif | |
139 } | |
140 | |
OLD | NEW |