summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/app/generated_resources.grd15
-rw-r--r--chrome/browser/chrome_plugin_message_filter.cc45
-rw-r--r--chrome/browser/chrome_plugin_message_filter.h10
-rw-r--r--chrome/browser/plugin_download_helper.cc100
-rw-r--r--chrome/browser/plugin_download_helper.h57
-rw-r--r--chrome/browser/plugin_installer.cc42
-rw-r--r--chrome/browser/plugin_installer.h27
-rw-r--r--chrome/browser/plugin_installer_infobar_delegate.cc8
-rw-r--r--chrome/browser/plugin_installer_infobar_delegate.h14
-rw-r--r--chrome/browser/plugin_installer_observer.cc25
-rw-r--r--chrome/browser/plugin_installer_observer.h29
-rw-r--r--chrome/browser/plugin_observer.cc113
-rw-r--r--chrome/browser/plugin_observer.h7
-rw-r--r--chrome/browser/plugin_test.cc45
-rw-r--r--chrome/browser/resources/plugins_mac.json6
-rw-r--r--chrome/chrome_browser.gypi6
-rw-r--r--chrome/common/render_messages.h10
-rw-r--r--chrome/renderer/plugins/missing_plugin.cc14
-rw-r--r--chrome/renderer/plugins/missing_plugin.h4
19 files changed, 425 insertions, 152 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 736b598..f5c9320 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -5209,9 +5209,24 @@ Because search results are requested even while you're typing your query, your d
<message name="IDS_PLUGIN_SEARCHING" desc="The placeholder text when searching for a missing plug-in.">
Looking for plug-in...
</message>
+ <message name="IDS_PLUGIN_DOWNLOADING" desc="The placeholder text when downloading a missing plug-in.">
+ Downloading plug-in...
+ </message>
+ <message name="IDS_PLUGIN_INSTALLING" desc="The placeholder text when installing a missing plug-in.">
+ After installing the plug-in, reload the page.
+ </message>
<message name="IDS_PLUGIN_FOUND" desc="The placeholder text for a known plug-in that is not installed.">
The <ph name="PLUGIN_NAME">$1<ex>Quicktime</ex></ph> plug-in is required to display this content.
</message>
+ <message name="IDS_PLUGIN_CONFIRM_INSTALL_DIALOG_TITLE" desc="Title of the plug-in installation confirmation dialog.">
+ <ph name="PLUGIN_NAME">$1<ex>Realplayer</ex></ph> plug-in needed
+ </message>
+ <message name="IDS_PLUGIN_CONFIRM_INSTALL_DIALOG_MSG" desc="Message of the plug-in installation confirmation dialog.">
+ Please confirm that you would like to install the <ph name="PLUGIN_NAME">$1<ex>Realplayer</ex></ph> plug-in. You should only install plug-ins that you trust.
+ </message>
+ <message name="IDS_PLUGIN_CONFIRM_INSTALL_DIALOG_ACCEPT_BUTTON" desc="Button title to install a missing plug-in.">
+ Get Plug-in
+ </message>
<message name="IDS_PLUGIN_DISABLED" desc="The placeholder text for a disabled plug-in.">
The <ph name="PLUGIN_NAME">$1<ex>Flash</ex></ph> plug-in has been disabled. To re-enable it, please go to <ph name="CHROME_PLUGINS_LINK">chrome://plugins</ph>.
</message>
diff --git a/chrome/browser/chrome_plugin_message_filter.cc b/chrome/browser/chrome_plugin_message_filter.cc
index 8d68825..7d18173 100644
--- a/chrome/browser/chrome_plugin_message_filter.cc
+++ b/chrome/browser/chrome_plugin_message_filter.cc
@@ -1,10 +1,11 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/chrome_plugin_message_filter.h"
#include "base/bind.h"
+#include "base/file_path.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/infobars/infobar_tab_helper.h"
#include "chrome/browser/plugin_installer_infobar_delegate.h"
@@ -68,33 +69,45 @@ void ChromePluginMessageFilter::OnDownloadUrl(const std::string& url,
render_process_id));
}
+// static
void ChromePluginMessageFilter::OnDownloadUrlOnUIThread(
const std::string& url,
gfx::NativeWindow caller_window,
int render_process_id) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
content::RenderProcessHost* host =
content::RenderProcessHost::FromID(render_process_id);
if (!host) {
return;
}
- BrowserThread::PostTask(
- BrowserThread::FILE, FROM_HERE,
- base::Bind(&ChromePluginMessageFilter::OnDownloadUrlOnFileThread,
- url, caller_window,
- host->GetBrowserContext()->GetRequestContext()));
+ // |download_url_helper| will delete itself after running the callback.
+ PluginDownloadUrlHelper* download_url_helper =
+ new PluginDownloadUrlHelper();
+ download_url_helper->InitiateDownload(
+ GURL(url),
+ host->GetBrowserContext()->GetRequestContext(),
+ base::Bind(&ChromePluginMessageFilter::OnPluginDownloadFinished,
+ caller_window));
}
-void ChromePluginMessageFilter::OnDownloadUrlOnFileThread(
- const std::string& url,
+// static
+void ChromePluginMessageFilter::OnPluginDownloadFinished(
gfx::NativeWindow caller_window,
- net::URLRequestContextGetter* context) {
- PluginDownloadUrlHelper* download_url_helper =
- new PluginDownloadUrlHelper(url, caller_window, NULL);
- download_url_helper->InitiateDownload(
- context,
- BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE));
+ const FilePath& response_file) {
+ FilePath::StringType path = response_file.value();
+ COPYDATASTRUCT download_file_data = {0};
+ download_file_data.cbData =
+ static_cast<unsigned long>((path.length() + 1) *
+ sizeof(FilePath::CharType));
+ download_file_data.lpData = const_cast<FilePath::CharType *>(path.c_str());
+ download_file_data.dwData = !path.empty();
+
+ if (::IsWindow(caller_window)) {
+ ::SendMessage(caller_window, WM_COPYDATA, NULL,
+ reinterpret_cast<LPARAM>(&download_file_data));
+ }
}
-#endif
+#endif // OS_WIN
void ChromePluginMessageFilter::OnGetPluginFinderUrl(
std::string* plugin_finder_url) {
@@ -137,7 +150,7 @@ void ChromePluginMessageFilter::HandleMissingPluginStatus(
if (status == webkit::npapi::default_plugin::MISSING_PLUGIN_AVAILABLE) {
infobar_helper->AddInfoBar(new PluginInstallerInfoBarDelegate(
- infobar_helper, string16(), GURL(),
+ NULL, infobar_helper, string16(), GURL(),
base::Bind(&ChromePluginMessageFilter::InstallMissingPlugin,
base::Unretained(window))));
return;
diff --git a/chrome/browser/chrome_plugin_message_filter.h b/chrome/browser/chrome_plugin_message_filter.h
index 5ea5088..b0d50ab 100644
--- a/chrome/browser/chrome_plugin_message_filter.h
+++ b/chrome/browser/chrome_plugin_message_filter.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -9,6 +9,7 @@
#include "ipc/ipc_channel_proxy.h"
#include "ui/gfx/native_widget_types.h"
+class FilePath;
class PluginProcessHost;
namespace net {
@@ -35,16 +36,13 @@ class ChromePluginMessageFilter : public IPC::ChannelProxy::MessageFilter,
void OnDownloadUrl(const std::string& url,
gfx::NativeWindow caller_window,
int render_process_id);
- // Helper function to issue the download request on the file thread.
- static void OnDownloadUrlOnFileThread(
- const std::string& url,
- gfx::NativeWindow caller_window,
- net::URLRequestContextGetter* context);
// Helper function to handle the initial portions of the download request
// on the UI thread.
static void OnDownloadUrlOnUIThread(const std::string& url,
gfx::NativeWindow caller_window,
int render_process_id);
+ static void OnPluginDownloadFinished(gfx::NativeWindow caller_window,
+ const FilePath& response_file);
#endif
void OnGetPluginFinderUrl(std::string* plugin_finder_url);
void OnMissingPluginStatus(int status,
diff --git a/chrome/browser/plugin_download_helper.cc b/chrome/browser/plugin_download_helper.cc
index 0621a6a..f153356 100644
--- a/chrome/browser/plugin_download_helper.cc
+++ b/chrome/browser/plugin_download_helper.cc
@@ -1,83 +1,77 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/plugin_download_helper.h"
-#include <windows.h>
-
+#include "base/bind.h"
#include "base/file_util.h"
+#include "base/message_loop_proxy.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/url_fetcher.h"
-#include "net/base/io_buffer.h"
+#include "net/base/net_errors.h"
+#include "net/url_request/url_request_status.h"
+
+using content::BrowserThread;
-PluginDownloadUrlHelper::PluginDownloadUrlHelper(
- const std::string& download_url,
- gfx::NativeWindow caller_window,
- PluginDownloadUrlHelper::DownloadDelegate* delegate)
- : download_file_fetcher_(NULL),
- download_file_caller_window_(caller_window),
- download_url_(download_url),
- delegate_(delegate) {
+PluginDownloadUrlHelper::PluginDownloadUrlHelper() {
}
PluginDownloadUrlHelper::~PluginDownloadUrlHelper() {
}
void PluginDownloadUrlHelper::InitiateDownload(
+ const GURL& download_url,
net::URLRequestContextGetter* request_context,
- base::MessageLoopProxy* file_thread_proxy) {
+ const DownloadFinishedCallback& callback) {
+ download_url_ = download_url;
+ callback_ = callback;
download_file_fetcher_.reset(content::URLFetcher::Create(
- GURL(download_url_), content::URLFetcher::GET, this));
+ download_url_, content::URLFetcher::GET, this));
download_file_fetcher_->SetRequestContext(request_context);
- download_file_fetcher_->SaveResponseToTemporaryFile(file_thread_proxy);
+ download_file_fetcher_->SaveResponseToTemporaryFile(
+ BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE));
download_file_fetcher_->Start();
}
void PluginDownloadUrlHelper::OnURLFetchComplete(
const content::URLFetcher* source) {
- bool success = source->GetStatus().is_success();
- FilePath response_file;
+ net::URLRequestStatus status = source->GetStatus();
+ if (status.is_success()) {
+ bool success = source->GetResponseAsFilePath(true, &downloaded_file_);
+ DCHECK(success);
+ BrowserThread::PostTaskAndReply(
+ BrowserThread::FILE, FROM_HERE,
+ base::Bind(&PluginDownloadUrlHelper::RenameDownloadedFile,
+ base::Unretained(this)),
+ base::Bind(&PluginDownloadUrlHelper::RunCallback,
+ base::Unretained(this)));
+ } else {
+ NOTREACHED() << "Failed to download the plugin installer: "
+ << net::ErrorToString(status.error());
+ RunCallback();
+ }
+}
- if (success) {
- if (source->GetResponseAsFilePath(true, &response_file)) {
- FilePath new_download_file_path =
- response_file.DirName().AppendASCII(
- download_file_fetcher_->GetURL().ExtractFileName());
+void PluginDownloadUrlHelper::RenameDownloadedFile() {
+ FilePath new_download_file_path =
+ downloaded_file_.DirName().AppendASCII(
+ download_file_fetcher_->GetURL().ExtractFileName());
- file_util::Delete(new_download_file_path, false);
+ file_util::Delete(new_download_file_path, false);
- if (!file_util::ReplaceFileW(response_file,
- new_download_file_path)) {
- DLOG(ERROR) << "Failed to rename file:"
- << response_file.value()
- << " to file:"
- << new_download_file_path.value();
- } else {
- response_file = new_download_file_path;
- }
- } else {
- NOTREACHED() << "Failed to download the plugin installer.";
- success = false;
- }
- }
-
- if (delegate_) {
- delegate_->OnDownloadCompleted(response_file, success);
+ if (file_util::ReplaceFile(downloaded_file_,
+ new_download_file_path)) {
+ downloaded_file_ = new_download_file_path;
} else {
- std::wstring path = response_file.value();
- COPYDATASTRUCT download_file_data = {0};
- download_file_data.cbData =
- static_cast<unsigned long>((path.length() + 1) * sizeof(wchar_t));
- download_file_data.lpData = const_cast<wchar_t *>(path.c_str());
- download_file_data.dwData = success;
-
- if (::IsWindow(download_file_caller_window_)) {
- ::SendMessage(download_file_caller_window_, WM_COPYDATA, NULL,
- reinterpret_cast<LPARAM>(&download_file_data));
- }
+ DPLOG(ERROR) << "Failed to rename file: "
+ << downloaded_file_.value()
+ << " to file: "
+ << new_download_file_path.value();
}
- // Don't access any members after this.
- delete this;
}
+void PluginDownloadUrlHelper::RunCallback() {
+ callback_.Run(downloaded_file_);
+ delete this;
+}
diff --git a/chrome/browser/plugin_download_helper.h b/chrome/browser/plugin_download_helper.h
index 18d3f8f..83036a3 100644
--- a/chrome/browser/plugin_download_helper.h
+++ b/chrome/browser/plugin_download_helper.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -6,15 +6,15 @@
#define CHROME_BROWSER_PLUGIN_DOWNLOAD_HELPER_H_
#pragma once
-#include <string>
-
-#include "build/build_config.h"
+#include "base/callback.h"
#include "base/file_path.h"
-#include "base/message_loop_proxy.h"
+#include "base/memory/scoped_ptr.h"
#include "content/public/common/url_fetcher_delegate.h"
-#include "net/base/file_stream.h"
-#include "net/url_request/url_request.h"
-#include "ui/gfx/native_widget_types.h"
+#include "googleurl/src/gurl.h"
+
+namespace base {
+class MessageLoopProxy;
+}
namespace net {
class URLRequestContextGetter;
@@ -25,40 +25,33 @@ class URLRequestContextGetter;
// of this class.
class PluginDownloadUrlHelper : public content::URLFetcherDelegate {
public:
- // The delegate receives notification about the status of downloads
- // initiated.
- class DownloadDelegate {
- public:
- virtual ~DownloadDelegate() {}
+ typedef base::Callback<void(const FilePath&)> DownloadFinishedCallback;
- virtual void OnDownloadCompleted(const FilePath& download_path,
- bool success) {}
- };
+ PluginDownloadUrlHelper();
+ virtual ~PluginDownloadUrlHelper();
- PluginDownloadUrlHelper(const std::string& download_url,
- gfx::NativeWindow caller_window,
- PluginDownloadUrlHelper::DownloadDelegate* delegate);
- ~PluginDownloadUrlHelper();
-
- void InitiateDownload(net::URLRequestContextGetter* request_context,
- base::MessageLoopProxy* file_thread_proxy);
+ void InitiateDownload(const GURL& download_url,
+ net::URLRequestContextGetter* request_context,
+ const DownloadFinishedCallback& callback);
// content::URLFetcherDelegate
- virtual void OnURLFetchComplete(const content::URLFetcher* source);
+ virtual void OnURLFetchComplete(const content::URLFetcher* source) OVERRIDE;
+
+ private:
+ // Renames the file (which was downloaded to a temporary file) to the filename
+ // of the download URL.
+ void RenameDownloadedFile();
- void OnDownloadCompleted(net::URLRequest* request);
+ // Runs the callback and deletes itself.
+ void RunCallback();
- protected:
// The download file request initiated by the plugin.
scoped_ptr<content::URLFetcher> download_file_fetcher_;
- // TODO(port): this comment doesn't describe the situation on Posix.
- // The window handle for sending the WM_COPYDATA notification,
- // indicating that the download completed.
- gfx::NativeWindow download_file_caller_window_;
- std::string download_url_;
+ GURL download_url_;
+ FilePath downloaded_file_;
- PluginDownloadUrlHelper::DownloadDelegate* delegate_;
+ DownloadFinishedCallback callback_;
DISALLOW_COPY_AND_ASSIGN(PluginDownloadUrlHelper);
};
diff --git a/chrome/browser/plugin_installer.cc b/chrome/browser/plugin_installer.cc
index 00d6c49..bbdfa6e 100644
--- a/chrome/browser/plugin_installer.cc
+++ b/chrome/browser/plugin_installer.cc
@@ -1,9 +1,16 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/plugin_installer.h"
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/process.h"
+#include "chrome/browser/platform_util.h"
+#include "chrome/browser/plugin_download_helper.h"
+#include "chrome/browser/plugin_installer_observer.h"
+
PluginInstaller::~PluginInstaller() {
}
@@ -12,9 +19,40 @@ PluginInstaller::PluginInstaller(const std::string& identifier,
const GURL& help_url,
const string16& name,
bool url_for_display)
- : identifier_(identifier),
+ : state_(kStateIdle),
+ identifier_(identifier),
plugin_url_(plugin_url),
help_url_(help_url),
name_(name),
url_for_display_(url_for_display) {
}
+
+void PluginInstaller::AddObserver(PluginInstallerObserver* observer) {
+ observers_.AddObserver(observer);
+}
+
+void PluginInstaller::RemoveObserver(PluginInstallerObserver* observer) {
+ observers_.RemoveObserver(observer);
+}
+
+void PluginInstaller::StartInstalling(
+ net::URLRequestContextGetter* request_context) {
+ DCHECK(state_ == kStateIdle);
+ DCHECK(!url_for_display_);
+ state_ = kStateDownloading;
+ FOR_EACH_OBSERVER(PluginInstallerObserver, observers_, DidStartDownload());
+ // |downloader| will delete itself after running the callback.
+ PluginDownloadUrlHelper* downloader = new PluginDownloadUrlHelper();
+ downloader->InitiateDownload(
+ plugin_url_,
+ request_context,
+ base::Bind(&PluginInstaller::DidFinishDownload, base::Unretained(this)));
+}
+
+void PluginInstaller::DidFinishDownload(const FilePath& downloaded_file) {
+ DCHECK(state_ == kStateDownloading);
+ state_ = kStateIdle;
+ DVLOG(1) << "Plug-in installer is at \"" << downloaded_file.value() << "\"";
+ FOR_EACH_OBSERVER(PluginInstallerObserver, observers_, DidFinishDownload());
+ platform_util::OpenItem(downloaded_file);
+}
diff --git a/chrome/browser/plugin_installer.h b/chrome/browser/plugin_installer.h
index 69f4a58..eef0ca5 100644
--- a/chrome/browser/plugin_installer.h
+++ b/chrome/browser/plugin_installer.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -6,11 +6,24 @@
#define CHROME_BROWSER_PLUGIN_INSTALLER_H_
#pragma once
+#include "base/observer_list.h"
#include "base/string16.h"
#include "googleurl/src/gurl.h"
+class FilePath;
+class PluginInstallerObserver;
+
+namespace net {
+class URLRequestContextGetter;
+}
+
class PluginInstaller {
public:
+ enum State {
+ kStateIdle,
+ kStateDownloading,
+ };
+
PluginInstaller(const std::string& identifier,
const GURL& plugin_url,
const GURL& help_url,
@@ -18,6 +31,11 @@ class PluginInstaller {
bool url_for_display);
~PluginInstaller();
+ void AddObserver(PluginInstallerObserver* observer);
+ void RemoveObserver(PluginInstallerObserver* observer);
+
+ State state() const { return state_; }
+
// Unique identifier for the plug-in. Should be kept in sync with the
// identifier in plugin_list.cc.
const std::string& identifier() const { return identifier_; }
@@ -35,7 +53,14 @@ class PluginInstaller {
// URL to open when the user clicks on the "Problems installing?" link.
const GURL& help_url() const { return help_url_; }
+ void StartInstalling(net::URLRequestContextGetter* request_context);
+
private:
+ void DidFinishDownload(const FilePath& downloaded_file);
+
+ State state_;
+ ObserverList<PluginInstallerObserver> observers_;
+
std::string identifier_;
GURL plugin_url_;
GURL help_url_;
diff --git a/chrome/browser/plugin_installer_infobar_delegate.cc b/chrome/browser/plugin_installer_infobar_delegate.cc
index 9c29b6b..e0de3a1 100644
--- a/chrome/browser/plugin_installer_infobar_delegate.cc
+++ b/chrome/browser/plugin_installer_infobar_delegate.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -18,11 +18,13 @@ using content::OpenURLParams;
using content::Referrer;
PluginInstallerInfoBarDelegate::PluginInstallerInfoBarDelegate(
+ PluginInstaller* installer,
InfoBarTabHelper* infobar_helper,
const string16& plugin_name,
const GURL& learn_more_url,
const base::Closure& callback)
: ConfirmInfoBarDelegate(infobar_helper),
+ PluginInstallerObserver(installer),
plugin_name_(plugin_name),
learn_more_url_(learn_more_url),
callback_(callback) {
@@ -84,3 +86,7 @@ bool PluginInstallerInfoBarDelegate::LinkClicked(
owner()->web_contents()->OpenURL(params);
return false;
}
+
+void PluginInstallerInfoBarDelegate::DidStartDownload() {
+ owner()->RemoveInfoBar(this);
+}
diff --git a/chrome/browser/plugin_installer_infobar_delegate.h b/chrome/browser/plugin_installer_infobar_delegate.h
index 3d2f68f..b72da4e 100644
--- a/chrome/browser/plugin_installer_infobar_delegate.h
+++ b/chrome/browser/plugin_installer_infobar_delegate.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -7,16 +7,21 @@
#pragma once
#include "base/callback.h"
+#include "chrome/browser/plugin_installer_observer.h"
#include "chrome/browser/tab_contents/confirm_infobar_delegate.h"
#include "googleurl/src/gurl.h"
// The main purpose for this class is to popup/close the infobar when there is
// a missing plugin.
-class PluginInstallerInfoBarDelegate : public ConfirmInfoBarDelegate {
+class PluginInstallerInfoBarDelegate : public ConfirmInfoBarDelegate,
+ public PluginInstallerObserver {
public:
// Shows an infobar asking whether to install the plugin with the name
// |plugin_name|. When the user accepts, |callback| is called.
- PluginInstallerInfoBarDelegate(InfoBarTabHelper* infobar_helper,
+ // If |installer| is not NULL, registers itself as its observer, to dismiss
+ // the infobar if it's accepted in another tab.
+ PluginInstallerInfoBarDelegate(PluginInstaller* installer,
+ InfoBarTabHelper* infobar_helper,
const string16& plugin_name,
const GURL& learn_more_url,
const base::Closure& callback);
@@ -35,6 +40,9 @@ class PluginInstallerInfoBarDelegate : public ConfirmInfoBarDelegate {
virtual string16 GetLinkText() const OVERRIDE;
virtual bool LinkClicked(WindowOpenDisposition disposition) OVERRIDE;
+ // PluginInstallerObserver:
+ virtual void DidStartDownload() OVERRIDE;
+
string16 plugin_name_;
GURL learn_more_url_;
base::Closure callback_;
diff --git a/chrome/browser/plugin_installer_observer.cc b/chrome/browser/plugin_installer_observer.cc
new file mode 100644
index 0000000..ed210ec
--- /dev/null
+++ b/chrome/browser/plugin_installer_observer.cc
@@ -0,0 +1,25 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/plugin_installer_observer.h"
+
+#include "chrome/browser/plugin_installer.h"
+
+PluginInstallerObserver::PluginInstallerObserver(PluginInstaller* installer)
+ : installer_(installer) {
+ if (installer)
+ installer->AddObserver(this);
+}
+
+PluginInstallerObserver::~PluginInstallerObserver() {
+ if (installer_)
+ installer_->RemoveObserver(this);
+}
+
+void PluginInstallerObserver::DidStartDownload() {
+}
+
+void PluginInstallerObserver::DidFinishDownload() {
+}
+
diff --git a/chrome/browser/plugin_installer_observer.h b/chrome/browser/plugin_installer_observer.h
new file mode 100644
index 0000000..ac5f881
--- /dev/null
+++ b/chrome/browser/plugin_installer_observer.h
@@ -0,0 +1,29 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_PLUGIN_INSTALLER_OBSERVER_H_
+#define CHROME_BROWSER_PLUGIN_INSTALLER_OBSERVER_H_
+#pragma once
+
+class PluginInstaller;
+
+class PluginInstallerObserver {
+ public:
+ explicit PluginInstallerObserver(PluginInstaller* installer);
+ virtual ~PluginInstallerObserver();
+
+ protected:
+ PluginInstaller* installer() { return installer_; }
+
+ private:
+ friend class PluginInstaller;
+
+ virtual void DidStartDownload();
+ virtual void DidFinishDownload();
+
+ // Weak pointer; Owned by PluginFinder, which is a singleton.
+ PluginInstaller* installer_;
+};
+
+#endif // CHROME_BROWSER_PLUGIN_INSTALLER_OBSERVER_H_
diff --git a/chrome/browser/plugin_observer.cc b/chrome/browser/plugin_observer.cc
index 615d953..0f3517f 100644
--- a/chrome/browser/plugin_observer.cc
+++ b/chrome/browser/plugin_observer.cc
@@ -1,9 +1,10 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/plugin_observer.h"
+#include "base/auto_reset.h"
#include "base/bind.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/browser_process.h"
@@ -13,9 +14,12 @@
#include "chrome/browser/plugin_finder.h"
#include "chrome/browser/plugin_installer.h"
#include "chrome/browser/plugin_installer_infobar_delegate.h"
+#include "chrome/browser/plugin_installer_observer.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/tab_contents/confirm_infobar_delegate.h"
+#include "chrome/browser/ui/browser_dialogs.h"
#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
+#include "chrome/browser/ui/tab_modal_confirm_dialog_delegate.h"
#include "chrome/common/render_messages.h"
#include "chrome/common/url_constants.h"
#include "content/browser/renderer_host/render_view_host.h"
@@ -24,6 +28,7 @@
#include "content/public/browser/web_contents_delegate.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources_standard.h"
+#include "grit/theme_resources.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "webkit/plugins/npapi/plugin_group.h"
@@ -32,6 +37,7 @@
using content::OpenURLParams;
using content::Referrer;
using content::UserMetricsAction;
+using content::WebContents;
namespace {
@@ -289,11 +295,101 @@ bool OutdatedPluginInfoBarDelegate::LinkClicked(
return PluginInfoBarDelegate::LinkClicked(disposition);
}
-} // namespace
+class ConfirmInstallDialogDelegate : public TabModalConfirmDialogDelegate,
+ public PluginInstallerObserver {
+ public:
+ ConfirmInstallDialogDelegate(WebContents* web_contents,
+ PluginInstaller* installer);
+
+ // TabModalConfirmDialogDelegate methods:
+ virtual string16 GetTitle() OVERRIDE;
+ virtual string16 GetMessage() OVERRIDE;
+ virtual string16 GetAcceptButtonTitle() OVERRIDE;
+ virtual void OnAccepted() OVERRIDE;
+ virtual void OnCanceled() OVERRIDE;
+ // PluginInstallerObserver methods:
+ virtual void DidStartDownload() OVERRIDE;
+
+ private:
+ net::URLRequestContextGetter* request_context_;
+};
+
+ConfirmInstallDialogDelegate::ConfirmInstallDialogDelegate(
+ WebContents* web_contents,
+ PluginInstaller* installer)
+ : TabModalConfirmDialogDelegate(web_contents),
+ PluginInstallerObserver(installer),
+ request_context_(web_contents->GetBrowserContext()->GetRequestContext()) {
+}
+
+string16 ConfirmInstallDialogDelegate::GetTitle() {
+ return l10n_util::GetStringFUTF16(
+ IDS_PLUGIN_CONFIRM_INSTALL_DIALOG_TITLE, installer()->name());
+}
+
+string16 ConfirmInstallDialogDelegate::GetMessage() {
+ return l10n_util::GetStringFUTF16(IDS_PLUGIN_CONFIRM_INSTALL_DIALOG_MSG,
+ installer()->name());
+}
+
+string16 ConfirmInstallDialogDelegate::GetAcceptButtonTitle() {
+ return l10n_util::GetStringUTF16(
+ IDS_PLUGIN_CONFIRM_INSTALL_DIALOG_ACCEPT_BUTTON);
+}
+
+void ConfirmInstallDialogDelegate::OnAccepted() {
+ installer()->StartInstalling(request_context_);
+}
+
+void ConfirmInstallDialogDelegate::OnCanceled() {
+}
+
+void ConfirmInstallDialogDelegate::DidStartDownload() {
+ Cancel();
+}
+
+} // namespace
// PluginObserver -------------------------------------------------------------
+class PluginObserver::MissingPluginHost : public PluginInstallerObserver {
+ public:
+ MissingPluginHost(PluginObserver* observer,
+ int routing_id,
+ PluginInstaller* installer)
+ : PluginInstallerObserver(installer),
+ observer_(observer),
+ routing_id_(routing_id) {
+ switch (installer->state()) {
+ case PluginInstaller::kStateIdle: {
+ observer->Send(new ChromeViewMsg_FoundMissingPlugin(routing_id_,
+ installer->name()));
+ break;
+ }
+ case PluginInstaller::kStateDownloading: {
+ DidStartDownload();
+ break;
+ }
+ }
+ }
+
+ // PluginInstallerObserver methods:
+ virtual void DidStartDownload() OVERRIDE {
+ observer_->Send(new ChromeViewMsg_StartedDownloadingPlugin(routing_id_));
+ }
+
+ virtual void DidFinishDownload() OVERRIDE {
+ observer_->Send(new ChromeViewMsg_FinishedDownloadingPlugin(routing_id_));
+ }
+
+ private:
+ // Weak pointer; owns us.
+ PluginObserver* observer_;
+
+ int routing_id_;
+};
+
PluginObserver::PluginObserver(TabContentsWrapper* tab_contents)
: content::WebContentsObserver(tab_contents->tab_contents()),
ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)),
@@ -341,14 +437,17 @@ void PluginObserver::OnFindMissingPlugin(int placeholder_id,
void PluginObserver::FoundMissingPlugin(int placeholder_id,
const std::string& mime_type,
PluginInstaller* installer) {
- Send(new ChromeViewMsg_FoundMissingPlugin(placeholder_id, installer->name()));
+ missing_plugins_.push_back(
+ new MissingPluginHost(this, placeholder_id, installer));
InfoBarTabHelper* infobar_helper = tab_contents_->infobar_tab_helper();
- infobar_helper->AddInfoBar(new PluginInstallerInfoBarDelegate(
+ PluginInstallerInfoBarDelegate* delegate = new PluginInstallerInfoBarDelegate(
+ installer,
infobar_helper,
installer->name(),
installer->help_url(),
base::Bind(&PluginObserver::InstallMissingPlugin,
- weak_ptr_factory_.GetWeakPtr(), installer)));
+ weak_ptr_factory_.GetWeakPtr(), installer));
+ infobar_helper->AddInfoBar(delegate);
}
void PluginObserver::DidNotFindMissingPlugin(int placeholder_id,
@@ -364,6 +463,8 @@ void PluginObserver::InstallMissingPlugin(PluginInstaller* installer) {
WebKit::WebReferrerPolicyDefault),
NEW_FOREGROUND_TAB, content::PAGE_TRANSITION_TYPED, false));
} else {
- NOTIMPLEMENTED();
+ browser::ShowTabModalConfirmDialog(
+ new ConfirmInstallDialogDelegate(web_contents(), installer),
+ tab_contents_);
}
}
diff --git a/chrome/browser/plugin_observer.h b/chrome/browser/plugin_observer.h
index 917df14..76399e2 100644
--- a/chrome/browser/plugin_observer.h
+++ b/chrome/browser/plugin_observer.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -6,6 +6,7 @@
#define CHROME_BROWSER_PLUGIN_OBSERVER_H_
#pragma once
+#include "base/memory/scoped_vector.h"
#include "base/memory/weak_ptr.h"
#include "content/public/browser/web_contents_observer.h"
@@ -23,6 +24,8 @@ class PluginObserver : public content::WebContentsObserver {
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
private:
+ class MissingPluginHost;
+
void OnBlockedOutdatedPlugin(const string16& name, const GURL& update_url);
void OnFindMissingPlugin(int placeholder_id, const std::string& mime_type);
@@ -37,6 +40,8 @@ class PluginObserver : public content::WebContentsObserver {
TabContentsWrapper* tab_contents_;
+ ScopedVector<MissingPluginHost> missing_plugins_;
+
DISALLOW_COPY_AND_ASSIGN(PluginObserver);
};
diff --git a/chrome/browser/plugin_test.cc b/chrome/browser/plugin_test.cc
index afc1458..711ef0d 100644
--- a/chrome/browser/plugin_test.cc
+++ b/chrome/browser/plugin_test.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -32,6 +32,7 @@
#include "base/message_loop.h"
#include "base/path_service.h"
#include "base/test/test_timeouts.h"
+#include "chrome/browser/plugin_download_helper.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/test/automation/automation_proxy.h"
@@ -39,6 +40,7 @@
#include "chrome/test/base/ui_test_utils.h"
#include "chrome/test/ui/ui_test.h"
#include "content/browser/net/url_request_mock_http_job.h"
+#include "content/test/test_browser_thread.h"
#include "net/base/net_util.h"
#include "net/url_request/url_request_context_getter.h"
#include "net/url_request/url_request_test_util.h"
@@ -49,7 +51,6 @@
#if defined(OS_WIN)
#include "base/win/registry.h"
-#include "chrome/browser/plugin_download_helper.h"
#endif
class PluginTest : public UITest {
@@ -249,7 +250,9 @@ TEST_F(PluginTest, Silverlight) {
TestPlugin("silverlight.html", "",
TestTimeouts::action_max_timeout_ms(), false);
}
+#endif // defined(OS_WIN)
+#if !defined(OS_CHROMEOS)
namespace {
class TestURLRequestContextGetter : public net::URLRequestContextGetter {
@@ -276,37 +279,38 @@ class TestURLRequestContextGetter : public net::URLRequestContextGetter {
};
} // namespace
+
// This class provides functionality to test the plugin installer download
// file functionality.
-class PluginInstallerDownloadTest
- : public PluginDownloadUrlHelper::DownloadDelegate,
- public testing::Test {
+class PluginInstallerDownloadTest : public testing::Test {
public:
PluginInstallerDownloadTest()
- : success_(false),
- download_helper_(NULL) {}
+ : message_loop_(MessageLoop::TYPE_IO),
+ file_thread_(content::BrowserThread::FILE, &message_loop_),
+ download_helper_(NULL),
+ success_(false) {}
~PluginInstallerDownloadTest() {}
void Start() {
initial_download_path_ = PluginTest::GetTestUrl("flash.html", "", false);
- download_helper_ = new PluginDownloadUrlHelper(
- initial_download_path_.spec(), NULL,
- static_cast<PluginDownloadUrlHelper::DownloadDelegate*>(this));
+ download_helper_ = new PluginDownloadUrlHelper();
TestURLRequestContextGetter* context_getter =
new TestURLRequestContextGetter;
- download_helper_->InitiateDownload(context_getter,
- context_getter->GetIOMessageLoopProxy());
+ download_helper_->InitiateDownload(
+ initial_download_path_,
+ context_getter,
+ base::Bind(&PluginInstallerDownloadTest::OnDownloadCompleted,
+ base::Unretained(this)));
- MessageLoop::current()->PostDelayedTask(
+ message_loop_.PostDelayedTask(
FROM_HERE, MessageLoop::QuitClosure(),
TestTimeouts::action_max_timeout_ms());
}
- virtual void OnDownloadCompleted(const FilePath& download_path,
- bool success) {
- success_ = success;
+ void OnDownloadCompleted(const FilePath& download_path) {
+ success_ = true;
final_download_path_ = download_path;
- MessageLoop::current()->Quit();
+ message_loop_.Quit();
download_helper_ = NULL;
}
@@ -323,6 +327,8 @@ class PluginInstallerDownloadTest
}
private:
+ MessageLoop message_loop_;
+ content::TestBrowserThread file_thread_;
FilePath final_download_path_;
PluginDownloadUrlHelper* download_helper_;
bool success_;
@@ -332,12 +338,11 @@ class PluginInstallerDownloadTest
// This test validates that the plugin downloader downloads the specified file
// to a temporary path with the same file name.
TEST_F(PluginInstallerDownloadTest, PluginInstallerDownloadPathTest) {
- MessageLoop loop(MessageLoop::TYPE_IO);
Start();
- loop.Run();
+ MessageLoop::current()->Run();
EXPECT_TRUE(success());
EXPECT_TRUE(initial_download_path().BaseName().value() ==
final_download_path().BaseName().value());
}
-#endif // defined(OS_WIN)
+#endif // !defined(OS_CHROMEOS)
diff --git a/chrome/browser/resources/plugins_mac.json b/chrome/browser/resources/plugins_mac.json
index 09c1e92..ba0d2b7 100644
--- a/chrome/browser/resources/plugins_mac.json
+++ b/chrome/browser/resources/plugins_mac.json
@@ -50,8 +50,7 @@
"lang": "en-US",
"name": "RealPlayer",
"identifier": "realplayer",
- "url": "http://www.real.com/realplayer/download",
- "displayurl": true
+ "url": "http://director.real.com/realplayer?type=rpsp_mac"
},
{
"mime_types": [
@@ -174,8 +173,7 @@
"lang": "en-US",
"name": "DivX Web Player",
"identifier": "divx-player",
- "url": "http://www.divx.com/en/downloads/divx/mac",
- "displayurl": true
+ "url": "http://www.divx.com/en/downloads/divx/mac"
}
]
} \ No newline at end of file
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 1b3db1a..615079d 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -1780,6 +1780,8 @@
'browser/plugin_installer.h',
'browser/plugin_installer_infobar_delegate.cc',
'browser/plugin_installer_infobar_delegate.h',
+ 'browser/plugin_installer_observer.cc',
+ 'browser/plugin_installer_observer.h',
'browser/plugin_observer.cc',
'browser/plugin_observer.h',
'browser/plugin_prefs.cc',
@@ -4762,10 +4764,6 @@
# Exclude try chrome dialog.
['exclude', '^browser/first_run/try_chrome_dialog_view.cc'],
['exclude', '^browser/first_run/try_chrome_dialog_view.h'],
-
- # Exclude plugin download helper.
- ['exclude', '^browser/plugin_download_helper.cc'],
- ['exclude', '^browser/plugin_download_helper.h'],
],
'conditions': [
['OS=="linux" or use_aura==1',{
diff --git a/chrome/common/render_messages.h b/chrome/common/render_messages.h
index eacfc6b..3c5410d 100644
--- a/chrome/common/render_messages.h
+++ b/chrome/common/render_messages.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -438,6 +438,14 @@ IPC_MESSAGE_ROUTED1(ChromeViewMsg_FoundMissingPlugin,
// Notifies a missing plug-in placeholder that no plug-in has been found.
IPC_MESSAGE_ROUTED0(ChromeViewMsg_DidNotFindMissingPlugin)
+// Notifies a missing plug-in placeholder that we have started downloading
+// the plug-in.
+IPC_MESSAGE_ROUTED0(ChromeViewMsg_StartedDownloadingPlugin)
+
+// Notifies a missing plug-in placeholder that we have finished downloading
+// the plug-in.
+IPC_MESSAGE_ROUTED0(ChromeViewMsg_FinishedDownloadingPlugin)
+
// Specifies the URL as the first parameter (a wstring) and thumbnail as
// binary data as the second parameter.
IPC_MESSAGE_ROUTED3(ChromeViewHostMsg_Thumbnail,
diff --git a/chrome/renderer/plugins/missing_plugin.cc b/chrome/renderer/plugins/missing_plugin.cc
index 07da5d1..842817d 100644
--- a/chrome/renderer/plugins/missing_plugin.cc
+++ b/chrome/renderer/plugins/missing_plugin.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -133,6 +133,10 @@ bool MissingPlugin::OnMessageReceived(const IPC::Message& message) {
OnFoundMissingPlugin)
IPC_MESSAGE_HANDLER(ChromeViewMsg_DidNotFindMissingPlugin,
OnDidNotFindMissingPlugin)
+ IPC_MESSAGE_HANDLER(ChromeViewMsg_StartedDownloadingPlugin,
+ OnStartedDownloadingPlugin)
+ IPC_MESSAGE_HANDLER(ChromeViewMsg_FinishedDownloadingPlugin,
+ OnFinishedDownloadingPlugin)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
@@ -147,6 +151,14 @@ void MissingPlugin::OnDidNotFindMissingPlugin() {
SetMessage(l10n_util::GetStringUTF16(IDS_PLUGIN_NOT_FOUND));
}
+void MissingPlugin::OnStartedDownloadingPlugin() {
+ SetMessage(l10n_util::GetStringUTF16(IDS_PLUGIN_DOWNLOADING));
+}
+
+void MissingPlugin::OnFinishedDownloadingPlugin() {
+ SetMessage(l10n_util::GetStringUTF16(IDS_PLUGIN_INSTALLING));
+}
+
void MissingPlugin::SetMessage(const string16& message) {
message_ = message;
if (!plugin()->web_view()->mainFrame()->isLoading())
diff --git a/chrome/renderer/plugins/missing_plugin.h b/chrome/renderer/plugins/missing_plugin.h
index 4e5481f..bcce19f 100644
--- a/chrome/renderer/plugins/missing_plugin.h
+++ b/chrome/renderer/plugins/missing_plugin.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -44,6 +44,8 @@ class MissingPlugin : public PluginPlaceholder {
void OnFoundMissingPlugin(const string16& plugin_name);
void OnDidNotFindMissingPlugin();
+ void OnStartedDownloadingPlugin();
+ void OnFinishedDownloadingPlugin();
void SetMessage(const string16& message);
void UpdateMessage();