Chromium Code Reviews| Index: extensions/utility/utility_handler.cc |
| diff --git a/extensions/utility/utility_handler.cc b/extensions/utility/utility_handler.cc |
| index 59fcdfe38fdd35b144db044544da96cf92368c15..78f85e71990f1100ac095c30c696aab02d7cf7fe 100644 |
| --- a/extensions/utility/utility_handler.cc |
| +++ b/extensions/utility/utility_handler.cc |
| @@ -6,12 +6,10 @@ |
| #include "base/command_line.h" |
| #include "base/files/file_path.h" |
| -#include "base/files/file_util.h" |
| -#include "base/i18n/rtl.h" |
| #include "content/public/utility/utility_thread.h" |
| #include "extensions/common/constants.h" |
| -#include "extensions/common/extension.h" |
| #include "extensions/common/extension_l10n_util.h" |
| +#include "extensions/common/extension_unpacker.mojom.h" |
| #include "extensions/common/extension_utility_messages.h" |
| #include "extensions/common/extensions_client.h" |
| #include "extensions/common/manifest.h" |
| @@ -20,6 +18,8 @@ |
| #include "extensions/utility/unpacker.h" |
| #include "ipc/ipc_message.h" |
| #include "ipc/ipc_message_macros.h" |
| +#include "mojo/public/cpp/bindings/strong_binding.h" |
| +#include "services/service_manager/public/cpp/interface_registry.h" |
| #include "third_party/zlib/google/zip.h" |
| #include "ui/base/l10n/l10n_util.h" |
| #include "ui/base/ui_base_switches.h" |
| @@ -28,24 +28,83 @@ namespace extensions { |
| namespace { |
| -bool Send(IPC::Message* message) { |
| - return content::UtilityThread::Get()->Send(message); |
| -} |
| +class ExtensionUnpackerImpl : public extensions::mojom::ExtensionUnpacker { |
| + public: |
| + ExtensionUnpackerImpl() = default; |
| + ~ExtensionUnpackerImpl() override = default; |
| -void ReleaseProcessIfNeeded() { |
| - content::UtilityThread::Get()->ReleaseProcessIfNeeded(); |
| -} |
| + static void Create(extensions::mojom::ExtensionUnpackerRequest request) { |
| + mojo::MakeStrongBinding(base::MakeUnique<ExtensionUnpackerImpl>(), |
| + std::move(request)); |
| + } |
| + |
| + private: |
| + // extensions::mojom::ExtensionUnpacker: |
| + void Unzip(const base::FilePath& file, |
| + const base::FilePath& path, |
| + const UnzipCallback& callback) override { |
| + std::unique_ptr<base::DictionaryValue> manifest; |
| + if (UnzipFileManifestIntoPath(file, path, &manifest)) { |
| + callback.Run(UnzipFileIntoPath(file, path, std::move(manifest))); |
| + } else { |
| + callback.Run(false); |
| + } |
| + } |
| + |
| + void Unpack(const base::FilePath& path, |
| + const std::string& extension_id, |
| + Manifest::Location location, |
| + int32_t creation_flags, |
| + const UnpackCallback& callback) override { |
| + CHECK_NE(location, Manifest::INVALID_LOCATION); |
|
dcheng
2017/03/07 09:45:14
I would suggest DCHECK_NE here, as we should be ab
Noel Gordon
2017/03/08 13:44:26
See https://codereview.chromium.org/2711513003
Tu
Devlin
2017/03/08 16:22:24
As Noel points out, this has been a problem lately
Noel Gordon
2017/03/08 17:56:09
My vote is leave the CHECK.
dcheng
2017/03/09 01:03:32
OK, I'm OK with that as long as we figure out what
|
| + DCHECK(ExtensionsClient::Get()); |
| + |
| + content::UtilityThread::Get()->EnsureBlinkInitialized(); |
| + |
| + Unpacker unpacker(path.DirName(), path, extension_id, location, |
| + creation_flags); |
| + if (unpacker.Run()) { |
| + callback.Run(base::string16(), unpacker.TakeParsedManifest()); |
| + } else { |
| + callback.Run(unpacker.error_message(), nullptr); |
| + } |
| + } |
| + |
| + static bool UnzipFileManifestIntoPath( |
| + const base::FilePath& file, |
| + const base::FilePath& path, |
| + std::unique_ptr<base::DictionaryValue>* manifest) { |
| + if (zip::UnzipWithFilterCallback( |
| + file, path, base::Bind(&Unpacker::IsManifestFile), false)) { |
| + std::string error; |
| + *manifest = Unpacker::ReadManifest(path, &error); |
| + return error.empty() && manifest->get(); |
| + } |
| + |
| + return false; |
| + } |
| + |
| + static bool UnzipFileIntoPath( |
| + const base::FilePath& file, |
| + const base::FilePath& path, |
| + std::unique_ptr<base::DictionaryValue> manifest) { |
| + Manifest internal(Manifest::INTERNAL, std::move(manifest)); |
| + // TODO(crbug.com/645263): This silently ignores blocked file types. |
| + // Add install warnings. |
| + return zip::UnzipWithFilterCallback( |
| + file, path, |
| + base::Bind(&Unpacker::ShouldExtractFile, internal.is_theme()), |
| + true /* log_skipped_files */); |
| + } |
| -const char kExtensionHandlerUnzipError[] = |
| - "Could not unzip extension for install."; |
| + DISALLOW_COPY_AND_ASSIGN(ExtensionUnpackerImpl); |
| +}; |
| } // namespace |
| -UtilityHandler::UtilityHandler() { |
| -} |
| +UtilityHandler::UtilityHandler() = default; |
| -UtilityHandler::~UtilityHandler() { |
| -} |
| +UtilityHandler::~UtilityHandler() = default; |
| // static |
| void UtilityHandler::UtilityThreadStarted() { |
| @@ -55,13 +114,23 @@ void UtilityHandler::UtilityThreadStarted() { |
| extension_l10n_util::SetProcessLocale(lang); |
| } |
| +// static |
| +void UtilityHandler::ExposeInterfacesToBrowser( |
| + service_manager::InterfaceRegistry* registry, |
| + bool running_elevated) { |
| + // If our process runs with elevated privileges, only add elevated Mojo |
| + // services to the interface registry. |
| + if (running_elevated) |
| + return; |
| + |
| + registry->AddInterface(base::Bind(&ExtensionUnpackerImpl::Create)); |
| +} |
| + |
| bool UtilityHandler::OnMessageReceived(const IPC::Message& message) { |
| bool handled = true; |
| IPC_BEGIN_MESSAGE_MAP(UtilityHandler, message) |
| IPC_MESSAGE_HANDLER(ExtensionUtilityMsg_ParseUpdateManifest, |
| OnParseUpdateManifest) |
| - IPC_MESSAGE_HANDLER(ExtensionUtilityMsg_UnzipToDir, OnUnzipToDir) |
| - IPC_MESSAGE_HANDLER(ExtensionUtilityMsg_UnpackExtension, OnUnpackExtension) |
| IPC_MESSAGE_UNHANDLED(handled = false) |
| IPC_END_MESSAGE_MAP() |
| return handled; |
| @@ -70,73 +139,15 @@ bool UtilityHandler::OnMessageReceived(const IPC::Message& message) { |
| void UtilityHandler::OnParseUpdateManifest(const std::string& xml) { |
| UpdateManifest manifest; |
| if (!manifest.Parse(xml)) { |
| - Send(new ExtensionUtilityHostMsg_ParseUpdateManifest_Failed( |
| - manifest.errors())); |
| - } else { |
| - Send(new ExtensionUtilityHostMsg_ParseUpdateManifest_Succeeded( |
| - manifest.results())); |
| - } |
| - ReleaseProcessIfNeeded(); |
| -} |
| - |
| -void UtilityHandler::OnUnzipToDir(const base::FilePath& zip_path, |
| - const base::FilePath& dir) { |
| - // First extract only the manifest to determine the extension type. |
| - if (!zip::UnzipWithFilterCallback(zip_path, dir, |
| - base::Bind(&Unpacker::IsManifestFile), |
| - false /* log_skipped_files */)) { |
| - Send(new ExtensionUtilityHostMsg_UnzipToDir_Failed( |
| - std::string(kExtensionHandlerUnzipError))); |
| - ReleaseProcessIfNeeded(); |
| - return; |
| - } |
| - |
| - // Load the manifest. |
| - std::string error; |
| - std::unique_ptr<base::DictionaryValue> dict = |
| - Unpacker::ReadManifest(dir, &error); |
| - if (!dict.get()) { |
| - Send(new ExtensionUtilityHostMsg_UnzipToDir_Failed( |
| - std::string(kExtensionHandlerUnzipError))); |
| - ReleaseProcessIfNeeded(); |
| - return; |
| - } |
| - |
| - Manifest manifest(Manifest::INTERNAL, std::move(dict)); |
| - base::Callback<bool(const base::FilePath&)> filetype_filter_cb = |
| - base::Bind(&Unpacker::ShouldExtractFile, manifest.is_theme()); |
| - |
| - // TODO(crbug.com/645263): This silently ignores blocked file types. |
| - // Add install warnings. |
| - if (!zip::UnzipWithFilterCallback(zip_path, dir, filetype_filter_cb, |
| - true /* log_skipped_files */)) { |
| - Send(new ExtensionUtilityHostMsg_UnzipToDir_Failed( |
| - std::string(kExtensionHandlerUnzipError))); |
| + content::UtilityThread::Get()->Send( |
| + new ExtensionUtilityHostMsg_ParseUpdateManifest_Failed( |
| + manifest.errors())); |
| } else { |
| - Send(new ExtensionUtilityHostMsg_UnzipToDir_Succeeded(dir)); |
| + content::UtilityThread::Get()->Send( |
| + new ExtensionUtilityHostMsg_ParseUpdateManifest_Succeeded( |
| + manifest.results())); |
| } |
| - ReleaseProcessIfNeeded(); |
| -} |
| - |
| -void UtilityHandler::OnUnpackExtension(const base::FilePath& directory_path, |
| - const std::string& extension_id, |
| - int location, |
| - int creation_flags) { |
| - CHECK_GT(location, Manifest::INVALID_LOCATION); |
| - CHECK_LT(location, Manifest::NUM_LOCATIONS); |
| - DCHECK(ExtensionsClient::Get()); |
| - content::UtilityThread::Get()->EnsureBlinkInitialized(); |
| - Unpacker unpacker(directory_path.DirName(), directory_path, extension_id, |
| - static_cast<Manifest::Location>(location), creation_flags); |
| - if (unpacker.Run()) { |
| - Send(new ExtensionUtilityHostMsg_UnpackExtension_Succeeded( |
| - *unpacker.parsed_manifest())); |
| - } else { |
| - Send(new ExtensionUtilityHostMsg_UnpackExtension_Failed( |
| - unpacker.error_message())); |
| - } |
| - ReleaseProcessIfNeeded(); |
| + content::UtilityThread::Get()->ReleaseProcessIfNeeded(); |
| } |
| - |
| } // namespace extensions |