Commit 92eb8807 authored by Colin Blundell's avatar Colin Blundell Committed by Commit Bot

[WebLayer] Package and index subresource filter ruleset data

This patch extends WebLayer to package and index the subresource
filter's unindexed ruleset data that is currently pulled into the tree
at gclient sync. To do so it does the following:

- Packages that data and its manifest as compressed resources in the
  app
- Has WebLayer kick off indexing as part of startup, using the
  subresource filter component's recently-added ability to read the
  unindexed ruleset data from a resource in the ResourceBundle and
  obtaining the version of the data from the manifest

We note the following:
- The compressed unindexed data is ~70 KB. The uncompressed data is ~300
  KB. Both of these will slowly grow over time.
- RulesetService short-circuits out of indexing the data if the content
  version has not changed from that of the last-indexed version
  (saved in prefs), so this operation will have an impact on startup
  only when the unindexed ruleset data changes (which will happen at
  maximum only once with every weblayer app update, and in practice
  presumably less often than that). Nonetheless, to limit impact on
  startup in that case we post the indexing as a BEST_EFFORT task from
  the startup flow. BEST_EFFORT tasks are guaranteed to executee in a
  reasonable delay assuming that the app isn't closed.

At this point in time Chrome is continuing to use the component updater;
using of the in-tree subresource filter data is done *only* by
WebLayer.

