diff options
author | aa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-01 00:12:02 +0000 |
---|---|---|
committer | aa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-01 00:12:02 +0000 |
commit | 25e02aca12eabfdcd8ba0506ce242cf91ef54150 (patch) | |
tree | 8886296a844e7e2b5338b4ef9a146aaf8f257dd1 /chrome | |
parent | 6fd3e87645a59cbc5d28b2173ead9004ce22559e (diff) | |
download | chromium_src-25e02aca12eabfdcd8ba0506ce242cf91ef54150.zip chromium_src-25e02aca12eabfdcd8ba0506ce242cf91ef54150.tar.gz chromium_src-25e02aca12eabfdcd8ba0506ce242cf91ef54150.tar.bz2 |
Rollback 22228
TBR=mpcomplete@chromium.org
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@22231 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/download/download_manager.cc | 15 | ||||
-rw-r--r-- | chrome/browser/extensions/crx_installer.cc | 177 | ||||
-rw-r--r-- | chrome/browser/extensions/crx_installer.h | 96 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_install_ui.cc | 118 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_install_ui.h | 39 | ||||
-rw-r--r-- | chrome/browser/extensions/extensions_service.cc | 71 | ||||
-rw-r--r-- | chrome/browser/extensions/extensions_service.h | 18 | ||||
-rw-r--r-- | chrome/browser/extensions/sandboxed_extension_unpacker.cc | 13 | ||||
-rw-r--r-- | chrome/browser/extensions/sandboxed_extension_unpacker.h | 2 | ||||
-rw-r--r-- | chrome/browser/extensions/theme_preview_infobar_delegate.cc | 13 | ||||
-rw-r--r-- | chrome/browser/extensions/theme_preview_infobar_delegate.h | 1 | ||||
-rw-r--r-- | chrome/chrome.gyp | 2 |
12 files changed, 189 insertions, 376 deletions
diff --git a/chrome/browser/download/download_manager.cc b/chrome/browser/download/download_manager.cc index 9609292..9c548d2 100644 --- a/chrome/browser/download/download_manager.cc +++ b/chrome/browser/download/download_manager.cc @@ -19,7 +19,6 @@ #include "chrome/browser/browser_list.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/download/download_file.h" -#include "chrome/browser/extensions/extension_install_ui.h" #include "chrome/browser/extensions/extensions_service.h" #include "chrome/browser/profile.h" #include "chrome/browser/renderer_host/render_process_host.h" @@ -1252,17 +1251,9 @@ void DownloadManager::OpenChromeExtension(const FilePath& full_path, const GURL& download_url, const GURL& referrer_url) { // We don't support extensions in OTR mode. - ExtensionsService* service = profile_->GetExtensionsService(); - if (service) { - CrxInstaller::Start(full_path, - service->install_directory(), - Extension::INTERNAL, - "", // no expected id - true, // please delete crx on completion - g_browser_process->file_thread()->message_loop(), - service, - new ExtensionInstallUI(profile_)); - } + if (profile_->GetExtensionsService()) + profile_->GetExtensionsService()->InstallExtension(full_path, download_url, + referrer_url); } void DownloadManager::OpenDownloadInShell(const DownloadItem* download, diff --git a/chrome/browser/extensions/crx_installer.cc b/chrome/browser/extensions/crx_installer.cc index 42d156a..6b6c732 100644 --- a/chrome/browser/extensions/crx_installer.cc +++ b/chrome/browser/extensions/crx_installer.cc @@ -14,48 +14,38 @@ #include "chrome/common/extensions/extension_error_reporter.h" #include "grit/chromium_strings.h" -namespace { - // Helper function to delete files. This is used to avoid ugly casts which - // would be necessary with PostMessage since file_util::Delete is overloaded. - static void DeleteFileHelper(const FilePath& path, bool recursive) { - file_util::Delete(path, recursive); - } -} - -void CrxInstaller::Start(const FilePath& crx_path, - const FilePath& install_directory, - Extension::Location install_source, - const std::string& expected_id, - bool delete_crx, - MessageLoop* file_loop, - ExtensionsService* frontend, - CrxInstallerClient* client) { - // Note: We don't keep a reference because this object manages its own - // lifetime. - new CrxInstaller(crx_path, install_directory, install_source, expected_id, - delete_crx, file_loop, frontend, client); -} +#if defined(OS_WIN) +#include "app/win_util.h" +#elif defined(OS_MACOSX) +#include "base/scoped_cftyperef.h" +#include "base/sys_string_conversions.h" +#include <CoreFoundation/CFUserNotification.h> +#endif CrxInstaller::CrxInstaller(const FilePath& crx_path, const FilePath& install_directory, Extension::Location install_source, const std::string& expected_id, + bool extensions_enabled, + bool is_from_gallery, + bool show_prompts, bool delete_crx, MessageLoop* file_loop, - ExtensionsService* frontend, - CrxInstallerClient* client) + ExtensionsService* frontend) : crx_path_(crx_path), install_directory_(install_directory), install_source_(install_source), expected_id_(expected_id), + extensions_enabled_(extensions_enabled), + is_from_gallery_(is_from_gallery), + show_prompts_(show_prompts), delete_crx_(delete_crx), file_loop_(file_loop), - frontend_(frontend), - client_(client), ui_loop_(MessageLoop::current()) { - extensions_enabled_ = frontend_->extensions_enabled(); - + // Note: this is a refptr so that we keep the frontend alive long enough to + // get our response. + frontend_ = frontend; unpacker_ = new SandboxedExtensionUnpacker( crx_path, g_browser_process->resource_dispatcher_host(), this); @@ -63,40 +53,31 @@ CrxInstaller::CrxInstaller(const FilePath& crx_path, &SandboxedExtensionUnpacker::Start)); } -CrxInstaller::~CrxInstaller() { - // Delete the temp directory and crx file as necessary. Note that the - // destructor might be called on any thread, so we post a task to the file - // thread to make sure the delete happens there. - if (!temp_dir_.value().empty()) { - file_loop_->PostTask(FROM_HERE, NewRunnableFunction(&DeleteFileHelper, - temp_dir_, true)); // recursive delete - } - - if (delete_crx_) { - file_loop_->PostTask(FROM_HERE, NewRunnableFunction(&DeleteFileHelper, - crx_path_, false)); // non-recursive delete - } -} - void CrxInstaller::OnUnpackFailure(const std::string& error_message) { - DCHECK(MessageLoop::current() == file_loop_); ReportFailureFromFileThread(error_message); } void CrxInstaller::OnUnpackSuccess(const FilePath& temp_dir, const FilePath& extension_dir, Extension* extension) { - DCHECK(MessageLoop::current() == file_loop_); - // Note: We take ownership of |extension| and |temp_dir|. extension_.reset(extension); temp_dir_ = temp_dir; + // temp_dir_deleter is stack allocated instead of a member of CrxInstaller, so + // that delete always happens on the file thread. + ScopedTempDir temp_dir_deleter; + temp_dir_deleter.Set(temp_dir); + // The unpack dir we don't have to delete explicity since it is a child of // the temp dir. unpacked_extension_root_ = extension_dir; DCHECK(file_util::ContainsPath(temp_dir_, unpacked_extension_root_)); + // If we were supposed to delete the source file, we can do that now. + if (delete_crx_) + file_util::Delete(crx_path_, false); // non-recursive + // Determine whether to allow installation. We always allow themes and // external installs. if (!extensions_enabled_ && !extension->IsTheme() && @@ -108,36 +89,59 @@ void CrxInstaller::OnUnpackSuccess(const FilePath& temp_dir, // Make sure the expected id matches. // TODO(aa): Also support expected version? if (!expected_id_.empty() && expected_id_ != extension->id()) { - ReportFailureFromFileThread(StringPrintf( - "ID in new extension manifest (%s) does not match expected id (%s)", - extension->id().c_str(), - expected_id_.c_str())); + ReportFailureFromFileThread( + StringPrintf("ID in new extension manifest (%s) does not match " + "expected id (%s)", + extension->id().c_str(), + expected_id_.c_str())); return; } - if (client_.get()) { - ui_loop_->PostTask(FROM_HERE, NewRunnableMethod(this, - &CrxInstaller::ConfirmInstall)); - } else { - CompleteInstall(); + // Show the confirm UI if necessary. + // NOTE: We also special case themes to not have a dialog, because we show + // a special infobar UI for them instead. + if (show_prompts_ && !extension->IsTheme()) { + if (!ConfirmInstall()) + return; // error reported by ConfirmInstall() } + + CompleteInstall(); } -void CrxInstaller::ConfirmInstall() { - if (!client_->ConfirmInstall(extension_.get())) { - // We're done. Since we don't post any more tasks to ourselves, our ref - // count should go to zero and we die. The destructor will clean up the temp - // dir. - return; +bool CrxInstaller::ConfirmInstall() { +#if defined(OS_WIN) + if (win_util::MessageBox(GetForegroundWindow(), + L"Are you sure you want to install this extension?\n\n" + L"You should only install extensions from sources you trust.", + l10n_util::GetString(IDS_PRODUCT_NAME).c_str(), + MB_OKCANCEL) != IDOK) { + ReportFailureFromFileThread("User did not allow extension to be " + "installed."); + return false; } +#elif defined(OS_MACOSX) + // Using CoreFoundation to do this dialog is unimaginably lame but will do + // until the UI is redone. + scoped_cftyperef<CFStringRef> product_name( + base::SysWideToCFStringRef(l10n_util::GetString(IDS_PRODUCT_NAME))); + CFOptionFlags response; + if (kCFUserNotificationAlternateResponse == CFUserNotificationDisplayAlert( + 0, kCFUserNotificationCautionAlertLevel, NULL, NULL, NULL, + product_name, + CFSTR("Are you sure you want to install this extension?\n\n" + "This is a temporary message and it will be removed when " + "extensions UI is finalized."), + NULL, CFSTR("Cancel"), NULL, &response)) { + ReportFailureFromFileThread("User did not allow extension to be " + "installed."); + return false; + } +#endif // OS_* - file_loop_->PostTask(FROM_HERE, NewRunnableMethod(this, - &CrxInstaller::CompleteInstall)); + return true; } void CrxInstaller::CompleteInstall() { - DCHECK(MessageLoop::current() == file_loop_); - FilePath version_dir; Extension::InstallType install_type = Extension::INSTALL_ERROR; std::string error_msg; @@ -169,57 +173,22 @@ void CrxInstaller::CompleteInstall() { } void CrxInstaller::ReportFailureFromFileThread(const std::string& error) { - DCHECK(MessageLoop::current() == file_loop_); ui_loop_->PostTask(FROM_HERE, NewRunnableMethod(this, &CrxInstaller::ReportFailureFromUIThread, error)); } void CrxInstaller::ReportFailureFromUIThread(const std::string& error) { - DCHECK(MessageLoop::current() == ui_loop_); - - // This isn't really necessary, it is only used because unit tests expect to - // see errors get reported via this interface. - // - // TODO(aa): Need to go through unit tests and clean them up too, probably get - // rid of this line. - ExtensionErrorReporter::GetInstance()->ReportError(error, false); // quiet - - if (client_) - client_->OnInstallFailure(error); + ExtensionErrorReporter::GetInstance()->ReportError(error, show_prompts_); } void CrxInstaller::ReportOverinstallFromFileThread() { - DCHECK(MessageLoop::current() == file_loop_); - ui_loop_->PostTask(FROM_HERE, NewRunnableMethod(this, - &CrxInstaller::ReportOverinstallFromUIThread)); -} - -void CrxInstaller::ReportOverinstallFromUIThread() { - DCHECK(MessageLoop::current() == ui_loop_); - - if (client_.get()) - client_->OnOverinstallAttempted(extension_.get()); - - frontend_->OnExtensionOverinstallAttempted(extension_->id()); + ui_loop_->PostTask(FROM_HERE, NewRunnableMethod(frontend_.get(), + &ExtensionsService::OnExtensionOverinstallAttempted, extension_->id())); } void CrxInstaller::ReportSuccessFromFileThread() { - DCHECK(MessageLoop::current() == file_loop_); - ui_loop_->PostTask(FROM_HERE, NewRunnableMethod(this, - &CrxInstaller::ReportSuccessFromUIThread)); -} - -void CrxInstaller::ReportSuccessFromUIThread() { - DCHECK(MessageLoop::current() == ui_loop_); - - // If there is a client, tell the client about installation. - if (client_.get()) - client_->OnInstallSuccess(extension_.get()); - // Tell the frontend about the installation and hand off ownership of // extension_ to it. - frontend_->OnExtensionInstalled(extension_.release()); - - // We're done. We don't post any more tasks to ourselves so we are deleted - // soon. + ui_loop_->PostTask(FROM_HERE, NewRunnableMethod(frontend_.get(), + &ExtensionsService::OnExtensionInstalled, extension_.release())); } diff --git a/chrome/browser/extensions/crx_installer.h b/chrome/browser/extensions/crx_installer.h index 5c373d9..9e5ff7c 100644 --- a/chrome/browser/extensions/crx_installer.h +++ b/chrome/browser/extensions/crx_installer.h @@ -14,28 +14,6 @@ #include "chrome/browser/extensions/sandboxed_extension_unpacker.h" #include "chrome/common/extensions/extension.h" -// Classes that want to know about install completion, or that want to have an -// opportunity to reject the unpacked extension before installation, should -// implement this interface. -class CrxInstallerClient - : public base::RefCountedThreadSafe<CrxInstallerClient> { - public: - virtual ~CrxInstallerClient() {} - - // Return true to indicate that installation should proceed, false otherwise. - virtual bool ConfirmInstall(Extension* extension) = 0; - - // Installation was successful. - virtual void OnInstallSuccess(Extension* extension) = 0; - - // Intallation failed. - virtual void OnInstallFailure(const std::string& error) = 0; - - // The install was rejected because the same extension/version is already - // installed. - virtual void OnOverinstallAttempted(Extension* extension) = 0; -}; - // This class installs a crx file into a profile. // // Installing a CRX is a multi-step process, including unpacking the crx, @@ -44,6 +22,7 @@ class CrxInstallerClient // necessary to do its job. (This also minimizes external dependencies for // easier testing). // +// // Lifetime management: // // This class is ref-counted by each call it makes to itself on another thread, @@ -51,54 +30,46 @@ class CrxInstallerClient // // Additionally, we hold a reference to our own client so that it lives at least // long enough to receive the result of unpacking. +// +// +// NOTE: This class is rather huge at the moment because it is handling all +// types of installation (external, autoupdate, and manual). In the future, +// manual installation will probably pulled out of it. // +// TODO(aa): Pull out the manual installation bits. // TODO(aa): Pull out a frontend interface for testing? class CrxInstaller : public SandboxedExtensionUnpackerClient { public: - // Starts the installation of the crx file in |crx_path| into - // |install_directory|. - // - // Other params: - // install_source: The source of the install (external, --load-extension, etc - // expected_id: Optional. If the caller knows what the ID of this extension - // should be after unpacking, it can be specified here as a - // sanity check. - // delete_crx: Whether the crx should be deleted on completion. - // file_loop: The message loop to do file IO on. - // frontend: The ExtensionsService to report the successfully installed - // extension to. - // client: Optional. If specified, will be used to confirm installation and - // also notified of success/fail. Note that we hold a reference to - // this, so it can outlive its creator (eg the UI). - static void Start(const FilePath& crx_path, - const FilePath& install_directory, - Extension::Location install_source, - const std::string& expected_id, - bool delete_crx, - MessageLoop* file_loop, - ExtensionsService* frontend, - CrxInstallerClient* client); - - private: CrxInstaller(const FilePath& crx_path, const FilePath& install_directory, Extension::Location install_source, const std::string& expected_id, + bool extensions_enabled, + bool is_from_gallery, + bool show_prompts, bool delete_crx, MessageLoop* file_loop, - ExtensionsService* frontend, - CrxInstallerClient* client); - ~CrxInstaller(); + ExtensionsService* frontend); + ~CrxInstaller() { + // This is only here for debugging purposes, as a convenient place to set + // breakpoints. + } + private: // SandboxedExtensionUnpackerClient virtual void OnUnpackFailure(const std::string& error_message); virtual void OnUnpackSuccess(const FilePath& temp_dir, const FilePath& extension_dir, Extension* extension); - // Runs on the UI thread. Confirms with the user (via CrxInstallerClient) that - // it is OK to install this extension. - void ConfirmInstall(); + // Confirm with the user that it is OK to install this extension. + // + // Note that this runs on the file thread. It happens to be OK to do this on + // Windows and Mac, and although ugly, we leave it because this is all getting + // pulled out soon, anyway. + // + // TODO(aa): Pull this up, closer to the UI layer. + bool ConfirmInstall(); // Runs on File thread. Install the unpacked extension into the profile and // notify the frontend. @@ -108,9 +79,7 @@ class CrxInstaller : public SandboxedExtensionUnpackerClient { void ReportFailureFromFileThread(const std::string& error); void ReportFailureFromUIThread(const std::string& error); void ReportOverinstallFromFileThread(); - void ReportOverinstallFromUIThread(); void ReportSuccessFromFileThread(); - void ReportSuccessFromUIThread(); // The crx file we're installing. FilePath crx_path_; @@ -127,11 +96,18 @@ class CrxInstaller : public SandboxedExtensionUnpackerClient { // extension to contain. std::string expected_id_; - // Whether manual extension installation is enabled. We can't just check this - // before trying to install because themes are special-cased to always be - // allowed. + // Whether extension installation is set. We can't just check this before + // trying to install because themes are special-cased to always be allowed. bool extensions_enabled_; + // Whether this installation was initiated from the gallery. We trust it more + // and have special UI if it was. + bool is_from_gallery_; + + // Whether we shoud should show prompts. This is sometimes false for testing + // and autoupdate. + bool show_prompts_; + // Whether we're supposed to delete the source crx file on destruction. bool delete_crx_; @@ -152,10 +128,6 @@ class CrxInstaller : public SandboxedExtensionUnpackerClient { // The frontend we will report results back to. scoped_refptr<ExtensionsService> frontend_; - // The client we will work with to do the installation. This can be NULL, in - // which case the install is silent. - scoped_refptr<CrxInstallerClient> client_; - // The root of the unpacked extension directory. This is a subdirectory of // temp_dir_, so we don't have to delete it explicitly. FilePath unpacked_extension_root_; diff --git a/chrome/browser/extensions/extension_install_ui.cc b/chrome/browser/extensions/extension_install_ui.cc deleted file mode 100644 index 4416701..0000000 --- a/chrome/browser/extensions/extension_install_ui.cc +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright (c) 2009 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/extensions/extension_install_ui.h" - -#include "app/l10n_util.h" -#include "grit/chromium_strings.h" -#include "chrome/browser/browser_list.h" -#include "chrome/browser/extensions/theme_preview_infobar_delegate.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/tab_contents/tab_contents.h" - -#if defined(OS_WIN) -#include "app/win_util.h" -#elif defined(OS_MACOSX) -#include "base/scoped_cftyperef.h" -#include "base/sys_string_conversions.h" -#include <CoreFoundation/CFUserNotification.h> -#endif - -ExtensionInstallUI::ExtensionInstallUI(Profile* profile) - : profile_(profile), ui_loop_(MessageLoop::current()) { -} - -bool ExtensionInstallUI::ConfirmInstall(Extension* extension) { - DCHECK(ui_loop_ == MessageLoop::current()); - - // We special-case themes to not show any confirm UI. Instead they are - // immediately installed, and then we show an infobar (see OnInstallSuccess) - // to allow the user to revert if they don't like it. - if (extension->IsTheme()) - return true; - -#if defined(OS_WIN) - if (win_util::MessageBox(GetForegroundWindow(), - L"Are you sure you want to install this extension?\n\n" - L"You should only install extensions from sources you trust.", - l10n_util::GetString(IDS_PRODUCT_NAME).c_str(), - MB_OKCANCEL) != IDOK) { - return false; - } -#elif defined(OS_MACOSX) - // Using CoreFoundation to do this dialog is unimaginably lame but will do - // until the UI is redone. - scoped_cftyperef<CFStringRef> product_name( - base::SysWideToCFStringRef(l10n_util::GetString(IDS_PRODUCT_NAME))); - CFOptionFlags response; - if (kCFUserNotificationAlternateResponse == CFUserNotificationDisplayAlert( - 0, kCFUserNotificationCautionAlertLevel, NULL, NULL, NULL, - product_name, - CFSTR("Are you sure you want to install this extension?\n\n" - "This is a temporary message and it will be removed when " - "extensions UI is finalized."), - NULL, CFSTR("Cancel"), NULL, &response)) { - return false; - } -#else - NOTREACHED(); -#endif // OS_* - - return true; -} - -void ExtensionInstallUI::OnInstallSuccess(Extension* extension) { - ShowThemeInfoBar(extension); -} - -void ExtensionInstallUI::OnInstallFailure(const std::string& error) { - DCHECK(ui_loop_ == MessageLoop::current()); - -#if defined(OS_WIN) - win_util::MessageBox(NULL, UTF8ToWide(error), L"Extension Install Error", - MB_OK | MB_SETFOREGROUND); -#elif defined(OS_MACOSX) - // There must be a better way to do this, for all platforms. - scoped_cftyperef<CFStringRef> message_cf( - base::SysUTF8ToCFStringRef(error)); - CFOptionFlags response; - CFUserNotificationDisplayAlert( - 0, kCFUserNotificationCautionAlertLevel, NULL, NULL, NULL, - CFSTR("Extension Install Error"), message_cf, - NULL, NULL, NULL, &response); -#else - LOG(ERROR) << "Extension install failed: " << error.c_str(); - NOTREACHED(); -#endif -} - -void ExtensionInstallUI::OnOverinstallAttempted(Extension* extension) { - ShowThemeInfoBar(extension); -} - -void ExtensionInstallUI::ShowThemeInfoBar(Extension* extension) { - if (!extension->IsTheme()) - return; - - Browser* browser = BrowserList::GetLastActiveWithProfile(profile_); - if (!browser) - return; - - TabContents* tab_contents = browser->GetSelectedTabContents(); - if (!tab_contents) - return; - - // First remove any previous theme preview infobar. - for (int i = 0; i < tab_contents->infobar_delegate_count(); ++i) { - InfoBarDelegate* delegate = tab_contents->GetInfoBarDelegateAt(i); - if (delegate->AsThemePreviewInfobarDelegate()) { - tab_contents->RemoveInfoBar(delegate); - break; - } - } - - // Now add the new one. - tab_contents->AddInfoBar(new ThemePreviewInfobarDelegate( - tab_contents, extension->name())); -} diff --git a/chrome/browser/extensions/extension_install_ui.h b/chrome/browser/extensions/extension_install_ui.h deleted file mode 100644 index 1fc0379..0000000 --- a/chrome/browser/extensions/extension_install_ui.h +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) 2009 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_EXTENSIONS_EXTENSION_INSTALL_UI_H_ -#define CHROME_BROWSER_EXTENSIONS_EXTENSION_INSTALL_UI_H_ - -#include "base/file_path.h" -#include "base/gfx/native_widget_types.h" -#include "base/ref_counted.h" -#include "chrome/browser/extensions/crx_installer.h" - -class ExtensionsService; -class MessageLoop; -class Profile; -class SandboxedExtensionUnpacker; - -// Displays all the UI around extension installation. -// -// TODO(aa): This will become a view and move to browser/views/extensions in the -// future. -class ExtensionInstallUI : public CrxInstallerClient { - public: - ExtensionInstallUI(Profile* profile); - - private: - // CrxInstallerClient - virtual bool ConfirmInstall(Extension* extension); - virtual void OnInstallSuccess(Extension* extension); - virtual void OnInstallFailure(const std::string& error); - virtual void OnOverinstallAttempted(Extension* extension); - - void ShowThemeInfoBar(Extension* extension); - - Profile* profile_; - MessageLoop* ui_loop_; -}; - -#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_INSTALL_UI_H_ diff --git a/chrome/browser/extensions/extensions_service.cc b/chrome/browser/extensions/extensions_service.cc index bf657c7..3302f4d 100644 --- a/chrome/browser/extensions/extensions_service.cc +++ b/chrome/browser/extensions/extensions_service.cc @@ -14,7 +14,9 @@ #include "chrome/browser/extensions/extension_updater.h" #include "chrome/browser/extensions/external_extension_provider.h" #include "chrome/browser/extensions/external_pref_extension_provider.h" +#include "chrome/browser/extensions/theme_preview_infobar_delegate.h" #include "chrome/browser/profile.h" +#include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/extensions/extension.h" #include "chrome/common/extensions/extension_error_reporter.h" @@ -32,16 +34,10 @@ const char* ExtensionsService::kInstallDirectoryName = "Extensions"; const char* ExtensionsService::kCurrentVersionFileName = "Current Version"; -/* const char* ExtensionsService::kGalleryDownloadURLPrefix = "https://dl-ssl.google.com/chrome/"; const char* ExtensionsService::kGalleryURLPrefix = "https://tools.google.com/chrome/"; -*/ -const char* ExtensionsService::kGalleryDownloadURLPrefix = - "http://www.corp.google.com/~glen/chrome/"; -const char* ExtensionsService::kGalleryURLPrefix = - "http://www.corp.google.com/~glen/chrome/"; // static bool ExtensionsService::IsDownloadFromGallery(const GURL& download_url, @@ -112,12 +108,20 @@ void ExtensionsService::Init() { } void ExtensionsService::InstallExtension(const FilePath& extension_path) { - CrxInstaller::Start(extension_path, install_directory_, Extension::INTERNAL, - "", // no expected id - false, // don't delete crx when complete - backend_loop_, - this, - NULL); // no client (silent install) + InstallExtension(extension_path, GURL(), GURL()); +} + +void ExtensionsService::InstallExtension(const FilePath& extension_path, + const GURL& download_url, + const GURL& referrer_url) { + new CrxInstaller(extension_path, install_directory_, Extension::INTERNAL, + "", // no expected id + extensions_enabled_, + IsDownloadFromGallery(download_url, referrer_url), + show_extensions_prompts(), + false, // don't delete crx when complete + backend_loop_, + this); } void ExtensionsService::UpdateExtension(const std::string& id, @@ -128,12 +132,13 @@ void ExtensionsService::UpdateExtension(const std::string& id, return; } - CrxInstaller::Start(extension_path, install_directory_, Extension::INTERNAL, - id, - true, // delete crx when complete - backend_loop_, - this, - NULL); // no client (silent install) + new CrxInstaller(extension_path, install_directory_, Extension::INTERNAL, + id, extensions_enabled_, + false, // not from gallery + show_extensions_prompts(), + true, // delete crx when complete + backend_loop_, + this); } void ExtensionsService::ReloadExtension(const std::string& extension_id) { @@ -306,6 +311,7 @@ void ExtensionsService::OnExtensionInstalled(Extension* extension) { // If the extension is a theme, tell the profile (and therefore ThemeProvider) // to apply it. if (extension->IsTheme()) { + ShowThemePreviewInfobar(extension); NotificationService::current()->Notify( NotificationType::THEME_INSTALLED, Source<ExtensionsService>(this), @@ -327,6 +333,7 @@ void ExtensionsService::OnExtensionInstalled(Extension* extension) { void ExtensionsService::OnExtensionOverinstallAttempted(const std::string& id) { Extension* extension = GetExtensionById(id); if (extension && extension->IsTheme()) { + ShowThemePreviewInfobar(extension); NotificationService::current()->Notify( NotificationType::THEME_INSTALLED, Source<ExtensionsService>(this), @@ -361,6 +368,23 @@ void ExtensionsService::SetProviderForTesting( location, test_provider)); } +bool ExtensionsService::ShowThemePreviewInfobar(Extension* extension) { + if (!profile_) + return false; + + Browser* browser = BrowserList::GetLastActiveWithProfile(profile_); + if (!browser) + return false; + + TabContents* tab_contents = browser->GetSelectedTabContents(); + if (!tab_contents) + return false; + + tab_contents->AddInfoBar(new ThemePreviewInfobarDelegate(tab_contents, + extension->name())); + return true; +} + void ExtensionsService::OnExternalExtensionFound(const std::string& id, const std::string& version, const FilePath& path, @@ -385,11 +409,12 @@ void ExtensionsService::OnExternalExtensionFound(const std::string& id, } } - CrxInstaller::Start(path, install_directory_, location, id, - false, // don't delete crx when complete - backend_loop_, - this, - NULL); // no client (silent install) + new CrxInstaller(path, install_directory_, location, id, extensions_enabled_, + false, // not from gallery + show_extensions_prompts(), + false, // don't delete crx when complete + backend_loop_, + this); } diff --git a/chrome/browser/extensions/extensions_service.h b/chrome/browser/extensions/extensions_service.h index 640700e..67f7c4a 100644 --- a/chrome/browser/extensions/extensions_service.h +++ b/chrome/browser/extensions/extensions_service.h @@ -89,8 +89,6 @@ class ExtensionsService return &extensions_; } - const FilePath& install_directory() const { return install_directory_; } - // Initialize and start all installed extensions. void Init(); @@ -98,14 +96,16 @@ class ExtensionsService // update if an older version is already installed. // For fresh installs, this method also causes the extension to be // immediately loaded. - // TODO(aa): This method can be removed. It is only used by the unit tests, - // and they could use CrxInstaller directly instead. void InstallExtension(const FilePath& extension_path); + // XXX Hack: This is a temporary nasty hack to get theme installation working + // without a dialog. Will be fixed by making ExtensionsService more modular. + void InstallExtension(const FilePath& extension_path, + const GURL& download_url, + const GURL& referrer_url); + // Updates a currently-installed extension with the contents from // |extension_path|. - // TODO(aa): This method can be removed. ExtensionUpdater could use - // CrxInstaller directly instead. virtual void UpdateExtension(const std::string& id, const FilePath& extension_path); @@ -195,6 +195,12 @@ class ExtensionsService bool is_ready() { return ready_; } private: + // Show a confirm installation infobar on the currently active tab. + // TODO(aa): This should be moved up into the UI and attached to the tab it + // actually occured in. This requires some modularization of + // ExtensionsService. + bool ShowThemePreviewInfobar(Extension* extension); + // The profile this ExtensionsService is part of. Profile* profile_; diff --git a/chrome/browser/extensions/sandboxed_extension_unpacker.cc b/chrome/browser/extensions/sandboxed_extension_unpacker.cc index 46a8382..8048ff2 100644 --- a/chrome/browser/extensions/sandboxed_extension_unpacker.cc +++ b/chrome/browser/extensions/sandboxed_extension_unpacker.cc @@ -28,15 +28,11 @@ const char SandboxedExtensionUnpacker::kExtensionHeaderMagic[] = "Cr24"; SandboxedExtensionUnpacker::SandboxedExtensionUnpacker( const FilePath& crx_path, ResourceDispatcherHost* rdh, SandboxedExtensionUnpackerClient* client) - : crx_path_(crx_path), file_loop_(NULL), rdh_(rdh), client_(client), - got_response_(false) { + : crx_path_(crx_path), client_loop_(MessageLoop::current()), rdh_(rdh), + client_(client), got_response_(false) { } void SandboxedExtensionUnpacker::Start() { - // We assume that we are started on the thread that the client wants us to do - // file IO on. - file_loop_ = MessageLoop::current(); - // Create a temporary directory to work in. if (!temp_dir_.CreateUniqueTempDir()) { ReportFailure("Could not create temporary directory."); @@ -76,13 +72,13 @@ void SandboxedExtensionUnpacker::Start() { void SandboxedExtensionUnpacker::StartProcessOnIOThread( const FilePath& temp_crx_path) { - UtilityProcessHost* host = new UtilityProcessHost(rdh_, this, file_loop_); + UtilityProcessHost* host = new UtilityProcessHost(rdh_, this, + MessageLoop::current()); host->StartExtensionUnpacker(temp_crx_path); } void SandboxedExtensionUnpacker::OnUnpackExtensionSucceeded( const DictionaryValue& manifest) { - DCHECK(file_loop_ == MessageLoop::current()); got_response_ = true; ExtensionUnpacker::DecodedImages images; @@ -168,7 +164,6 @@ void SandboxedExtensionUnpacker::OnUnpackExtensionSucceeded( void SandboxedExtensionUnpacker::OnUnpackExtensionFailed( const std::string& error) { - DCHECK(file_loop_ == MessageLoop::current()); got_response_ = true; ReportFailure(error); } diff --git a/chrome/browser/extensions/sandboxed_extension_unpacker.h b/chrome/browser/extensions/sandboxed_extension_unpacker.h index e6fe25c..02b34fb 100644 --- a/chrome/browser/extensions/sandboxed_extension_unpacker.h +++ b/chrome/browser/extensions/sandboxed_extension_unpacker.h @@ -124,7 +124,7 @@ class SandboxedExtensionUnpacker : public UtilityProcessHost::Client { void ReportSuccess(); FilePath crx_path_; - MessageLoop* file_loop_; + MessageLoop* client_loop_; ResourceDispatcherHost* rdh_; scoped_refptr<SandboxedExtensionUnpackerClient> client_; ScopedTempDir temp_dir_; diff --git a/chrome/browser/extensions/theme_preview_infobar_delegate.cc b/chrome/browser/extensions/theme_preview_infobar_delegate.cc index d22ebda..75c1ce8 100644 --- a/chrome/browser/extensions/theme_preview_infobar_delegate.cc +++ b/chrome/browser/extensions/theme_preview_infobar_delegate.cc @@ -16,6 +16,19 @@ ThemePreviewInfobarDelegate::ThemePreviewInfobarDelegate( profile_(tab_contents->profile()), name_(name) { } +bool ThemePreviewInfobarDelegate::EqualsDelegate(InfoBarDelegate* delegate) + const { + // If another infobar of this type is showing, this will prevent us adding + // a new one, we only care if they're the same type, as pressing undo always + // has the same result each time. This does mean that the text continues + // to refer to the old theme, but this is good enough for beta. + // http://crbug.com/17932 + if (delegate->AsThemePreviewInfobarDelegate()) + return true; + + return false; +} + void ThemePreviewInfobarDelegate::InfoBarClosed() { delete this; } diff --git a/chrome/browser/extensions/theme_preview_infobar_delegate.h b/chrome/browser/extensions/theme_preview_infobar_delegate.h index 54a8507..0d2b564 100644 --- a/chrome/browser/extensions/theme_preview_infobar_delegate.h +++ b/chrome/browser/extensions/theme_preview_infobar_delegate.h @@ -18,6 +18,7 @@ class ThemePreviewInfobarDelegate : public ConfirmInfoBarDelegate { public: ThemePreviewInfobarDelegate(TabContents* tab_contents, const std::string& name); + virtual bool EqualsDelegate(InfoBarDelegate* delegate) const; virtual void InfoBarClosed(); virtual std::wstring GetMessageText() const; virtual SkBitmap* GetIcon() const; diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp index 3362fed..dd70419 100644 --- a/chrome/chrome.gyp +++ b/chrome/chrome.gyp @@ -955,8 +955,6 @@ 'browser/extensions/extension_function_dispatcher.h', 'browser/extensions/extension_host.cc', 'browser/extensions/extension_host.h', - 'browser/extensions/extension_install_ui.cc', - 'browser/extensions/extension_install_ui.h', 'browser/extensions/extension_message_service.cc', 'browser/extensions/extension_message_service.h', 'browser/extensions/extension_browser_event_router.cc', |