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