summaryrefslogtreecommitdiffstats
path: root/chrome/browser/extensions/crx_installer.cc
diff options
context:
space:
mode:
authoraa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-08-01 00:12:02 +0000
committeraa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-08-01 00:12:02 +0000
commit25e02aca12eabfdcd8ba0506ce242cf91ef54150 (patch)
tree8886296a844e7e2b5338b4ef9a146aaf8f257dd1 /chrome/browser/extensions/crx_installer.cc
parent6fd3e87645a59cbc5d28b2173ead9004ce22559e (diff)
downloadchromium_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/browser/extensions/crx_installer.cc')
-rw-r--r--chrome/browser/extensions/crx_installer.cc177
1 files changed, 73 insertions, 104 deletions
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()));
}