Bug: 1116095
Binary-Size: 40K increase due to packaging compressed ruleset data
Change-Id: Ifeffd6d8fcd223a9783020a97e246dafc69c4276
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2469562Reviewed-by: default avatarCharlie Harrison <csharrison@chromium.org>
Reviewed-by: default avatarAndrew Grieve <agrieve@chromium.org>
Reviewed-by: default avatarSami Kyöstilä <skyostil@chromium.org>
Commit-Queue: Colin Blundell <blundell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#825333}
parent 9a9e6c8e
...@@ -795,6 +795,7 @@ if (is_android) { ...@@ -795,6 +795,7 @@ if (is_android) {
grit("resources") { grit("resources") {
source = "weblayer_resources.grd" source = "weblayer_resources.grd"
use_brotli = true
outputs = [ outputs = [
"grit/weblayer_resources.h", "grit/weblayer_resources.h",
......
...@@ -6,7 +6,9 @@ ...@@ -6,7 +6,9 @@
#include "base/base_switches.h" #include "base/base_switches.h"
#include "base/bind.h" #include "base/bind.h"
#include "base/json/json_reader.h"
#include "base/task/current_thread.h" #include "base/task/current_thread.h"
#include "base/task/task_traits.h"
#include "base/threading/thread.h" #include "base/threading/thread.h"
#include "base/threading/thread_restrictions.h" #include "base/threading/thread_restrictions.h"
#include "build/build_config.h" #include "build/build_config.h"
...@@ -14,7 +16,9 @@ ...@@ -14,7 +16,9 @@
#include "components/captive_portal/core/buildflags.h" #include "components/captive_portal/core/buildflags.h"
#include "components/prefs/pref_service.h" #include "components/prefs/pref_service.h"
#include "components/startup_metric_utils/browser/startup_metric_utils.h" #include "components/startup_metric_utils/browser/startup_metric_utils.h"
#include "components/subresource_filter/content/browser/ruleset_service.h"
#include "components/translate/core/browser/translate_download_manager.h" #include "components/translate/core/browser/translate_download_manager.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
#include "content/public/browser/devtools_agent_host.h" #include "content/public/browser/devtools_agent_host.h"
#include "content/public/browser/render_process_host.h" #include "content/public/browser/render_process_host.h"
...@@ -35,6 +39,7 @@ ...@@ -35,6 +39,7 @@
#include "weblayer/browser/translate_accept_languages_factory.h" #include "weblayer/browser/translate_accept_languages_factory.h"
#include "weblayer/browser/translate_ranker_factory.h" #include "weblayer/browser/translate_ranker_factory.h"
#include "weblayer/browser/webui/web_ui_controller_factory.h" #include "weblayer/browser/webui/web_ui_controller_factory.h"
#include "weblayer/grit/weblayer_resources.h"
#include "weblayer/public/main.h" #include "weblayer/public/main.h"
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
...@@ -72,6 +77,27 @@ namespace weblayer { ...@@ -72,6 +77,27 @@ namespace weblayer {
namespace { namespace {
// Indexes and publishes the subresource filter ruleset data from resources in
// the resource bundle.
void PublishSubresourceFilterRulesetFromResourceBundle() {
// First obtain the version of the ruleset data from the manifest.
std::string ruleset_manifest_string =
ui::ResourceBundle::GetSharedInstance().LoadDataResourceString(
IDR_SUBRESOURCE_FILTER_UNINDEXED_RULESET_MANIFEST_JSON);
auto ruleset_manifest = base::JSONReader::Read(ruleset_manifest_string);
DCHECK(ruleset_manifest);
std::string* content_version = ruleset_manifest->FindStringKey("version");
// Instruct the RulesetService to obtain the unindexed ruleset data from the
// ResourceBundle and give it the version of that data.
auto* ruleset_service =
BrowserProcess::GetInstance()->subresource_filter_ruleset_service();
subresource_filter::UnindexedRulesetInfo ruleset_info;
ruleset_info.resource_id = IDR_SUBRESOURCE_FILTER_UNINDEXED_RULESET;
ruleset_info.content_version = *content_version;
ruleset_service->IndexAndStoreAndPublishRulesetIfNeeded(ruleset_info);
}
// Instantiates all weblayer KeyedService factories, which is // Instantiates all weblayer KeyedService factories, which is
// especially important for services that should be created at profile // especially important for services that should be created at profile
// creation time as compared to lazily on first access. // creation time as compared to lazily on first access.
...@@ -184,6 +210,17 @@ void BrowserMainPartsImpl::PreMainMessageLoopRun() { ...@@ -184,6 +210,17 @@ void BrowserMainPartsImpl::PreMainMessageLoopRun() {
BrowserProcess::GetInstance()->PreMainMessageLoopRun(); BrowserProcess::GetInstance()->PreMainMessageLoopRun();
// Publish the ruleset data. On the vast majority of runs this will
// effectively be a no-op as the version of the data changes at most once per
// release. Nonetheless, post it as a best-effort task to take it off the
// critical path of startup. Note that best-effort tasks are guaranteed to
// execute within a reasonable delay (assuming of course that the app isn't
// shut down first).
content::GetUIThreadTaskRunner({base::TaskPriority::BEST_EFFORT})
->PostTask(
FROM_HERE,
base::BindOnce(&PublishSubresourceFilterRulesetFromResourceBundle));
if (main_function_params_.ui_task) { if (main_function_params_.ui_task) {
std::move(*main_function_params_.ui_task).Run(); std::move(*main_function_params_.ui_task).Run();
delete main_function_params_.ui_task; delete main_function_params_.ui_task;
......
...@@ -2,8 +2,12 @@ ...@@ -2,8 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "base/json/json_reader.h"
#include "components/subresource_filter/content/browser/ruleset_service.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/resource/resource_bundle.h"
#include "weblayer/browser/browser_process.h" #include "weblayer/browser/browser_process.h"
#include "weblayer/grit/weblayer_resources.h"
#include "weblayer/test/weblayer_browser_test.h" #include "weblayer/test/weblayer_browser_test.h"
namespace weblayer { namespace weblayer {
...@@ -23,4 +27,36 @@ IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, RulesetService) { ...@@ -23,4 +27,36 @@ IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, RulesetService) {
nullptr); nullptr);
} }
// Tests that the ruleset is published as part of startup.
IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, RulesArePublished) {
auto* ruleset_service =
BrowserProcess::GetInstance()->subresource_filter_ruleset_service();
// Publishing might or might not have already finished at this point; wait for
// it to finish if necessary.
if (!ruleset_service->GetMostRecentlyIndexedVersion().IsValid()) {
base::RunLoop run_loop;
ruleset_service->SetRulesetPublishedCallbackForTesting(
run_loop.QuitClosure());
run_loop.Run();
}
auto ruleset_version = ruleset_service->GetMostRecentlyIndexedVersion();
EXPECT_TRUE(ruleset_version.IsValid());
std::string most_recently_indexed_content_version =
ruleset_version.content_version;
std::string packaged_ruleset_manifest_string =
ui::ResourceBundle::GetSharedInstance().LoadDataResourceString(
IDR_SUBRESOURCE_FILTER_UNINDEXED_RULESET_MANIFEST_JSON);
auto packaged_ruleset_manifest =
base::JSONReader::Read(packaged_ruleset_manifest_string);
std::string* packaged_content_version =
packaged_ruleset_manifest->FindStringKey("version");
EXPECT_EQ(most_recently_indexed_content_version, *packaged_content_version);
}
} // namespace weblayer } // namespace weblayer
...@@ -111,6 +111,7 @@ test("weblayer_browsertests") { ...@@ -111,6 +111,7 @@ test("weblayer_browsertests") {
"//components/signin/core/browser", "//components/signin/core/browser",
"//components/site_isolation", "//components/site_isolation",
"//components/strings", "//components/strings",
"//components/subresource_filter/content/browser",
"//components/translate/content/browser", "//components/translate/content/browser",
"//components/translate/content/browser:test_support", "//components/translate/content/browser:test_support",
"//components/ukm:test_support", "//components/ukm:test_support",
...@@ -125,6 +126,7 @@ test("weblayer_browsertests") { ...@@ -125,6 +126,7 @@ test("weblayer_browsertests") {
"//testing/gtest", "//testing/gtest",
"//ui/base", "//ui/base",
"//ui/gfx:test_support", "//ui/gfx:test_support",
"//weblayer:resources",
"//weblayer/shell:weblayer_shell_lib", "//weblayer/shell:weblayer_shell_lib",
] ]
......
...@@ -12,6 +12,8 @@ ...@@ -12,6 +12,8 @@
<include name="IDR_WEBLAYER_INTERNALS_HTML" file="browser/resources/weblayer_internals/weblayer_internals.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" /> <include name="IDR_WEBLAYER_INTERNALS_HTML" file="browser/resources/weblayer_internals/weblayer_internals.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
<include name="IDR_WEBLAYER_INTERNALS_JS" file="browser/resources/weblayer_internals/weblayer_internals.js" flattenhtml="true" type="BINDATA" /> <include name="IDR_WEBLAYER_INTERNALS_JS" file="browser/resources/weblayer_internals/weblayer_internals.js" flattenhtml="true" type="BINDATA" />
<include name="IDR_WEBLAYER_INTERNALS_MOJO_JS" file="${root_gen_dir}/weblayer/browser/webui/weblayer_internals.mojom-lite.js" use_base_dir="false" type="BINDATA" /> <include name="IDR_WEBLAYER_INTERNALS_MOJO_JS" file="${root_gen_dir}/weblayer/browser/webui/weblayer_internals.mojom-lite.js" use_base_dir="false" type="BINDATA" />
<include name="IDR_SUBRESOURCE_FILTER_UNINDEXED_RULESET" file="../third_party/subresource-filter-ruleset/data/UnindexedRules" type="BINDATA" compress="brotli" />
<include name="IDR_SUBRESOURCE_FILTER_UNINDEXED_RULESET_MANIFEST_JSON" file="../third_party/subresource-filter-ruleset/manifest.json" type="BINDATA" />
</includes> </includes>
</release> </release>
</grit> </grit>
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