Commit c1608dd3 authored by My Nguyen's avatar My Nguyen Committed by Commit Bot

Add Assistive.Match for emoji suggestions

This allows for tracking the opportunity for emoji suggestions.

Bug: 1108251
Change-Id: Iffbf3b52f0abcde442e203a63c634e710765c6da
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2318487
Commit-Queue: My Nguyen <myy@chromium.org>
Reviewed-by: default avatarKeith Lee <keithlee@chromium.org>
Cr-Commit-Position: refs/heads/master@{#792164}
parent e10f1283
......@@ -269,6 +269,13 @@ bool AssistiveSuggester::OnKeyEvent(
return false;
}
void AssistiveSuggester::RecordAssistiveMatchMetricsForAction(
AssistiveType action) {
RecordAssistiveMatch(action);
if (!IsActionEnabled(action))
RecordAssistiveDisabled(action);
}
void AssistiveSuggester::RecordAssistiveMatchMetrics(const base::string16& text,
int cursor_pos,
int anchor_pos) {
......@@ -278,11 +285,14 @@ void AssistiveSuggester::RecordAssistiveMatchMetrics(const base::string16& text,
int start_pos = std::max(0, cursor_pos - kMaxTextBeforeCursorLength);
base::string16 text_before_cursor =
text.substr(start_pos, cursor_pos - start_pos);
AssistiveType action = ProposeAssistiveAction(text_before_cursor);
// Personal info suggestion match
AssistiveType action =
ProposePersonalInfoAssistiveAction(text_before_cursor);
if (action != AssistiveType::kGenericAction) {
RecordAssistiveMatch(action);
if (!IsActionEnabled(action))
RecordAssistiveDisabled(action);
RecordAssistiveMatchMetricsForAction(action);
// Emoji suggestion match
} else if (emoji_suggester_.ShouldShowSuggestion(text_before_cursor)) {
RecordAssistiveMatchMetricsForAction(AssistiveType::kEmoji);
}
}
}
......
......@@ -50,6 +50,10 @@ class AssistiveSuggester {
// Accepts the suggestion at a given index if a suggester is currently active.
void AcceptSuggestion(size_t index);
EmojiSuggester* get_emoji_suggester_for_testing() {
return &emoji_suggester_;
}
private:
// Returns if any suggestion text should be displayed according to the
// surrounding text information.
......@@ -64,6 +68,8 @@ class AssistiveSuggester {
bool IsEmojiSuggestAdditionEnabled();
void RecordAssistiveMatchMetricsForAction(AssistiveType action);
bool IsActionEnabled(AssistiveType action);
Profile* profile_;
......
......@@ -188,6 +188,18 @@ SuggestionStatus EmojiSuggester::HandleKeyEvent(
return SuggestionStatus::kNotHandled;
}
bool EmojiSuggester::ShouldShowSuggestion(const base::string16& text) {
if (text[text.length() - 1] != kSpaceChar)
return false;
std::string last_word =
base::ToLowerASCII(GetLastWord(base::UTF16ToUTF8(text)));
if (!last_word.empty() && emoji_map_.count(last_word)) {
return true;
}
return false;
}
bool EmojiSuggester::Suggest(const base::string16& text) {
if (emoji_map_.empty() || text[text.length() - 1] != kSpaceChar)
return false;
......
......@@ -36,6 +36,8 @@ class EmojiSuggester : public Suggester {
void DismissSuggestion() override;
AssistiveType GetProposeActionType() override;
bool ShouldShowSuggestion(const base::string16& text);
void LoadEmojiMapForTesting(const std::string& emoji_data);
bool GetSuggestionShownForTesting() const;
size_t GetCandidatesSizeForTesting() const;
......
......@@ -72,6 +72,7 @@ void NativeInputMethodEngine::Initialize(
std::make_unique<AssistiveSuggester>(this, profile);
// Wrap the given observer in our observer that will decide whether to call
// Mojo directly or forward to the extension.
assistive_suggester_ = assistive_suggester.get();
auto native_observer =
std::make_unique<chromeos::NativeInputMethodEngine::ImeObserver>(
std::move(observer), std::move(assistive_suggester));
......
......@@ -42,6 +42,10 @@ class NativeInputMethodEngine : public InputMethodEngine {
// Returns whether this is connected to the input engine.
bool IsConnectedForTesting() const;
AssistiveSuggester* get_assistive_suggester_for_testing() {
return assistive_suggester_;
}
private:
class ImeObserver : public InputMethodEngineBase::Observer,
public ime::mojom::InputChannel {
......@@ -125,6 +129,7 @@ class NativeInputMethodEngine : public InputMethodEngine {
};
ImeObserver* GetNativeObserver() const;
AssistiveSuggester* assistive_suggester_;
};
} // namespace chromeos
......
......@@ -45,6 +45,8 @@ using chromeos::InputMethodEngineBase;
namespace {
constexpr char kEmojiData[] = "happy,😀;😃;😄";
class TestObserver : public InputMethodEngineBase::Observer {
public:
TestObserver() = default;
......@@ -136,7 +138,8 @@ class NativeInputMethodEngineTest : public InProcessBrowserTest,
public:
NativeInputMethodEngineTest() : input_method_(this) {
feature_list_.InitWithFeatures({chromeos::features::kNativeRuleBasedTyping,
chromeos::features::kAssistPersonalInfo},
chromeos::features::kAssistPersonalInfo,
chromeos::features::kEmojiSuggestAddition},
{});
}
......@@ -160,6 +163,9 @@ class NativeInputMethodEngineTest : public InProcessBrowserTest,
prefs_->Set(prefs::kLanguageInputMethodSpecificSettings,
base::DictionaryValue());
engine_.Initialize(std::move(observer), "", profile_);
engine_.get_assistive_suggester_for_testing()
->get_emoji_suggester_for_testing()
->LoadEmojiMapForTesting(kEmojiData);
InProcessBrowserTest::SetUpOnMainThread();
}
......@@ -442,6 +448,32 @@ IN_PROC_BROWSER_TEST_F(NativeInputMethodEngineTest, SuggestUserName) {
SetFocus(nullptr);
}
IN_PROC_BROWSER_TEST_F(NativeInputMethodEngineTest, SuggestEmoji) {
base::HistogramTester histogram_tester;
engine_.Enable(kEngineIdUs);
chromeos::TextInputTestHelper helper(GetBrowserInputMethod());
SetUpTextInput(helper);
const base::string16 prefix_text = base::UTF8ToUTF16("happy ");
const base::string16 expected_result_text = base::UTF8ToUTF16("happy 😀");
helper.GetTextInputClient()->InsertText(prefix_text);
helper.WaitForSurroundingTextChanged(prefix_text);
// Selects first emoji.
DispatchKeyPress(ui::VKEY_DOWN, false);
DispatchKeyPress(ui::VKEY_RETURN, false);
helper.WaitForSurroundingTextChanged(expected_result_text);
EXPECT_EQ(expected_result_text, helper.GetSurroundingText());
histogram_tester.ExpectUniqueSample("InputMethod.Assistive.Match",
chromeos::AssistiveType::kEmoji, 1);
histogram_tester.ExpectUniqueSample("InputMethod.Assistive.Coverage",
chromeos::AssistiveType::kEmoji, 1);
histogram_tester.ExpectUniqueSample("InputMethod.Assistive.Success",
chromeos::AssistiveType::kEmoji, 1);
SetFocus(nullptr);
}
IN_PROC_BROWSER_TEST_F(
NativeInputMethodEngineTest,
OnLearnMoreButtonClickedOpensEmojiSuggestionSettingsPage) {
......
......@@ -95,7 +95,7 @@ void TtsHandler::Speak(const std::string& text) {
tts_controller->SpeakOrEnqueue(std::move(utterance));
}
AssistiveType ProposeAssistiveAction(const base::string16& text) {
AssistiveType ProposePersonalInfoAssistiveAction(const base::string16& text) {
AssistiveType action = AssistiveType::kGenericAction;
if (base::EndsWith(text, base::UTF8ToUTF16(kAssistEmailPrefix),
base::CompareCase::INSENSITIVE_ASCII)) {
......@@ -234,7 +234,7 @@ bool PersonalInfoSuggester::Suggest(const base::string16& text) {
base::string16 PersonalInfoSuggester::GetSuggestion(
const base::string16& text) {
proposed_action_type_ = ProposeAssistiveAction(text);
proposed_action_type_ = ProposePersonalInfoAssistiveAction(text);
if (proposed_action_type_ == AssistiveType::kGenericAction)
return base::EmptyString16();
......
......@@ -30,7 +30,7 @@ const char kPersonalInfoSuggesterShowSettingCount[] =
"personal_info_suggester_show_setting_count";
const int kMaxShowSettingCount = 10;
AssistiveType ProposeAssistiveAction(const base::string16& text);
AssistiveType ProposePersonalInfoAssistiveAction(const base::string16& text);
class TtsHandler : public content::UtteranceEventDelegate {
public:
......
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