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/install_extension_handler.h" 6 7 #include "base/bind.h" 8 #include "base/strings/string_util.h" 9 #include "base/strings/utf_string_conversions.h" 10 #include "chrome/browser/extensions/crx_installer.h" 11 #include "chrome/browser/extensions/extension_install_prompt.h" 12 #include "chrome/browser/extensions/extension_service.h" 13 #include "chrome/browser/extensions/extension_system.h" 14 #include "chrome/browser/extensions/unpacked_installer.h" 15 #include "chrome/browser/profiles/profile.h" 16 #include "chrome/common/extensions/feature_switch.h" 17 #include "content/public/browser/web_contents.h" 18 #include "content/public/browser/web_contents_view.h" 19 #include "content/public/browser/web_ui.h" 20 #include "content/public/browser/web_ui_data_source.h" 21 #include "content/public/common/drop_data.h" 22 #include "grit/generated_resources.h" 23 #include "net/base/net_util.h" 24 #include "ui/base/l10n/l10n_util.h" 25 26 namespace extensions { 27 28 InstallExtensionHandler::InstallExtensionHandler() { 29 } 30 31 InstallExtensionHandler::~InstallExtensionHandler() { 32 } 33 34 void InstallExtensionHandler::GetLocalizedValues( 35 content::WebUIDataSource* source) { 36 source->AddString( 37 "extensionSettingsInstallDropTarget", 38 l10n_util::GetStringUTF16(IDS_EXTENSIONS_INSTALL_DROP_TARGET)); 39 source->AddBoolean( 40 "offStoreInstallEnabled", 41 FeatureSwitch::easy_off_store_install()->IsEnabled()); 42 } 43 44 void InstallExtensionHandler::RegisterMessages() { 45 web_ui()->RegisterMessageCallback( 46 "startDrag", 47 base::Bind(&InstallExtensionHandler::HandleStartDragMessage, 48 base::Unretained(this))); 49 web_ui()->RegisterMessageCallback( 50 "stopDrag", 51 base::Bind(&InstallExtensionHandler::HandleStopDragMessage, 52 base::Unretained(this))); 53 web_ui()->RegisterMessageCallback( 54 "installDroppedFile", 55 base::Bind(&InstallExtensionHandler::HandleInstallMessage, 56 base::Unretained(this))); 57 web_ui()->RegisterMessageCallback( 58 "installDroppedDirectory", 59 base::Bind(&InstallExtensionHandler::HandleInstallDirectoryMessage, 60 base::Unretained(this))); 61 } 62 63 void InstallExtensionHandler::HandleStartDragMessage(const ListValue* args) { 64 content::DropData* drop_data = 65 web_ui()->GetWebContents()->GetView()->GetDropData(); 66 if (!drop_data) { 67 DLOG(ERROR) << "No current drop data."; 68 return; 69 } 70 71 if (drop_data->filenames.empty()) { 72 DLOG(ERROR) << "Current drop data contains no files."; 73 return; 74 } 75 76 const content::DropData::FileInfo& file_info = drop_data->filenames.front(); 77 78 file_to_install_ = base::FilePath::FromWStringHack( 79 UTF16ToWide(file_info.path)); 80 // Use the display name if provided, for checking file names 81 // (.path is likely a random hash value in that case). 82 file_display_name_ = 83 file_info.display_name.empty() ? file_info.path : file_info.display_name; 84 } 85 86 void InstallExtensionHandler::HandleStopDragMessage(const ListValue* args) { 87 file_to_install_.clear(); 88 file_display_name_.clear(); 89 } 90 91 void InstallExtensionHandler::HandleInstallMessage(const ListValue* args) { 92 if (file_to_install_.empty()) { 93 LOG(ERROR) << "No file captured to install."; 94 return; 95 } 96 97 Profile* profile = Profile::FromBrowserContext( 98 web_ui()->GetWebContents()->GetBrowserContext()); 99 scoped_ptr<ExtensionInstallPrompt> prompt( 100 new ExtensionInstallPrompt(web_ui()->GetWebContents())); 101 scoped_refptr<CrxInstaller> crx_installer(CrxInstaller::Create( 102 ExtensionSystem::Get(profile)->extension_service(), 103 prompt.Pass())); 104 crx_installer->set_error_on_unsupported_requirements(true); 105 crx_installer->set_off_store_install_allow_reason( 106 CrxInstaller::OffStoreInstallAllowedFromSettingsPage); 107 crx_installer->set_install_wait_for_idle(false); 108 109 const bool kCaseSensitive = false; 110 111 if (EndsWith(file_display_name_, ASCIIToUTF16(".user.js"), kCaseSensitive)) { 112 crx_installer->InstallUserScript( 113 file_to_install_, 114 net::FilePathToFileURL(file_to_install_)); 115 } else if (EndsWith(file_display_name_, 116 ASCIIToUTF16(".crx"), 117 kCaseSensitive)) { 118 crx_installer->InstallCrx(file_to_install_); 119 } else { 120 CHECK(false); 121 } 122 123 file_to_install_.clear(); 124 file_display_name_.clear(); 125 } 126 127 void InstallExtensionHandler::HandleInstallDirectoryMessage( 128 const ListValue* args) { 129 Profile* profile = Profile::FromBrowserContext( 130 web_ui()->GetWebContents()->GetBrowserContext()); 131 UnpackedInstaller::Create( 132 ExtensionSystem::Get(profile)-> 133 extension_service())->Load(file_to_install_); 134 } 135 136 } // namespace extensions 137