| 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);
|
| + 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
|
|
|