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