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 17namespace extensions { 18 19PackExtensionHandler::PackExtensionHandler() { 20} 21 22PackExtensionHandler::~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 32void 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 57void 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 68void 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 78void 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 94void 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 101void PackExtensionHandler::MultiFilesSelected( 102 const std::vector<base::FilePath>& files, void* params) { 103 NOTREACHED(); 104} 105 106void 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 150void 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 201void 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