7c5ae8520435a6b8f6fafa14b188b7bc7b47c199
[platform/framework/web/crosswalk.git] / src / chrome / browser / plugins / plugin_installer.cc
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/plugins/plugin_installer.h"
6
7 #include "base/bind.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"
19
20 using content::DownloadItem;
21
22 PluginInstaller::PluginInstaller()
23     : state_(INSTALLER_STATE_IDLE),
24       strong_observer_count_(0) {
25 }
26
27 PluginInstaller::~PluginInstaller() {
28 }
29
30 void PluginInstaller::OnDownloadUpdated(DownloadItem* download) {
31   DownloadItem::DownloadState state = download->GetState();
32   switch (state) {
33     case DownloadItem::IN_PROGRESS:
34       return;
35     case DownloadItem::COMPLETE: {
36       DCHECK_EQ(INSTALLER_STATE_DOWNLOADING, state_);
37       state_ = INSTALLER_STATE_IDLE;
38       FOR_EACH_OBSERVER(PluginInstallerObserver, observers_,
39                         DownloadFinished());
40       break;
41     }
42     case DownloadItem::CANCELLED: {
43       DownloadCancelled();
44       break;
45     }
46     case DownloadItem::INTERRUPTED: {
47       content::DownloadInterruptReason reason = download->GetLastReason();
48       DownloadError(content::DownloadInterruptReasonToString(reason));
49       break;
50     }
51     case DownloadItem::MAX_DOWNLOAD_STATE: {
52       NOTREACHED();
53       return;
54     }
55   }
56   download->RemoveObserver(this);
57 }
58
59 void PluginInstaller::OnDownloadDestroyed(DownloadItem* download) {
60   DCHECK_EQ(INSTALLER_STATE_DOWNLOADING, state_);
61   state_ = INSTALLER_STATE_IDLE;
62   download->RemoveObserver(this);
63 }
64
65 void PluginInstaller::AddObserver(PluginInstallerObserver* observer) {
66   strong_observer_count_++;
67   observers_.AddObserver(observer);
68 }
69
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());
76   }
77 }
78
79 void PluginInstaller::AddWeakObserver(WeakPluginInstallerObserver* observer) {
80   weak_observers_.AddObserver(observer);
81 }
82
83 void PluginInstaller::RemoveWeakObserver(
84     WeakPluginInstallerObserver* observer) {
85   weak_observers_.RemoveObserver(observer);
86 }
87
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);
95 }
96
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,
106                                                       plugin_url));
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());
111 }
112
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(
118         "Error %d: %s",
119         interrupt_reason,
120         content::DownloadInterruptReasonToString(interrupt_reason).c_str());
121     DownloadError(msg);
122     return;
123   }
124   item->SetOpenWhenComplete(true);
125   item->AddObserver(this);
126 }
127
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(
132       plugin_url,
133       content::Referrer(web_contents->GetURL(),
134                         blink::WebReferrerPolicyDefault),
135       NEW_FOREGROUND_TAB, content::PAGE_TRANSITION_TYPED, false));
136   FOR_EACH_OBSERVER(PluginInstallerObserver, observers_, DownloadFinished());
137 }
138
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));
143 }
144
145 void PluginInstaller::DownloadCancelled() {
146   DCHECK_EQ(INSTALLER_STATE_DOWNLOADING, state_);
147   state_ = INSTALLER_STATE_IDLE;
148   FOR_EACH_OBSERVER(PluginInstallerObserver, observers_, DownloadCancelled());
149 }