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_ui.h"
     13 #include "content/public/browser/web_ui_data_source.h"
     14 #include "grit/generated_resources.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(base::Value::CreateStringValue(
     72       base::UTF16ToUTF8(PackExtensionJob::StandardSuccessMessage(
     73           crx_file, pem_file))));
     74   web_ui()->CallJavascriptFunction(
     75       "extensions.PackExtensionOverlay.showSuccessMessage", arguments);
     76 }
     77 
     78 void PackExtensionHandler::OnPackFailure(const std::string& error,
     79                                          ExtensionCreator::ErrorType type) {
     80   if (type == ExtensionCreator::kCRXExists) {
     81     base::StringValue error_str(error);
     82     base::StringValue extension_path_str(extension_path_.value());
     83     base::StringValue key_path_str(private_key_path_.value());
     84     base::FundamentalValue overwrite_flag(ExtensionCreator::kOverwriteCRX);
     85 
     86     web_ui()->CallJavascriptFunction(
     87         "extensions.ExtensionSettings.askToOverrideWarning",
     88         error_str, extension_path_str, key_path_str, overwrite_flag);
     89   } else {
     90     ShowAlert(error);
     91   }
     92 }
     93 
     94 void PackExtensionHandler::FileSelected(const base::FilePath& path, int index,
     95                                         void* params) {
     96   base::ListValue results;
     97   results.Append(base::Value::CreateStringValue(path.value()));
     98   web_ui()->CallJavascriptFunction("window.handleFilePathSelected", results);
     99 }
    100 
    101 void PackExtensionHandler::MultiFilesSelected(
    102     const std::vector<base::FilePath>& files, void* params) {
    103   NOTREACHED();
    104 }
    105 
    106 void PackExtensionHandler::HandlePackMessage(const base::ListValue* args) {
    107   DCHECK_EQ(3U, args->GetSize());
    108 
    109   double flags_double = 0.0;
    110   base::FilePath::StringType extension_path_str;
    111   base::FilePath::StringType private_key_path_str;
    112   if (!args->GetString(0, &extension_path_str) ||
    113       !args->GetString(1, &private_key_path_str) ||
    114       !args->GetDouble(2, &flags_double)) {
    115     NOTREACHED();
    116     return;
    117   }
    118 
    119   extension_path_ = base::FilePath(extension_path_str);
    120   private_key_path_ = base::FilePath(private_key_path_str);
    121 
    122   int run_flags = static_cast<int>(flags_double);
    123 
    124   base::FilePath root_directory = extension_path_;
    125   base::FilePath key_file = private_key_path_;
    126   last_used_path_ = extension_path_;
    127 
    128   if (root_directory.empty()) {
    129     if (extension_path_.empty()) {
    130       ShowAlert(l10n_util::GetStringUTF8(
    131           IDS_EXTENSION_PACK_DIALOG_ERROR_ROOT_REQUIRED));
    132     } else {
    133       ShowAlert(l10n_util::GetStringUTF8(
    134           IDS_EXTENSION_PACK_DIALOG_ERROR_ROOT_INVALID));
    135     }
    136 
    137     return;
    138   }
    139 
    140   if (!private_key_path_.empty() && key_file.empty()) {
    141     ShowAlert(l10n_util::GetStringUTF8(
    142         IDS_EXTENSION_PACK_DIALOG_ERROR_KEY_INVALID));
    143     return;
    144   }
    145 
    146   pack_job_ = new PackExtensionJob(this, root_directory, key_file, run_flags);
    147   pack_job_->Start();
    148 }
    149 
    150 void PackExtensionHandler::HandleSelectFilePathMessage(
    151     const base::ListValue* args) {
    152   DCHECK_EQ(2U, args->GetSize());
    153 
    154   std::string select_type;
    155   if (!args->GetString(0, &select_type))
    156     NOTREACHED();
    157 
    158   std::string operation;
    159   if (!args->GetString(1, &operation))
    160     NOTREACHED();
    161 
    162   ui::SelectFileDialog::Type type = ui::SelectFileDialog::SELECT_FOLDER;
    163   ui::SelectFileDialog::FileTypeInfo info;
    164   int file_type_index = 0;
    165   base::FilePath path_to_use = last_used_path_;
    166   if (select_type == "file") {
    167     type = ui::SelectFileDialog::SELECT_OPEN_FILE;
    168     path_to_use = base::FilePath();
    169   }
    170 
    171   base::string16 select_title;
    172   if (operation == "load") {
    173     select_title = l10n_util::GetStringUTF16(IDS_EXTENSION_LOAD_FROM_DIRECTORY);
    174   } else if (operation == "pem") {
    175     select_title = l10n_util::GetStringUTF16(
    176         IDS_EXTENSION_PACK_DIALOG_SELECT_KEY);
    177     info.extensions.push_back(std::vector<base::FilePath::StringType>());
    178         info.extensions.front().push_back(FILE_PATH_LITERAL("pem"));
    179         info.extension_description_overrides.push_back(
    180             l10n_util::GetStringUTF16(
    181                 IDS_EXTENSION_PACK_DIALOG_KEY_FILE_TYPE_DESCRIPTION));
    182         info.include_all_files = true;
    183     file_type_index = 1;
    184   } else {
    185     NOTREACHED();
    186   }
    187 
    188   load_extension_dialog_ = ui::SelectFileDialog::Create(
    189       this, new ChromeSelectFilePolicy(web_ui()->GetWebContents()));
    190   load_extension_dialog_->SelectFile(
    191       type,
    192       select_title,
    193       path_to_use,
    194       &info,
    195       file_type_index,
    196       base::FilePath::StringType(),
    197       web_ui()->GetWebContents()->GetTopLevelNativeWindow(),
    198       NULL);
    199 }
    200 
    201 void PackExtensionHandler::ShowAlert(const std::string& message) {
    202   base::ListValue arguments;
    203   arguments.Append(base::Value::CreateStringValue(message));
    204   web_ui()->CallJavascriptFunction(
    205       "extensions.PackExtensionOverlay.showError", arguments);
    206 }
    207 
    208 }  // namespace extensions
    209