Commit 650cb6aa authored by Rayan Kanso's avatar Rayan Kanso Committed by Commit Bot

[ContentIndex] Provide a quality score for offline items.

Use the site engagement service to rank content index entries when
handing off offline items.

Change-Id: Ie9929f73e0fb52edff297fd63f21e0069eb3c8f5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1866710
Commit-Queue: Rayan Kanso <rayankans@chromium.org>
Reviewed-by: default avatarShakti Sahu <shaktisahu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#707030}
parent 77cff635
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "chrome/browser/content_index/content_index_provider_factory.h" #include "chrome/browser/content_index/content_index_provider_factory.h"
#include "chrome/browser/content_index/content_index_provider_impl.h" #include "chrome/browser/content_index/content_index_provider_impl.h"
#include "chrome/browser/engagement/site_engagement_service_factory.h"
#include "chrome/browser/metrics/ukm_background_recorder_service.h" #include "chrome/browser/metrics/ukm_background_recorder_service.h"
#include "chrome/browser/offline_items_collection/offline_content_aggregator_factory.h" #include "chrome/browser/offline_items_collection/offline_content_aggregator_factory.h"
#include "chrome/browser/profiles/incognito_helpers.h" #include "chrome/browser/profiles/incognito_helpers.h"
...@@ -29,6 +30,7 @@ ContentIndexProviderFactory::ContentIndexProviderFactory() ...@@ -29,6 +30,7 @@ ContentIndexProviderFactory::ContentIndexProviderFactory()
BrowserContextDependencyManager::GetInstance()) { BrowserContextDependencyManager::GetInstance()) {
DependsOn(OfflineContentAggregatorFactory::GetInstance()); DependsOn(OfflineContentAggregatorFactory::GetInstance());
DependsOn(ukm::UkmBackgroundRecorderFactory::GetInstance()); DependsOn(ukm::UkmBackgroundRecorderFactory::GetInstance());
DependsOn(SiteEngagementServiceFactory::GetInstance());
} }
ContentIndexProviderFactory::~ContentIndexProviderFactory() = default; ContentIndexProviderFactory::~ContentIndexProviderFactory() = default;
......
...@@ -11,6 +11,9 @@ ...@@ -11,6 +11,9 @@
#include "base/strings/string_split.h" #include "base/strings/string_split.h"
#include "base/task/post_task.h" #include "base/task/post_task.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "chrome/browser/engagement/site_engagement_score.h"
#include "chrome/browser/engagement/site_engagement_service.h"
#include "chrome/browser/engagement/site_engagement_service_factory.h"
#include "chrome/browser/metrics/ukm_background_recorder_service.h" #include "chrome/browser/metrics/ukm_background_recorder_service.h"
#include "chrome/browser/offline_items_collection/offline_content_aggregator_factory.h" #include "chrome/browser/offline_items_collection/offline_content_aggregator_factory.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
...@@ -95,53 +98,15 @@ OfflineItemFilter CategoryToFilter(blink::mojom::ContentCategory category) { ...@@ -95,53 +98,15 @@ OfflineItemFilter CategoryToFilter(blink::mojom::ContentCategory category) {
} }
} }
OfflineItem EntryToOfflineItem(const content::ContentIndexEntry& entry) {
OfflineItem item;
item.id = ContentId(kProviderNamespace, EntryKey(entry));
item.title = entry.description->title;
item.description = entry.description->description;
item.filter = CategoryToFilter(entry.description->category);
item.is_transient = false;
item.is_suggested = true;
item.creation_time = entry.registration_time;
item.is_openable = true;
item.state = offline_items_collection::OfflineItemState::COMPLETE;
item.is_resumable = false;
item.can_rename = false;
item.page_url = entry.launch_url;
return item;
}
void DidGetAllEntries(base::OnceClosure done_closure,
ContentIndexProviderImpl::OfflineItemList* item_list,
blink::mojom::ContentIndexError error,
std::vector<content::ContentIndexEntry> entries) {
if (error != blink::mojom::ContentIndexError::NONE) {
std::move(done_closure).Run();
return;
}
for (const auto& entry : entries)
item_list->push_back(EntryToOfflineItem(entry));
std::move(done_closure).Run();
}
void DidGetAllEntriesAcrossStorageParitions(
std::unique_ptr<ContentIndexProviderImpl::OfflineItemList> item_list,
ContentIndexProviderImpl::MultipleItemCallback callback) {
ContentIndexMetrics::RecordContentIndexEntries(item_list->size());
std::move(callback).Run(*item_list);
}
} // namespace } // namespace
ContentIndexProviderImpl::ContentIndexProviderImpl(Profile* profile) ContentIndexProviderImpl::ContentIndexProviderImpl(Profile* profile)
: profile_(profile), : profile_(profile),
metrics_(ukm::UkmBackgroundRecorderFactory::GetForProfile(profile)), metrics_(ukm::UkmBackgroundRecorderFactory::GetForProfile(profile)),
aggregator_(OfflineContentAggregatorFactory::GetForKey( aggregator_(
profile->GetProfileKey())) { OfflineContentAggregatorFactory::GetForKey(profile->GetProfileKey())),
site_engagement_service_(
SiteEngagementServiceFactory::GetForProfile(profile)) {
aggregator_->RegisterProvider(kProviderNamespace, this); aggregator_->RegisterProvider(kProviderNamespace, this);
} }
...@@ -153,6 +118,7 @@ ContentIndexProviderImpl::~ContentIndexProviderImpl() { ...@@ -153,6 +118,7 @@ ContentIndexProviderImpl::~ContentIndexProviderImpl() {
void ContentIndexProviderImpl::Shutdown() { void ContentIndexProviderImpl::Shutdown() {
aggregator_->UnregisterProvider(kProviderNamespace); aggregator_->UnregisterProvider(kProviderNamespace);
aggregator_ = nullptr; aggregator_ = nullptr;
site_engagement_service_ = nullptr;
} }
std::vector<gfx::Size> ContentIndexProviderImpl::GetIconSizes( std::vector<gfx::Size> ContentIndexProviderImpl::GetIconSizes(
...@@ -287,15 +253,17 @@ void ContentIndexProviderImpl::GetItemById(const ContentId& id, ...@@ -287,15 +253,17 @@ void ContentIndexProviderImpl::GetItemById(const ContentId& id,
storage_partition->GetContentIndexContext()->GetEntry( storage_partition->GetContentIndexContext()->GetEntry(
components.service_worker_registration_id, components.description_id, components.service_worker_registration_id, components.description_id,
base::BindOnce( base::BindOnce(&ContentIndexProviderImpl::DidGetItem,
[](SingleItemCallback callback, weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
base::Optional<content::ContentIndexEntry> entry) { }
if (!entry)
std::move(callback).Run(base::nullopt); void ContentIndexProviderImpl::DidGetItem(
else SingleItemCallback callback,
std::move(callback).Run(EntryToOfflineItem(*entry)); base::Optional<content::ContentIndexEntry> entry) {
}, if (!entry)
std::move(callback))); std::move(callback).Run(base::nullopt);
else
std::move(callback).Run(EntryToOfflineItem(*entry));
} }
void ContentIndexProviderImpl::GetAllItems(MultipleItemCallback callback) { void ContentIndexProviderImpl::GetAllItems(MultipleItemCallback callback) {
...@@ -317,8 +285,10 @@ void ContentIndexProviderImpl::GetAllItems(MultipleItemCallback callback) { ...@@ -317,8 +285,10 @@ void ContentIndexProviderImpl::GetAllItems(MultipleItemCallback callback) {
// Get the all entries from every partition. // Get the all entries from every partition.
auto barrier_closure = base::BarrierClosure( auto barrier_closure = base::BarrierClosure(
storage_paritions.size(), storage_paritions.size(),
base::BindOnce(&DidGetAllEntriesAcrossStorageParitions, base::BindOnce(
std::move(item_list), std::move(callback))); &ContentIndexProviderImpl::DidGetAllEntriesAcrossStorageParitions,
weak_ptr_factory_.GetWeakPtr(), std::move(item_list),
std::move(callback)));
for (auto* storage_partition : storage_paritions) { for (auto* storage_partition : storage_paritions) {
if (!storage_partition || !storage_partition->GetContentIndexContext()) { if (!storage_partition || !storage_partition->GetContentIndexContext()) {
...@@ -328,11 +298,35 @@ void ContentIndexProviderImpl::GetAllItems(MultipleItemCallback callback) { ...@@ -328,11 +298,35 @@ void ContentIndexProviderImpl::GetAllItems(MultipleItemCallback callback) {
// |item_list_ptr| is safe to use since it is owned by the barrier // |item_list_ptr| is safe to use since it is owned by the barrier
// closure. // closure.
storage_partition->GetContentIndexContext()->GetAllEntries( storage_partition->GetContentIndexContext()->GetAllEntries(base::BindOnce(
base::BindOnce(&DidGetAllEntries, barrier_closure, item_list_ptr)); &ContentIndexProviderImpl::DidGetAllEntries,
weak_ptr_factory_.GetWeakPtr(), barrier_closure, item_list_ptr));
} }
} }
void ContentIndexProviderImpl::DidGetAllEntriesAcrossStorageParitions(
std::unique_ptr<OfflineItemList> item_list,
MultipleItemCallback callback) {
ContentIndexMetrics::RecordContentIndexEntries(item_list->size());
std::move(callback).Run(*item_list);
}
void ContentIndexProviderImpl::DidGetAllEntries(
base::OnceClosure done_closure,
OfflineItemList* item_list,
blink::mojom::ContentIndexError error,
std::vector<content::ContentIndexEntry> entries) {
if (error != blink::mojom::ContentIndexError::NONE) {
std::move(done_closure).Run();
return;
}
for (const auto& entry : entries)
item_list->push_back(EntryToOfflineItem(entry));
std::move(done_closure).Run();
}
void ContentIndexProviderImpl::GetVisualsForItem(const ContentId& id, void ContentIndexProviderImpl::GetVisualsForItem(const ContentId& id,
GetVisualsOptions options, GetVisualsOptions options,
VisualsCallback callback) { VisualsCallback callback) {
...@@ -353,6 +347,31 @@ void ContentIndexProviderImpl::GetVisualsForItem(const ContentId& id, ...@@ -353,6 +347,31 @@ void ContentIndexProviderImpl::GetVisualsForItem(const ContentId& id,
weak_ptr_factory_.GetWeakPtr(), id, std::move(callback))); weak_ptr_factory_.GetWeakPtr(), id, std::move(callback)));
} }
OfflineItem ContentIndexProviderImpl::EntryToOfflineItem(
const content::ContentIndexEntry& entry) {
OfflineItem item;
item.id = ContentId(kProviderNamespace, EntryKey(entry));
item.title = entry.description->title;
item.description = entry.description->description;
item.filter = CategoryToFilter(entry.description->category);
item.is_transient = false;
item.is_suggested = true;
item.creation_time = entry.registration_time;
item.is_openable = true;
item.state = offline_items_collection::OfflineItemState::COMPLETE;
item.is_resumable = false;
item.can_rename = false;
item.page_url = entry.launch_url;
if (site_engagement_service_) {
item.content_quality_score =
site_engagement_service_->GetScore(entry.launch_url.GetOrigin()) /
SiteEngagementScore::kMaxPoints;
}
return item;
}
void ContentIndexProviderImpl::DidGetIcons(const ContentId& id, void ContentIndexProviderImpl::DidGetIcons(const ContentId& id,
VisualsCallback callback, VisualsCallback callback,
std::vector<SkBitmap> icons) { std::vector<SkBitmap> icons) {
......
...@@ -26,6 +26,7 @@ class OfflineContentAggregator; ...@@ -26,6 +26,7 @@ class OfflineContentAggregator;
} // namespace offline_items_collection } // namespace offline_items_collection
class Profile; class Profile;
class SiteEngagementService;
class ContentIndexProviderImpl class ContentIndexProviderImpl
: public KeyedService, : public KeyedService,
...@@ -73,16 +74,28 @@ class ContentIndexProviderImpl ...@@ -73,16 +74,28 @@ class ContentIndexProviderImpl
} }
private: private:
void DidGetItem(SingleItemCallback callback,
base::Optional<content::ContentIndexEntry> entry);
void DidGetAllEntriesAcrossStorageParitions(
std::unique_ptr<OfflineItemList> item_list,
MultipleItemCallback callback);
void DidGetAllEntries(base::OnceClosure done_closure,
OfflineItemList* item_list,
blink::mojom::ContentIndexError error,
std::vector<content::ContentIndexEntry> entries);
void DidGetIcons(const offline_items_collection::ContentId& id, void DidGetIcons(const offline_items_collection::ContentId& id,
VisualsCallback callback, VisualsCallback callback,
std::vector<SkBitmap> icons); std::vector<SkBitmap> icons);
void DidGetEntryToOpen(base::Optional<content::ContentIndexEntry> entry); void DidGetEntryToOpen(base::Optional<content::ContentIndexEntry> entry);
void DidOpenTab(content::ContentIndexEntry entry, void DidOpenTab(content::ContentIndexEntry entry,
content::WebContents* web_contents); content::WebContents* web_contents);
offline_items_collection::OfflineItem EntryToOfflineItem(
const content::ContentIndexEntry& entry);
Profile* profile_; Profile* profile_;
ContentIndexMetrics metrics_; ContentIndexMetrics metrics_;
offline_items_collection::OfflineContentAggregator* aggregator_; offline_items_collection::OfflineContentAggregator* aggregator_;
SiteEngagementService* site_engagement_service_;
base::ObserverList<Observer>::Unchecked observers_; base::ObserverList<Observer>::Unchecked observers_;
base::Optional<std::vector<gfx::Size>> icon_sizes_for_testing_; base::Optional<std::vector<gfx::Size>> icon_sizes_for_testing_;
base::WeakPtrFactory<ContentIndexProviderImpl> weak_ptr_factory_{this}; base::WeakPtrFactory<ContentIndexProviderImpl> weak_ptr_factory_{this};
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "base/run_loop.h" #include "base/run_loop.h"
#include "base/test/bind_test_util.h" #include "base/test/bind_test_util.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "chrome/browser/engagement/site_engagement_service.h"
#include "chrome/test/base/testing_profile.h" #include "chrome/test/base/testing_profile.h"
#include "components/offline_items_collection/core/offline_content_provider.h" #include "components/offline_items_collection/core/offline_content_provider.h"
#include "content/public/browser/content_index_provider.h" #include "content/public/browser/content_index_provider.h"
...@@ -30,6 +31,7 @@ using offline_items_collection::UpdateDelta; ...@@ -30,6 +31,7 @@ using offline_items_collection::UpdateDelta;
using testing::_; using testing::_;
constexpr int64_t kServiceWorkerRegistrationId = 42; constexpr int64_t kServiceWorkerRegistrationId = 42;
constexpr double kEngagementScore = 42.0;
const GURL kLaunchURL = GURL("https://example.com/foo"); const GURL kLaunchURL = GURL("https://example.com/foo");
const url::Origin kOrigin = url::Origin::Create(kLaunchURL.GetOrigin()); const url::Origin kOrigin = url::Origin::Create(kLaunchURL.GetOrigin());
...@@ -39,6 +41,9 @@ class ContentIndexProviderImplTest : public testing::Test, ...@@ -39,6 +41,9 @@ class ContentIndexProviderImplTest : public testing::Test,
void SetUp() override { void SetUp() override {
ASSERT_TRUE(profile_.CreateHistoryService(/* delete_file= */ true, ASSERT_TRUE(profile_.CreateHistoryService(/* delete_file= */ true,
/* no_db= */ false)); /* no_db= */ false));
auto* service = SiteEngagementService::Get(&profile_);
service->ResetBaseScoreForURL(kOrigin.GetURL(), kEngagementScore);
provider_ = std::make_unique<ContentIndexProviderImpl>(&profile_); provider_ = std::make_unique<ContentIndexProviderImpl>(&profile_);
provider_->AddObserver(this); provider_->AddObserver(this);
} }
...@@ -86,6 +91,7 @@ TEST_F(ContentIndexProviderImplTest, OfflineItemCreation) { ...@@ -86,6 +91,7 @@ TEST_F(ContentIndexProviderImplTest, OfflineItemCreation) {
EXPECT_TRUE(item.is_suggested); EXPECT_TRUE(item.is_suggested);
EXPECT_TRUE(item.is_openable); EXPECT_TRUE(item.is_openable);
EXPECT_EQ(item.page_url, kLaunchURL); EXPECT_EQ(item.page_url, kLaunchURL);
EXPECT_EQ(item.content_quality_score, kEngagementScore / 100.0);
} }
TEST_F(ContentIndexProviderImplTest, ObserverUpdates) { TEST_F(ContentIndexProviderImplTest, ObserverUpdates) {
......
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