summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/browser_resources.grd2
-rw-r--r--chrome/browser/extensions/pack_extension_job.cc52
-rw-r--r--chrome/browser/extensions/pack_extension_job.h48
-rw-r--r--chrome/browser/resources/extensions_ui.html10
-rw-r--r--chrome/browser/views/extensions/extension_pack_dialog.cc100
-rw-r--r--chrome/chrome.gyp2
6 files changed, 129 insertions, 85 deletions
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd
index b840604..9480db9 100644
--- a/chrome/browser/browser_resources.grd
+++ b/chrome/browser/browser_resources.grd
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- This comment is only here because changes to resources are not picked up
-without changes to the corresponding grd file. aa3 -->
+without changes to the corresponding grd file. aa4 -->
<grit latest_public_release="0" current_release="1">
<outputs>
<output filename="grit/browser_resources.h" type="rc_header">
diff --git a/chrome/browser/extensions/pack_extension_job.cc b/chrome/browser/extensions/pack_extension_job.cc
new file mode 100644
index 0000000..c9c26cf
--- /dev/null
+++ b/chrome/browser/extensions/pack_extension_job.cc
@@ -0,0 +1,52 @@
+// 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/pack_extension_job.h"
+
+#include "base/message_loop.h"
+#include "base/string_util.h"
+#include "base/task.h"
+#include "chrome/browser/extensions/extension_creator.h"
+
+PackExtensionJob::PackExtensionJob(Client* client,
+ const FilePath& root_directory,
+ const FilePath& key_file,
+ MessageLoop* file_loop)
+ : ui_loop_(MessageLoop::current()), file_loop_(file_loop), client_(client),
+ root_directory_(root_directory), key_file_(key_file) {
+ file_loop_->PostTask(FROM_HERE, NewRunnableMethod(this,
+ &PackExtensionJob::RunOnFileThread));
+}
+
+void PackExtensionJob::ClearClient() {
+ client_ = NULL;
+}
+
+void PackExtensionJob::RunOnFileThread() {
+ crx_file_out_ = root_directory_.ReplaceExtension(FILE_PATH_LITERAL("crx"));
+
+ if (key_file_.empty())
+ key_file_out_ = root_directory_.ReplaceExtension(FILE_PATH_LITERAL("pem"));
+
+ // TODO(aa): Need to internationalize the errors that ExtensionCreator
+ // returns. See bug 20734.
+ ExtensionCreator creator;
+ if (creator.Run(root_directory_, crx_file_out_, key_file_, key_file_out_)) {
+ ui_loop_->PostTask(FROM_HERE, NewRunnableMethod(this,
+ &PackExtensionJob::ReportSuccessOnUIThread));
+ } else {
+ ui_loop_->PostTask(FROM_HERE, NewRunnableMethod(this,
+ &PackExtensionJob::ReportFailureOnUIThread, creator.error_message()));
+ }
+}
+
+void PackExtensionJob::ReportSuccessOnUIThread() {
+ if (client_)
+ client_->OnPackSuccess(crx_file_out_, key_file_out_);
+}
+
+void PackExtensionJob::ReportFailureOnUIThread(const std::string& error) {
+ if (client_)
+ client_->OnPackFailure(UTF8ToWide(error));
+}
diff --git a/chrome/browser/extensions/pack_extension_job.h b/chrome/browser/extensions/pack_extension_job.h
new file mode 100644
index 0000000..ec00f21
--- /dev/null
+++ b/chrome/browser/extensions/pack_extension_job.h
@@ -0,0 +1,48 @@
+// 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 <string>
+
+#include "base/file_path.h"
+#include "base/ref_counted.h"
+
+class MessageLoop;
+
+// Manages packing an extension on the file thread and reporting the result
+// back to the UI.
+class PackExtensionJob : public base::RefCounted<PackExtensionJob> {
+ public:
+
+ // Interface for people who want to use PackExtensionJob to implement.
+ class Client {
+ public:
+ virtual void OnPackSuccess(const FilePath& crx_file,
+ const FilePath& key_file) = 0;
+ virtual void OnPackFailure(const std::wstring& message) = 0;
+ };
+
+ PackExtensionJob(Client* client,
+ const FilePath& root_directory,
+ const FilePath& key_file,
+ MessageLoop* file_loop);
+
+ // The client should call this when it is destroyed to prevent
+ // PackExtensionJob from attempting to access it.
+ void ClearClient();
+
+ private:
+ void RunOnFileThread();
+ void ReportSuccessOnUIThread();
+ void ReportFailureOnUIThread(const std::string& error);
+
+ MessageLoop* ui_loop_;
+ MessageLoop* file_loop_;
+ Client* client_;
+ FilePath root_directory_;
+ FilePath key_file_;
+ FilePath crx_file_out_;
+ FilePath key_file_out_;
+
+ DISALLOW_COPY_AND_ASSIGN(PackExtensionJob);
+};
diff --git a/chrome/browser/resources/extensions_ui.html b/chrome/browser/resources/extensions_ui.html
index 86abf84..383fa3d 100644
--- a/chrome/browser/resources/extensions_ui.html
+++ b/chrome/browser/resources/extensions_ui.html
@@ -289,13 +289,13 @@ function packExtension() {
<tr>
<td width="100%" valign="top" align="left">
- <h2>Installed Extensions</h2>
+ <h2>Installed extensions</h2>
<div class="content">
<div id="extensionTemplate">
<div class="extension-name" jsdisplay="extensions.length === 0">
- No Extensions Installed</div>
+ No extensions installed</div>
<div jsdisplay="extensions.length > 0">
<div class="extension" jsselect="extensions">
@@ -307,7 +307,7 @@ function packExtension() {
<div class="extension-details">
<div class="extension-id">ID: <span jscontent="id"></div>
<div class="extension-description" jscontent="description"></div>
- Active Views:
+ Active views:
<ul class="extension-views">
<li jsselect="views"><span jscontent="path"></span> -
<a jsvalues=".extensionView:$this" href="#"
@@ -342,8 +342,8 @@ function packExtension() {
<h2>Tools</h2>
<div class="sidebar-content">
- <button onclick="loadExtension()">Load Unpacked Extension...</button><br />
- <button onclick="packExtension()">Pack Extension...</button>
+ <button onclick="loadExtension()">Load unpacked extension...</button><br />
+ <button onclick="packExtension()">Pack extension...</button>
</div>
</td>
</tr>
diff --git a/chrome/browser/views/extensions/extension_pack_dialog.cc b/chrome/browser/views/extensions/extension_pack_dialog.cc
index 757ab0e..eab0e38 100644
--- a/chrome/browser/views/extensions/extension_pack_dialog.cc
+++ b/chrome/browser/views/extensions/extension_pack_dialog.cc
@@ -8,8 +8,8 @@
#include "chrome/browser/browser_list.h"
#include "chrome/browser/browser_window.h"
#include "chrome/browser/chrome_thread.h"
-#include "chrome/browser/extensions/extension_creator.h"
#include "chrome/browser/extensions/extensions_ui.h"
+#include "chrome/browser/extensions/pack_extension_job.h"
#include "chrome/browser/shell_dialogs.h"
#include "grit/generated_resources.h"
#include "views/controls/label.h"
@@ -17,42 +17,12 @@
#include "views/controls/textfield/textfield.h"
#include "views/standard_layout.h"
#include "views/view.h"
+#include "views/window/dialog_client_view.h"
#include "views/window/dialog_delegate.h"
#include "views/window/window.h"
namespace {
-class PackDialogContent;
-
-// Manages packing an extension on the file thread and reporting the result
-// back to the UI.
-class PackExtensionJob : public base::RefCounted<PackExtensionJob> {
- public:
- PackExtensionJob(PackDialogContent* dialog_content,
- const FilePath& root_directory,
- const FilePath& key_file);
-
- // PackDialogContent calls this when it is closing, so that PackExtensionJob
- // doesn't try to call back to the UI after it's destroyed.
- void OnDialogClosed();
-
- private:
- void RunOnFileThread();
- void ReportSuccessOnUIThread();
- void ReportFailureOnUIThread(const std::string& error);
-
- MessageLoop* ui_loop_;
- MessageLoop* file_loop_;
- PackDialogContent* dialog_content_;
- FilePath root_directory_;
- FilePath key_file_;
- FilePath crx_file_out_;
- FilePath key_file_out_;
-
- DISALLOW_COPY_AND_ASSIGN(PackExtensionJob);
-};
-
-
// Puts up the the pack dialog, which has this basic layout:
//
// Select the extension to pack.
@@ -63,11 +33,12 @@ class PackExtensionJob : public base::RefCounted<PackExtensionJob> {
// [ok] [cancel]
class PackDialogContent
: public views::View,
+ public PackExtensionJob::Client,
public SelectFileDialog::Listener,
public views::ButtonListener,
public views::DialogDelegate {
public:
- PackDialogContent() {
+ PackDialogContent() : ok_button_(NULL) {
using views::GridLayout;
// Setup the layout.
@@ -116,7 +87,10 @@ class PackDialogContent
layout->AddView(private_key_button_);
}
- void OnPackSuccess(const FilePath& crx_file, const FilePath& pem_file) {
+ // PackExtensionJob::Client
+ virtual void OnPackSuccess(const FilePath& crx_file,
+ const FilePath& pem_file) {
+ ok_button_->SetEnabled(true);
std::wstring message;
if (!pem_file.empty()) {
message = l10n_util::GetStringF(
@@ -132,9 +106,10 @@ class PackDialogContent
l10n_util::GetString(IDS_EXTENSION_PACK_DIALOG_SUCCESS_TITLE),
MB_OK | MB_SETFOREGROUND);
GetWindow()->Close();
-}
+ }
void OnPackFailure(const std::wstring& error) {
+ ok_button_->SetEnabled(true);
win_util::MessageBox(GetWindow()->GetNativeWindow(), error,
l10n_util::GetString(IDS_EXTENSION_PACK_DIALOG_FAILURE_TITLE),
MB_OK | MB_SETFOREGROUND);
@@ -165,16 +140,24 @@ class PackDialogContent
return false;
}
- pack_job_ = new PackExtensionJob(this, root_directory, key_file);
+ pack_job_ = new PackExtensionJob(this, root_directory, key_file,
+ ChromeThread::GetMessageLoop(ChromeThread::FILE));
// Prevent the dialog from closing because PackExtensionJob is asynchronous.
// We need to wait to find out if it succeeded before closing the window.
+ //
+ // Also disable the OK button while this is going so the user understands
+ // that something is happening.
+ views::DialogClientView* dialog = static_cast<views::DialogClientView*>(
+ GetWindow()->GetClientView());
+ ok_button_ = dialog->ok_button();
+ ok_button_->SetEnabled(false);
return false;
}
virtual void OnClose() {
if (pack_job_)
- pack_job_->OnDialogClosed();
+ pack_job_->ClearClient();
}
// WindowDelegate
@@ -225,6 +208,7 @@ class PackDialogContent
views::Textfield* private_key_textbox_;
views::NativeButton* extension_root_button_;
views::NativeButton* private_key_button_;
+ views::NativeButton* ok_button_;
scoped_refptr<SelectFileDialog> file_dialog_;
scoped_refptr<PackExtensionJob> pack_job_;
@@ -232,48 +216,6 @@ class PackDialogContent
DISALLOW_COPY_AND_ASSIGN(PackDialogContent);
};
-
-PackExtensionJob::PackExtensionJob(PackDialogContent* dialog_content,
- const FilePath& root_directory,
- const FilePath& key_file)
- : ui_loop_(MessageLoop::current()), dialog_content_(dialog_content),
- root_directory_(root_directory), key_file_(key_file) {
- ChromeThread::GetMessageLoop(ChromeThread::FILE)->PostTask(FROM_HERE,
- NewRunnableMethod(this, &PackExtensionJob::RunOnFileThread));
-}
-
-void PackExtensionJob::OnDialogClosed() {
- dialog_content_ = NULL;
-}
-
-void PackExtensionJob::RunOnFileThread() {
- crx_file_out_ = root_directory_.ReplaceExtension(FILE_PATH_LITERAL("crx"));
-
- if (key_file_.empty())
- key_file_out_ = root_directory_.ReplaceExtension(FILE_PATH_LITERAL("pem"));
-
- // TODO(aa): Need to internationalize the errors that ExtensionCreator
- // returns.
- ExtensionCreator creator;
- if (creator.Run(root_directory_, crx_file_out_, key_file_, key_file_out_)) {
- ui_loop_->PostTask(FROM_HERE, NewRunnableMethod(this,
- &PackExtensionJob::ReportSuccessOnUIThread));
- } else {
- ui_loop_->PostTask(FROM_HERE, NewRunnableMethod(this,
- &PackExtensionJob::ReportFailureOnUIThread, creator.error_message()));
- }
-}
-
-void PackExtensionJob::ReportSuccessOnUIThread() {
- if (dialog_content_)
- dialog_content_->OnPackSuccess(crx_file_out_, key_file_out_);
-}
-
-void PackExtensionJob::ReportFailureOnUIThread(const std::string& error) {
- if (dialog_content_)
- dialog_content_->OnPackFailure(UTF8ToWide(error));
-}
-
} // namespace
// static
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index 2958fe7..1e02c2c 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -1139,6 +1139,8 @@
'browser/extensions/external_registry_extension_provider_win.h',
'browser/extensions/external_pref_extension_provider.cc',
'browser/extensions/external_pref_extension_provider.h',
+ 'browser/extensions/pack_extension_job.cc',
+ 'browser/extensions/pack_extension_job.h',
'browser/extensions/sandboxed_extension_unpacker.cc',
'browser/extensions/sandboxed_extension_unpacker.h',
'browser/extensions/theme_preview_infobar_delegate.cc',