diff options
-rw-r--r-- | chrome/app/generated_resources.grd | 15 | ||||
-rw-r--r-- | chrome/browser/chrome_plugin_message_filter.cc | 45 | ||||
-rw-r--r-- | chrome/browser/chrome_plugin_message_filter.h | 10 | ||||
-rw-r--r-- | chrome/browser/plugin_download_helper.cc | 100 | ||||
-rw-r--r-- | chrome/browser/plugin_download_helper.h | 57 | ||||
-rw-r--r-- | chrome/browser/plugin_installer.cc | 42 | ||||
-rw-r--r-- | chrome/browser/plugin_installer.h | 27 | ||||
-rw-r--r-- | chrome/browser/plugin_installer_infobar_delegate.cc | 8 | ||||
-rw-r--r-- | chrome/browser/plugin_installer_infobar_delegate.h | 14 | ||||
-rw-r--r-- | chrome/browser/plugin_installer_observer.cc | 25 | ||||
-rw-r--r-- | chrome/browser/plugin_installer_observer.h | 29 | ||||
-rw-r--r-- | chrome/browser/plugin_observer.cc | 113 | ||||
-rw-r--r-- | chrome/browser/plugin_observer.h | 7 | ||||
-rw-r--r-- | chrome/browser/plugin_test.cc | 45 | ||||
-rw-r--r-- | chrome/browser/resources/plugins_mac.json | 6 | ||||
-rw-r--r-- | chrome/chrome_browser.gypi | 6 | ||||
-rw-r--r-- | chrome/common/render_messages.h | 10 | ||||
-rw-r--r-- | chrome/renderer/plugins/missing_plugin.cc | 14 | ||||
-rw-r--r-- | chrome/renderer/plugins/missing_plugin.h | 4 |
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(); |