| 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 "sync/api/string_ordinal.h" | 20 #include "sync/api/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, syncer::StringOrdinal()); // Not from web store. | 72 extension_, |
| 73 false, // Not from web store. |
| 74 syncer::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 require_modern_manifest_version_(true) { | 99 require_modern_manifest_version_(true) { |
| 94 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 100 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 95 } | 101 } |
| 96 | 102 |
| 97 UnpackedInstaller::~UnpackedInstaller() { | 103 UnpackedInstaller::~UnpackedInstaller() { |
| 98 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || | 104 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || |
| 99 BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 105 BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 100 } | 106 } |
| 101 | 107 |
| 102 void UnpackedInstaller::Load(const FilePath& path_in) { | 108 void UnpackedInstaller::Load(const FilePath& path_in) { |
| 109 DCHECK(extension_path_.empty()); |
| 103 extension_path_ = path_in; | 110 extension_path_ = path_in; |
| 104 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, | 111 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
| 105 base::Bind(&UnpackedInstaller::GetAbsolutePath, this)); | 112 base::Bind(&UnpackedInstaller::GetAbsolutePath, this)); |
| 106 } | 113 } |
| 107 | 114 |
| 108 void UnpackedInstaller::LoadFromCommandLine(const FilePath& path_in) { | 115 void UnpackedInstaller::LoadFromCommandLine(const FilePath& path_in) { |
| 116 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 117 DCHECK(extension_path_.empty()); |
| 118 |
| 109 if (!service_weak_.get()) | 119 if (!service_weak_.get()) |
| 110 return; | 120 return; |
| 111 // Load extensions from the command line synchronously to avoid a race | 121 // Load extensions from the command line synchronously to avoid a race |
| 112 // between extension loading and loading an URL from the command line. | 122 // between extension loading and loading an URL from the command line. |
| 113 base::ThreadRestrictions::ScopedAllowIO allow_io; | 123 base::ThreadRestrictions::ScopedAllowIO allow_io; |
| 114 | 124 |
| 115 extension_path_ = path_in; | 125 extension_path_ = path_in; |
| 116 file_util::AbsolutePath(&extension_path_); | 126 file_util::AbsolutePath(&extension_path_); |
| 117 | 127 |
| 118 if (!IsLoadingUnpackedAllowed()) { | 128 if (!IsLoadingUnpackedAllowed()) { |
| 119 ReportExtensionLoadError(kUnpackedExtensionsBlacklistedError); | 129 ReportExtensionLoadError(kUnpackedExtensionsBlacklistedError); |
| 120 return; | 130 return; |
| 121 } | 131 } |
| 122 | 132 |
| 123 std::string error; | 133 std::string error; |
| 124 scoped_refptr<const Extension> extension(extension_file_util::LoadExtension( | 134 extension_ = extension_file_util::LoadExtension( |
| 125 extension_path_, | 135 extension_path_, |
| 126 Extension::LOAD, | 136 Extension::LOAD, |
| 127 GetFlags(), | 137 GetFlags(), |
| 128 &error)); | 138 &error); |
| 129 | 139 |
| 130 if (!extension) { | 140 if (!extension_.get()) { |
| 131 ReportExtensionLoadError(error); | 141 ReportExtensionLoadError(error); |
| 132 return; | 142 return; |
| 133 } | 143 } |
| 134 | 144 |
| 135 OnLoaded(extension); | 145 CheckRequirements(); |
| 146 } |
| 147 |
| 148 void UnpackedInstaller::CheckRequirements() { |
| 149 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 150 requirements_checker_->Check( |
| 151 extension_, |
| 152 base::Bind(&UnpackedInstaller::OnRequirementsChecked, this)); |
| 153 } |
| 154 |
| 155 void UnpackedInstaller::OnRequirementsChecked( |
| 156 std::vector<std::string> requirement_errors) { |
| 157 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 158 |
| 159 if (!requirement_errors.empty()) { |
| 160 ReportExtensionLoadError(JoinString(requirement_errors, ' ')); |
| 161 return; |
| 162 } |
| 163 |
| 164 OnLoaded(); |
| 136 } | 165 } |
| 137 | 166 |
| 138 int UnpackedInstaller::GetFlags() { | 167 int UnpackedInstaller::GetFlags() { |
| 139 std::string id = Extension::GenerateIdForPath(extension_path_); | 168 std::string id = Extension::GenerateIdForPath(extension_path_); |
| 140 bool allow_file_access = | 169 bool allow_file_access = |
| 141 Extension::ShouldAlwaysAllowFileAccess(Extension::LOAD); | 170 Extension::ShouldAlwaysAllowFileAccess(Extension::LOAD); |
| 142 if (service_weak_->extension_prefs()->HasAllowFileAccessSetting(id)) | 171 if (service_weak_->extension_prefs()->HasAllowFileAccessSetting(id)) |
| 143 allow_file_access = service_weak_->extension_prefs()->AllowFileAccess(id); | 172 allow_file_access = service_weak_->extension_prefs()->AllowFileAccess(id); |
| 144 | 173 |
| 145 int result = Extension::FOLLOW_SYMLINKS_ANYWHERE; | 174 int result = Extension::FOLLOW_SYMLINKS_ANYWHERE; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 180 | 209 |
| 181 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, | 210 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
| 182 base::Bind( | 211 base::Bind( |
| 183 &UnpackedInstaller::LoadWithFileAccess, this, GetFlags())); | 212 &UnpackedInstaller::LoadWithFileAccess, this, GetFlags())); |
| 184 } | 213 } |
| 185 | 214 |
| 186 void UnpackedInstaller::LoadWithFileAccess(int flags) { | 215 void UnpackedInstaller::LoadWithFileAccess(int flags) { |
| 187 CHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 216 CHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 188 | 217 |
| 189 std::string error; | 218 std::string error; |
| 190 scoped_refptr<const Extension> extension(extension_file_util::LoadExtension( | 219 extension_ = extension_file_util::LoadExtension( |
| 191 extension_path_, | 220 extension_path_, |
| 192 Extension::LOAD, | 221 Extension::LOAD, |
| 193 flags, | 222 flags, |
| 194 &error)); | 223 &error); |
| 195 | 224 |
| 196 if (!extension) { | 225 if (!extension_.get()) { |
| 197 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 226 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 198 base::Bind( | 227 base::Bind( |
| 199 &UnpackedInstaller::ReportExtensionLoadError, | 228 &UnpackedInstaller::ReportExtensionLoadError, |
| 200 this, error)); | 229 this, error)); |
| 201 return; | 230 return; |
| 202 } | 231 } |
| 203 | 232 |
| 204 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 233 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 205 base::Bind( | 234 base::Bind(&UnpackedInstaller::CheckRequirements, this)); |
| 206 &UnpackedInstaller::OnLoaded, | |
| 207 this, extension)); | |
| 208 } | 235 } |
| 209 | 236 |
| 210 void UnpackedInstaller::ReportExtensionLoadError(const std::string &error) { | 237 void UnpackedInstaller::ReportExtensionLoadError(const std::string &error) { |
| 211 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 238 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 212 if (!service_weak_.get()) | 239 if (!service_weak_.get()) |
| 213 return; | 240 return; |
| 214 service_weak_->ReportExtensionLoadError(extension_path_, error, true); | 241 service_weak_->ReportExtensionLoadError(extension_path_, error, true); |
| 215 } | 242 } |
| 216 | 243 |
| 217 void UnpackedInstaller::OnLoaded( | 244 void UnpackedInstaller::OnLoaded() { |
| 218 const scoped_refptr<const Extension>& extension) { | |
| 219 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 245 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 220 if (!service_weak_.get()) | 246 if (!service_weak_.get()) |
| 221 return; | 247 return; |
| 222 const ExtensionSet* disabled_extensions = | 248 const ExtensionSet* disabled_extensions = |
| 223 service_weak_->disabled_extensions(); | 249 service_weak_->disabled_extensions(); |
| 224 if (service_weak_->show_extensions_prompts() && | 250 if (service_weak_->show_extensions_prompts() && |
| 225 prompt_for_plugins_ && | 251 prompt_for_plugins_ && |
| 226 !extension->plugins().empty() && | 252 !extension_->plugins().empty() && |
| 227 !disabled_extensions->Contains(extension->id())) { | 253 !disabled_extensions->Contains(extension_->id())) { |
| 228 SimpleExtensionLoadPrompt* prompt = new SimpleExtensionLoadPrompt( | 254 SimpleExtensionLoadPrompt* prompt = new SimpleExtensionLoadPrompt( |
| 229 service_weak_->profile(), | 255 service_weak_->profile(), |
| 230 service_weak_, | 256 service_weak_, |
| 231 extension); | 257 extension_); |
| 232 prompt->ShowPrompt(); | 258 prompt->ShowPrompt(); |
| 233 return; // continues in SimpleExtensionLoadPrompt::InstallPrompt* | 259 return; // continues in SimpleExtensionLoadPrompt::InstallPrompt* |
| 234 } | 260 } |
| 235 | 261 |
| 236 PermissionsUpdater perms_updater(service_weak_->profile()); | 262 PermissionsUpdater perms_updater(service_weak_->profile()); |
| 237 perms_updater.GrantActivePermissions(extension, false); | 263 perms_updater.GrantActivePermissions(extension_, false); |
| 238 service_weak_->OnExtensionInstalled(extension, | 264 service_weak_->OnExtensionInstalled(extension_, |
| 239 false, // Not from web store. | 265 false, // Not from web store. |
| 240 syncer::StringOrdinal()); | 266 syncer::StringOrdinal(), |
| 267 false /* no requirement errors */); |
| 241 } | 268 } |
| 242 | 269 |
| 243 } // namespace extensions | 270 } // namespace extensions |
| OLD | NEW |