Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chrome / browser / download / download_ui_controller.cc
blobae197a84cb20182f7f4803728ad6b461202d9264
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.
5 #include "chrome/browser/download/download_ui_controller.h"
7 #include "base/callback.h"
8 #include "base/stl_util.h"
9 #include "chrome/browser/download/download_item_model.h"
10 #include "chrome/browser/download/download_shelf.h"
11 #include "chrome/browser/ui/browser_finder.h"
12 #include "chrome/browser/ui/browser_tabstrip.h"
13 #include "chrome/browser/ui/browser_window.h"
14 #include "chrome/browser/ui/tabs/tab_strip_model.h"
15 #include "content/public/browser/download_item.h"
16 #include "content/public/browser/web_contents.h"
17 #include "content/public/browser/web_contents_delegate.h"
19 #if defined(OS_ANDROID)
20 #include "content/public/browser/android/download_controller_android.h"
21 #else
22 #include "chrome/browser/download/notification/download_notification_manager.h"
23 #include "chrome/browser/profiles/profile.h"
24 #include "chrome/browser/ui/browser_finder.h"
25 #include "chrome/browser/ui/host_desktop.h"
26 #endif
28 namespace {
30 // DownloadShelfUIControllerDelegate{Android,} is used when a
31 // DownloadUIController is
32 // constructed without specifying an explicit Delegate.
33 #if defined(OS_ANDROID)
35 class AndroidUIControllerDelegate : public DownloadUIController::Delegate {
36 public:
37 AndroidUIControllerDelegate() {}
38 ~AndroidUIControllerDelegate() override {}
40 private:
41 // DownloadUIController::Delegate
42 void OnNewDownloadReady(content::DownloadItem* item) override;
45 void AndroidUIControllerDelegate::OnNewDownloadReady(
46 content::DownloadItem* item) {
47 // The Android DownloadController is only interested in IN_PROGRESS downloads.
48 // Ones which are INTERRUPTED etc. can't be handed over to the Android
49 // DownloadManager.
50 if (item->GetState() != content::DownloadItem::IN_PROGRESS)
51 return;
53 // GET downloads without authentication are delegated to the Android
54 // DownloadManager. Chrome is responsible for the rest. See
55 // InterceptDownloadResourceThrottle::ProcessDownloadRequest().
56 content::DownloadControllerAndroid::Get()->OnDownloadStarted(item);
59 #else // OS_ANDROID
61 class DownloadShelfUIControllerDelegate
62 : public DownloadUIController::Delegate {
63 public:
64 // |profile| is required to outlive DownloadShelfUIControllerDelegate.
65 explicit DownloadShelfUIControllerDelegate(Profile* profile)
66 : profile_(profile) {}
67 ~DownloadShelfUIControllerDelegate() override {}
69 private:
70 // DownloadUIController::Delegate
71 void OnNewDownloadReady(content::DownloadItem* item) override;
73 Profile* profile_;
76 void DownloadShelfUIControllerDelegate::OnNewDownloadReady(
77 content::DownloadItem* item) {
78 content::WebContents* web_contents = item->GetWebContents();
79 Browser* browser =
80 web_contents ? chrome::FindBrowserWithWebContents(web_contents) : NULL;
82 // As a last resort, use the last active browser for this profile. Not ideal,
83 // but better than not showing the download at all.
84 if (browser == NULL) {
85 browser = chrome::FindLastActiveWithProfile(profile_,
86 chrome::GetActiveDesktop());
89 if (browser && browser->window() &&
90 DownloadItemModel(item).ShouldShowInShelf()) {
91 // GetDownloadShelf creates the download shelf if it was not yet created.
92 browser->window()->GetDownloadShelf()->AddDownload(item);
96 #endif // !OS_ANDROID
98 } // namespace
100 DownloadUIController::Delegate::~Delegate() {
103 DownloadUIController::DownloadUIController(content::DownloadManager* manager,
104 scoped_ptr<Delegate> delegate)
105 : download_notifier_(manager, this),
106 delegate_(delegate.Pass()) {
107 if (!delegate_) {
108 #if defined(OS_ANDROID)
109 delegate_.reset(new AndroidUIControllerDelegate());
110 #else
111 // The delegate should not be invoked after the profile has gone away. This
112 // should be the case since DownloadUIController is owned by
113 // DownloadService, which in turn is a profile keyed service.
114 if (DownloadNotificationManager::IsEnabled()) {
115 delegate_.reset(new DownloadNotificationManager(
116 Profile::FromBrowserContext(manager->GetBrowserContext())));
117 } else {
118 delegate_.reset(new DownloadShelfUIControllerDelegate(
119 Profile::FromBrowserContext(manager->GetBrowserContext())));
121 #endif
125 DownloadUIController::~DownloadUIController() {
128 void DownloadUIController::OnDownloadCreated(content::DownloadManager* manager,
129 content::DownloadItem* item) {
130 // SavePackage downloads are created in a state where they can be shown in the
131 // browser. Call OnDownloadUpdated() once to notify the UI immediately.
132 OnDownloadUpdated(manager, item);
135 void DownloadUIController::OnDownloadUpdated(content::DownloadManager* manager,
136 content::DownloadItem* item) {
137 DownloadItemModel item_model(item);
139 // Ignore if we've already notified the UI about |item| or if it isn't a new
140 // download.
141 if (item_model.WasUINotified() || !item_model.ShouldNotifyUI())
142 return;
144 // Wait until the target path is determined.
145 if (item->GetTargetFilePath().empty())
146 return;
148 DownloadItemModel(item).SetWasUINotified(true);
150 #if !defined(OS_ANDROID)
151 content::WebContents* web_contents = item->GetWebContents();
152 if (web_contents) {
153 Browser* browser = chrome::FindBrowserWithWebContents(web_contents);
154 // If the download occurs in a new tab, and it's not a save page
155 // download (started before initial navigation completed) close it.
156 // Avoid calling CloseContents if the tab is not in this browser's tab strip
157 // model; this can happen if the download was initiated by something
158 // internal to Chrome, such as by the app list.
159 if (browser && web_contents->GetController().IsInitialNavigation() &&
160 browser->tab_strip_model()->count() > 1 &&
161 browser->tab_strip_model()->GetIndexOfWebContents(web_contents) !=
162 TabStripModel::kNoTab &&
163 !item->IsSavePackageDownload()) {
164 web_contents->Close();
167 #endif
169 delegate_->OnNewDownloadReady(item);