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