diff options
-rw-r--r-- | chrome/browser/browser_resources.grd | 2 | ||||
-rw-r--r-- | chrome/browser/extensions/pack_extension_job.cc | 52 | ||||
-rw-r--r-- | chrome/browser/extensions/pack_extension_job.h | 48 | ||||
-rw-r--r-- | chrome/browser/resources/extensions_ui.html | 10 | ||||
-rw-r--r-- | chrome/browser/views/extensions/extension_pack_dialog.cc | 100 | ||||
-rw-r--r-- | chrome/chrome.gyp | 2 |
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', |