Commit aa8b4a65 authored by Devlin Cronin's avatar Devlin Cronin Committed by Commit Bot

[Extensions] Extract a LoadAndLocalizeResource() method

Pull the logic to load and localize a file out from ExecuteCodeFunction.
This will be useful in the upcoming scripting.executeScript() API.

This CL has no functional changes.

Bug: 1144839
Change-Id: I587aa928a9526ae494a6208ba5debb7789f5c01a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2518113
Commit-Queue: Devlin <rdevlin.cronin@chromium.org>
Reviewed-by: default avatarKaran Bhatia <karandeepb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#824615}
parent 61f25db9
......@@ -280,6 +280,8 @@ source_set("browser_sources") {
"lazy_context_id.h",
"lazy_context_task_queue.cc",
"lazy_context_task_queue.h",
"load_and_localize_file.cc",
"load_and_localize_file.h",
"management_policy.cc",
"management_policy.h",
"media_capture_util.cc",
......
......@@ -10,20 +10,10 @@
#include <utility>
#include "base/bind.h"
#include "base/task/post_task.h"
#include "base/task/thread_pool.h"
#include "base/threading/scoped_blocking_call.h"
#include "extensions/browser/component_extension_resource_manager.h"
#include "extensions/browser/extension_api_frame_id_map.h"
#include "extensions/browser/extensions_browser_client.h"
#include "extensions/browser/file_reader.h"
#include "extensions/browser/load_and_localize_file.h"
#include "extensions/common/error_utils.h"
#include "extensions/common/extension_messages.h"
#include "extensions/common/file_util.h"
#include "extensions/common/manifest_constants.h"
#include "extensions/common/message_bundle.h"
#include "net/base/filename_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "extensions/common/extension.h"
namespace {
......@@ -50,52 +40,6 @@ ExecuteCodeFunction::ExecuteCodeFunction() {
ExecuteCodeFunction::~ExecuteCodeFunction() {
}
void ExecuteCodeFunction::MaybeLocalizeInBackground(
const std::string& extension_id,
const base::FilePath& extension_path,
const std::string& extension_default_locale,
extension_l10n_util::GzippedMessagesPermission gzip_permission,
bool might_require_localization,
std::string* data) {
// TODO(karandeepb): Limit scope of ScopedBlockingCall.
base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
base::BlockingType::MAY_BLOCK);
// TODO(devlin): Don't call the localization function if no localization is
// potentially required.
if (!might_require_localization)
return;
bool needs_message_substituion =
data->find(extensions::MessageBundle::kMessageBegin) != std::string::npos;
if (!needs_message_substituion)
return;
std::unique_ptr<SubstitutionMap> localization_messages(
file_util::LoadMessageBundleSubstitutionMap(extension_path, extension_id,
extension_default_locale,
gzip_permission));
std::string error;
MessageBundle::ReplaceMessagesWithExternalDictionary(*localization_messages,
data, &error);
}
std::unique_ptr<std::string>
ExecuteCodeFunction::LocalizeComponentResourceInBackground(
std::unique_ptr<std::string> data,
const std::string& extension_id,
const base::FilePath& extension_path,
const std::string& extension_default_locale,
extension_l10n_util::GzippedMessagesPermission gzip_permission,
bool might_require_localization) {
MaybeLocalizeInBackground(extension_id, extension_path,
extension_default_locale, gzip_permission,
might_require_localization, data.get());
return data;
}
void ExecuteCodeFunction::DidLoadAndLocalizeFile(
const std::string& file,
bool success,
......@@ -222,62 +166,21 @@ ExtensionFunction::ResponseAction ExecuteCodeFunction::Run() {
bool ExecuteCodeFunction::LoadFile(const std::string& file,
std::string* error) {
resource_ = extension()->GetResource(file);
if (resource_.extension_root().empty() || resource_.relative_path().empty()) {
*error = kNoCodeOrFileToExecuteError;
return false;
}
script_url_ = extension()->GetResourceURL(file);
const std::string& extension_id = extension()->id();
base::FilePath extension_path = extension()->path();
std::string extension_default_locale;
extension()->manifest()->GetString(manifest_keys::kDefaultLocale,
&extension_default_locale);
auto gzip_permission =
extension_l10n_util::GetGzippedMessagesPermissionForExtension(
extension());
// TODO(lazyboy): |extension_id| should not be empty(), turn this into a
// DCHECK.
bool might_require_localization =
(ShouldInsertCSS() || ShouldRemoveCSS()) && !extension_id.empty();
int resource_id = 0;
const ComponentExtensionResourceManager*
component_extension_resource_manager =
ExtensionsBrowserClient::Get()
->GetComponentExtensionResourceManager();
if (component_extension_resource_manager &&
component_extension_resource_manager->IsComponentExtensionResource(
resource_.extension_root(), resource_.relative_path(),
&resource_id)) {
auto data = std::make_unique<std::string>(
ui::ResourceBundle::GetSharedInstance().LoadDataResourceString(
resource_id));
base::ThreadPool::PostTaskAndReplyWithResult(
FROM_HERE,
{base::MayBlock(), base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
base::BindOnce(
&ExecuteCodeFunction::LocalizeComponentResourceInBackground, this,
std::move(data), extension_id, extension_path,
extension_default_locale, gzip_permission,
might_require_localization),
base::BindOnce(&ExecuteCodeFunction::DidLoadAndLocalizeFile, this,
resource_.relative_path().AsUTF8Unsafe(),
true /* We assume this call always succeeds */));
} else {
FileReader::OptionalFileSequenceTask get_file_and_l10n_callback =
base::BindOnce(&ExecuteCodeFunction::MaybeLocalizeInBackground, this,
extension_id, extension_path, extension_default_locale,
gzip_permission, might_require_localization);
auto file_reader = base::MakeRefCounted<FileReader>(
resource_, std::move(get_file_and_l10n_callback),
base::BindOnce(&ExecuteCodeFunction::DidLoadAndLocalizeFile, this,
resource_.relative_path().AsUTF8Unsafe()));
file_reader->Start();
}
(ShouldInsertCSS() || ShouldRemoveCSS()) && !extension()->id().empty();
LoadAndLocalizeResource(
*extension(), resource_, might_require_localization,
base::BindOnce(&ExecuteCodeFunction::DidLoadAndLocalizeFile, this,
resource_.relative_path().AsUTF8Unsafe()));
return true;
}
......
......@@ -10,7 +10,6 @@
#include "extensions/browser/extension_function.h"
#include "extensions/browser/script_executor.h"
#include "extensions/common/api/extension_types.h"
#include "extensions/common/extension_l10n_util.h"
#include "extensions/common/host_id.h"
namespace extensions {
......@@ -84,28 +83,6 @@ class ExecuteCodeFunction : public ExtensionFunction {
const GURL& on_url,
const base::ListValue& result);
// Optionally localizes |data|.
// Localization depends on whether |might_require_localization| was specified.
// Only CSS file content needs to be localized.
void MaybeLocalizeInBackground(
const std::string& extension_id,
const base::FilePath& extension_path,
const std::string& extension_default_locale,
extension_l10n_util::GzippedMessagesPermission gzip_permission,
bool might_require_localization,
std::string* data);
// Optionally localizes |data|.
// Similar to MaybeLocalizeInBackground, but only applies to component
// extension resources.
std::unique_ptr<std::string> LocalizeComponentResourceInBackground(
std::unique_ptr<std::string> data,
const std::string& extension_id,
const base::FilePath& extension_path,
const std::string& extension_default_locale,
extension_l10n_util::GzippedMessagesPermission gzip_permission,
bool might_require_localization);
// Run in UI thread. Code string contains the code to be executed. Returns
// true on success. If true is returned, this does an AddRef. Returns false on
// failure and sets |error|.
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "extensions/browser/load_and_localize_file.h"
#include "base/task/task_traits.h"
#include "base/task/thread_pool.h"
#include "base/threading/scoped_blocking_call.h"
#include "extensions/browser/component_extension_resource_manager.h"
#include "extensions/browser/extensions_browser_client.h"
#include "extensions/browser/file_reader.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_id.h"
#include "extensions/common/extension_l10n_util.h"
#include "extensions/common/extension_resource.h"
#include "extensions/common/file_util.h"
#include "extensions/common/manifest.h"
#include "extensions/common/manifest_constants.h"
#include "extensions/common/message_bundle.h"
#include "ui/base/resource/resource_bundle.h"
namespace extensions {
namespace {
void MaybeLocalizeInBackground(
const ExtensionId& extension_id,
const base::FilePath& extension_path,
const std::string& extension_default_locale,
extension_l10n_util::GzippedMessagesPermission gzip_permission,
bool localize_file,
std::string* data) {
// TODO(karandeepb): Limit scope of ScopedBlockingCall.
base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
base::BlockingType::MAY_BLOCK);
// TODO(devlin): Don't call the localization function if no localization is
// potentially required.
if (!localize_file)
return;
bool needs_message_substituion =
data->find(extensions::MessageBundle::kMessageBegin) != std::string::npos;
if (!needs_message_substituion)
return;
std::unique_ptr<MessageBundle::SubstitutionMap> localization_messages(
file_util::LoadMessageBundleSubstitutionMap(extension_path, extension_id,
extension_default_locale,
gzip_permission));
std::string error;
MessageBundle::ReplaceMessagesWithExternalDictionary(*localization_messages,
data, &error);
}
// A simple wrapper around MaybeLocalizeInBackground() that returns |data| to
// serve as an adapter for PostTaskAndReply.
std::unique_ptr<std::string> LocalizeComponentResourceInBackground(
std::unique_ptr<std::string> data,
const ExtensionId& extension_id,
const base::FilePath& extension_path,
const std::string& extension_default_locale,
extension_l10n_util::GzippedMessagesPermission gzip_permission,
bool localize_file) {
MaybeLocalizeInBackground(extension_id, extension_path,
extension_default_locale, gzip_permission,
localize_file, data.get());
return data;
}
} // namespace
void LoadAndLocalizeResource(const Extension& extension,
const ExtensionResource& resource,
bool localize_file,
LoadAndLocalizeResourceCallback callback) {
DCHECK(!resource.extension_root().empty());
DCHECK(!resource.relative_path().empty());
std::string extension_default_locale;
extension.manifest()->GetString(manifest_keys::kDefaultLocale,
&extension_default_locale);
auto gzip_permission =
extension_l10n_util::GetGzippedMessagesPermissionForExtension(&extension);
// Check whether the resource should be loaded as a component resource (from
// the resource bundle) or read from disk.
int resource_id = 0;
const ComponentExtensionResourceManager*
component_extension_resource_manager =
ExtensionsBrowserClient::Get()
->GetComponentExtensionResourceManager();
if (component_extension_resource_manager &&
component_extension_resource_manager->IsComponentExtensionResource(
resource.extension_root(), resource.relative_path(), &resource_id)) {
auto data = std::make_unique<std::string>(
ui::ResourceBundle::GetSharedInstance().LoadDataResourceString(
resource_id));
base::ThreadPool::PostTaskAndReplyWithResult(
FROM_HERE,
{base::MayBlock(), base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
base::BindOnce(&LocalizeComponentResourceInBackground, std::move(data),
extension.id(), extension.path(),
extension_default_locale, gzip_permission,
localize_file),
base::BindOnce(std::move(callback),
true /* We assume this call always succeeds */));
} else {
FileReader::OptionalFileSequenceTask get_file_and_l10n_callback =
base::BindOnce(&MaybeLocalizeInBackground, extension.id(),
extension.path(), extension_default_locale,
gzip_permission, localize_file);
auto file_reader = base::MakeRefCounted<FileReader>(
resource, std::move(get_file_and_l10n_callback), std::move(callback));
file_reader->Start();
}
}
} // namespace extensions
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef EXTENSIONS_BROWSER_LOAD_AND_LOCALIZE_FILE_H_
#define EXTENSIONS_BROWSER_LOAD_AND_LOCALIZE_FILE_H_
#include <memory>
#include <string>
#include "base/callback.h"
namespace extensions {
class Extension;
class ExtensionResource;
// Invoked with the result of the file read and localization. The bool
// indicates success and failure. On success, |data| contains the
// localized content of the file.
// TODO(devlin): Update this to just pass |data| and have null indicate
// failure once FileReader's callback signature is updated.
using LoadAndLocalizeResourceCallback =
base::OnceCallback<void(bool success, std::unique_ptr<std::string> data)>;
// Loads |resource| from |extension|, optionally localizing the content, and
// invokes |callback| with the result. Handles both component and non-component
// extension resources. |resource| must be valid.
void LoadAndLocalizeResource(const Extension& extension,
const ExtensionResource& resource,
bool localize_file,
LoadAndLocalizeResourceCallback callback);
} // namespace extensions
#endif // EXTENSIONS_BROWSER_LOAD_AND_LOCALIZE_FILE_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment