Commit 9bdc2af5 authored by tby's avatar tby Committed by Commit Bot

Remove multiplier on launcher search provider groups.

This is the first in a series of changes to how search providers are
created and configured, with the aim of reducing the number of ranking
and filtering steps between the providers and the UI.

Eventually I'd like to repurpose the concept of a 'mixer group'.
This change makes a small start by removing a feature of
groups that we don't use anymore: multipliers on result scores.

This CL also deletes some obsolete tests that don't take into account
modern ranking. This coverage is mostly duplicated by search result
ranker tests.

Bug: 1028447
Change-Id: Ib6d27975ede3b9ee0a9d4b508d262ebff154670b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2342533
Commit-Queue: Tony Yeoman <tby@chromium.org>
Reviewed-by: default avatarJia Meng <jiameng@chromium.org>
Cr-Commit-Position: refs/heads/master@{#798526}
parent 7382060b
...@@ -45,8 +45,8 @@ bool Mixer::SortData::operator<(const SortData& other) const { ...@@ -45,8 +45,8 @@ bool Mixer::SortData::operator<(const SortData& other) const {
// Used to group relevant providers together for mixing their results. // Used to group relevant providers together for mixing their results.
class Mixer::Group { class Mixer::Group {
public: public:
Group(size_t max_results, double multiplier, double boost) Group(size_t max_results, double boost)
: max_results_(max_results), multiplier_(multiplier), boost_(boost) {} : max_results_(max_results), boost_(boost) {}
~Group() {} ~Group() {}
void AddProvider(SearchProvider* provider) { void AddProvider(SearchProvider* provider) {
...@@ -64,8 +64,7 @@ class Mixer::Group { ...@@ -64,8 +64,7 @@ class Mixer::Group {
// [0.0, 1.0]. Clamp to that range. // [0.0, 1.0]. Clamp to that range.
const double relevance = const double relevance =
base::ClampToRange(result->relevance(), 0.0, 1.0); base::ClampToRange(result->relevance(), 0.0, 1.0);
double boost = boost_; results_.emplace_back(result.get(), relevance + boost_);
results_.emplace_back(result.get(), relevance * multiplier_ + boost);
} }
} }
...@@ -81,7 +80,6 @@ class Mixer::Group { ...@@ -81,7 +80,6 @@ class Mixer::Group {
private: private:
typedef std::vector<SearchProvider*> Providers; typedef std::vector<SearchProvider*> Providers;
const size_t max_results_; const size_t max_results_;
const double multiplier_;
const double boost_; const double boost_;
Providers providers_; // Not owned. Providers providers_; // Not owned.
...@@ -104,8 +102,8 @@ void Mixer::InitializeRankers(Profile* profile, ...@@ -104,8 +102,8 @@ void Mixer::InitializeRankers(Profile* profile,
} }
} }
size_t Mixer::AddGroup(size_t max_results, double multiplier, double boost) { size_t Mixer::AddGroup(size_t max_results, double boost) {
groups_.push_back(std::make_unique<Group>(max_results, multiplier, boost)); groups_.push_back(std::make_unique<Group>(max_results, boost));
return groups_.size() - 1; return groups_.size() - 1;
} }
......
...@@ -34,8 +34,7 @@ enum class RankingItemType; ...@@ -34,8 +34,7 @@ enum class RankingItemType;
// Mixer collects results from providers, sorts them and publishes them to the // Mixer collects results from providers, sorts them and publishes them to the
// SearchResults UI model. The targeted results have 6 slots to hold the // SearchResults UI model. The targeted results have 6 slots to hold the
// result. The search controller can specify any number of groups, each with a // result.
// different number of results and priority boost.
class Mixer { class Mixer {
public: public:
explicit Mixer(AppListModelUpdater* model_updater); explicit Mixer(AppListModelUpdater* model_updater);
...@@ -45,9 +44,8 @@ class Mixer { ...@@ -45,9 +44,8 @@ class Mixer {
// chosen from this group (if 0, will allow unlimited results from this // chosen from this group (if 0, will allow unlimited results from this
// group). If there aren't enough results from all groups, more than // group). If there aren't enough results from all groups, more than
// |max_results| may be chosen from this group. Each result in the group will // |max_results| may be chosen from this group. Each result in the group will
// have its score multiplied by |multiplier| and added by |boost|. Returns the // have its score increased by |boost|. Returns the group's group_id.
// group's group_id. size_t AddGroup(size_t max_results, double boost);
size_t AddGroup(size_t max_results, double multiplier, double boost);
// Associates a provider with a mixer group. // Associates a provider with a mixer group.
void AddProviderToGroup(size_t group_id, SearchProvider* provider); void AddProviderToGroup(size_t group_id, SearchProvider* provider);
......
...@@ -133,10 +133,8 @@ void SearchController::InvokeResultAction(ChromeSearchResult* result, ...@@ -133,10 +133,8 @@ void SearchController::InvokeResultAction(ChromeSearchResult* result,
result->InvokeAction(action_index, event_flags); result->InvokeAction(action_index, event_flags);
} }
size_t SearchController::AddGroup(size_t max_results, size_t SearchController::AddGroup(size_t max_results, double boost) {
double multiplier, return mixer_->AddGroup(max_results, boost);
double boost) {
return mixer_->AddGroup(max_results, multiplier, boost);
} }
void SearchController::AddProvider(size_t group_id, void SearchController::AddProvider(size_t group_id,
......
...@@ -59,7 +59,7 @@ class SearchController { ...@@ -59,7 +59,7 @@ class SearchController {
int event_flags); int event_flags);
// Adds a new mixer group. See Mixer::AddGroup. // Adds a new mixer group. See Mixer::AddGroup.
size_t AddGroup(size_t max_results, double multiplier, double boost); size_t AddGroup(size_t max_results, double boost = 0.0f);
// Takes ownership of |provider| and associates it with given mixer group. // Takes ownership of |provider| and associates it with given mixer group.
void AddProvider(size_t group_id, std::unique_ptr<SearchProvider> provider); void AddProvider(size_t group_id, std::unique_ptr<SearchProvider> provider);
......
...@@ -80,9 +80,7 @@ constexpr size_t kMaxAssistantResults = 1; ...@@ -80,9 +80,7 @@ constexpr size_t kMaxAssistantResults = 1;
// TODO(wutao): Need UX spec. // TODO(wutao): Need UX spec.
constexpr size_t kMaxSettingsShortcutResults = 6; constexpr size_t kMaxSettingsShortcutResults = 6;
constexpr float kBoostOfSettingsShortcut = 10.0f; constexpr double kAppBoost = 8.0;
// Keep in sync with value in search_result_ranker.cc.
constexpr float kBoostOfApps = 8.0f;
} // namespace } // namespace
...@@ -103,33 +101,34 @@ std::unique_ptr<SearchController> CreateSearchController( ...@@ -103,33 +101,34 @@ std::unique_ptr<SearchController> CreateSearchController(
// a query turns up very few results, the mixer may take more than this // a query turns up very few results, the mixer may take more than this
// maximum from a particular group. // maximum from a particular group.
// For fullscreen app list, Settings shortcuts will show on the very top and // For the fullscreen app list, apps appear above the answer card, which
// apps and answer card in the middle and other search results in the bottom. // appears above other results. Set boosts to |kAppBoost| for apps of all
// So set boost 10.0, 8.0, 5.0, 0.0 respectively. // kinds, 5.0 for answer card, and otherwise 0.0.
size_t answer_card_group_id = controller->AddGroup(1, 1.0, 5.0); size_t apps_group_id = controller->AddGroup(kMaxAppsGroupResults, kAppBoost);
size_t apps_group_id = size_t answer_card_group_id = controller->AddGroup(1, 5.0);
controller->AddGroup(kMaxAppsGroupResults, 1.0, kBoostOfApps);
size_t omnibox_group_id = controller->AddGroup( size_t omnibox_group_id = controller->AddGroup(
ash::AppListConfig::instance().max_search_result_list_items(), 1.0, 0.0); ash::AppListConfig::instance().max_search_result_list_items());
// Add search providers. // Add search providers.
controller->AddProvider( controller->AddProvider(
apps_group_id, std::make_unique<AppSearchProvider>( apps_group_id, std::make_unique<AppSearchProvider>(
profile, list_controller, profile, list_controller,
base::DefaultClock::GetInstance(), model_updater)); base::DefaultClock::GetInstance(), model_updater));
controller->AddProvider(omnibox_group_id, std::make_unique<OmniboxProvider>(
profile, list_controller));
if (app_list_features::IsAnswerCardEnabled()) { if (app_list_features::IsAnswerCardEnabled()) {
controller->AddProvider(answer_card_group_id, controller->AddProvider(answer_card_group_id,
std::make_unique<AnswerCardSearchProvider>( std::make_unique<AnswerCardSearchProvider>(
profile, model_updater, list_controller)); profile, model_updater, list_controller));
} }
controller->AddProvider(omnibox_group_id, std::make_unique<OmniboxProvider>(
profile, list_controller));
// The Assistant search provider currently only contributes search results // The Assistant search provider currently only contributes search results
// when launcher chip integration is enabled. // when launcher chip integration is enabled.
if (chromeos::assistant::features::IsLauncherChipIntegrationEnabled()) { if (chromeos::assistant::features::IsLauncherChipIntegrationEnabled()) {
size_t assistant_group_id = controller->AddGroup( size_t assistant_group_id =
kMaxAssistantResults, /*multiplier=*/1.0, kBoostOfApps); controller->AddGroup(kMaxAssistantResults, kAppBoost);
controller->AddProvider(assistant_group_id, controller->AddProvider(assistant_group_id,
std::make_unique<AssistantSearchProvider>()); std::make_unique<AssistantSearchProvider>());
} }
...@@ -138,7 +137,7 @@ std::unique_ptr<SearchController> CreateSearchController( ...@@ -138,7 +137,7 @@ std::unique_ptr<SearchController> CreateSearchController(
// session and running on Chrome OS. // session and running on Chrome OS.
if (!profile->IsGuestSession()) { if (!profile->IsGuestSession()) {
size_t search_api_group_id = size_t search_api_group_id =
controller->AddGroup(kMaxLauncherSearchResults, 1.0, 0.0); controller->AddGroup(kMaxLauncherSearchResults);
controller->AddProvider(search_api_group_id, controller->AddProvider(search_api_group_id,
std::make_unique<LauncherSearchProvider>(profile)); std::make_unique<LauncherSearchProvider>(profile));
} }
...@@ -147,7 +146,7 @@ std::unique_ptr<SearchController> CreateSearchController( ...@@ -147,7 +146,7 @@ std::unique_ptr<SearchController> CreateSearchController(
if (app_list_features::IsAppReinstallZeroStateEnabled() && if (app_list_features::IsAppReinstallZeroStateEnabled() &&
arc::IsArcAllowedForProfile(profile)) { arc::IsArcAllowedForProfile(profile)) {
size_t recommended_app_group_id = size_t recommended_app_group_id =
controller->AddGroup(kMaxAppReinstallSearchResults, 1.0, kBoostOfApps); controller->AddGroup(kMaxAppReinstallSearchResults, kAppBoost);
controller->AddProvider(recommended_app_group_id, controller->AddProvider(recommended_app_group_id,
std::make_unique<ArcAppReinstallSearchProvider>( std::make_unique<ArcAppReinstallSearchProvider>(
profile, kMaxAppReinstallSearchResults)); profile, kMaxAppReinstallSearchResults));
...@@ -157,7 +156,7 @@ std::unique_ptr<SearchController> CreateSearchController( ...@@ -157,7 +156,7 @@ std::unique_ptr<SearchController> CreateSearchController(
// Set same boost as apps group since Play store results are placed // Set same boost as apps group since Play store results are placed
// with apps. // with apps.
size_t playstore_api_group_id = size_t playstore_api_group_id =
controller->AddGroup(kMaxPlayStoreResults, 1.0, kBoostOfApps); controller->AddGroup(kMaxPlayStoreResults, kAppBoost);
controller->AddProvider( controller->AddProvider(
playstore_api_group_id, playstore_api_group_id,
std::make_unique<ArcPlayStoreSearchProvider>(kMaxPlayStoreResults, std::make_unique<ArcPlayStoreSearchProvider>(kMaxPlayStoreResults,
...@@ -166,15 +165,17 @@ std::unique_ptr<SearchController> CreateSearchController( ...@@ -166,15 +165,17 @@ std::unique_ptr<SearchController> CreateSearchController(
if (app_list_features::IsAppDataSearchEnabled()) { if (app_list_features::IsAppDataSearchEnabled()) {
size_t app_data_api_group_id = size_t app_data_api_group_id =
controller->AddGroup(kMaxAppDataResults, 1.0, kBoostOfApps); controller->AddGroup(kMaxAppDataResults, kAppBoost);
controller->AddProvider(app_data_api_group_id, controller->AddProvider(app_data_api_group_id,
std::make_unique<ArcAppDataSearchProvider>( std::make_unique<ArcAppDataSearchProvider>(
kMaxAppDataResults, list_controller)); kMaxAppDataResults, list_controller));
} }
// TODO(crbug.com/1028447): Remove the settings shortcut provider, superseded
// by OsSettingsProvider.
if (app_list_features::IsSettingsShortcutSearchEnabled()) { if (app_list_features::IsSettingsShortcutSearchEnabled()) {
size_t settings_shortcut_group_id = controller->AddGroup( size_t settings_shortcut_group_id =
kMaxSettingsShortcutResults, 1.0, kBoostOfSettingsShortcut); controller->AddGroup(kMaxSettingsShortcutResults);
controller->AddProvider( controller->AddProvider(
settings_shortcut_group_id, settings_shortcut_group_id,
std::make_unique<SettingsShortcutProvider>(profile)); std::make_unique<SettingsShortcutProvider>(profile));
...@@ -182,7 +183,7 @@ std::unique_ptr<SearchController> CreateSearchController( ...@@ -182,7 +183,7 @@ std::unique_ptr<SearchController> CreateSearchController(
if (arc::IsArcAllowedForProfile(profile)) { if (arc::IsArcAllowedForProfile(profile)) {
size_t app_shortcut_group_id = size_t app_shortcut_group_id =
controller->AddGroup(kMaxAppShortcutResults, 1.0, kBoostOfApps); controller->AddGroup(kMaxAppShortcutResults, kAppBoost);
controller->AddProvider( controller->AddProvider(
app_shortcut_group_id, app_shortcut_group_id,
std::make_unique<ArcAppShortcutsSearchProvider>( std::make_unique<ArcAppShortcutsSearchProvider>(
...@@ -194,11 +195,11 @@ std::unique_ptr<SearchController> CreateSearchController( ...@@ -194,11 +195,11 @@ std::unique_ptr<SearchController> CreateSearchController(
// scores changed to fit with these providers. // scores changed to fit with these providers.
if (app_list_features::IsZeroStateMixedTypesRankerEnabled()) { if (app_list_features::IsZeroStateMixedTypesRankerEnabled()) {
size_t zero_state_files_group_id = size_t zero_state_files_group_id =
controller->AddGroup(kMaxZeroStateFileResults, 1.0, 0.0); controller->AddGroup(kMaxZeroStateFileResults);
controller->AddProvider(zero_state_files_group_id, controller->AddProvider(zero_state_files_group_id,
std::make_unique<ZeroStateFileProvider>(profile)); std::make_unique<ZeroStateFileProvider>(profile));
size_t drive_quick_access_group_id = size_t drive_quick_access_group_id =
controller->AddGroup(kMaxDriveQuickAccessResults, 1.0, 0.0); controller->AddGroup(kMaxDriveQuickAccessResults);
controller->AddProvider( controller->AddProvider(
drive_quick_access_group_id, drive_quick_access_group_id,
std::make_unique<DriveQuickAccessProvider>(profile, controller.get())); std::make_unique<DriveQuickAccessProvider>(profile, controller.get()));
...@@ -206,7 +207,7 @@ std::unique_ptr<SearchController> CreateSearchController( ...@@ -206,7 +207,7 @@ std::unique_ptr<SearchController> CreateSearchController(
if (app_list_features::IsLauncherSettingsSearchEnabled()) { if (app_list_features::IsLauncherSettingsSearchEnabled()) {
size_t os_settings_search_group_id = size_t os_settings_search_group_id =
controller->AddGroup(kGenericMaxResults, 1.0, 0.0); controller->AddGroup(kGenericMaxResults);
controller->AddProvider(os_settings_search_group_id, controller->AddProvider(os_settings_search_group_id,
std::make_unique<OsSettingsProvider>(profile)); std::make_unique<OsSettingsProvider>(profile));
} }
......
...@@ -157,10 +157,9 @@ class MixerTest : public testing::Test { ...@@ -157,10 +157,9 @@ class MixerTest : public testing::Test {
// TODO(warx): when fullscreen app list is default enabled, modify this test // TODO(warx): when fullscreen app list is default enabled, modify this test
// to test answer card/apps group having relevance boost. // to test answer card/apps group having relevance boost.
size_t apps_group_id = mixer_->AddGroup(kMaxAppsGroupResults, 1.0, 0.0); size_t apps_group_id = mixer_->AddGroup(kMaxAppsGroupResults, 0.0);
size_t omnibox_group_id = mixer_->AddGroup(kMaxOmniboxResults, 1.0, 0.0); size_t omnibox_group_id = mixer_->AddGroup(kMaxOmniboxResults, 0.0);
size_t playstore_group_id = size_t playstore_group_id = mixer_->AddGroup(kMaxPlaystoreResults, 0.0);
mixer_->AddGroup(kMaxPlaystoreResults, 0.5, 0.0);
mixer_->AddProviderToGroup(apps_group_id, providers_[0].get()); mixer_->AddProviderToGroup(apps_group_id, providers_[0].get());
mixer_->AddProviderToGroup(omnibox_group_id, providers_[1].get()); mixer_->AddProviderToGroup(omnibox_group_id, providers_[1].get());
...@@ -210,58 +209,6 @@ class MixerTest : public testing::Test { ...@@ -210,58 +209,6 @@ class MixerTest : public testing::Test {
DISALLOW_COPY_AND_ASSIGN(MixerTest); DISALLOW_COPY_AND_ASSIGN(MixerTest);
}; };
TEST_F(MixerTest, Basic) {
CreateMixer();
// Note: Some cases in |expected| have vastly more results than others, due to
// the "at least 6" mechanism. If it gets at least 6 results from all
// providers, it stops at 6. If not, it fetches potentially many more results
// from all providers. Not ideal, but currently by design.
struct TestCase {
const size_t app_results;
const size_t omnibox_results;
const size_t playstore_results;
const char* expected;
} kTestCases[] = {
{0, 0, 0, ""},
{10, 0, 0, "app0,app1,app2,app3,app4,app5,app6,app7,app8,app9"},
{0, 0, 10,
"playstore0,playstore1,playstore2,playstore3,playstore4,playstore5,"
"playstore6,playstore7,playstore8,playstore9"},
{4, 6, 0, "app0,omnibox0,app1,omnibox1,app2,omnibox2,app3,omnibox3"},
{4, 6, 2,
"app0,omnibox0,app1,omnibox1,app2,omnibox2,app3,omnibox3,playstore0,"
"playstore1"},
{10, 10, 10,
"app0,omnibox0,app1,omnibox1,app2,omnibox2,app3,omnibox3,playstore0,"
"playstore1"},
{0, 10, 0,
"omnibox0,omnibox1,omnibox2,omnibox3,omnibox4,omnibox5,omnibox6,"
"omnibox7,omnibox8,omnibox9"},
{0, 10, 1,
"omnibox0,omnibox1,omnibox2,omnibox3,playstore0,omnibox4,omnibox5,"
"omnibox6,omnibox7,omnibox8,omnibox9"},
{0, 10, 2, "omnibox0,omnibox1,omnibox2,omnibox3,playstore0,playstore1"},
{1, 10, 0,
"app0,omnibox0,omnibox1,omnibox2,omnibox3,omnibox4,omnibox5,omnibox6,"
"omnibox7,omnibox8,omnibox9"},
{2, 10, 0, "app0,omnibox0,app1,omnibox1,omnibox2,omnibox3"},
{2, 10, 1, "app0,omnibox0,app1,omnibox1,omnibox2,omnibox3,playstore0"},
{2, 10, 2,
"app0,omnibox0,app1,omnibox1,omnibox2,omnibox3,playstore0,playstore1"},
{2, 0, 2, "app0,app1,playstore0,playstore1"},
{0, 0, 0, ""}};
for (size_t i = 0; i < base::size(kTestCases); ++i) {
app_provider()->set_count(kTestCases[i].app_results);
omnibox_provider()->set_count(kTestCases[i].omnibox_results);
playstore_provider()->set_count(kTestCases[i].playstore_results);
RunQuery();
EXPECT_EQ(kTestCases[i].expected, GetResults()) << "Case " << i;
}
}
// Tests that results with display index defined, will be shown in the final // Tests that results with display index defined, will be shown in the final
// results. // results.
TEST_F(MixerTest, ResultsWithDisplayIndex) { TEST_F(MixerTest, ResultsWithDisplayIndex) {
...@@ -275,8 +222,8 @@ TEST_F(MixerTest, ResultsWithDisplayIndex) { ...@@ -275,8 +222,8 @@ TEST_F(MixerTest, ResultsWithDisplayIndex) {
RunQuery(); RunQuery();
EXPECT_EQ( EXPECT_EQ(
"app0,omnibox0,app1,omnibox1,app2,omnibox2,app3,omnibox3,playstore0," "app0,omnibox0,playstore0,app1,omnibox1,playstore1,app2,omnibox2,app3,"
"playstore1", "omnibox3",
GetResults()); GetResults());
// If the last result has display index defined, it will be in the final // If the last result has display index defined, it will be in the final
...@@ -285,8 +232,8 @@ TEST_F(MixerTest, ResultsWithDisplayIndex) { ...@@ -285,8 +232,8 @@ TEST_F(MixerTest, ResultsWithDisplayIndex) {
RunQuery(); RunQuery();
EXPECT_EQ( EXPECT_EQ(
"app5,app0,omnibox0,app1,omnibox1,app2,omnibox2,omnibox3,playstore0," "app5,app0,omnibox0,playstore0,app1,omnibox1,playstore1,app2,omnibox2,"
"playstore1", "omnibox3",
GetResults()); GetResults());
} }
......
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