Home | History | Annotate | Download | only in extensions
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/ui/webui/extensions/pack_extension_handler.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/strings/utf_string_conversions.h"
      9 #include "chrome/browser/extensions/extension_creator.h"
     10 #include "chrome/browser/ui/chrome_select_file_policy.h"
     11 #include "content/public/browser/web_contents.h"
     12 #include "content/public/browser/web_contents_view.h"
     13 #include "content/public/browser/web_ui.h"
     14 #include "content/public/browser/web_ui_data_source.h"
     15 #include "grit/generated_resources.h"
     16 #include "ui/base/l10n/l10n_util.h"
     17 
     18 namespace extensions {
     19 
     20 PackExtensionHandler::PackExtensionHandler() {
     21 }
     22 
     23 PackExtensionHandler::~PackExtensionHandler() {
     24   // There may be pending file dialogs, we need to tell them that we've gone
     25   // away so they don't try and call back to us.
     26   if (load_extension_dialog_.get())
     27     load_extension_dialog_->ListenerDestroyed();
     28 
     29   if (pack_job_.get())
     30     pack_job_->ClearClient();
     31 }
     32 
     33 void PackExtensionHandler::GetLocalizedValues(
     34     content::WebUIDataSource* source) {
     35   source->AddString("packExtensionOverlay",
     36       l10n_util::GetStringUTF16(IDS_EXTENSION_PACK_DIALOG_TITLE));
     37   source->AddString("packExtensionHeading",
     38       l10n_util::GetStringUTF16(IDS_EXTENSION_PACK_DIALOG_HEADING));
     39   source->AddString("packExtensionCommit",
     40       l10n_util::GetStringUTF16(IDS_EXTENSION_PACK_BUTTON));
     41   source->AddString("ok", l10n_util::GetStringUTF16(IDS_OK));
     42   source->AddString("cancel", l10n_util::GetStringUTF16(IDS_CANCEL));
     43   source->AddString("packExtensionRootDir",
     44       l10n_util::GetStringUTF16(
     45           IDS_EXTENSION_PACK_DIALOG_ROOT_DIRECTORY_LABEL));
     46   source->AddString("packExtensionPrivateKey",
     47       l10n_util::GetStringUTF16(IDS_EXTENSION_PACK_DIALOG_PRIVATE_KEY_LABEL));
     48   source->AddString("packExtensionBrowseButton",
     49       l10n_util::GetStringUTF16(IDS_EXTENSION_PACK_DIALOG_BROWSE));
     50   source->AddString("packExtensionProceedAnyway",
     51       l10n_util::GetStringUTF16(IDS_EXTENSION_PROCEED_ANYWAY));
     52   source->AddString("packExtensionWarningTitle",
     53       l10n_util::GetStringUTF16(IDS_EXTENSION_PACK_WARNING_TITLE));
     54   source->AddString("packExtensionErrorTitle",
     55       l10n_util::GetStringUTF16(IDS_EXTENSION_PACK_ERROR_TITLE));
     56 }
     57 
     58 void PackExtensionHandler::RegisterMessages() {
     59   web_ui()->RegisterMessageCallback(
     60       "pack",
     61       base::Bind(&PackExtensionHandler::HandlePackMessage,
     62                  base::Unretained(this)));
     63   web_ui()->RegisterMessageCallback(
     64       "packExtensionSelectFilePath",
     65       base::Bind(&PackExtensionHandler::HandleSelectFilePathMessage,
     66                  base::Unretained(this)));
     67 }
     68 
     69 void PackExtensionHandler::OnPackSuccess(const base::FilePath& crx_file,
     70                                          const base::FilePath& pem_file) {
     71   ListValue arguments;
     72   arguments.Append(Value::CreateStringValue(
     73       UTF16ToUTF8(PackExtensionJob::StandardSuccessMessage(
     74           crx_file, pem_file))));
     75   web_ui()->CallJavascriptFunction(
     76       "PackExtensionOverlay.showSuccessMessage", arguments);
     77 }
     78 
     79 void PackExtensionHandler::OnPackFailure(const std::string& error,
     80                                          ExtensionCreator::ErrorType type) {
     81   if (type == ExtensionCreator::kCRXExists) {
     82     base::StringValue error_str(error);
     83     base::StringValue extension_path_str(extension_path_.value());
     84     base::StringValue key_path_str(private_key_path_.value());
     85     base::FundamentalValue overwrite_flag(ExtensionCreator::kOverwriteCRX);
     86 
     87     web_ui()->CallJavascriptFunction(
     88         "ExtensionSettings.askToOverrideWarning", error_str, extension_path_str,
     89             key_path_str, overwrite_flag);
     90   } else {
     91     ShowAlert(error);
     92   }
     93 }
     94 
     95 void PackExtensionHandler::FileSelected(const base::FilePath& path, int index,
     96                                         void* params) {
     97   ListValue results;
     98   results.Append(Value::CreateStringValue(path.value()));
     99   web_ui()->CallJavascriptFunction("window.handleFilePathSelected", results);
    100 }
    101 
    102 void PackExtensionHandler::MultiFilesSelected(
    103     const std::vector<base::FilePath>& files, void* params) {
    104   NOTREACHED();
    105 }
    106 
    107 void PackExtensionHandler::HandlePackMessage(const ListValue* args) {
    108   DCHECK_EQ(3U, args->GetSize());
    109 
    110   double flags_double = 0.0;
    111   base::FilePath::StringType extension_path_str;
    112   base::FilePath::StringType private_key_path_str;
    113   if (!args->GetString(0, &extension_path_str) ||
    114       !args->GetString(1, &private_key_path_str) ||
    115       !args->GetDouble(2, &flags_double)) {
    116     NOTREACHED();
    117     return;
    118   }
    119 
    120   extension_path_ = base::FilePath(extension_path_str);
    121   private_key_path_ = base::FilePath(private_key_path_str);
    122 
    123   int run_flags = static_cast<int>(flags_double);
    124 
    125   base::FilePath root_directory = extension_path_;
    126   base::FilePath key_file = private_key_path_;
    127   last_used_path_ = extension_path_;
    128 
    129   if (root_directory.empty()) {
    130     if (extension_path_.empty()) {
    131       ShowAlert(l10n_util::GetStringUTF8(
    132           IDS_EXTENSION_PACK_DIALOG_ERROR_ROOT_REQUIRED));
    133     } else {
    134       ShowAlert(l10n_util::GetStringUTF8(
    135           IDS_EXTENSION_PACK_DIALOG_ERROR_ROOT_INVALID));
    136     }
    137 
    138     return;
    139   }
    140 
    141   if (!private_key_path_.empty() && key_file.empty()) {
    142     ShowAlert(l10n_util::GetStringUTF8(
    143         IDS_EXTENSION_PACK_DIALOG_ERROR_KEY_INVALID));
    144     return;
    145   }
    146 
    147   pack_job_ = new PackExtensionJob(this, root_directory, key_file, run_flags);
    148   pack_job_->Start();
    149 }
    150 
    151 void PackExtensionHandler::HandleSelectFilePathMessage(
    152     const ListValue* args) {
    153   DCHECK_EQ(2U, args->GetSize());
    154 
    155   std::string select_type;
    156   if (!args->GetString(0, &select_type))
    157     NOTREACHED();
    158 
    159   std::string operation;
    160   if (!args->GetString(1, &operation))
    161     NOTREACHED();
    162 
    163   ui::SelectFileDialog::Type type = ui::SelectFileDialog::SELECT_FOLDER;
    164   ui::SelectFileDialog::FileTypeInfo info;
    165   int file_type_index = 0;
    166   base::FilePath path_to_use = last_used_path_;
    167   if (select_type == "file") {
    168     type = ui::SelectFileDialog::SELECT_OPEN_FILE;
    169     path_to_use = base::FilePath();
    170   }
    171 
    172   string16 select_title;
    173   if (operation == "load") {
    174     select_title = l10n_util::GetStringUTF16(IDS_EXTENSION_LOAD_FROM_DIRECTORY);
    175   } else if (operation == "pem") {
    176     select_title = l10n_util::GetStringUTF16(
    177         IDS_EXTENSION_PACK_DIALOG_SELECT_KEY);
    178     info.extensions.push_back(std::vector<base::FilePath::StringType>());
    179         info.extensions.front().push_back(FILE_PATH_LITERAL("pem"));
    180         info.extension_description_overrides.push_back(
    181             l10n_util::GetStringUTF16(
    182                 IDS_EXTENSION_PACK_DIALOG_KEY_FILE_TYPE_DESCRIPTION));
    183         info.include_all_files = true;
    184     file_type_index = 1;
    185   } else {
    186     NOTREACHED();
    187   }
    188 
    189   load_extension_dialog_ = ui::SelectFileDialog::Create(
    190       this, new ChromeSelectFilePolicy(web_ui()->GetWebContents()));
    191   load_extension_dialog_->SelectFile(
    192       type,
    193       select_title,
    194       path_to_use,
    195       &info,
    196       file_type_index,
    197       base::FilePath::StringType(),
    198       web_ui()->GetWebContents()->GetView()->GetTopLevelNativeWindow(),
    199       NULL);
    200 }
    201 
    202 void PackExtensionHandler::ShowAlert(const std::string& message) {
    203   ListValue arguments;
    204   arguments.Append(Value::CreateStringValue(message));
    205   web_ui()->CallJavascriptFunction("PackExtensionOverlay.showError", arguments);
    206 }
    207 
    208 }  // namespace extensions
    209