Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Quick Answers: Add spell checker in utility process
This change adds a spell checker for Quick answers feature in utility process. A follow up change will add browser side implementation. The spell checker is added because QA needs different set of languages from spellcheck, and the two features are controlled by different set of settings toggles. Utility process is used because the third party Hunspell library is unstable and we want to protect browser process. DD: go/qa-spellcheck, go/qa-always-trigger Bug: b/221967354 Test: Run existing tests Change-Id: Ic92d1b5074a9456521ab8ccebbd0400a3f8fa50a Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3528261 Reviewed-by: Avi Drissman <avi@chromium.org> Reviewed-by: Josh Simmons <jds@google.com> Reviewed-by: Daniel Cheng <dcheng@chromium.org> Commit-Queue: Yue Li <updowndota@chromium.org> Cr-Commit-Position: refs/heads/main@{#984946}
- Loading branch information
Yue Li
authored and
Chromium LUCI CQ
committed
Mar 24, 2022
1 parent
e9e69a2
commit e378cf5
Showing
12 changed files
with
227 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
45 changes: 45 additions & 0 deletions
45
chromeos/components/quick_answers/public/cpp/service/spell_check_dictionary.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
// Copyright 2022 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/quick_answers/public/cpp/service/spell_check_dictionary.h" | ||
|
||
#include "base/files/memory_mapped_file.h" | ||
#include "base/logging.h" | ||
#include "third_party/hunspell/src/hunspell/hunspell.hxx" | ||
|
||
namespace quick_answers { | ||
|
||
SpellCheckDictionary::SpellCheckDictionary() = default; | ||
|
||
SpellCheckDictionary::~SpellCheckDictionary() = default; | ||
|
||
bool SpellCheckDictionary::Initialize(base::File file) { | ||
mapped_dict_file_ = std::make_unique<base::MemoryMappedFile>(); | ||
|
||
if (!mapped_dict_file_->Initialize(std::move(file))) { | ||
LOG(ERROR) << "Failed to mmap dictionary file."; | ||
return false; | ||
} | ||
|
||
if (!hunspell::BDict::Verify( | ||
reinterpret_cast<const char*>(mapped_dict_file_->data()), | ||
mapped_dict_file_->length())) { | ||
LOG(ERROR) << "Failed to verify dictionary file."; | ||
return false; | ||
} | ||
|
||
hunspell_ = std::make_unique<Hunspell>(mapped_dict_file_->data(), | ||
mapped_dict_file_->length()); | ||
|
||
return true; | ||
} | ||
|
||
void SpellCheckDictionary::CheckSpelling(const std::string& word, | ||
CheckSpellingCallback callback) { | ||
DCHECK(hunspell_); | ||
|
||
std::move(callback).Run(hunspell_->spell(word) != 0); | ||
} | ||
|
||
} // namespace quick_answers |
44 changes: 44 additions & 0 deletions
44
chromeos/components/quick_answers/public/cpp/service/spell_check_dictionary.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
// Copyright 2022 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_QUICK_ANSWERS_PUBLIC_CPP_SERVICE_SPELL_CHECK_DICTIONARY_H_ | ||
#define CHROMEOS_COMPONENTS_QUICK_ANSWERS_PUBLIC_CPP_SERVICE_SPELL_CHECK_DICTIONARY_H_ | ||
|
||
#include <memory> | ||
#include <string> | ||
|
||
#include "base/memory/weak_ptr.h" | ||
#include "chromeos/components/quick_answers/public/mojom/spell_check.mojom.h" | ||
|
||
class Hunspell; | ||
|
||
namespace base { | ||
class MemoryMappedFile; | ||
} // namespace base | ||
|
||
namespace quick_answers { | ||
|
||
// Utility class for spell check ran in renderer process. | ||
class SpellCheckDictionary : public mojom::SpellCheckDictionary { | ||
public: | ||
SpellCheckDictionary(); | ||
|
||
SpellCheckDictionary(const SpellCheckDictionary&) = delete; | ||
SpellCheckDictionary& operator=(const SpellCheckDictionary&) = delete; | ||
|
||
~SpellCheckDictionary() override; | ||
|
||
bool Initialize(base::File file); | ||
|
||
void CheckSpelling(const std::string& word, | ||
CheckSpellingCallback callback) override; | ||
|
||
private: | ||
std::unique_ptr<base::MemoryMappedFile> mapped_dict_file_; | ||
std::unique_ptr<Hunspell> hunspell_; | ||
}; | ||
|
||
} // namespace quick_answers | ||
|
||
#endif // CHROMEOS_COMPONENTS_QUICK_ANSWERS_PUBLIC_CPP_SERVICE_SPELL_CHECK_DICTIONARY_H_ |
33 changes: 33 additions & 0 deletions
33
chromeos/components/quick_answers/public/cpp/service/spell_check_service.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
// Copyright 2022 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/quick_answers/public/cpp/service/spell_check_service.h" | ||
|
||
#include "base/logging.h" | ||
#include "mojo/public/cpp/bindings/self_owned_receiver.h" | ||
|
||
namespace quick_answers { | ||
|
||
SpellCheckService::SpellCheckService( | ||
mojo::PendingReceiver<quick_answers::mojom::SpellCheckService> | ||
pending_receiver) | ||
: receiver_(this, std::move(pending_receiver)) {} | ||
|
||
SpellCheckService::~SpellCheckService() = default; | ||
|
||
void SpellCheckService::CreateDictionary(base::File file, | ||
CreateDictionaryCallback callback) { | ||
auto dictionary = std::make_unique<SpellCheckDictionary>(); | ||
if (!dictionary->Initialize(std::move(file))) { | ||
std::move(callback).Run(std::move(mojo::NullRemote())); | ||
return; | ||
} | ||
|
||
mojo::PendingRemote<mojom::SpellCheckDictionary> pending_remote; | ||
mojo::MakeSelfOwnedReceiver(std::move(dictionary), | ||
pending_remote.InitWithNewPipeAndPassReceiver()); | ||
std::move(callback).Run(std::move(pending_remote)); | ||
} | ||
|
||
} // namespace quick_answers |
41 changes: 41 additions & 0 deletions
41
chromeos/components/quick_answers/public/cpp/service/spell_check_service.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
// Copyright 2022 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_QUICK_ANSWERS_PUBLIC_CPP_SERVICE_SPELL_CHECK_SERVICE_H_ | ||
#define CHROMEOS_COMPONENTS_QUICK_ANSWERS_PUBLIC_CPP_SERVICE_SPELL_CHECK_SERVICE_H_ | ||
|
||
#include <memory> | ||
#include <string> | ||
|
||
#include "base/memory/weak_ptr.h" | ||
#include "chromeos/components/quick_answers/public/cpp/service/spell_check_dictionary.h" | ||
#include "chromeos/components/quick_answers/public/mojom/spell_check.mojom.h" | ||
#include "mojo/public/cpp/bindings/pending_receiver.h" | ||
#include "mojo/public/cpp/bindings/receiver.h" | ||
|
||
namespace quick_answers { | ||
|
||
// Utility class for spell check ran in renderer process. | ||
class SpellCheckService : public mojom::SpellCheckService { | ||
public: | ||
explicit SpellCheckService( | ||
mojo::PendingReceiver<mojom::SpellCheckService> pending_receiver); | ||
|
||
SpellCheckService(const SpellCheckService&) = delete; | ||
SpellCheckService& operator=(const SpellCheckService&) = delete; | ||
|
||
~SpellCheckService() override; | ||
|
||
void CreateDictionary(base::File file, | ||
CreateDictionaryCallback callback) override; | ||
|
||
private: | ||
std::unique_ptr<SpellCheckDictionary> dictionary_; | ||
|
||
mojo::Receiver<mojom::SpellCheckService> receiver_; | ||
}; | ||
|
||
} // namespace quick_answers | ||
|
||
#endif // CHROMEOS_COMPONENTS_QUICK_ANSWERS_PUBLIC_CPP_SERVICE_SPELL_CHECK_SERVICE_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
# Copyright 2022 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. | ||
|
||
import("//mojo/public/tools/bindings/mojom.gni") | ||
|
||
mojom("mojom") { | ||
sources = [ "spell_check.mojom" ] | ||
|
||
public_deps = [ | ||
"//mojo/public/mojom/base", | ||
"//sandbox/policy/mojom", | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
per-file *.mojom=set noparent | ||
per-file *.mojom=file://ipc/SECURITY_OWNERS |
29 changes: 29 additions & 0 deletions
29
chromeos/components/quick_answers/public/mojom/spell_check.mojom
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
// Copyright 2022 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 quick_answers.mojom; | ||
|
||
import "mojo/public/mojom/base/read_only_file.mojom"; | ||
import "sandbox/policy/mojom/sandbox.mojom"; | ||
|
||
// Provides a way to query hunspell in a sandboxed utility process, since | ||
// the inputs may be untrustworthy and hunspell library is somewhat prone | ||
// to crashes. | ||
[ServiceSandbox=sandbox.mojom.Sandbox.kService] | ||
interface SpellCheckService { | ||
// Creates a new SpellCheckerDictionary instance from |dictionary_file|. | ||
// If hunspell initialization failed, returns a null remote. | ||
// Can be called multiple times if the dictionary file changes or the | ||
// previous call did not success. | ||
CreateDictionary(mojo_base.mojom.ReadOnlyFile dictionary_file) | ||
=> (pending_remote<SpellCheckDictionary>? dictionary); | ||
}; | ||
|
||
// Handles spell check requests for a hunspell dictionary loaded via | ||
// |CreateDictionary()|. | ||
interface SpellCheckDictionary { | ||
// Check spelling of the given word, |correctness| is true if the word is | ||
// spelled correctly. | ||
CheckSpelling(string word) => (bool correctness); | ||
}; |