| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/extensions/unpacked_installer.h" | 5 #include "chrome/browser/extensions/unpacked_installer.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/callback.h" | 8 #include "base/callback.h" |
| 9 #include "base/file_util.h" | 9 #include "base/file_util.h" |
| 10 #include "base/string_util.h" |
| 10 #include "base/threading/thread_restrictions.h" | 11 #include "base/threading/thread_restrictions.h" |
| 11 #include "chrome/browser/extensions/extension_install_prompt.h" | 12 #include "chrome/browser/extensions/extension_install_prompt.h" |
| 12 #include "chrome/browser/extensions/extension_install_ui.h" | 13 #include "chrome/browser/extensions/extension_install_ui.h" |
| 13 #include "chrome/browser/extensions/extension_prefs.h" | 14 #include "chrome/browser/extensions/extension_prefs.h" |
| 14 #include "chrome/browser/extensions/extension_service.h" | 15 #include "chrome/browser/extensions/extension_service.h" |
| 15 #include "chrome/browser/extensions/permissions_updater.h" | 16 #include "chrome/browser/extensions/permissions_updater.h" |
| 17 #include "chrome/browser/extensions/requirements_checker.h" |
| 16 #include "chrome/common/extensions/extension.h" | 18 #include "chrome/common/extensions/extension.h" |
| 17 #include "chrome/common/extensions/extension_file_util.h" | 19 #include "chrome/common/extensions/extension_file_util.h" |
| 18 #include "chrome/common/string_ordinal.h" | 20 #include "chrome/common/string_ordinal.h" |
| 19 | 21 |
| 20 using content::BrowserThread; | 22 using content::BrowserThread; |
| 21 using extensions::Extension; | 23 using extensions::Extension; |
| 22 | 24 |
| 23 namespace { | 25 namespace { |
| 24 | 26 |
| 25 const char kUnpackedExtensionsBlacklistedError[] = | 27 const char kUnpackedExtensionsBlacklistedError[] = |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 60 | 62 |
| 61 void SimpleExtensionLoadPrompt::ShowPrompt() { | 63 void SimpleExtensionLoadPrompt::ShowPrompt() { |
| 62 install_ui_->ConfirmInstall(this, extension_); | 64 install_ui_->ConfirmInstall(this, extension_); |
| 63 } | 65 } |
| 64 | 66 |
| 65 void SimpleExtensionLoadPrompt::InstallUIProceed() { | 67 void SimpleExtensionLoadPrompt::InstallUIProceed() { |
| 66 if (service_weak_.get()) { | 68 if (service_weak_.get()) { |
| 67 extensions::PermissionsUpdater perms_updater(service_weak_->profile()); | 69 extensions::PermissionsUpdater perms_updater(service_weak_->profile()); |
| 68 perms_updater.GrantActivePermissions(extension_, false); | 70 perms_updater.GrantActivePermissions(extension_, false); |
| 69 service_weak_->OnExtensionInstalled( | 71 service_weak_->OnExtensionInstalled( |
| 70 extension_, false, StringOrdinal()); // Not from web store. | 72 extension_, |
| 73 false, // Not from web store. |
| 74 StringOrdinal(), |
| 75 false /* no requirement errors */); |
| 71 } | 76 } |
| 72 delete this; | 77 delete this; |
| 73 } | 78 } |
| 74 | 79 |
| 75 void SimpleExtensionLoadPrompt::InstallUIAbort(bool user_initiated) { | 80 void SimpleExtensionLoadPrompt::InstallUIAbort(bool user_initiated) { |
| 76 delete this; | 81 delete this; |
| 77 } | 82 } |
| 78 | 83 |
| 79 } // namespace | 84 } // namespace |
| 80 | 85 |
| 81 namespace extensions { | 86 namespace extensions { |
| 82 | 87 |
| 83 // static | 88 // static |
| 84 scoped_refptr<UnpackedInstaller> UnpackedInstaller::Create( | 89 scoped_refptr<UnpackedInstaller> UnpackedInstaller::Create( |
| 85 ExtensionService* extension_service) { | 90 ExtensionService* extension_service) { |
| 86 return scoped_refptr<UnpackedInstaller>( | 91 return scoped_refptr<UnpackedInstaller>( |
| 87 new UnpackedInstaller(extension_service)); | 92 new UnpackedInstaller(extension_service)); |
| 88 } | 93 } |
| 89 | 94 |
| 90 UnpackedInstaller::UnpackedInstaller(ExtensionService* extension_service) | 95 UnpackedInstaller::UnpackedInstaller(ExtensionService* extension_service) |
| 91 : service_weak_(extension_service->AsWeakPtr()), | 96 : service_weak_(extension_service->AsWeakPtr()), |
| 92 prompt_for_plugins_(true) { | 97 prompt_for_plugins_(true), |
| 98 requirements_checker_(new RequirementsChecker()) { |
| 93 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 99 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 94 } | 100 } |
| 95 | 101 |
| 96 UnpackedInstaller::~UnpackedInstaller() { | 102 UnpackedInstaller::~UnpackedInstaller() { |
| 97 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || | 103 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || |
| 98 BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 104 BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 99 } | 105 } |
| 100 | 106 |
| 101 void UnpackedInstaller::Load(const FilePath& path_in) { | 107 void UnpackedInstaller::Load(const FilePath& path_in) { |
| 102 extension_path_ = path_in; | 108 extension_path_ = path_in; |
| 103 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, | 109 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
| 104 base::Bind(&UnpackedInstaller::GetAbsolutePath, this)); | 110 base::Bind(&UnpackedInstaller::GetAbsolutePath, this)); |
| 105 } | 111 } |
| 106 | 112 |
| 107 void UnpackedInstaller::LoadFromCommandLine(const FilePath& path_in) { | 113 void UnpackedInstaller::LoadFromCommandLine(const FilePath& path_in) { |
| 114 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 115 |
| 108 if (!service_weak_.get()) | 116 if (!service_weak_.get()) |
| 109 return; | 117 return; |
| 110 // Load extensions from the command line synchronously to avoid a race | 118 // Load extensions from the command line synchronously to avoid a race |
| 111 // between extension loading and loading an URL from the command line. | 119 // between extension loading and loading an URL from the command line. |
| 112 base::ThreadRestrictions::ScopedAllowIO allow_io; | 120 base::ThreadRestrictions::ScopedAllowIO allow_io; |
| 113 | 121 |
| 114 extension_path_ = path_in; | 122 extension_path_ = path_in; |
| 115 file_util::AbsolutePath(&extension_path_); | 123 file_util::AbsolutePath(&extension_path_); |
| 116 | 124 |
| 117 if (!IsLoadingUnpackedAllowed()) { | 125 if (!IsLoadingUnpackedAllowed()) { |
| 118 ReportExtensionLoadError(kUnpackedExtensionsBlacklistedError); | 126 ReportExtensionLoadError(kUnpackedExtensionsBlacklistedError); |
| 119 return; | 127 return; |
| 120 } | 128 } |
| 121 | 129 |
| 122 std::string id = Extension::GenerateIdForPath(extension_path_); | 130 std::string id = Extension::GenerateIdForPath(extension_path_); |
| 123 bool allow_file_access = | 131 bool allow_file_access = |
| 124 Extension::ShouldAlwaysAllowFileAccess(Extension::LOAD); | 132 Extension::ShouldAlwaysAllowFileAccess(Extension::LOAD); |
| 125 if (service_weak_->extension_prefs()->HasAllowFileAccessSetting(id)) | 133 if (service_weak_->extension_prefs()->HasAllowFileAccessSetting(id)) |
| 126 allow_file_access = service_weak_->extension_prefs()->AllowFileAccess(id); | 134 allow_file_access = service_weak_->extension_prefs()->AllowFileAccess(id); |
| 127 | 135 |
| 128 int flags = Extension::REQUIRE_MODERN_MANIFEST_VERSION; | 136 int flags = Extension::REQUIRE_MODERN_MANIFEST_VERSION; |
| 129 if (allow_file_access) | 137 if (allow_file_access) |
| 130 flags |= Extension::ALLOW_FILE_ACCESS; | 138 flags |= Extension::ALLOW_FILE_ACCESS; |
| 131 | 139 |
| 132 std::string error; | 140 std::string error; |
| 133 scoped_refptr<const Extension> extension(extension_file_util::LoadExtension( | 141 extension_ = extension_file_util::LoadExtension( |
| 134 extension_path_, | 142 extension_path_, |
| 135 Extension::LOAD, | 143 Extension::LOAD, |
| 136 flags | Extension::FOLLOW_SYMLINKS_ANYWHERE, | 144 flags | Extension::FOLLOW_SYMLINKS_ANYWHERE, |
| 137 &error)); | 145 &error); |
| 138 | 146 |
| 139 if (!extension) { | 147 if (!extension_.get()) { |
| 140 ReportExtensionLoadError(error); | 148 ReportExtensionLoadError(error); |
| 141 return; | 149 return; |
| 142 } | 150 } |
| 143 | 151 |
| 144 OnLoaded(extension); | 152 CheckRequirements(); |
| 153 } |
| 154 |
| 155 void UnpackedInstaller::CheckRequirements() { |
| 156 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 157 requirements_checker_->Check( |
| 158 extension_, |
| 159 base::Bind(&UnpackedInstaller::RequirementsChecked, this)); |
| 160 } |
| 161 |
| 162 void UnpackedInstaller::RequirementsChecked(std::vector<std::string> errors) { |
| 163 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 164 |
| 165 if (!errors.empty()) { |
| 166 ReportExtensionLoadError(JoinString(errors, ' ')); |
| 167 return; |
| 168 } |
| 169 |
| 170 OnLoaded(); |
| 145 } | 171 } |
| 146 | 172 |
| 147 bool UnpackedInstaller::IsLoadingUnpackedAllowed() const { | 173 bool UnpackedInstaller::IsLoadingUnpackedAllowed() const { |
| 148 if (!service_weak_) | 174 if (!service_weak_) |
| 149 return true; | 175 return true; |
| 150 // If there is a "*" in the extension blacklist, then no extensions should be | 176 // If there is a "*" in the extension blacklist, then no extensions should be |
| 151 // allowed at all (except explicitly whitelisted extensions). | 177 // allowed at all (except explicitly whitelisted extensions). |
| 152 return !service_weak_->extension_prefs()->ExtensionsBlacklistedByDefault(); | 178 return !service_weak_->extension_prefs()->ExtensionsBlacklistedByDefault(); |
| 153 } | 179 } |
| 154 | 180 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 184 &UnpackedInstaller::LoadWithFileAccess, | 210 &UnpackedInstaller::LoadWithFileAccess, |
| 185 this, allow_file_access)); | 211 this, allow_file_access)); |
| 186 } | 212 } |
| 187 | 213 |
| 188 void UnpackedInstaller::LoadWithFileAccess(bool allow_file_access) { | 214 void UnpackedInstaller::LoadWithFileAccess(bool allow_file_access) { |
| 189 CHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 215 CHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 190 int flags = Extension::REQUIRE_MODERN_MANIFEST_VERSION; | 216 int flags = Extension::REQUIRE_MODERN_MANIFEST_VERSION; |
| 191 if (allow_file_access) | 217 if (allow_file_access) |
| 192 flags |= Extension::ALLOW_FILE_ACCESS; | 218 flags |= Extension::ALLOW_FILE_ACCESS; |
| 193 std::string error; | 219 std::string error; |
| 194 scoped_refptr<const Extension> extension(extension_file_util::LoadExtension( | 220 extension_ = extension_file_util::LoadExtension( |
| 195 extension_path_, | 221 extension_path_, |
| 196 Extension::LOAD, | 222 Extension::LOAD, |
| 197 flags | Extension::FOLLOW_SYMLINKS_ANYWHERE, | 223 flags | Extension::FOLLOW_SYMLINKS_ANYWHERE, |
| 198 &error)); | 224 &error); |
| 199 | 225 |
| 200 if (!extension) { | 226 if (!extension_.get()) { |
| 201 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 227 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 202 base::Bind( | 228 base::Bind( |
| 203 &UnpackedInstaller::ReportExtensionLoadError, | 229 &UnpackedInstaller::ReportExtensionLoadError, |
| 204 this, error)); | 230 this, error)); |
| 205 return; | 231 return; |
| 206 } | 232 } |
| 207 | 233 |
| 208 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 234 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 209 base::Bind( | 235 base::Bind(&UnpackedInstaller::CheckRequirements, this)); |
| 210 &UnpackedInstaller::OnLoaded, | |
| 211 this, extension)); | |
| 212 } | 236 } |
| 213 | 237 |
| 214 void UnpackedInstaller::ReportExtensionLoadError(const std::string &error) { | 238 void UnpackedInstaller::ReportExtensionLoadError(const std::string &error) { |
| 215 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 239 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 216 if (!service_weak_.get()) | 240 if (!service_weak_.get()) |
| 217 return; | 241 return; |
| 218 service_weak_->ReportExtensionLoadError(extension_path_, error, true); | 242 service_weak_->ReportExtensionLoadError(extension_path_, error, true); |
| 219 } | 243 } |
| 220 | 244 |
| 221 void UnpackedInstaller::OnLoaded( | 245 void UnpackedInstaller::OnLoaded() { |
| 222 const scoped_refptr<const Extension>& extension) { | |
| 223 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 246 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 224 if (!service_weak_.get()) | 247 if (!service_weak_.get()) |
| 225 return; | 248 return; |
| 226 const ExtensionSet* disabled_extensions = | 249 const ExtensionSet* disabled_extensions = |
| 227 service_weak_->disabled_extensions(); | 250 service_weak_->disabled_extensions(); |
| 228 if (service_weak_->show_extensions_prompts() && | 251 if (service_weak_->show_extensions_prompts() && |
| 229 prompt_for_plugins_ && | 252 prompt_for_plugins_ && |
| 230 !extension->plugins().empty() && | 253 !extension_->plugins().empty() && |
| 231 !disabled_extensions->Contains(extension->id())) { | 254 !disabled_extensions->Contains(extension_->id())) { |
| 232 SimpleExtensionLoadPrompt* prompt = new SimpleExtensionLoadPrompt( | 255 SimpleExtensionLoadPrompt* prompt = new SimpleExtensionLoadPrompt( |
| 233 service_weak_->profile(), | 256 service_weak_->profile(), |
| 234 service_weak_, | 257 service_weak_, |
| 235 extension); | 258 extension_); |
| 236 prompt->ShowPrompt(); | 259 prompt->ShowPrompt(); |
| 237 return; // continues in SimpleExtensionLoadPrompt::InstallPrompt* | 260 return; // continues in SimpleExtensionLoadPrompt::InstallPrompt* |
| 238 } | 261 } |
| 239 | 262 |
| 240 PermissionsUpdater perms_updater(service_weak_->profile()); | 263 PermissionsUpdater perms_updater(service_weak_->profile()); |
| 241 perms_updater.GrantActivePermissions(extension, false); | 264 perms_updater.GrantActivePermissions(extension_, false); |
| 242 service_weak_->OnExtensionInstalled(extension, | 265 service_weak_->OnExtensionInstalled(extension_, |
| 243 false, // Not from web store. | 266 false, // Not from web store. |
| 244 StringOrdinal()); | 267 StringOrdinal(), |
| 268 false /* no requirement errors */); |
| 245 } | 269 } |
| 246 | 270 |
| 247 } // namespace extensions | 271 } // namespace extensions |
| OLD | NEW |