12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/download/download_ui_controller.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/callback.h" 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/stl_util.h" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/download/download_item_model.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser_finder.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser_tabstrip.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/download_item.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/web_contents.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/web_contents_delegate.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_ANDROID) 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/android/download_controller_android.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/profiles/profile.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// DefaultUIControllerDelegate{Android,} is used when a DownloadUIController is 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// constructed without specifying an explicit Delegate. 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_ANDROID) 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class DefaultUIControllerDelegateAndroid 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : public DownloadUIController::Delegate { 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DefaultUIControllerDelegateAndroid() {} 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~DefaultUIControllerDelegateAndroid() {} 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // DownloadUIController::Delegate 36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual void OnNewDownloadReady(content::DownloadItem* item) OVERRIDE; 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void DefaultUIControllerDelegateAndroid::OnNewDownloadReady( 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::DownloadItem* item) { 41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // The Android DownloadController is only interested in IN_PROGRESS downloads. 42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Ones which are INTERRUPTED etc. can't be handed over to the Android 43cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // DownloadManager. 44cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (item->GetState() != content::DownloadItem::IN_PROGRESS) 45cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 46cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // GET downloads without authentication are delegated to the Android 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // DownloadManager. Chrome is responsible for the rest. See 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // InterceptDownloadResourceThrottle::ProcessDownloadRequest(). 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) content::DownloadControllerAndroid::Get()->OnDownloadStarted(item); 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else // OS_ANDROID 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class DefaultUIControllerDelegate : public DownloadUIController::Delegate { 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |profile| is required to outlive DefaultUIControllerDelegate. 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) explicit DefaultUIControllerDelegate(Profile* profile) 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : profile_(profile) {} 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~DefaultUIControllerDelegate() {} 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // DownloadUIController::Delegate 64cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual void OnNewDownloadReady(content::DownloadItem* item) OVERRIDE; 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Profile* profile_; 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void DefaultUIControllerDelegate::OnNewDownloadReady( 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::DownloadItem* item) { 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::WebContents* web_contents = item->GetWebContents(); 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Browser* browser = 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) web_contents ? chrome::FindBrowserWithWebContents(web_contents) : NULL; 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // As a last resort, use the last active browser for this profile. Not ideal, 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // but better than not showing the download at all. 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (browser == NULL) { 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser = chrome::FindLastActiveWithProfile(profile_, 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chrome::GetActiveDesktop()); 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (browser) 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser->ShowDownload(item); 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif // !OS_ANDROID 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DownloadUIController::Delegate::~Delegate() { 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DownloadUIController::DownloadUIController(content::DownloadManager* manager, 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<Delegate> delegate) 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : download_notifier_(manager, this), 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delegate_(delegate.Pass()) { 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!delegate_) { 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_ANDROID) 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delegate_.reset(new DefaultUIControllerDelegateAndroid()); 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The delegate should not be invoked after the profile has gone away. This 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // should be the case since DownloadUIController is owned by 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // DownloadService, which in turn is a profile keyed service. 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delegate_.reset(new DefaultUIControllerDelegate( 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Profile::FromBrowserContext(manager->GetBrowserContext()))); 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DownloadUIController::~DownloadUIController() { 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DownloadUIController::OnDownloadCreated(content::DownloadManager* manager, 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::DownloadItem* item) { 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // SavePackage downloads are created in a state where they can be shown in the 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // browser. Call OnDownloadUpdated() once to notify the UI immediately. 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OnDownloadUpdated(manager, item); 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DownloadUIController::OnDownloadUpdated(content::DownloadManager* manager, 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::DownloadItem* item) { 122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DownloadItemModel item_model(item); 123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Ignore if we've already notified the UI about |item| or if it isn't a new 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // download. 126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (item_model.WasUINotified() || !item_model.ShouldNotifyUI()) 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Wait until the target path is determined. 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (item->GetTargetFilePath().empty()) 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DownloadItemModel(item).SetWasUINotified(true); 134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) delegate_->OnNewDownloadReady(item); 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 136