blob: 8f0107f50e1c47fbe034ff5c435ef9d7bf278ae9 [file] [log] [blame]
// Copyright 2018 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 "base/strings/utf_string_conversions.h"
#include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
#include "chrome/browser/chromeos/accessibility/dictation_chromeos.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "ui/base/ime/dummy_text_input_client.h"
#include "ui/base/ime/ime_bridge.h"
#include "ui/base/ime/input_method_base.h"
#include "ui/base/ime/mock_ime_input_context_handler.h"
namespace chromeos {
namespace {
const char kFirstSpeechResult[] = "help";
const char kSecondSpeechResult[] = "help oh";
const char kFinalSpeechResult[] = "hello world";
} // namespace
class DictationTest : public InProcessBrowserTest {
protected:
DictationTest() {
input_context_handler_.reset(new ui::MockIMEInputContextHandler());
empty_composition_text_ =
ui::MockIMEInputContextHandler::UpdateCompositionTextArg()
.composition_text;
}
~DictationTest() override = default;
void SetUpOnMainThread() override {
ui::IMEBridge::Get()->SetInputContextHandler(input_context_handler_.get());
}
AccessibilityManager* GetManager() { return AccessibilityManager::Get(); }
void EnableChromeVox() { GetManager()->EnableSpokenFeedback(true); }
void SendSpeechResult(const char* result, bool is_final) {
GetManager()->dictation_->OnSpeechResult(base::ASCIIToUTF16(result),
is_final);
}
void NotifyTextInputStateChanged(ui::TextInputClient* client) {
GetManager()->dictation_->OnTextInputStateChanged(client);
}
ui::CompositionText GetLastCompositionText() {
return input_context_handler_->last_update_composition_arg()
.composition_text;
}
std::unique_ptr<ui::MockIMEInputContextHandler> input_context_handler_;
ui::CompositionText empty_composition_text_;
};
IN_PROC_BROWSER_TEST_F(DictationTest, RecognitionEnds) {
AccessibilityManager* manager = GetManager();
manager->ToggleDictation();
EXPECT_EQ(GetLastCompositionText().text, empty_composition_text_.text);
SendSpeechResult(kFirstSpeechResult, false /* is_final */);
EXPECT_EQ(base::ASCIIToUTF16(kFirstSpeechResult),
GetLastCompositionText().text);
SendSpeechResult(kSecondSpeechResult, false /* is_final */);
EXPECT_EQ(base::ASCIIToUTF16(kSecondSpeechResult),
GetLastCompositionText().text);
SendSpeechResult(kFinalSpeechResult, true /* is_final */);
EXPECT_EQ(1, input_context_handler_->commit_text_call_count());
EXPECT_EQ(kFinalSpeechResult, input_context_handler_->last_commit_text());
}
IN_PROC_BROWSER_TEST_F(DictationTest, RecognitionEndsWithChromeVoxEnabled) {
AccessibilityManager* manager = GetManager();
EnableChromeVox();
EXPECT_TRUE(manager->IsSpokenFeedbackEnabled());
manager->ToggleDictation();
EXPECT_EQ(GetLastCompositionText().text, empty_composition_text_.text);
SendSpeechResult(kFirstSpeechResult, false /* is_final */);
EXPECT_EQ(GetLastCompositionText().text, empty_composition_text_.text);
SendSpeechResult(kSecondSpeechResult, false /* is_final */);
EXPECT_EQ(GetLastCompositionText().text, empty_composition_text_.text);
SendSpeechResult(kFinalSpeechResult, true /* is_final */);
EXPECT_EQ(1, input_context_handler_->commit_text_call_count());
EXPECT_EQ(kFinalSpeechResult, input_context_handler_->last_commit_text());
}
IN_PROC_BROWSER_TEST_F(DictationTest, UserEndsDictation) {
AccessibilityManager* manager = GetManager();
manager->ToggleDictation();
EXPECT_EQ(GetLastCompositionText().text, empty_composition_text_.text);
SendSpeechResult(kFinalSpeechResult, false /* is_final */);
EXPECT_EQ(base::ASCIIToUTF16(kFinalSpeechResult),
GetLastCompositionText().text);
manager->ToggleDictation();
EXPECT_EQ(1, input_context_handler_->commit_text_call_count());
EXPECT_EQ(kFinalSpeechResult, input_context_handler_->last_commit_text());
}
IN_PROC_BROWSER_TEST_F(DictationTest, UserEndsDictationWhenChromeVoxEnabled) {
AccessibilityManager* manager = GetManager();
EnableChromeVox();
EXPECT_TRUE(manager->IsSpokenFeedbackEnabled());
manager->ToggleDictation();
EXPECT_EQ(GetLastCompositionText().text, empty_composition_text_.text);
SendSpeechResult(kFinalSpeechResult, false /* is_final */);
EXPECT_EQ(GetLastCompositionText().text, empty_composition_text_.text);
manager->ToggleDictation();
EXPECT_EQ(1, input_context_handler_->commit_text_call_count());
EXPECT_EQ(kFinalSpeechResult, input_context_handler_->last_commit_text());
}
IN_PROC_BROWSER_TEST_F(DictationTest, SwitchInputContext) {
// Turn on dictation and say something.
AccessibilityManager::Get()->ToggleDictation();
SendSpeechResult(kFirstSpeechResult, true /* is_final */);
// Speech goes to the default IMEInputContextHandler.
EXPECT_EQ(kFirstSpeechResult, input_context_handler_->last_commit_text());
// Simulate a remote app instantiating a new IMEInputContextHandler, like the
// keyboard shortcut viewer app creating a second InputMethodChromeOS.
ui::MockIMEInputContextHandler input_context_handler2;
ui::IMEBridge::Get()->SetInputContextHandler(&input_context_handler2);
// Turn on dictation and say something else.
AccessibilityManager::Get()->ToggleDictation();
SendSpeechResult(kSecondSpeechResult, true /* is_final */);
// Speech goes to the new IMEInputContextHandler.
EXPECT_EQ(kSecondSpeechResult, input_context_handler2.last_commit_text());
ui::IMEBridge::Get()->SetInputContextHandler(nullptr);
}
IN_PROC_BROWSER_TEST_F(DictationTest, ChangeInputField) {
// Turn on dictation and start speaking.
AccessibilityManager::Get()->ToggleDictation();
SendSpeechResult(kFinalSpeechResult, false /* is_final */);
// Change the input state to a new client.
std::unique_ptr<ui::TextInputClient> new_client =
std::make_unique<ui::DummyTextInputClient>();
NotifyTextInputStateChanged(new_client.get());
// Check that dictation has turned off.
EXPECT_EQ(1, input_context_handler_->commit_text_call_count());
EXPECT_EQ(kFinalSpeechResult, input_context_handler_->last_commit_text());
}
} // namespace chromeos