Commit f70f8f4a authored by Dan Harrington's avatar Dan Harrington Committed by Commit Bot

Add PageAutoFetcher Mojo interface and new OfflinePages client policy

PageAutoFetcher isn't yet used, but it is fully functional. It schedules
requests and cancels scheduled requests, and uses a new client policy.

Note PageAutoFetcher isn't yet called anywhere.

Bug: 883486
Change-Id: If1f9ed401e30466d6c55f7598477150feb983f27
Reviewed-on: https://chromium-review.googlesource.com/c/1234358Reviewed-by: default avatarBrian White <bcwhite@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarCathy Li <chili@chromium.org>
Reviewed-by: default avatarCarlos Knippschild <carlosk@chromium.org>
Commit-Queue: Dan H <harringtond@google.com>
Cr-Commit-Position: refs/heads/master@{#601363}
parent e793e1bc
...@@ -4075,6 +4075,8 @@ jumbo_split_static_library("browser") { ...@@ -4075,6 +4075,8 @@ jumbo_split_static_library("browser") {
"offline_pages/downloads/resource_throttle.h", "offline_pages/downloads/resource_throttle.h",
"offline_pages/fresh_offline_content_observer.cc", "offline_pages/fresh_offline_content_observer.cc",
"offline_pages/fresh_offline_content_observer.h", "offline_pages/fresh_offline_content_observer.h",
"offline_pages/offline_page_auto_fetcher.cc",
"offline_pages/offline_page_auto_fetcher.h",
"offline_pages/offline_page_bookmark_observer.cc", "offline_pages/offline_page_bookmark_observer.cc",
"offline_pages/offline_page_bookmark_observer.h", "offline_pages/offline_page_bookmark_observer.h",
"offline_pages/offline_page_info_handler.cc", "offline_pages/offline_page_info_handler.cc",
...@@ -4155,6 +4157,7 @@ jumbo_split_static_library("browser") { ...@@ -4155,6 +4157,7 @@ jumbo_split_static_library("browser") {
] ]
} }
deps += [ deps += [
"//chrome/common:offline_page_auto_fetcher_mojom",
"//components/offline_pages/content/background_loader", "//components/offline_pages/content/background_loader",
"//components/offline_pages/content/renovations", "//components/offline_pages/content/renovations",
"//components/offline_pages/core", "//components/offline_pages/core",
......
// Copyright 2018 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 "chrome/browser/offline_pages/offline_page_auto_fetcher.h"
#include "base/time/time.h"
#include "chrome/browser/offline_pages/request_coordinator_factory.h"
#include "components/offline_pages/core/background/request_coordinator.h"
#include "components/offline_pages/core/background/save_page_request.h"
#include "components/offline_pages/core/client_id.h"
#include "components/offline_pages/core/client_namespace_constants.h"
#include "components/offline_pages/core/offline_page_model.h"
#include "components/offline_pages/core/offline_store_utils.h"
#include "url/gurl.h"
namespace offline_pages {
namespace {
constexpr int kMaximumInFlight = 3;
ClientId URLToClientId(const GURL& url) {
// By using namespace.URL as the client ID, we ensure that only a single
// request for a page can be in flight.
// We strip the fragment, because when loading an offline page, only the most
// recent page saved with the URL (fragment stripped) can be loaded.
GURL::Replacements remove_fragment;
remove_fragment.ClearRef();
GURL url_to_match = url.ReplaceComponents(remove_fragment);
return ClientId(kAutoAsyncNamespace, url_to_match.spec());
}
} // namespace
// This is an attempt to verify that a task callback eventually calls
// TaskComplete exactly once. If the token is never std::move'd, it will DCHECK
// when it is destroyed.
class OfflinePageAutoFetcher::TaskToken {
public:
// The static methods should only be called by StartOrEnqueue or TaskComplete.
static TaskToken NewToken() { return TaskToken(); }
static void Finalize(TaskToken& token) { token.alive_ = false; }
TaskToken(TaskToken&& other) : alive_(other.alive_) {
DCHECK(other.alive_);
other.alive_ = false;
}
~TaskToken() { DCHECK(!alive_); }
private:
TaskToken() {}
bool alive_ = true;
DISALLOW_COPY_AND_ASSIGN(TaskToken);
};
OfflinePageAutoFetcher::OfflinePageAutoFetcher(
content::BrowserContext* browser_context)
: browser_context_(browser_context) {}
OfflinePageAutoFetcher::~OfflinePageAutoFetcher() = default;
void OfflinePageAutoFetcher::TrySchedule(bool user_requested,
const GURL& url,
TryScheduleCallback callback) {
StartOrEnqueue(base::BindOnce(&OfflinePageAutoFetcher::TryScheduleStep1,
GetWeakPtr(), user_requested, url,
std::move(callback)));
}
void OfflinePageAutoFetcher::CancelSchedule(const GURL& url) {
StartOrEnqueue(base::BindOnce(&OfflinePageAutoFetcher::CancelScheduleStep1,
GetWeakPtr(), url));
}
void OfflinePageAutoFetcher::TryScheduleStep1(bool user_requested,
const GURL& url,
TryScheduleCallback callback,
TaskToken token) {
// Return an early failure if the URL is not suitable.
if (!OfflinePageModel::CanSaveURL(url)) {
std::move(callback).Run(OfflinePageAutoFetcherScheduleResult::kOtherError);
TaskComplete(std::move(token));
return;
}
// We need to do some checks on in-flight requests before scheduling the
// fetch. So first, get the list of all requests, and proceed to step 2.
RequestCoordinator* coordinator =
RequestCoordinatorFactory::GetForBrowserContext(browser_context_);
coordinator->GetAllRequests(
base::BindOnce(&OfflinePageAutoFetcher::TryScheduleStep2, GetWeakPtr(),
std::move(token), user_requested, url, std::move(callback),
// Unretained is OK because coordinator is calling us back.
base::Unretained(coordinator)));
}
void OfflinePageAutoFetcher::TryScheduleStep2(
TaskToken token,
bool user_requested,
const GURL& url,
TryScheduleCallback callback,
RequestCoordinator* coordinator,
std::vector<std::unique_ptr<SavePageRequest>> all_requests) {
// If a request for this page is already scheduled, report scheduling as
// successful without doing anything.
const ClientId url_client_id = URLToClientId(url);
for (const auto& request : all_requests) {
if (url_client_id == request->client_id()) {
std::move(callback).Run(
OfflinePageAutoFetcherScheduleResult::kAlreadyScheduled);
TaskComplete(std::move(token));
return;
}
}
// Respect kMaximumInFlight.
if (!user_requested) {
int in_flight_count = 0;
for (const auto& request : all_requests) {
if (request->client_id().name_space == kAutoAsyncNamespace) {
++in_flight_count;
}
}
if (in_flight_count >= kMaximumInFlight) {
std::move(callback).Run(
OfflinePageAutoFetcherScheduleResult::kNotEnoughQuota);
TaskComplete(std::move(token));
return;
}
}
// Finally, schedule a new request, and proceed to step 3.
RequestCoordinator::SavePageLaterParams params;
params.url = url;
params.client_id = url_client_id;
params.user_requested = false;
params.availability =
RequestCoordinator::RequestAvailability::ENABLED_FOR_OFFLINER;
coordinator->SavePageLater(
params,
base::BindOnce(&OfflinePageAutoFetcher::TryScheduleStep3, GetWeakPtr(),
std::move(token), std::move(callback)));
}
void OfflinePageAutoFetcher::TryScheduleStep3(TaskToken token,
TryScheduleCallback callback,
AddRequestResult result) {
// Just forward the response to the mojo caller.
std::move(callback).Run(
result == AddRequestResult::SUCCESS
? OfflinePageAutoFetcherScheduleResult::kScheduled
: OfflinePageAutoFetcherScheduleResult::kOtherError);
TaskComplete(std::move(token));
}
void OfflinePageAutoFetcher::CancelScheduleStep1(const GURL& url,
TaskToken token) {
// Get all requests, and proceed to step 2.
RequestCoordinator* coordinator =
RequestCoordinatorFactory::GetForBrowserContext(browser_context_);
coordinator->GetAllRequests(
base::BindOnce(&OfflinePageAutoFetcher::CancelScheduleStep2, GetWeakPtr(),
std::move(token), url, coordinator));
}
void OfflinePageAutoFetcher::CancelScheduleStep2(
TaskToken token,
const GURL& url,
RequestCoordinator* coordinator,
std::vector<std::unique_ptr<SavePageRequest>> requests) {
// Cancel the request if it's found in the list of all requests.
const ClientId url_client_id = URLToClientId(url);
for (const auto& request : requests) {
if (url_client_id == request->client_id()) {
coordinator->RemoveRequests(
{request->request_id()},
base::BindOnce(&OfflinePageAutoFetcher::CancelScheduleStep3,
GetWeakPtr(), std::move(token)));
return;
}
}
TaskComplete(std::move(token));
}
void OfflinePageAutoFetcher::CancelScheduleStep3(TaskToken token,
const MultipleItemStatuses&) {
TaskComplete(std::move(token));
}
void OfflinePageAutoFetcher::StartOrEnqueue(TaskCallback task) {
bool can_run = task_queue_.empty();
task_queue_.push(std::move(task));
if (can_run)
std::move(task_queue_.front()).Run(TaskToken::NewToken());
}
void OfflinePageAutoFetcher::TaskComplete(TaskToken token) {
TaskToken::Finalize(token);
DCHECK(!task_queue_.empty());
DCHECK(!task_queue_.front());
task_queue_.pop();
if (!task_queue_.empty())
std::move(task_queue_.front()).Run(TaskToken::NewToken());
}
bool OfflinePageAutoFetcher::IsTaskQueueEmptyForTesting() {
return task_queue_.empty();
}
} // namespace offline_pages
// Copyright 2018 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 CHROME_BROWSER_OFFLINE_PAGES_OFFLINE_PAGE_AUTO_FETCHER_H_
#define CHROME_BROWSER_OFFLINE_PAGES_OFFLINE_PAGE_AUTO_FETCHER_H_
#include <memory>
#include <vector>
#include "base/memory/weak_ptr.h"
#include "chrome/common/offline_page_auto_fetcher.mojom.h"
#include "components/offline_pages/core/background/request_queue_results.h"
#include "components/offline_pages/core/background/save_page_request.h"
namespace content {
class BrowserContext;
}
namespace offline_pages {
class RequestCoordinator;
// Provides control of fetching pages for later in an automatic / quiet way.
// TODO(crbug.com/883486): This class is not yet used.
class OfflinePageAutoFetcher : public chrome::mojom::OfflinePageAutoFetcher {
public:
explicit OfflinePageAutoFetcher(content::BrowserContext* browser_context);
~OfflinePageAutoFetcher() override;
void TrySchedule(bool user_requested,
const GURL& url,
TryScheduleCallback callback) override;
void CancelSchedule(const GURL& url) override;
bool IsTaskQueueEmptyForTesting();
private:
class TaskToken;
using TaskCallback = base::OnceCallback<void(TaskToken)>;
using OfflinePageAutoFetcherScheduleResult =
chrome::mojom::OfflinePageAutoFetcherScheduleResult;
// Task management methods. Each request made to this class is serialized by
// appending the tasks as callbacks to task_queue_.
// Starts or enqueues a new task.
void StartOrEnqueue(TaskCallback task);
// Reports a task complete. Must be called when the task is completely
// finished.
void TaskComplete(TaskToken token);
base::WeakPtr<OfflinePageAutoFetcher> GetWeakPtr() {
return weak_ptr_factory_.GetWeakPtr();
}
// Implementation details for public methods.
void TryScheduleStep1(bool user_requested,
const GURL& url,
TryScheduleCallback callback,
TaskToken token);
void TryScheduleStep2(
TaskToken token,
bool user_requested,
const GURL& url,
TryScheduleCallback callback,
RequestCoordinator* coordinator,
std::vector<std::unique_ptr<SavePageRequest>> all_requests);
void TryScheduleStep3(TaskToken token,
TryScheduleCallback callback,
AddRequestResult result);
void CancelScheduleStep1(const GURL& url, TaskToken token);
void CancelScheduleStep2(
TaskToken token,
const GURL& url,
RequestCoordinator* coordinator,
std::vector<std::unique_ptr<SavePageRequest>> requests);
void CancelScheduleStep3(TaskToken token, const MultipleItemStatuses&);
content::BrowserContext* browser_context_;
// TODO(harringtond): Pull out task management into another class, or use
// offline_pages::TaskQueue.
std::queue<TaskCallback> task_queue_;
base::WeakPtrFactory<OfflinePageAutoFetcher> weak_ptr_factory_{this};
};
} // namespace offline_pages
#endif // CHROME_BROWSER_OFFLINE_PAGES_OFFLINE_PAGE_AUTO_FETCHER_H_
// Copyright 2018 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 "chrome/browser/offline_pages/offline_page_auto_fetcher.h"
#include "base/test/bind_test_util.h"
#include "base/test/mock_callback.h"
#include "chrome/browser/offline_pages/request_coordinator_factory.h"
#include "chrome/browser/offline_pages/test_request_coordinator_builder.h"
#include "chrome/test/base/testing_profile.h"
#include "components/offline_pages/core/background/request_coordinator.h"
#include "components/offline_pages/core/background/test_request_queue_store.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace offline_pages {
namespace {
using OfflinePageAutoFetcherScheduleResult =
chrome::mojom::OfflinePageAutoFetcherScheduleResult;
class OfflinePageAutoFetcherTest : public testing::Test {
public:
void SetUp() override {
RequestCoordinator* coordinator = static_cast<RequestCoordinator*>(
RequestCoordinatorFactory::GetInstance()->SetTestingFactoryAndUse(
&profile_, BuildTestRequestCoordinator));
queue_store_ = static_cast<TestRequestQueueStore*>(
coordinator->queue_for_testing()->GetStoreForTesting());
}
void TearDown() override {
browser_thread_bundle_.RunUntilIdle();
ASSERT_TRUE(fetcher_.IsTaskQueueEmptyForTesting());
}
TestRequestQueueStore* queue_store() { return queue_store_; }
std::vector<std::unique_ptr<SavePageRequest>> GetRequestsSync() {
bool completed = false;
std::vector<std::unique_ptr<SavePageRequest>> result;
queue_store_->GetRequests(base::BindLambdaForTesting(
[&](bool success,
std::vector<std::unique_ptr<SavePageRequest>> requests) {
completed = true;
result = std::move(requests);
}));
browser_thread_bundle_.RunUntilIdle();
CHECK(completed);
return result;
}
protected:
content::TestBrowserThreadBundle browser_thread_bundle_;
TestingProfile profile_;
// Owned by the request queue.
TestRequestQueueStore* queue_store_ = nullptr;
OfflinePageAutoFetcher fetcher_{&profile_};
};
TEST_F(OfflinePageAutoFetcherTest, TryScheduleSuccess) {
base::MockCallback<
base::OnceCallback<void(OfflinePageAutoFetcherScheduleResult)>>
result_callback;
EXPECT_CALL(result_callback,
Run(OfflinePageAutoFetcherScheduleResult::kScheduled));
fetcher_.TrySchedule(false, GURL("http://foo.com"), result_callback.Get());
browser_thread_bundle_.RunUntilIdle();
EXPECT_EQ(1ul, GetRequestsSync().size());
}
TEST_F(OfflinePageAutoFetcherTest, AttemptInvalidURL) {
base::MockCallback<
base::OnceCallback<void(OfflinePageAutoFetcherScheduleResult)>>
result_callback;
EXPECT_CALL(result_callback,
Run(OfflinePageAutoFetcherScheduleResult::kOtherError));
fetcher_.TrySchedule(false, GURL("ftp://foo.com"), result_callback.Get());
browser_thread_bundle_.RunUntilIdle();
EXPECT_EQ(0ul, GetRequestsSync().size());
}
TEST_F(OfflinePageAutoFetcherTest, TryScheduleDuplicate) {
base::MockCallback<
base::RepeatingCallback<void(OfflinePageAutoFetcherScheduleResult)>>
result_callback;
EXPECT_CALL(result_callback,
Run(OfflinePageAutoFetcherScheduleResult::kScheduled))
.Times(1);
EXPECT_CALL(result_callback,
Run(OfflinePageAutoFetcherScheduleResult::kAlreadyScheduled))
.Times(1);
// The page should only be saved once, because the fragment is ignored.
fetcher_.TrySchedule(false, GURL("http://foo.com#A"), result_callback.Get());
fetcher_.TrySchedule(false, GURL("http://foo.com#Z"), result_callback.Get());
browser_thread_bundle_.RunUntilIdle();
EXPECT_EQ(1ul, GetRequestsSync().size());
}
TEST_F(OfflinePageAutoFetcherTest, AttemptAutoScheduleMoreThanMaximum) {
base::MockCallback<
base::RepeatingCallback<void(OfflinePageAutoFetcherScheduleResult)>>
result_callback;
testing::InSequence in_sequence;
EXPECT_CALL(result_callback,
Run(OfflinePageAutoFetcherScheduleResult::kScheduled))
.Times(3);
EXPECT_CALL(result_callback,
Run(OfflinePageAutoFetcherScheduleResult::kNotEnoughQuota))
.Times(1);
EXPECT_CALL(result_callback,
Run(OfflinePageAutoFetcherScheduleResult::kScheduled))
.Times(1);
// Three requests within quota.
fetcher_.TrySchedule(false, GURL("http://foo.com/1"), result_callback.Get());
fetcher_.TrySchedule(false, GURL("http://foo.com/2"), result_callback.Get());
fetcher_.TrySchedule(false, GURL("http://foo.com/3"), result_callback.Get());
// Quota is exhausted.
fetcher_.TrySchedule(false, GURL("http://foo.com/4"), result_callback.Get());
// User-requested, quota is not enforced.
fetcher_.TrySchedule(true, GURL("http://foo.com/5"), result_callback.Get());
browser_thread_bundle_.RunUntilIdle();
}
TEST_F(OfflinePageAutoFetcherTest, TryScheduleMoreThanMaximumUserRequested) {
base::MockCallback<
base::RepeatingCallback<void(OfflinePageAutoFetcherScheduleResult)>>
result_callback;
EXPECT_CALL(result_callback,
Run(OfflinePageAutoFetcherScheduleResult::kScheduled))
.Times(4);
fetcher_.TrySchedule(true, GURL("http://foo.com/1"), result_callback.Get());
fetcher_.TrySchedule(true, GURL("http://foo.com/2"), result_callback.Get());
fetcher_.TrySchedule(true, GURL("http://foo.com/3"), result_callback.Get());
fetcher_.TrySchedule(true, GURL("http://foo.com/4"), result_callback.Get());
browser_thread_bundle_.RunUntilIdle();
}
TEST_F(OfflinePageAutoFetcherTest, CancelSuccess) {
fetcher_.TrySchedule(false, GURL("http://foo.com"), base::DoNothing());
browser_thread_bundle_.RunUntilIdle();
fetcher_.CancelSchedule(GURL("http://foo.com"));
browser_thread_bundle_.RunUntilIdle();
EXPECT_EQ(0ul, GetRequestsSync().size());
}
TEST_F(OfflinePageAutoFetcherTest, CancelNotExist) {
fetcher_.TrySchedule(false, GURL("http://foo.com"), base::DoNothing());
browser_thread_bundle_.RunUntilIdle();
fetcher_.CancelSchedule(GURL("http://NOT-FOO.com"));
browser_thread_bundle_.RunUntilIdle();
EXPECT_EQ(1ul, GetRequestsSync().size());
}
TEST_F(OfflinePageAutoFetcherTest, CancelQueueEmpty) {
fetcher_.CancelSchedule(GURL("http://foo.com"));
browser_thread_bundle_.RunUntilIdle();
}
} // namespace
} // namespace offline_pages
...@@ -218,6 +218,7 @@ static_library("common") { ...@@ -218,6 +218,7 @@ static_library("common") {
":common_param_traits_macros", ":common_param_traits_macros",
":ini_parser", ":ini_parser",
":mojo_bindings", ":mojo_bindings",
":offline_page_auto_fetcher_mojom",
":page_load_metrics_mojom", ":page_load_metrics_mojom",
":supervised_user_commands_mojom", ":supervised_user_commands_mojom",
"//base:base", "//base:base",
...@@ -823,3 +824,12 @@ mojom("available_offline_content_mojom") { ...@@ -823,3 +824,12 @@ mojom("available_offline_content_mojom") {
"//url/mojom:url_mojom_gurl", "//url/mojom:url_mojom_gurl",
] ]
} }
mojom("offline_page_auto_fetcher_mojom") {
sources = [
"offline_page_auto_fetcher.mojom",
]
public_deps = [
"//url/mojom:url_mojom_gurl",
]
}
// Copyright 2018 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.
module chrome.mojom;
import "url/mojom/url.mojom";
enum OfflinePageAutoFetcherScheduleResult {
// There are too many in flight requests, so the new request was not
// scheduled.
kNotEnoughQuota,
// An error prevented the request from being scheduled.
kOtherError,
// There already exists a request for the URL, so the request was not
// scheduled.
kAlreadyScheduled,
// The request was scheduled.
kScheduled
};
// Provides controls for fetching offline pages automatically and quietly in
// the background.
interface OfflinePageAutoFetcher {
// Attempts to schedule an auto fetch for this URL, and returns the result.
// If user_requested is false, only schedules the fetch if there is remaining
// quota.
TrySchedule(bool user_requested, url.mojom.Url url) =>
(OfflinePageAutoFetcherScheduleResult out);
// Cancels a previously scheduled auto fetch.
CancelSchedule(url.mojom.Url url);
};
...@@ -2943,6 +2943,7 @@ test("unit_tests") { ...@@ -2943,6 +2943,7 @@ test("unit_tests") {
sources += [ sources += [
"../browser/offline_pages/background_loader_offliner_unittest.cc", "../browser/offline_pages/background_loader_offliner_unittest.cc",
"../browser/offline_pages/download_archive_manager_unittest.cc", "../browser/offline_pages/download_archive_manager_unittest.cc",
"../browser/offline_pages/offline_page_auto_fetcher_unittest.cc",
"../browser/offline_pages/offline_page_mhtml_archiver_unittest.cc", "../browser/offline_pages/offline_page_mhtml_archiver_unittest.cc",
"../browser/offline_pages/offline_page_request_handler_unittest.cc", "../browser/offline_pages/offline_page_request_handler_unittest.cc",
"../browser/offline_pages/offline_page_tab_helper_unittest.cc", "../browser/offline_pages/offline_page_tab_helper_unittest.cc",
......
...@@ -119,6 +119,8 @@ class RequestQueue : public TaskQueue::Delegate { ...@@ -119,6 +119,8 @@ class RequestQueue : public TaskQueue::Delegate {
cleanup_factory_ = std::move(factory); cleanup_factory_ = std::move(factory);
} }
RequestQueueStore* GetStoreForTesting() { return store_.get(); }
private: private:
// Store initialization functions. // Store initialization functions.
void Initialize(); void Initialize();
......
...@@ -17,6 +17,7 @@ const char kNTPSuggestionsNamespace[] = "ntp_suggestions"; ...@@ -17,6 +17,7 @@ const char kNTPSuggestionsNamespace[] = "ntp_suggestions";
const char kSuggestedArticlesNamespace[] = "suggested_articles"; const char kSuggestedArticlesNamespace[] = "suggested_articles";
const char kBrowserActionsNamespace[] = "browser_actions"; const char kBrowserActionsNamespace[] = "browser_actions";
const char kLivePageSharingNamespace[] = "live_page_sharing"; const char kLivePageSharingNamespace[] = "live_page_sharing";
const char kAutoAsyncNamespace[] = "auto_async_loading";
const char kDefaultNamespace[] = "default"; const char kDefaultNamespace[] = "default";
......
...@@ -25,6 +25,7 @@ extern const char kNTPSuggestionsNamespace[]; ...@@ -25,6 +25,7 @@ extern const char kNTPSuggestionsNamespace[];
extern const char kSuggestedArticlesNamespace[]; extern const char kSuggestedArticlesNamespace[];
extern const char kBrowserActionsNamespace[]; extern const char kBrowserActionsNamespace[];
extern const char kLivePageSharingNamespace[]; extern const char kLivePageSharingNamespace[];
extern const char kAutoAsyncNamespace[];
// Enum of namespaces used by metric collection. // Enum of namespaces used by metric collection.
// See OfflinePagesNamespaceEnumeration in enums.xml for histogram usages. // See OfflinePagesNamespaceEnumeration in enums.xml for histogram usages.
...@@ -41,7 +42,8 @@ enum class OfflinePagesNamespaceEnumeration { ...@@ -41,7 +42,8 @@ enum class OfflinePagesNamespaceEnumeration {
SUGGESTED_ARTICLES = 7, SUGGESTED_ARTICLES = 7,
BROWSER_ACTIONS = 8, BROWSER_ACTIONS = 8,
LIVE_PAGE_SHARING = 9, LIVE_PAGE_SHARING = 9,
kMaxValue = LIVE_PAGE_SHARING, ASYNC_AUTO_LOADING = 10,
kMaxValue = ASYNC_AUTO_LOADING,
}; };
} // namespace offline_pages } // namespace offline_pages
......
...@@ -91,6 +91,14 @@ ClientPolicyController::ClientPolicyController() { ...@@ -91,6 +91,14 @@ ClientPolicyController::ClientPolicyController() {
.SetExpirePeriod(base::TimeDelta::FromHours(1)) .SetExpirePeriod(base::TimeDelta::FromHours(1))
.SetIsRestrictedToTabFromClientId(true) .SetIsRestrictedToTabFromClientId(true)
.Build())); .Build()));
policies_.insert(std::make_pair(
kAutoAsyncNamespace,
OfflinePageClientPolicyBuilder(
kAutoAsyncNamespace, LifetimeType::TEMPORARY, kUnlimitedPages, 1)
.SetIsRemovedOnCacheReset(true)
.SetExpirePeriod(base::TimeDelta::FromDays(30))
.SetIsUserRequestedDownload(false)
.Build()));
// Fallback policy. // Fallback policy.
policies_.insert(std::make_pair( policies_.insert(std::make_pair(
......
...@@ -36844,7 +36844,8 @@ Called by update_net_trust_anchors.py.--> ...@@ -36844,7 +36844,8 @@ Called by update_net_trust_anchors.py.-->
Namespace used when offline page is saved as last_n page. Namespace used when offline page is saved as last_n page.
</int> </int>
<int value="3" label="Async_loading"> <int value="3" label="Async_loading">
Namespace used when offline page is saved from save page later on dino page. Namespace used when offline page is saved after the user clicks a button on
the dino page.
</int> </int>
<int value="4" label="Custom_tabs"> <int value="4" label="Custom_tabs">
Namespace used when offline page is saved from custom tabs. Namespace used when offline page is saved from custom tabs.
...@@ -36864,6 +36865,10 @@ Called by update_net_trust_anchors.py.--> ...@@ -36864,6 +36865,10 @@ Called by update_net_trust_anchors.py.-->
<int value="9" label="Live_page_sharing"> <int value="9" label="Live_page_sharing">
Namespace used when offline page is saved for live page sharing. Namespace used when offline page is saved for live page sharing.
</int> </int>
<int value="10" label="Auto_async_loading">
Namespace used for temporary offline pages requested to be downloaded when
the user landed in a dino page.
</int>
</enum> </enum>
<enum name="OfflinePagesOfflineUsage"> <enum name="OfflinePagesOfflineUsage">
...@@ -129927,6 +129927,8 @@ uploading your change for review. ...@@ -129927,6 +129927,8 @@ uploading your change for review.
<histogram_suffixes name="OfflinePagesNamespace" separator="."> <histogram_suffixes name="OfflinePagesNamespace" separator=".">
<suffix name="async_loading" label="Offline async loaded pages"/> <suffix name="async_loading" label="Offline async loaded pages"/>
<suffix name="auto_async_loading"
label="Automatic offline async loaded pages"/>
<suffix name="bookmark" label="Offline bookmark cache"/> <suffix name="bookmark" label="Offline bookmark cache"/>
<suffix name="browser_actions" label="Offline Browser Actions pages"/> <suffix name="browser_actions" label="Offline Browser Actions pages"/>
<suffix name="custom_tabs" label="Offline custom tabs"/> <suffix name="custom_tabs" label="Offline custom tabs"/>
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