fix: [extensions] load extensions on the IO thread (#21811)

This commit is contained in:
Jeremy Apthorp 2020-01-21 09:43:18 -08:00 committed by GitHub
parent acb5b75057
commit 100a85f93a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 46 additions and 35 deletions

View file

@ -615,15 +615,20 @@ v8::Local<v8::Promise> Session::LoadExtension(
auto* extension_system = static_cast<extensions::AtomExtensionSystem*>( auto* extension_system = static_cast<extensions::AtomExtensionSystem*>(
extensions::ExtensionSystem::Get(browser_context())); extensions::ExtensionSystem::Get(browser_context()));
// TODO(nornagon): make LoadExtension() asynchronous. extension_system->LoadExtension(
auto* extension = extension_system->LoadExtension(extension_path); extension_path,
base::BindOnce(
if (extension) { [](gin_helper::Promise<const extensions::Extension*> promise,
promise.Resolve(extension); const extensions::Extension* extension) {
} else { if (extension) {
// TODO(nornagon): plumb through error message from extension loader. promise.Resolve(extension);
promise.RejectWithErrorMessage("Failed to load extension"); } else {
} // TODO(nornagon): plumb through error message from extension
// loader.
promise.RejectWithErrorMessage("Failed to load extension");
}
},
std::move(promise)));
return handle; return handle;
} }

View file

@ -4,6 +4,8 @@
#include "shell/browser/extensions/atom_extension_loader.h" #include "shell/browser/extensions/atom_extension_loader.h"
#include <utility>
#include "base/auto_reset.h" #include "base/auto_reset.h"
#include "base/bind.h" #include "base/bind.h"
#include "base/files/file_path.h" #include "base/files/file_path.h"
@ -66,16 +68,14 @@ AtomExtensionLoader::AtomExtensionLoader(
AtomExtensionLoader::~AtomExtensionLoader() = default; AtomExtensionLoader::~AtomExtensionLoader() = default;
const Extension* AtomExtensionLoader::LoadExtension( void AtomExtensionLoader::LoadExtension(
const base::FilePath& extension_dir) { const base::FilePath& extension_dir,
// TODO(nornagon): load extensions asynchronously on base::OnceCallback<void(const Extension*)> loaded) {
// GetExtensionFileTaskRunner() base::PostTaskAndReplyWithResult(
base::ScopedAllowBlockingForTesting allow_blocking; GetExtensionFileTaskRunner().get(), FROM_HERE,
scoped_refptr<const Extension> extension = LoadUnpacked(extension_dir); base::BindOnce(&LoadUnpacked, extension_dir),
if (extension) base::BindOnce(&AtomExtensionLoader::FinishExtensionLoad,
extension_registrar_.AddExtension(extension); weak_factory_.GetWeakPtr(), std::move(loaded)));
return extension.get();
} }
void AtomExtensionLoader::ReloadExtension(const ExtensionId& extension_id) { void AtomExtensionLoader::ReloadExtension(const ExtensionId& extension_id) {
@ -100,6 +100,15 @@ void AtomExtensionLoader::UnloadExtension(
extension_registrar_.RemoveExtension(extension_id, reason); extension_registrar_.RemoveExtension(extension_id, reason);
} }
void AtomExtensionLoader::FinishExtensionLoad(
base::OnceCallback<void(const Extension*)> done,
scoped_refptr<const Extension> extension) {
if (extension) {
extension_registrar_.AddExtension(extension);
}
std::move(done).Run(extension.get());
}
void AtomExtensionLoader::FinishExtensionReload( void AtomExtensionLoader::FinishExtensionReload(
const ExtensionId& old_extension_id, const ExtensionId& old_extension_id,
scoped_refptr<const Extension> extension) { scoped_refptr<const Extension> extension) {

View file

@ -34,7 +34,9 @@ class AtomExtensionLoader : public ExtensionRegistrar::Delegate {
// Loads an unpacked extension from a directory synchronously. Returns the // Loads an unpacked extension from a directory synchronously. Returns the
// extension on success, or nullptr otherwise. // extension on success, or nullptr otherwise.
const Extension* LoadExtension(const base::FilePath& extension_dir); void LoadExtension(
const base::FilePath& extension_dir,
base::OnceCallback<void(const Extension* extension)> loaded);
// Starts reloading the extension. A keep-alive is maintained until the // Starts reloading the extension. A keep-alive is maintained until the
// reload succeeds/fails. If the extension is an app, it will be launched upon // reload succeeds/fails. If the extension is an app, it will be launched upon
@ -52,6 +54,9 @@ class AtomExtensionLoader : public ExtensionRegistrar::Delegate {
void FinishExtensionReload(const ExtensionId& old_extension_id, void FinishExtensionReload(const ExtensionId& old_extension_id,
scoped_refptr<const Extension> extension); scoped_refptr<const Extension> extension);
void FinishExtensionLoad(base::OnceCallback<void(const Extension*)> loaded,
scoped_refptr<const Extension> extension);
// ExtensionRegistrar::Delegate: // ExtensionRegistrar::Delegate:
void PreAddExtension(const Extension* extension, void PreAddExtension(const Extension* extension,
const Extension* old_extension) override; const Extension* old_extension) override;

View file

@ -6,6 +6,7 @@
#include <memory> #include <memory>
#include <string> #include <string>
#include <utility>
#include "base/bind.h" #include "base/bind.h"
#include "base/files/file_path.h" #include "base/files/file_path.h"
@ -43,14 +44,10 @@ AtomExtensionSystem::AtomExtensionSystem(BrowserContext* browser_context)
AtomExtensionSystem::~AtomExtensionSystem() = default; AtomExtensionSystem::~AtomExtensionSystem() = default;
const Extension* AtomExtensionSystem::LoadExtension( void AtomExtensionSystem::LoadExtension(
const base::FilePath& extension_dir) { const base::FilePath& extension_dir,
return extension_loader_->LoadExtension(extension_dir); base::OnceCallback<void(const Extension*)> loaded) {
} extension_loader_->LoadExtension(extension_dir, std::move(loaded));
const Extension* AtomExtensionSystem::LoadApp(const base::FilePath& app_dir) {
NOTIMPLEMENTED() << "Attempted to load platform app in Electron";
return nullptr;
} }
void AtomExtensionSystem::FinishInitialization() { void AtomExtensionSystem::FinishInitialization() {

View file

@ -39,13 +39,8 @@ class AtomExtensionSystem : public ExtensionSystem {
// Loads an unpacked extension from a directory. Returns the extension on // Loads an unpacked extension from a directory. Returns the extension on
// success, or nullptr otherwise. // success, or nullptr otherwise.
const Extension* LoadExtension(const base::FilePath& extension_dir); void LoadExtension(const base::FilePath& extension_dir,
base::OnceCallback<void(const Extension*)> loaded);
// Loads an unpacked platform app from a directory. Returns the extension on
// success, or nullptr otherwise.
// Currently this just calls LoadExtension, as apps are not loaded differently
// than other extensions. Use LaunchApp() to actually launch the loaded app.
const Extension* LoadApp(const base::FilePath& app_dir);
// Finish initialization for the shell extension system. // Finish initialization for the shell extension system.
void FinishInitialization(); void FinishInitialization();