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.
5 #include "chrome/browser/plugins/plugin_installer.h"
8 #include "base/bind_helpers.h"
9 #include "base/process/process.h"
10 #include "base/strings/stringprintf.h"
11 #include "chrome/browser/download/download_stats.h"
12 #include "chrome/browser/platform_util.h"
13 #include "chrome/browser/plugins/plugin_installer_observer.h"
14 #include "content/public/browser/browser_context.h"
15 #include "content/public/browser/download_item.h"
16 #include "content/public/browser/download_manager.h"
17 #include "content/public/browser/download_url_parameters.h"
18 #include "content/public/browser/web_contents.h"
20 using content::DownloadItem
;
22 PluginInstaller::PluginInstaller()
23 : state_(INSTALLER_STATE_IDLE
),
24 strong_observer_count_(0) {
27 PluginInstaller::~PluginInstaller() {
30 void PluginInstaller::OnDownloadUpdated(DownloadItem
* download
) {
31 DownloadItem::DownloadState state
= download
->GetState();
33 case DownloadItem::IN_PROGRESS
:
35 case DownloadItem::COMPLETE
: {
36 DCHECK_EQ(INSTALLER_STATE_DOWNLOADING
, state_
);
37 state_
= INSTALLER_STATE_IDLE
;
38 FOR_EACH_OBSERVER(PluginInstallerObserver
, observers_
,
42 case DownloadItem::CANCELLED
: {
46 case DownloadItem::INTERRUPTED
: {
47 content::DownloadInterruptReason reason
= download
->GetLastReason();
48 DownloadError(content::DownloadInterruptReasonToString(reason
));
51 case DownloadItem::MAX_DOWNLOAD_STATE
: {
56 download
->RemoveObserver(this);
59 void PluginInstaller::OnDownloadDestroyed(DownloadItem
* download
) {
60 DCHECK_EQ(INSTALLER_STATE_DOWNLOADING
, state_
);
61 state_
= INSTALLER_STATE_IDLE
;
62 download
->RemoveObserver(this);
65 void PluginInstaller::AddObserver(PluginInstallerObserver
* observer
) {
66 strong_observer_count_
++;
67 observers_
.AddObserver(observer
);
70 void PluginInstaller::RemoveObserver(PluginInstallerObserver
* observer
) {
71 strong_observer_count_
--;
72 observers_
.RemoveObserver(observer
);
73 if (strong_observer_count_
== 0) {
74 FOR_EACH_OBSERVER(WeakPluginInstallerObserver
, weak_observers_
,
75 OnlyWeakObserversLeft());
79 void PluginInstaller::AddWeakObserver(WeakPluginInstallerObserver
* observer
) {
80 weak_observers_
.AddObserver(observer
);
83 void PluginInstaller::RemoveWeakObserver(
84 WeakPluginInstallerObserver
* observer
) {
85 weak_observers_
.RemoveObserver(observer
);
88 void PluginInstaller::StartInstalling(const GURL
& plugin_url
,
89 content::WebContents
* web_contents
) {
90 content::DownloadManager
* download_manager
=
91 content::BrowserContext::GetDownloadManager(
92 web_contents
->GetBrowserContext());
93 StartInstallingWithDownloadManager(
94 plugin_url
, web_contents
, download_manager
);
97 void PluginInstaller::StartInstallingWithDownloadManager(
98 const GURL
& plugin_url
,
99 content::WebContents
* web_contents
,
100 content::DownloadManager
* download_manager
) {
101 DCHECK_EQ(INSTALLER_STATE_IDLE
, state_
);
102 state_
= INSTALLER_STATE_DOWNLOADING
;
103 FOR_EACH_OBSERVER(PluginInstallerObserver
, observers_
, DownloadStarted());
104 scoped_ptr
<content::DownloadUrlParameters
> download_parameters(
105 content::DownloadUrlParameters::FromWebContents(web_contents
,
107 download_parameters
->set_callback(
108 base::Bind(&PluginInstaller::DownloadStarted
, base::Unretained(this)));
109 RecordDownloadSource(DOWNLOAD_INITIATED_BY_PLUGIN_INSTALLER
);
110 download_manager
->DownloadUrl(download_parameters
.Pass());
113 void PluginInstaller::DownloadStarted(
114 content::DownloadItem
* item
,
115 content::DownloadInterruptReason interrupt_reason
) {
116 if (interrupt_reason
!= content::DOWNLOAD_INTERRUPT_REASON_NONE
) {
117 std::string msg
= base::StringPrintf(
120 content::DownloadInterruptReasonToString(interrupt_reason
).c_str());
124 item
->SetOpenWhenComplete(true);
125 item
->AddObserver(this);
128 void PluginInstaller::OpenDownloadURL(const GURL
& plugin_url
,
129 content::WebContents
* web_contents
) {
130 DCHECK_EQ(INSTALLER_STATE_IDLE
, state_
);
131 web_contents
->OpenURL(content::OpenURLParams(
133 content::Referrer(web_contents
->GetURL(),
134 blink::WebReferrerPolicyDefault
),
135 NEW_FOREGROUND_TAB
, ui::PAGE_TRANSITION_TYPED
, false));
136 FOR_EACH_OBSERVER(PluginInstallerObserver
, observers_
, DownloadFinished());
139 void PluginInstaller::DownloadError(const std::string
& msg
) {
140 DCHECK_EQ(INSTALLER_STATE_DOWNLOADING
, state_
);
141 state_
= INSTALLER_STATE_IDLE
;
142 FOR_EACH_OBSERVER(PluginInstallerObserver
, observers_
, DownloadError(msg
));
145 void PluginInstaller::DownloadCancelled() {
146 DCHECK_EQ(INSTALLER_STATE_DOWNLOADING
, state_
);
147 state_
= INSTALLER_STATE_IDLE
;
148 FOR_EACH_OBSERVER(PluginInstallerObserver
, observers_
, DownloadCancelled());