Commit 51c065fa authored by Thanh Nguyen's avatar Thanh Nguyen Committed by Commit Bot

[local-search-service] Implement Index mojom and LinearMapSearch

This CL adds Index mojom and its implementation. It also adds
LinearMapSearch functions that are inherited from new Index interface.

Design doc: go/lss-sandboxing
Implementation plan: go/lss-sandboxing-impl

Bug: 1137560
Change-Id: Ic12d6d5d93a3dddf7f34adf69041262608abeab4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2515422Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Reviewed-by: default avatarSam McNally <sammc@chromium.org>
Reviewed-by: default avatarRachel Carpenter <carpenterr@chromium.org>
Reviewed-by: default avatarJia Meng <jiameng@chromium.org>
Commit-Queue: Thanh Nguyen <thanhdng@chromium.org>
Cr-Commit-Position: refs/heads/master@{#825493}
parent f061483a
...@@ -2320,7 +2320,7 @@ static_library("browser") { ...@@ -2320,7 +2320,7 @@ static_library("browser") {
"//chromeos/components/help_app_ui", "//chromeos/components/help_app_ui",
"//chromeos/components/help_app_ui:mojo_bindings", "//chromeos/components/help_app_ui:mojo_bindings",
"//chromeos/components/local_search_service", "//chromeos/components/local_search_service",
"//chromeos/components/local_search_service/mojom", "//chromeos/components/local_search_service/public/mojom",
"//chromeos/components/media_app_ui", "//chromeos/components/media_app_ui",
"//chromeos/components/media_app_ui:mojo_bindings", "//chromeos/components/media_app_ui:mojo_bindings",
"//chromeos/components/multidevice/debug_webui", "//chromeos/components/multidevice/debug_webui",
......
...@@ -180,7 +180,7 @@ ...@@ -180,7 +180,7 @@
#include "chromeos/components/diagnostics_ui/mojom/system_data_provider.mojom.h" #include "chromeos/components/diagnostics_ui/mojom/system_data_provider.mojom.h"
#include "chromeos/components/help_app_ui/help_app_ui.h" #include "chromeos/components/help_app_ui/help_app_ui.h"
#include "chromeos/components/help_app_ui/help_app_ui.mojom.h" #include "chromeos/components/help_app_ui/help_app_ui.mojom.h"
#include "chromeos/components/local_search_service/mojom/local_search_service_proxy.mojom.h" #include "chromeos/components/local_search_service/public/mojom/local_search_service_proxy.mojom.h"
#include "chromeos/components/media_app_ui/media_app_ui.h" #include "chromeos/components/media_app_ui/media_app_ui.h"
#include "chromeos/components/media_app_ui/media_app_ui.mojom.h" #include "chromeos/components/media_app_ui/media_app_ui.mojom.h"
#include "chromeos/components/multidevice/debug_webui/proximity_auth_ui.h" #include "chromeos/components/multidevice/debug_webui/proximity_auth_ui.h"
......
...@@ -25,7 +25,7 @@ test("chromeos_components_unittests") { ...@@ -25,7 +25,7 @@ test("chromeos_components_unittests") {
"//chromeos/components/diagnostics_ui/backend:unit_tests", "//chromeos/components/diagnostics_ui/backend:unit_tests",
"//chromeos/components/drivefs:unit_tests", "//chromeos/components/drivefs:unit_tests",
"//chromeos/components/local_search_service:unit_tests", "//chromeos/components/local_search_service:unit_tests",
"//chromeos/components/local_search_service/mojom:unit_tests", "//chromeos/components/local_search_service/public/mojom:unit_tests",
"//chromeos/components/mojo_bootstrap:unit_tests", "//chromeos/components/mojo_bootstrap:unit_tests",
"//chromeos/components/multidevice:unit_tests", "//chromeos/components/multidevice:unit_tests",
"//chromeos/components/phonehub:unit_tests", "//chromeos/components/phonehub:unit_tests",
......
...@@ -26,8 +26,8 @@ static_library("help_app_ui") { ...@@ -26,8 +26,8 @@ static_library("help_app_ui") {
":mojo_bindings", ":mojo_bindings",
":mojo_bindings_js", ":mojo_bindings_js",
"//chromeos/components/local_search_service:local_search_service_proxy", "//chromeos/components/local_search_service:local_search_service_proxy",
"//chromeos/components/local_search_service/mojom:mojom", "//chromeos/components/local_search_service/public/mojom:mojom",
"//chromeos/components/local_search_service/mojom:mojom_js", "//chromeos/components/local_search_service/public/mojom:mojom_js",
"//chromeos/components/web_applications", "//chromeos/components/web_applications",
"//chromeos/constants", "//chromeos/constants",
"//chromeos/resources:help_app_bundle_resources", "//chromeos/resources:help_app_bundle_resources",
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
#include "chromeos/components/help_app_ui/url_constants.h" #include "chromeos/components/help_app_ui/url_constants.h"
#include "chromeos/components/local_search_service/local_search_service_sync_proxy.h" #include "chromeos/components/local_search_service/local_search_service_sync_proxy.h"
#include "chromeos/components/local_search_service/local_search_service_sync_proxy_factory.h" #include "chromeos/components/local_search_service/local_search_service_sync_proxy_factory.h"
#include "chromeos/components/local_search_service/mojom/types.mojom.h" #include "chromeos/components/local_search_service/public/mojom/types.mojom.h"
#include "chromeos/grit/chromeos_help_app_resources.h" #include "chromeos/grit/chromeos_help_app_resources.h"
#include "chromeos/strings/grit/chromeos_strings.h" #include "chromeos/strings/grit/chromeos_strings.h"
#include "components/content_settings/core/common/content_settings_types.h" #include "components/content_settings/core/common/content_settings_types.h"
......
...@@ -33,7 +33,7 @@ js_library("browser_proxy") { ...@@ -33,7 +33,7 @@ js_library("browser_proxy") {
deps = [ deps = [
":message_types", ":message_types",
"//chromeos/components/help_app_ui:mojo_bindings_js_library_for_compile", "//chromeos/components/help_app_ui:mojo_bindings_js_library_for_compile",
"//chromeos/components/local_search_service/mojom:mojom_js_library_for_compile", "//chromeos/components/local_search_service/public/mojom:mojom_js_library_for_compile",
"//chromeos/components/system_apps/public/js:message_pipe", "//chromeos/components/system_apps/public/js:message_pipe",
] ]
} }
......
...@@ -23,10 +23,10 @@ ...@@ -23,10 +23,10 @@
file="${root_gen_dir}/chromeos/components/help_app_ui/help_app_ui.mojom-lite.js" file="${root_gen_dir}/chromeos/components/help_app_ui/help_app_ui.mojom-lite.js"
use_base_dir="false" type="BINDATA" /> use_base_dir="false" type="BINDATA" />
<include name="IDR_HELP_APP_LOCAL_SEARCH_SERVICE_TYPES_MOJOM_JS" <include name="IDR_HELP_APP_LOCAL_SEARCH_SERVICE_TYPES_MOJOM_JS"
file="${root_gen_dir}/chromeos/components/local_search_service/mojom/types.mojom-lite.js" file="${root_gen_dir}/chromeos/components/local_search_service/public/mojom/types.mojom-lite.js"
use_base_dir="false" type="BINDATA" /> use_base_dir="false" type="BINDATA" />
<include name="IDR_HELP_APP_LOCAL_SEARCH_SERVICE_PROXY_MOJOM_JS" <include name="IDR_HELP_APP_LOCAL_SEARCH_SERVICE_PROXY_MOJOM_JS"
file="${root_gen_dir}/chromeos/components/local_search_service/mojom/local_search_service_proxy.mojom-lite.js" file="${root_gen_dir}/chromeos/components/local_search_service/public/mojom/local_search_service_proxy.mojom-lite.js"
use_base_dir="false" type="BINDATA" /> use_base_dir="false" type="BINDATA" />
<include name="IDR_HELP_APP_INDEX_SCRIPTS_JS" file="help_app_index_scripts.js" flattenhtml="true" type="BINDATA" /> <include name="IDR_HELP_APP_INDEX_SCRIPTS_JS" file="help_app_index_scripts.js" flattenhtml="true" type="BINDATA" />
......
...@@ -8,6 +8,8 @@ source_set("local_search_service") { ...@@ -8,6 +8,8 @@ source_set("local_search_service") {
sources = [ sources = [
"content_extraction_utils.cc", "content_extraction_utils.cc",
"content_extraction_utils.h", "content_extraction_utils.h",
"index.cc",
"index.h",
"index_sync.cc", "index_sync.cc",
"index_sync.h", "index_sync.h",
"inverted_index.cc", "inverted_index.cc",
...@@ -33,6 +35,7 @@ source_set("local_search_service") { ...@@ -33,6 +35,7 @@ source_set("local_search_service") {
deps = [ deps = [
"//base:i18n", "//base:i18n",
"//cc", "//cc",
"//chromeos/components/local_search_service/public/mojom",
"//chromeos/components/string_matching", "//chromeos/components/string_matching",
] ]
...@@ -64,7 +67,7 @@ source_set("local_search_service_proxy") { ...@@ -64,7 +67,7 @@ source_set("local_search_service_proxy") {
public_deps = [ public_deps = [
":local_search_service", ":local_search_service",
"//base", "//base",
"//chromeos/components/local_search_service/mojom", "//chromeos/components/local_search_service/public/mojom",
"//components/keyed_service/content:content", "//components/keyed_service/content:content",
"//components/prefs", "//components/prefs",
] ]
......
// 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 "chromeos/components/local_search_service/index.h"
#include "base/optional.h"
namespace chromeos {
namespace local_search_service {
Index::Index(IndexId index_id, Backend backend) {}
Index::~Index() = default;
void Index::BindReceiver(mojo::PendingReceiver<mojom::Index> receiver) {
receivers_.Add(this, std::move(receiver));
}
} // namespace local_search_service
} // namespace chromeos
// 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 CHROMEOS_COMPONENTS_LOCAL_SEARCH_SERVICE_INDEX_H_
#define CHROMEOS_COMPONENTS_LOCAL_SEARCH_SERVICE_INDEX_H_
#include <vector>
#include "base/strings/string16.h"
#include "chromeos/components/local_search_service/public/mojom/index.mojom.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/receiver_set.h"
namespace chromeos {
namespace local_search_service {
class Index : public mojom::Index {
public:
explicit Index(IndexId index_id, Backend backend);
~Index() override;
void BindReceiver(mojo::PendingReceiver<mojom::Index> receiver);
private:
mojo::ReceiverSet<mojom::Index> receivers_;
};
} // namespace local_search_service
} // namespace chromeos
#endif // CHROMEOS_COMPONENTS_LOCAL_SEARCH_SERVICE_INDEX_H_
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
#include <vector> #include <vector>
#include "base/strings/string16.h" #include "base/strings/string16.h"
#include "chromeos/components/local_search_service/mojom/local_search_service_proxy.mojom.h" #include "chromeos/components/local_search_service/public/mojom/local_search_service_proxy.mojom.h"
#include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/receiver_set.h" #include "mojo/public/cpp/bindings/receiver_set.h"
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "chromeos/components/local_search_service/linear_map_search.h" #include "chromeos/components/local_search_service/linear_map_search.h"
#include <utility> #include <utility>
#include <vector>
#include "base/optional.h" #include "base/optional.h"
#include "base/strings/string_split.h" #include "base/strings/string_split.h"
...@@ -67,10 +68,21 @@ bool IsItemRelevant(const TokenizedString& query, ...@@ -67,10 +68,21 @@ bool IsItemRelevant(const TokenizedString& query,
return false; return false;
} }
// Updates data given |id| and |contents|. If |id| already exists, it will
// overwrite earlier data.
void UpdateData(const std::string& id,
const std::vector<Content>& contents,
KeyToTagVector* data) {
DCHECK(data);
(*data)[id] = std::vector<TokenizedStringWithId>();
TokenizeSearchTags(contents, &((*data)[id]));
}
} // namespace } // namespace
LinearMapSearch::LinearMapSearch(IndexId index_id, PrefService* local_state) LinearMapSearch::LinearMapSearch(IndexId index_id, PrefService* local_state)
: IndexSync(index_id, Backend::kLinearMap, local_state) {} : IndexSync(index_id, Backend::kLinearMap, local_state),
Index(index_id, Backend::kLinearMap) {}
LinearMapSearch::~LinearMapSearch() = default; LinearMapSearch::~LinearMapSearch() = default;
...@@ -84,9 +96,7 @@ void LinearMapSearch::AddOrUpdateSync( ...@@ -84,9 +96,7 @@ void LinearMapSearch::AddOrUpdateSync(
const auto& id = item.id; const auto& id = item.id;
DCHECK(!id.empty()); DCHECK(!id.empty());
// If a key already exists, it will overwrite earlier data. UpdateData(id, item.contents, &data_);
data_[id] = std::vector<TokenizedStringWithId>();
TokenizeSearchTags(item.contents, &data_[id]);
} }
MaybeLogIndexSize(); MaybeLogIndexSize();
...@@ -96,13 +106,7 @@ uint32_t LinearMapSearch::DeleteSync(const std::vector<std::string>& ids) { ...@@ -96,13 +106,7 @@ uint32_t LinearMapSearch::DeleteSync(const std::vector<std::string>& ids) {
uint32_t num_deleted = 0u; uint32_t num_deleted = 0u;
for (const auto& id : ids) { for (const auto& id : ids) {
DCHECK(!id.empty()); DCHECK(!id.empty());
num_deleted += data_.erase(id);
const auto& it = data_.find(id);
if (it != data_.end()) {
// If id doesn't exist, just ignore it.
data_.erase(id);
++num_deleted;
}
} }
MaybeLogIndexSize(); MaybeLogIndexSize();
...@@ -140,6 +144,72 @@ ResponseStatus LinearMapSearch::FindSync(const base::string16& query, ...@@ -140,6 +144,72 @@ ResponseStatus LinearMapSearch::FindSync(const base::string16& query,
return status; return status;
} }
void LinearMapSearch::GetSize(GetSizeCallback callback) {
std::move(callback).Run(data_.size());
}
void LinearMapSearch::AddOrUpdate(const std::vector<Data>& data,
AddOrUpdateCallback callback) {
// TODO(thanhdng): Add logging to this function once we have the metrics
// reporter available.
for (const auto& item : data) {
const auto& id = item.id;
DCHECK(!id.empty());
UpdateData(id, item.contents, &data_);
}
std::move(callback).Run();
}
void LinearMapSearch::Delete(const std::vector<std::string>& ids,
DeleteCallback callback) {
uint32_t num_deleted = 0u;
for (const auto& id : ids) {
DCHECK(!id.empty());
num_deleted += data_.erase(id);
}
std::move(callback).Run(num_deleted);
}
void LinearMapSearch::UpdateDocuments(const std::vector<Data>& data,
UpdateDocumentsCallback callback) {
uint32_t num_deleted = 0u;
for (const auto& item : data) {
const auto& id = item.id;
DCHECK(!id.empty());
if (item.contents.empty()) {
num_deleted += data_.erase(id);
} else {
UpdateData(id, item.contents, &data_);
}
}
std::move(callback).Run(num_deleted);
}
void LinearMapSearch::Find(const base::string16& query,
uint32_t max_results,
FindCallback callback) {
if (query.empty()) {
std::move(callback).Run(ResponseStatus::kEmptyQuery, base::nullopt);
return;
}
if (data_.empty()) {
std::move(callback).Run(ResponseStatus::kEmptyIndex, base::nullopt);
return;
}
std::vector<Result> results = GetSearchResults(query, max_results);
std::move(callback).Run(ResponseStatus::kSuccess, std::move(results));
}
void LinearMapSearch::ClearIndex(ClearIndexCallback callback) {
data_.clear();
std::move(callback).Run();
}
std::vector<Result> LinearMapSearch::GetSearchResults( std::vector<Result> LinearMapSearch::GetSearchResults(
const base::string16& query, const base::string16& query,
uint32_t max_results) const { uint32_t max_results) const {
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "base/macros.h" #include "base/macros.h"
#include "base/strings/string16.h" #include "base/strings/string16.h"
#include "chromeos/components/local_search_service/index.h"
#include "chromeos/components/local_search_service/index_sync.h" #include "chromeos/components/local_search_service/index_sync.h"
#include "chromeos/components/local_search_service/shared_structs.h" #include "chromeos/components/local_search_service/shared_structs.h"
...@@ -25,11 +26,19 @@ class TokenizedString; ...@@ -25,11 +26,19 @@ class TokenizedString;
namespace local_search_service { namespace local_search_service {
// A map from key to a vector of (tag-id, tokenized tag).
typedef std::map<
std::string,
std::vector<
std::pair<std::string,
std::unique_ptr<chromeos::string_matching::TokenizedString>>>>
KeyToTagVector;
// An implementation of Index. // An implementation of Index.
// A search backend that linearly scans all documents in the storage and finds // A search backend that linearly scans all documents in the storage and finds
// documents that match the input query. Search is done by matching query with // documents that match the input query. Search is done by matching query with
// documents' search tags. // documents' search tags.
class LinearMapSearch : public IndexSync { class LinearMapSearch : public IndexSync, public Index {
public: public:
LinearMapSearch(IndexId index_id, PrefService* local_state); LinearMapSearch(IndexId index_id, PrefService* local_state);
~LinearMapSearch() override; ~LinearMapSearch() override;
...@@ -37,7 +46,7 @@ class LinearMapSearch : public IndexSync { ...@@ -37,7 +46,7 @@ class LinearMapSearch : public IndexSync {
LinearMapSearch(const LinearMapSearch&) = delete; LinearMapSearch(const LinearMapSearch&) = delete;
LinearMapSearch& operator=(const LinearMapSearch&) = delete; LinearMapSearch& operator=(const LinearMapSearch&) = delete;
// Index overrides: // IndexSync overrides:
uint64_t GetSizeSync() override; uint64_t GetSizeSync() override;
void AddOrUpdateSync(const std::vector<Data>& data) override; void AddOrUpdateSync(const std::vector<Data>& data) override;
uint32_t DeleteSync(const std::vector<std::string>& ids) override; uint32_t DeleteSync(const std::vector<std::string>& ids) override;
...@@ -49,17 +58,25 @@ class LinearMapSearch : public IndexSync { ...@@ -49,17 +58,25 @@ class LinearMapSearch : public IndexSync {
uint32_t max_results, uint32_t max_results,
std::vector<Result>* results) override; std::vector<Result>* results) override;
// Index overrides:
void GetSize(GetSizeCallback callback) override;
void AddOrUpdate(const std::vector<Data>& data,
AddOrUpdateCallback callback) override;
void Delete(const std::vector<std::string>& ids,
DeleteCallback callback) override;
void UpdateDocuments(const std::vector<Data>& data,
UpdateDocumentsCallback callback) override;
void Find(const base::string16& query,
uint32_t max_results,
FindCallback callback) override;
void ClearIndex(ClearIndexCallback callback) override;
private: private:
// Returns all search results for a given query. // Returns all search results for a given query.
std::vector<Result> GetSearchResults(const base::string16& query, std::vector<Result> GetSearchResults(const base::string16& query,
uint32_t max_results) const; uint32_t max_results) const;
// A map from key to a vector of (tag-id, tokenized tag). KeyToTagVector data_;
std::map<std::string,
std::vector<std::pair<
std::string,
std::unique_ptr<chromeos::string_matching::TokenizedString>>>>
data_;
}; };
} // namespace local_search_service } // namespace local_search_service
......
...@@ -68,6 +68,96 @@ void FindAndCheckResults(LinearMapSearch* index, ...@@ -68,6 +68,96 @@ void FindAndCheckResults(LinearMapSearch* index,
EXPECT_TRUE(expected_results.empty()); EXPECT_TRUE(expected_results.empty());
} }
void GetSizeAndCheckResultsWithCallback(LinearMapSearch* index,
uint32_t expectd_num_items) {
bool callback_done = false;
uint32_t num_items = 0;
index->GetSize(base::BindOnce(
[](bool* callback_done, uint32_t* num_items, uint64_t size) {
*callback_done = true;
*num_items = size;
},
&callback_done, &num_items));
ASSERT_TRUE(callback_done);
EXPECT_EQ(num_items, expectd_num_items);
}
void AddOrUpdateWithCallback(LinearMapSearch* index,
const std::vector<Data>& data) {
bool callback_done = false;
index->AddOrUpdate(
data, base::BindOnce([](bool* callback_done) { *callback_done = true; },
&callback_done));
ASSERT_TRUE(callback_done);
}
void UpdateDocumentsAndCheckResults(LinearMapSearch* index,
const std::vector<Data>& data,
uint32_t expect_num_deleted) {
bool callback_done = false;
uint32_t num_deleted = 0u;
index->UpdateDocuments(data,
base::BindOnce(
[](bool* callback_done, uint32_t* num_deleted,
uint32_t num_deleted_callback) {
*callback_done = true;
*num_deleted = num_deleted_callback;
},
&callback_done, &num_deleted));
ASSERT_TRUE(callback_done);
EXPECT_EQ(num_deleted, expect_num_deleted);
}
void FindAndCheckResultsWithCallback(
LinearMapSearch* index,
std::string query,
int32_t max_results,
ResponseStatus expected_status,
const std::vector<ResultWithIds>& expected_results) {
DCHECK(index);
bool callback_done = false;
ResponseStatus status;
std::vector<Result> results;
index->Find(
base::UTF8ToUTF16(query), max_results,
base::BindOnce(
[](bool* callback_done, ResponseStatus* status,
std::vector<Result>* results, ResponseStatus status_callback,
const base::Optional<std::vector<Result>>& results_callback) {
*callback_done = true;
*status = status_callback;
if (results_callback.has_value())
*results = results_callback.value();
},
&callback_done, &status, &results));
ASSERT_TRUE(callback_done);
EXPECT_EQ(status, expected_status);
if (!results.empty()) {
// If results are returned, check size and values match the expected.
EXPECT_EQ(results.size(), expected_results.size());
for (size_t i = 0; i < results.size(); ++i) {
EXPECT_EQ(results[i].id, expected_results[i].first);
EXPECT_EQ(results[i].positions.size(), expected_results[i].second.size());
for (size_t j = 0; j < results[i].positions.size(); ++j) {
EXPECT_EQ(results[i].positions[j].content_id,
expected_results[i].second[j]);
}
// Scores should be non-increasing.
if (i < results.size() - 1) {
EXPECT_GE(results[i].score, results[i + 1].score);
}
}
return;
}
// If no results are returned, expected ids should be empty.
EXPECT_TRUE(expected_results.empty());
}
} // namespace } // namespace
class LinearMapSearchTest : public testing::Test { class LinearMapSearchTest : public testing::Test {
...@@ -200,5 +290,133 @@ TEST_F(LinearMapSearchTest, ClearIndex) { ...@@ -200,5 +290,133 @@ TEST_F(LinearMapSearchTest, ClearIndex) {
EXPECT_EQ(index_->GetSizeSync(), 0u); EXPECT_EQ(index_->GetSizeSync(), 0u);
} }
TEST_F(LinearMapSearchTest, RelevanceThresholdCallback) {
const std::map<std::string, std::vector<ContentWithId>> data_to_register = {
{"id1", {{"tag1", "Wi-Fi"}}}, {"id2", {{"tag2", "famous"}}}};
std::vector<Data> data = CreateTestData(data_to_register);
AddOrUpdateWithCallback(index_.get(), data);
GetSizeAndCheckResultsWithCallback(index_.get(), 2u);
{
SearchParams search_params;
search_params.relevance_threshold = 0.0;
index_->SetSearchParams(search_params);
const std::vector<ResultWithIds> expected_results = {{"id1", {"tag1"}},
{"id2", {"tag2"}}};
FindAndCheckResultsWithCallback(index_.get(), "wifi",
/*max_results=*/-1,
ResponseStatus::kSuccess, expected_results);
}
{
SearchParams search_params;
search_params.relevance_threshold = 0.3;
index_->SetSearchParams(search_params);
const std::vector<ResultWithIds> expected_results = {{"id1", {"tag1"}}};
FindAndCheckResultsWithCallback(index_.get(), "wifi",
/*max_results=*/-1,
ResponseStatus::kSuccess, expected_results);
}
{
SearchParams search_params;
search_params.relevance_threshold = 0.9;
index_->SetSearchParams(search_params);
FindAndCheckResultsWithCallback(index_.get(), "wifi",
/*max_results=*/-1,
ResponseStatus::kSuccess, {});
}
}
TEST_F(LinearMapSearchTest, MaxResultsCallback) {
const std::map<std::string, std::vector<ContentWithId>> data_to_register = {
{"id1", {{"tag1", "abcde"}, {"tag2", "Wi-Fi"}}},
{"id2", {{"tag3", "wifi"}}}};
std::vector<Data> data = CreateTestData(data_to_register);
AddOrUpdateWithCallback(index_.get(), data);
GetSizeAndCheckResultsWithCallback(index_.get(), 2u);
SearchParams search_params;
search_params.relevance_threshold = 0.3;
index_->SetSearchParams(search_params);
{
const std::vector<ResultWithIds> expected_results = {{"id2", {"tag3"}},
{"id1", {"tag2"}}};
FindAndCheckResultsWithCallback(index_.get(), "wifi",
/*max_results=*/-1,
ResponseStatus::kSuccess, expected_results);
}
{
const std::vector<ResultWithIds> expected_results = {{"id2", {"tag3"}}};
FindAndCheckResultsWithCallback(index_.get(), "wifi",
/*max_results=*/1, ResponseStatus::kSuccess,
expected_results);
}
}
TEST_F(LinearMapSearchTest, ResultFoundCallback) {
const std::map<std::string, std::vector<ContentWithId>> data_to_register = {
{"id1", {{"cid1", "id1"}, {"cid2", "tag1a"}, {"cid3", "tag1b"}}},
{"xyz", {{"cid4", "xyz"}}}};
std::vector<Data> data = CreateTestData(data_to_register);
EXPECT_EQ(data.size(), 2u);
AddOrUpdateWithCallback(index_.get(), data);
GetSizeAndCheckResultsWithCallback(index_.get(), 2u);
// Find result with query "id1". It returns an exact match.
const std::vector<ResultWithIds> expected_results = {{"id1", {"cid1"}}};
FindAndCheckResultsWithCallback(index_.get(), "id1",
/*max_results=*/-1, ResponseStatus::kSuccess,
expected_results);
FindAndCheckResultsWithCallback(index_.get(), "abc",
/*max_results=*/-1, ResponseStatus::kSuccess,
{});
}
TEST_F(LinearMapSearchTest, ClearIndexCallback) {
const std::map<std::string, std::vector<ContentWithId>> data_to_register = {
{"id1", {{"cid1", "id1"}, {"cid2", "tag1a"}, {"cid3", "tag1b"}}},
{"xyz", {{"cid4", "xyz"}}}};
std::vector<Data> data = CreateTestData(data_to_register);
EXPECT_EQ(data.size(), 2u);
AddOrUpdateWithCallback(index_.get(), data);
GetSizeAndCheckResultsWithCallback(index_.get(), 2u);
bool callback_done = false;
index_->ClearIndex(base::BindOnce(
[](bool* callback_done) { *callback_done = true; }, &callback_done));
ASSERT_TRUE(callback_done);
GetSizeAndCheckResultsWithCallback(index_.get(), 0u);
}
TEST_F(LinearMapSearchTest, UpdateDocuments) {
const std::map<std::string, std::vector<ContentWithId>> data_to_register = {
{"id1", {{"cid1", "id1"}, {"cid2", "tag1a"}, {"cid3", "tag1b"}}},
{"xyz", {{"cid4", "xyz"}}}};
std::vector<Data> data = CreateTestData(data_to_register);
EXPECT_EQ(data.size(), 2u);
AddOrUpdateWithCallback(index_.get(), data);
GetSizeAndCheckResultsWithCallback(index_.get(), 2u);
const std::map<std::string, std::vector<ContentWithId>>
update_data_to_register = {{"id1",
{{"update cid1", "update id1"},
{"update cid2", "update tag1a"},
{"update cid3", "update tag1b"}}},
{"xyz", {}},
{"nonexistid", {}}};
std::vector<Data> update_data = CreateTestData(update_data_to_register);
EXPECT_EQ(update_data.size(), 3u);
UpdateDocumentsAndCheckResults(index_.get(), update_data, 1u);
GetSizeAndCheckResultsWithCallback(index_.get(), 1u);
}
} // namespace local_search_service } // namespace local_search_service
} // namespace chromeos } // namespace chromeos
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
#include <map> #include <map>
#include "chromeos/components/local_search_service/mojom/local_search_service_proxy.mojom.h" #include "chromeos/components/local_search_service/public/mojom/local_search_service_proxy.mojom.h"
#include "components/keyed_service/core/keyed_service.h" #include "components/keyed_service/core/keyed_service.h"
#include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/receiver_set.h" #include "mojo/public/cpp/bindings/receiver_set.h"
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
#include "base/test/task_environment.h" #include "base/test/task_environment.h"
#include "chromeos/components/local_search_service/index_sync_proxy.h" #include "chromeos/components/local_search_service/index_sync_proxy.h"
#include "chromeos/components/local_search_service/local_search_service_sync.h" #include "chromeos/components/local_search_service/local_search_service_sync.h"
#include "chromeos/components/local_search_service/mojom/types.mojom.h" #include "chromeos/components/local_search_service/public/mojom/types.mojom.h"
#include "mojo/public/cpp/bindings/remote.h" #include "mojo/public/cpp/bindings/remote.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
......
...@@ -6,6 +6,7 @@ import("//mojo/public/tools/bindings/mojom.gni") ...@@ -6,6 +6,7 @@ import("//mojo/public/tools/bindings/mojom.gni")
mojom("mojom") { mojom("mojom") {
sources = [ sources = [
"index.mojom",
"local_search_service_proxy.mojom", "local_search_service_proxy.mojom",
"types.mojom", "types.mojom",
] ]
...@@ -48,10 +49,8 @@ mojom("mojom") { ...@@ -48,10 +49,8 @@ mojom("mojom") {
cpp = "::chromeos::local_search_service::Backend" cpp = "::chromeos::local_search_service::Backend"
}, },
] ]
traits_headers = [ traits_headers = [ "//chromeos/components/local_search_service/public/mojom/types_mojom_traits.h" ]
"//chromeos/components/local_search_service/mojom/types_mojom_traits.h", traits_sources = [ "//chromeos/components/local_search_service/public/mojom/types_mojom_traits.cc" ]
]
traits_sources = [ "//chromeos/components/local_search_service/mojom/types_mojom_traits.cc" ]
}, },
] ]
} }
......
// 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.
module chromeos.local_search_service.mojom;
import "chromeos/components/local_search_service/public/mojom/types.mojom";
import "mojo/public/mojom/base/string16.mojom";
// An Index has a registry of searchable data, which can be updated. It also
// runs a search function to find matching items for a given query.
// Each Index can serve multiple clients, but only one client (the primary
// client) that owns the data should be allowed to modify the Index.
interface Index {
// Returns number of data items.
GetSize() => (uint64 num_items);
// Adds or updates data and callbacks upon completion.
// Only the primary client should be allowed to do this operation.
AddOrUpdate(array<Data> data) => ();
// Deletes data with |ids| and returns the number of items deleted.
// If an id doesn't exist in the Index, no operation will be done.
// Only the primary client should be allowed to do this operation.
Delete(array<string> ids) => (uint32 num_deleted);
// This method is a combination of two calls above. If the content
// field of Data is empty then it means the document should be deleted.
UpdateDocuments(array<Data> data) => (uint32 num_deleted);
// Takes an asynchronous search request call and returns results and status
// code via a callback. |results| will be null if there is an error.
Find(mojo_base.mojom.String16 query, uint32 max_results)
=> (ResponseStatus status, array<Result>? results);
// Clears all data stored by the index.
ClearIndex() => ();
};
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
module chromeos.local_search_service.mojom; module chromeos.local_search_service.mojom;
import "chromeos/components/local_search_service/mojom/types.mojom"; import "chromeos/components/local_search_service/public/mojom/types.mojom";
import "mojo/public/mojom/base/string16.mojom"; import "mojo/public/mojom/base/string16.mojom";
enum IndexId { enum IndexId {
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// 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 "chromeos/components/local_search_service/mojom/types_mojom_traits.h" #include "chromeos/components/local_search_service/public/mojom/types_mojom_traits.h"
#include "mojo/public/cpp/base/string16_mojom_traits.h" #include "mojo/public/cpp/base/string16_mojom_traits.h"
......
...@@ -2,12 +2,12 @@ ...@@ -2,12 +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.
#ifndef CHROMEOS_COMPONENTS_LOCAL_SEARCH_SERVICE_MOJOM_TYPES_MOJOM_TRAITS_H_ #ifndef CHROMEOS_COMPONENTS_LOCAL_SEARCH_SERVICE_PUBLIC_MOJOM_TYPES_MOJOM_TRAITS_H_
#define CHROMEOS_COMPONENTS_LOCAL_SEARCH_SERVICE_MOJOM_TYPES_MOJOM_TRAITS_H_ #define CHROMEOS_COMPONENTS_LOCAL_SEARCH_SERVICE_PUBLIC_MOJOM_TYPES_MOJOM_TRAITS_H_
#include "base/strings/string16.h" #include "base/strings/string16.h"
#include "chromeos/components/local_search_service/mojom/local_search_service_proxy.mojom-shared.h" #include "chromeos/components/local_search_service/public/mojom/local_search_service_proxy.mojom-shared.h"
#include "chromeos/components/local_search_service/mojom/types.mojom-shared.h" #include "chromeos/components/local_search_service/public/mojom/types.mojom-shared.h"
#include "chromeos/components/local_search_service/shared_structs.h" #include "chromeos/components/local_search_service/shared_structs.h"
#include "mojo/public/cpp/bindings/struct_traits.h" #include "mojo/public/cpp/bindings/struct_traits.h"
...@@ -142,4 +142,4 @@ struct EnumTraits<chromeos::local_search_service::mojom::ResponseStatus, ...@@ -142,4 +142,4 @@ struct EnumTraits<chromeos::local_search_service::mojom::ResponseStatus,
} // namespace mojo } // namespace mojo
#endif // CHROMEOS_COMPONENTS_LOCAL_SEARCH_SERVICE_MOJOM_TYPES_MOJOM_TRAITS_H_ #endif // CHROMEOS_COMPONENTS_LOCAL_SEARCH_SERVICE_PUBLIC_MOJOM_TYPES_MOJOM_TRAITS_H_
...@@ -2,10 +2,10 @@ ...@@ -2,10 +2,10 @@
// 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 "chromeos/components/local_search_service/mojom/types_mojom_traits.h" #include "chromeos/components/local_search_service/public/mojom/types_mojom_traits.h"
#include "base/strings/string16.h" #include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "chromeos/components/local_search_service/mojom/types.mojom.h" #include "chromeos/components/local_search_service/public/mojom/types.mojom.h"
#include "mojo/public/cpp/test_support/test_utils.h" #include "mojo/public/cpp/test_support/test_utils.h"
#include "testing/gmock/include/gmock/gmock.h" #include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
......
...@@ -141,7 +141,7 @@ grit("help_app_resources") { ...@@ -141,7 +141,7 @@ grit("help_app_resources") {
deps = [ deps = [
"//chromeos/components/help_app_ui:mojo_bindings_js", "//chromeos/components/help_app_ui:mojo_bindings_js",
"//chromeos/components/local_search_service/mojom:mojom_js", "//chromeos/components/local_search_service/public/mojom:mojom_js",
] ]
} }
......
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